1 /* SPDX-License-Identifier: BSD-3-Clause 2 * Copyright(c) 2020 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 "obj.h" 18 #include "thread.h" 19 20 static const char usage[] = 21 "%s EAL_ARGS -- [-h HOST] [-p PORT] [-s SCRIPT]\n"; 22 23 static struct app_params { 24 struct conn_params conn; 25 char *script_name; 26 } app = { 27 .conn = { 28 .welcome = "\nWelcome!\n\n", 29 .prompt = "pipeline> ", 30 .addr = "0.0.0.0", 31 .port = 8086, 32 .buf_size = 1024 * 1024, 33 .msg_in_len_max = 1024, 34 .msg_out_len_max = 1024 * 1024, 35 .msg_handle = cli_process, 36 .msg_handle_arg = NULL, /* set later. */ 37 }, 38 .script_name = NULL, 39 }; 40 41 static int 42 parse_args(int argc, char **argv) 43 { 44 char *app_name = argv[0]; 45 struct option lgopts[] = { 46 { NULL, 0, 0, 0 } 47 }; 48 int opt, option_index; 49 int h_present, p_present, s_present, n_args, i; 50 51 /* Skip EAL input args */ 52 n_args = argc; 53 for (i = 0; i < n_args; i++) 54 if (strcmp(argv[i], "--") == 0) { 55 argc -= i; 56 argv += i; 57 break; 58 } 59 60 if (i == n_args) 61 return 0; 62 63 /* Parse args */ 64 h_present = 0; 65 p_present = 0; 66 s_present = 0; 67 68 while ((opt = getopt_long(argc, argv, "h:p:s:", lgopts, &option_index)) 69 != EOF) 70 switch (opt) { 71 case 'h': 72 if (h_present) { 73 printf("Error: Multiple -h arguments\n"); 74 return -1; 75 } 76 h_present = 1; 77 78 if (!strlen(optarg)) { 79 printf("Error: Argument for -h not provided\n"); 80 return -1; 81 } 82 83 app.conn.addr = strdup(optarg); 84 if (app.conn.addr == NULL) { 85 printf("Error: Not enough memory\n"); 86 return -1; 87 } 88 break; 89 90 case 'p': 91 if (p_present) { 92 printf("Error: Multiple -p arguments\n"); 93 return -1; 94 } 95 p_present = 1; 96 97 if (!strlen(optarg)) { 98 printf("Error: Argument for -p not provided\n"); 99 return -1; 100 } 101 102 app.conn.port = (uint16_t) atoi(optarg); 103 break; 104 105 case 's': 106 if (s_present) { 107 printf("Error: Multiple -s arguments\n"); 108 return -1; 109 } 110 s_present = 1; 111 112 if (!strlen(optarg)) { 113 printf("Error: Argument for -s not provided\n"); 114 return -1; 115 } 116 117 app.script_name = strdup(optarg); 118 if (app.script_name == NULL) { 119 printf("Error: Not enough memory\n"); 120 return -1; 121 } 122 break; 123 124 default: 125 printf(usage, app_name); 126 return -1; 127 } 128 129 optind = 1; /* reset getopt lib */ 130 131 return 0; 132 } 133 134 int 135 main(int argc, char **argv) 136 { 137 struct conn *conn; 138 int status; 139 140 /* Parse application arguments */ 141 status = parse_args(argc, argv); 142 if (status < 0) 143 return status; 144 145 /* EAL */ 146 status = rte_eal_init(argc, argv); 147 if (status < 0) { 148 printf("Error: EAL initialization failed (%d)\n", status); 149 return status; 150 }; 151 152 /* Thread */ 153 status = thread_init(); 154 if (status) { 155 printf("Error: Thread initialization failed (%d)\n", status); 156 return status; 157 } 158 159 rte_eal_mp_remote_launch( 160 thread_main, 161 NULL, 162 SKIP_MAIN); 163 164 /* Script */ 165 if (app.script_name) 166 cli_script_process(app.script_name, 167 app.conn.msg_in_len_max, 168 app.conn.msg_out_len_max, 169 NULL); 170 171 /* Connectivity */ 172 app.conn.msg_handle_arg = NULL; 173 conn = conn_init(&app.conn); 174 if (!conn) { 175 printf("Error: Connectivity initialization failed (%d)\n", 176 status); 177 return status; 178 }; 179 180 /* Dispatch loop */ 181 for ( ; ; ) { 182 conn_poll_for_conn(conn); 183 184 conn_poll_for_msg(conn); 185 } 186 187 /* clean up the EAL */ 188 rte_eal_cleanup(); 189 } 190