1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2010-2018 Intel Corporation 3 */ 4 5 #include <stdio.h> 6 #include <stdlib.h> 7 #include <string.h> 8 #include <fcntl.h> 9 #include <unistd.h> 10 #include <getopt.h> 11 12 #include <rte_launch.h> 13 #include <rte_eal.h> 14 15 #include "cli.h" 16 #include "conn.h" 17 #include "kni.h" 18 #include "cryptodev.h" 19 #include "link.h" 20 #include "mempool.h" 21 #include "pipeline.h" 22 #include "swq.h" 23 #include "tap.h" 24 #include "thread.h" 25 #include "tmgr.h" 26 27 static const char usage[] = 28 "%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n"; 29 30 static const char welcome[] = 31 "\n" 32 "Welcome to IP Pipeline!\n" 33 "\n"; 34 35 static const char prompt[] = "pipeline> "; 36 37 static struct app_params { 38 struct conn_params conn; 39 char *script_name; 40 } app = { 41 .conn = { 42 .welcome = welcome, 43 .prompt = prompt, 44 .addr = "0.0.0.0", 45 .port = 8086, 46 .buf_size = 1024 * 1024, 47 .msg_in_len_max = 1024, 48 .msg_out_len_max = 1024 * 1024, 49 .msg_handle = cli_process, 50 }, 51 .script_name = NULL, 52 }; 53 54 static int 55 parse_args(int argc, char **argv) 56 { 57 char *app_name = argv[0]; 58 struct option lgopts[] = { 59 { NULL, 0, 0, 0 } 60 }; 61 int opt, option_index; 62 int h_present, p_present, s_present, n_args, i; 63 64 /* Skip EAL input args */ 65 n_args = argc; 66 for (i = 0; i < n_args; i++) 67 if (strcmp(argv[i], "--") == 0) { 68 argc -= i; 69 argv += i; 70 break; 71 } 72 73 if (i == n_args) 74 return 0; 75 76 /* Parse args */ 77 h_present = 0; 78 p_present = 0; 79 s_present = 0; 80 81 while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index)) 82 != EOF) 83 switch (opt) { 84 case 'h': 85 if (h_present) { 86 printf("Error: Multiple -h arguments\n"); 87 return -1; 88 } 89 h_present = 1; 90 91 if (!strlen(optarg)) { 92 printf("Error: Argument for -h not provided\n"); 93 return -1; 94 } 95 96 app.conn.addr = strdup(optarg); 97 if (app.conn.addr == NULL) { 98 printf("Error: Not enough memory\n"); 99 return -1; 100 } 101 break; 102 103 case 'p': 104 if (p_present) { 105 printf("Error: Multiple -p arguments\n"); 106 return -1; 107 } 108 p_present = 1; 109 110 if (!strlen(optarg)) { 111 printf("Error: Argument for -p not provided\n"); 112 return -1; 113 } 114 115 app.conn.port = (uint16_t) atoi(optarg); 116 break; 117 118 case 's': 119 if (s_present) { 120 printf("Error: Multiple -s arguments\n"); 121 return -1; 122 } 123 s_present = 1; 124 125 if (!strlen(optarg)) { 126 printf("Error: Argument for -s not provided\n"); 127 return -1; 128 } 129 130 app.script_name = strdup(optarg); 131 if (app.script_name == NULL) { 132 printf("Error: Not enough memory\n"); 133 return -1; 134 } 135 break; 136 137 default: 138 printf(usage, app_name); 139 return -1; 140 } 141 142 optind = 1; /* reset getopt lib */ 143 144 return 0; 145 } 146 147 int 148 main(int argc, char **argv) 149 { 150 struct conn *conn; 151 int status; 152 153 /* Parse application arguments */ 154 status = parse_args(argc, argv); 155 if (status < 0) 156 return status; 157 158 /* EAL */ 159 status = rte_eal_init(argc, argv); 160 if (status < 0) { 161 printf("Error: EAL initialization failed (%d)\n", status); 162 return status; 163 }; 164 165 /* Connectivity */ 166 conn = conn_init(&app.conn); 167 if (conn == NULL) { 168 printf("Error: Connectivity initialization failed (%d)\n", 169 status); 170 return status; 171 }; 172 173 /* Mempool */ 174 status = mempool_init(); 175 if (status) { 176 printf("Error: Mempool initialization failed (%d)\n", status); 177 return status; 178 } 179 180 /* Link */ 181 status = link_init(); 182 if (status) { 183 printf("Error: Link initialization failed (%d)\n", status); 184 return status; 185 } 186 187 /* SWQ */ 188 status = swq_init(); 189 if (status) { 190 printf("Error: SWQ initialization failed (%d)\n", status); 191 return status; 192 } 193 194 /* Traffic Manager */ 195 status = tmgr_init(); 196 if (status) { 197 printf("Error: TMGR initialization failed (%d)\n", status); 198 return status; 199 } 200 201 /* TAP */ 202 status = tap_init(); 203 if (status) { 204 printf("Error: TAP initialization failed (%d)\n", status); 205 return status; 206 } 207 208 /* KNI */ 209 status = kni_init(); 210 if (status) { 211 printf("Error: KNI initialization failed (%d)\n", status); 212 return status; 213 } 214 215 /* Sym Crypto */ 216 status = cryptodev_init(); 217 if (status) { 218 printf("Error: Cryptodev initialization failed (%d)\n", 219 status); 220 return status; 221 } 222 223 /* Action */ 224 status = port_in_action_profile_init(); 225 if (status) { 226 printf("Error: Input port action profile initialization failed (%d)\n", status); 227 return status; 228 } 229 230 status = table_action_profile_init(); 231 if (status) { 232 printf("Error: Action profile initialization failed (%d)\n", 233 status); 234 return status; 235 } 236 237 /* Pipeline */ 238 status = pipeline_init(); 239 if (status) { 240 printf("Error: Pipeline initialization failed (%d)\n", status); 241 return status; 242 } 243 244 /* Thread */ 245 status = thread_init(); 246 if (status) { 247 printf("Error: Thread initialization failed (%d)\n", status); 248 return status; 249 } 250 251 rte_eal_mp_remote_launch( 252 thread_main, 253 NULL, 254 SKIP_MAIN); 255 256 /* Script */ 257 if (app.script_name) 258 cli_script_process(app.script_name, 259 app.conn.msg_in_len_max, 260 app.conn.msg_out_len_max); 261 262 /* Dispatch loop */ 263 for ( ; ; ) { 264 conn_poll_for_conn(conn); 265 266 conn_poll_for_msg(conn); 267 268 kni_handle_request(); 269 } 270 } 271