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