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