Branch data Line data Source code
1 : : /* SPDX-License-Identifier: BSD-3-Clause
2 : : * Copyright(c) 2010-2017 Intel Corporation
3 : : */
4 : :
5 : : #include <errno.h>
6 : : #include <getopt.h>
7 : : #include <stdarg.h>
8 : : #include <stdio.h>
9 : : #include <stdlib.h>
10 : : #include <signal.h>
11 : : #include <string.h>
12 : : #include <time.h>
13 : : #include <fcntl.h>
14 : : #include <sys/types.h>
15 : :
16 : : #include <sys/queue.h>
17 : : #include <sys/stat.h>
18 : :
19 : : #include <stdint.h>
20 : : #include <unistd.h>
21 : : #include <inttypes.h>
22 : :
23 : : #include <rte_common.h>
24 : : #include <rte_byteorder.h>
25 : : #include <rte_log.h>
26 : : #include <rte_debug.h>
27 : : #include <rte_cycles.h>
28 : : #include <rte_memory.h>
29 : : #include <rte_launch.h>
30 : : #include <rte_eal.h>
31 : : #include <rte_per_lcore.h>
32 : : #include <rte_lcore.h>
33 : : #include <rte_branch_prediction.h>
34 : : #include <rte_mempool.h>
35 : : #include <rte_interrupts.h>
36 : : #include <rte_ether.h>
37 : : #include <rte_ethdev.h>
38 : : #include <rte_string_fns.h>
39 : : #include <rte_flow.h>
40 : :
41 : : #include "testpmd.h"
42 : :
43 : : static void
44 : 0 : usage(char* progname)
45 : : {
46 : : printf("\nUsage: %s [EAL options] -- [testpmd options]\n\n",
47 : : progname);
48 : : #ifdef RTE_LIB_CMDLINE
49 : : printf(" --interactive: run in interactive mode.\n");
50 : : printf(" --cmdline-file: execute cli commands before startup.\n");
51 : : #endif
52 : : printf(" --auto-start: start forwarding on init "
53 : : "[always when non-interactive].\n");
54 : : printf(" --help: display this message and quit.\n");
55 : : printf(" --tx-first: start forwarding sending a burst first "
56 : : "(only if interactive is disabled).\n");
57 : : printf(" --stats-period=PERIOD: statistics will be shown "
58 : : "every PERIOD seconds (only if interactive is disabled).\n");
59 : : printf(" --display-xstats xstat_name1[,...]: comma-separated list of "
60 : : "extended statistics to show. Used with --stats-period "
61 : : "specified or interactive commands that show Rx/Tx statistics "
62 : : "(i.e. 'show port stats').\n");
63 : : printf(" --num-procs=N: set the total number of multi-process instances.\n");
64 : : printf(" --proc-id=id: set the id of the current process from "
65 : : "multi-process instances (0 <= id < num-procs).\n");
66 : 0 : printf(" --nb-cores=N: set the number of forwarding cores "
67 : : "(1 <= N <= %d).\n", nb_lcores);
68 : 0 : printf(" --nb-ports=N: set the number of forwarding ports "
69 : : "(1 <= N <= %d).\n", nb_ports);
70 : : printf(" --coremask=COREMASK: hexadecimal bitmask of cores running "
71 : : "the packet forwarding test. The main lcore is reserved for "
72 : : "command line parsing only, and cannot be masked on for "
73 : : "packet forwarding.\n");
74 : : printf(" --portmask=PORTMASK: hexadecimal bitmask of ports used "
75 : : "by the packet forwarding test.\n");
76 : : printf(" --portlist=PORTLIST: list of forwarding ports\n");
77 : : printf(" --numa: enable NUMA-aware allocation of RX/TX rings and of "
78 : : "RX memory buffers (mbufs).\n");
79 : : printf(" --no-numa: disable NUMA-aware allocation.\n");
80 : : printf(" --port-numa-config=(port,socket)[,(port,socket)]: "
81 : : "specify the socket on which the memory pool "
82 : : "used by the port will be allocated.\n");
83 : : printf(" --ring-numa-config=(port,flag,socket)[,(port,flag,socket)]: "
84 : : "specify the socket on which the TX/RX rings for "
85 : : "the port will be allocated "
86 : : "(flag: 1 for RX; 2 for TX; 3 for RX and TX).\n");
87 : : printf(" --socket-num=N: set socket from which all memory is allocated "
88 : : "in NUMA mode.\n");
89 : : printf(" --mbuf-size=N,[N1[,..Nn]: set the data size of mbuf to "
90 : : "N bytes. If multiple numbers are specified the extra pools "
91 : : "will be created to receive packets based on the features "
92 : : "supported, like packet split, multi-rx-mempool.\n");
93 : : printf(" --total-num-mbufs=N: set the number of mbufs to be allocated "
94 : : "in mbuf pools.\n");
95 : : printf(" --max-pkt-len=N: set the maximum size of packet to N bytes.\n");
96 : : printf(" --max-lro-pkt-size=N: set the maximum LRO aggregated packet "
97 : : "size to N bytes.\n");
98 : : #ifdef RTE_LIB_CMDLINE
99 : : printf(" --eth-peers-configfile=name: config file with ethernet addresses "
100 : : "of peer ports.\n");
101 : : printf(" --eth-peer=X,M:M:M:M:M:M: set the MAC address of the X peer "
102 : : "port (0 <= X < %d).\n", RTE_MAX_ETHPORTS);
103 : : #endif
104 : : printf(" --disable-crc-strip: disable CRC stripping by hardware.\n");
105 : : printf(" --enable-scatter: enable scattered Rx.\n");
106 : : printf(" --enable-lro: enable large receive offload.\n");
107 : : printf(" --enable-rx-cksum: enable rx hardware checksum offload.\n");
108 : : printf(" --enable-rx-timestamp: enable rx hardware timestamp offload.\n");
109 : : printf(" --enable-hw-vlan: enable hardware vlan.\n");
110 : : printf(" --enable-hw-vlan-filter: enable hardware vlan filter.\n");
111 : : printf(" --enable-hw-vlan-strip: enable hardware vlan strip.\n");
112 : : printf(" --enable-hw-vlan-extend: enable hardware vlan extend.\n");
113 : : printf(" --enable-hw-qinq-strip: enable hardware qinq strip.\n");
114 : : printf(" --enable-drop-en: enable per queue packet drop.\n");
115 : : printf(" --disable-rss: disable rss.\n");
116 : : printf(" --port-topology=<paired|chained|loop>: set port topology (paired "
117 : : "is default).\n");
118 : 0 : printf(" --forward-mode=N: set forwarding mode (N: %s).\n",
119 : : list_pkt_forwarding_modes());
120 : : printf(" --forward-mode=5tswap: set forwarding mode to "
121 : : "swap L2,L3,L4 for MAC, IPv4/IPv6 and TCP/UDP only.\n");
122 : : printf(" --rss-ip: set RSS functions to IPv4/IPv6 only .\n");
123 : : printf(" --rss-udp: set RSS functions to IPv4/IPv6 + UDP.\n");
124 : : printf(" --rss-level-inner: set RSS hash level to innermost\n");
125 : : printf(" --rss-level-outer: set RSS hash level to outermost\n");
126 : : printf(" --rxq=N: set the number of RX queues per port to N.\n");
127 : : printf(" --rxd=N: set the number of descriptors in RX rings to N.\n");
128 : : printf(" --txq=N: set the number of TX queues per port to N.\n");
129 : : printf(" --txd=N: set the number of descriptors in TX rings to N.\n");
130 : : printf(" --hairpinq=N: set the number of hairpin queues per port to "
131 : : "N.\n");
132 : : printf(" --burst=N: set the number of packets per burst to N.\n");
133 : : printf(" --flowgen-clones=N: set the number of single packet clones to send in flowgen mode. Should be less than burst value.\n");
134 : : printf(" --flowgen-flows=N: set the number of flows in flowgen mode to N (1 <= N <= INT32_MAX).\n");
135 : : printf(" --mbcache=N: set the cache of mbuf memory pool to N.\n");
136 : : printf(" --rxpt=N: set prefetch threshold register of RX rings to N.\n");
137 : : printf(" --rxht=N: set the host threshold register of RX rings to N.\n");
138 : : printf(" --rxfreet=N: set the free threshold of RX descriptors to N "
139 : : "(0 <= N < value of rxd).\n");
140 : : printf(" --rxwt=N: set the write-back threshold register of RX rings to N.\n");
141 : : printf(" --txpt=N: set the prefetch threshold register of TX rings to N.\n");
142 : : printf(" --txht=N: set the nhost threshold register of TX rings to N.\n");
143 : : printf(" --txwt=N: set the write-back threshold register of TX rings to N.\n");
144 : : printf(" --txfreet=N: set the transmit free threshold of TX rings to N "
145 : : "(0 <= N <= value of txd).\n");
146 : : printf(" --txrst=N: set the transmit RS bit threshold of TX rings to N "
147 : : "(0 <= N <= value of txd).\n");
148 : : printf(" --no-flush-rx: Don't flush RX streams before forwarding."
149 : : " Used mainly with PCAP drivers.\n");
150 : : printf(" --rxoffs=X[,Y]*: set RX segment offsets for split.\n");
151 : : printf(" --rxpkts=X[,Y]*: set RX segment sizes to split.\n");
152 : : printf(" --rxhdrs=eth[,ipv4]*: set RX segment protocol to split.\n");
153 : : printf(" --txpkts=X[,Y]*: set TX segment sizes"
154 : : " or total packet length.\n");
155 : : printf(" --multi-rx-mempool: enable multi-rx-mempool support\n");
156 : : printf(" --txonly-multi-flow: generate multiple flows in txonly mode\n");
157 : : printf(" --tx-ip=src,dst: IP addresses in Tx-only mode\n");
158 : : printf(" --tx-udp=src[,dst]: UDP ports in Tx-only mode\n");
159 : : printf(" --eth-link-speed: force link speed.\n");
160 : : printf(" --rxq-share=X: number of ports per shared Rx queue groups, defaults to UINT32_MAX (1 group)\n");
161 : : printf(" --disable-link-check: disable check on link status when "
162 : : "starting/stopping ports.\n");
163 : : printf(" --disable-device-start: do not automatically start port\n");
164 : : printf(" --no-lsc-interrupt: disable link status change interrupt.\n");
165 : : printf(" --no-rmv-interrupt: disable device removal interrupt.\n");
166 : : #ifdef RTE_LIB_BITRATESTATS
167 : : printf(" --bitrate-stats=N: set the logical core N to perform "
168 : : "bit-rate calculation.\n");
169 : : #endif
170 : : #ifdef RTE_LIB_LATENCYSTATS
171 : : printf(" --latencystats=N: enable latency and jitter statistics "
172 : : "monitoring on forwarding lcore id N.\n");
173 : : #endif
174 : : printf(" --print-event <unknown|intr_lsc|queue_state|intr_reset|vf_mbox|macsec|intr_rmv|flow_aged|err_recovering|recovery_success|recovery_failed|all>: "
175 : : "enable print of designated event or all of them.\n");
176 : : printf(" --mask-event <unknown|intr_lsc|queue_state|intr_reset|vf_mbox|macsec|intr_rmv|flow_aged|err_recovering|recovery_success|recovery_failed||all>: "
177 : : "disable print of designated event or all of them.\n");
178 : : printf(" --flow-isolate-all: "
179 : : "requests flow API isolated mode on all ports at initialization time.\n");
180 : : printf(" --disable-flow-flush: disable port flow flush when stop port.\n");
181 : : printf(" --tx-offloads=0xXXXXXXXX: hexadecimal bitmask of TX queue offloads\n");
182 : : printf(" --rx-offloads=0xXXXXXXXX: hexadecimal bitmask of RX queue offloads\n");
183 : : printf(" --hot-plug: enable hot plug for device.\n");
184 : : printf(" --vxlan-gpe-port=N: UPD port of tunnel VXLAN-GPE\n");
185 : : printf(" --geneve-parsed-port=N: UPD port to parse GENEVE tunnel protocol\n");
186 : : #ifndef RTE_EXEC_ENV_WINDOWS
187 : : printf(" --mlockall: lock all memory\n");
188 : : printf(" --no-mlockall: do not lock all memory\n");
189 : : #endif
190 : : printf(" --mp-alloc <native|anon|xmem|xmemhuge>: mempool allocation method.\n"
191 : : " native: use regular DPDK memory to create and populate mempool\n"
192 : : " anon: use regular DPDK memory to create and anonymous memory to populate mempool\n"
193 : : " xmem: use anonymous memory to create and populate mempool\n"
194 : : " xmemhuge: use anonymous hugepage memory to create and populate mempool\n");
195 : : printf(" --noisy-forward-mode=<io|mac|macswap|5tswap>: set the sub-fwd mode, defaults to io\n");
196 : : printf(" --noisy-tx-sw-buffer-size=N: size of FIFO buffer\n");
197 : : printf(" --noisy-tx-sw-buffer-flushtime=N: flush FIFO after N ms\n");
198 : : printf(" --noisy-lkup-memory=N: allocate N MB of VNF memory\n");
199 : : printf(" --noisy-lkup-num-writes=N: do N random writes per packet\n");
200 : : printf(" --noisy-lkup-num-reads=N: do N random reads per packet\n");
201 : : printf(" --noisy-lkup-num-reads-writes=N: do N random reads and writes per packet\n");
202 : : printf(" --no-iova-contig: mempool memory can be IOVA non contiguous. "
203 : : "valid only with --mp-alloc=anon\n");
204 : : printf(" --rx-mq-mode=0xX: hexadecimal bitmask of RX mq mode can be "
205 : : "enabled\n");
206 : : printf(" --record-core-cycles: enable measurement of CPU cycles.\n");
207 : : printf(" --record-burst-stats: enable display of RX and TX bursts.\n");
208 : : printf(" --hairpin-mode=0xXX: bitmask set the hairpin port mode.\n"
209 : : " 0x10 - explicit Tx rule, 0x02 - hairpin ports paired\n"
210 : : " 0x01 - hairpin ports loop, 0x00 - hairpin port self\n");
211 : 0 : }
212 : :
213 : : #ifdef RTE_LIB_CMDLINE
214 : : static int
215 : 0 : init_peer_eth_addrs(const char *config_filename)
216 : : {
217 : : FILE *config_file;
218 : : portid_t i;
219 : : char buf[50];
220 : :
221 : 0 : config_file = fopen(config_filename, "r");
222 : 0 : if (config_file == NULL) {
223 : 0 : perror("Failed to open eth config file\n");
224 : 0 : return -1;
225 : : }
226 : :
227 : 0 : for (i = 0; i < RTE_MAX_ETHPORTS; i++) {
228 : :
229 : 0 : if (fgets(buf, sizeof(buf), config_file) == NULL)
230 : : break;
231 : :
232 : 0 : if (rte_ether_unformat_addr(buf, &peer_eth_addrs[i]) < 0) {
233 : 0 : fprintf(stderr, "Bad MAC address format on line %d\n",
234 : : i + 1);
235 : 0 : fclose(config_file);
236 : 0 : return -1;
237 : : }
238 : : }
239 : 0 : fclose(config_file);
240 : 0 : nb_peer_eth_addrs = (portid_t) i;
241 : 0 : return 0;
242 : : }
243 : : #endif
244 : :
245 : : /*
246 : : * Parse the coremask given as argument (hexadecimal string) and set
247 : : * the global configuration of forwarding cores.
248 : : */
249 : : static void
250 : 0 : parse_fwd_coremask(const char *coremask)
251 : : {
252 : : char *end;
253 : : unsigned long long int cm;
254 : :
255 : : /* parse hexadecimal string */
256 : 0 : end = NULL;
257 : 0 : cm = strtoull(coremask, &end, 16);
258 : 0 : if ((coremask[0] == '\0') || (end == NULL) || (*end != '\0'))
259 : 0 : rte_exit(EXIT_FAILURE, "Invalid fwd core mask\n");
260 : 0 : else if (set_fwd_lcores_mask((uint64_t) cm) < 0)
261 : 0 : rte_exit(EXIT_FAILURE, "coremask is not valid\n");
262 : 0 : }
263 : :
264 : : /*
265 : : * Parse the coremask given as argument (hexadecimal string) and set
266 : : * the global configuration of forwarding cores.
267 : : */
268 : : static void
269 : 0 : parse_fwd_portmask(const char *portmask)
270 : : {
271 : : char *end;
272 : : unsigned long long int pm;
273 : :
274 : : /* parse hexadecimal string */
275 : 0 : end = NULL;
276 : 0 : pm = strtoull(portmask, &end, 16);
277 : 0 : if ((portmask[0] == '\0') || (end == NULL) || (*end != '\0'))
278 : 0 : rte_exit(EXIT_FAILURE, "Invalid fwd port mask\n");
279 : : else
280 : 0 : set_fwd_ports_mask((uint64_t) pm);
281 : 0 : }
282 : :
283 : : static void
284 : 0 : print_invalid_socket_id_error(void)
285 : : {
286 : : unsigned int i = 0;
287 : :
288 : 0 : fprintf(stderr, "Invalid socket id, options are: ");
289 : 0 : for (i = 0; i < num_sockets; i++) {
290 : 0 : fprintf(stderr, "%u%s", socket_ids[i],
291 : 0 : (i == num_sockets - 1) ? "\n" : ",");
292 : : }
293 : 0 : }
294 : :
295 : : static int
296 : 0 : parse_portnuma_config(const char *q_arg)
297 : : {
298 : : char s[256];
299 : : const char *p, *p0 = q_arg;
300 : : char *end;
301 : : uint8_t i, socket_id;
302 : : portid_t port_id;
303 : : unsigned size;
304 : : enum fieldnames {
305 : : FLD_PORT = 0,
306 : : FLD_SOCKET,
307 : : _NUM_FLD
308 : : };
309 : : unsigned long int_fld[_NUM_FLD];
310 : : char *str_fld[_NUM_FLD];
311 : :
312 : : /* reset from value set at definition */
313 : 0 : while ((p = strchr(p0,'(')) != NULL) {
314 : 0 : ++p;
315 : 0 : if((p0 = strchr(p,')')) == NULL)
316 : : return -1;
317 : :
318 : 0 : size = p0 - p;
319 : 0 : if(size >= sizeof(s))
320 : : return -1;
321 : :
322 : : snprintf(s, sizeof(s), "%.*s", size, p);
323 : 0 : if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
324 : : return -1;
325 : 0 : for (i = 0; i < _NUM_FLD; i++) {
326 : 0 : errno = 0;
327 : 0 : int_fld[i] = strtoul(str_fld[i], &end, 0);
328 : 0 : if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
329 : : return -1;
330 : : }
331 : 0 : port_id = (portid_t)int_fld[FLD_PORT];
332 : 0 : if (port_id_is_invalid(port_id, ENABLED_WARN) ||
333 : : port_id == (portid_t)RTE_PORT_ALL) {
334 : 0 : print_valid_ports();
335 : 0 : return -1;
336 : : }
337 : 0 : socket_id = (uint8_t)int_fld[FLD_SOCKET];
338 : 0 : if (new_socket_id(socket_id)) {
339 : 0 : if (num_sockets >= RTE_MAX_NUMA_NODES) {
340 : 0 : print_invalid_socket_id_error();
341 : 0 : return -1;
342 : : }
343 : 0 : socket_ids[num_sockets++] = socket_id;
344 : : }
345 : 0 : port_numa[port_id] = socket_id;
346 : : }
347 : :
348 : : return 0;
349 : : }
350 : :
351 : : static int
352 : 0 : parse_ringnuma_config(const char *q_arg)
353 : : {
354 : : char s[256];
355 : : const char *p, *p0 = q_arg;
356 : : char *end;
357 : : uint8_t i, ring_flag, socket_id;
358 : : portid_t port_id;
359 : : unsigned size;
360 : : enum fieldnames {
361 : : FLD_PORT = 0,
362 : : FLD_FLAG,
363 : : FLD_SOCKET,
364 : : _NUM_FLD
365 : : };
366 : : unsigned long int_fld[_NUM_FLD];
367 : : char *str_fld[_NUM_FLD];
368 : : #define RX_RING_ONLY 0x1
369 : : #define TX_RING_ONLY 0x2
370 : : #define RXTX_RING 0x3
371 : :
372 : : /* reset from value set at definition */
373 : 0 : while ((p = strchr(p0,'(')) != NULL) {
374 : 0 : ++p;
375 : 0 : if((p0 = strchr(p,')')) == NULL)
376 : : return -1;
377 : :
378 : 0 : size = p0 - p;
379 : 0 : if(size >= sizeof(s))
380 : : return -1;
381 : :
382 : : snprintf(s, sizeof(s), "%.*s", size, p);
383 : 0 : if (rte_strsplit(s, sizeof(s), str_fld, _NUM_FLD, ',') != _NUM_FLD)
384 : : return -1;
385 : 0 : for (i = 0; i < _NUM_FLD; i++) {
386 : 0 : errno = 0;
387 : 0 : int_fld[i] = strtoul(str_fld[i], &end, 0);
388 : 0 : if (errno != 0 || end == str_fld[i] || int_fld[i] > 255)
389 : : return -1;
390 : : }
391 : 0 : port_id = (portid_t)int_fld[FLD_PORT];
392 : 0 : if (port_id_is_invalid(port_id, ENABLED_WARN) ||
393 : : port_id == (portid_t)RTE_PORT_ALL) {
394 : 0 : print_valid_ports();
395 : 0 : return -1;
396 : : }
397 : 0 : socket_id = (uint8_t)int_fld[FLD_SOCKET];
398 : 0 : if (new_socket_id(socket_id)) {
399 : 0 : if (num_sockets >= RTE_MAX_NUMA_NODES) {
400 : 0 : print_invalid_socket_id_error();
401 : 0 : return -1;
402 : : }
403 : 0 : socket_ids[num_sockets++] = socket_id;
404 : : }
405 : 0 : ring_flag = (uint8_t)int_fld[FLD_FLAG];
406 : 0 : if ((ring_flag < RX_RING_ONLY) || (ring_flag > RXTX_RING)) {
407 : 0 : fprintf(stderr,
408 : : "Invalid ring-flag=%d config for port =%d\n",
409 : : ring_flag,port_id);
410 : 0 : return -1;
411 : : }
412 : :
413 : 0 : switch (ring_flag & RXTX_RING) {
414 : 0 : case RX_RING_ONLY:
415 : 0 : rxring_numa[port_id] = socket_id;
416 : 0 : break;
417 : 0 : case TX_RING_ONLY:
418 : 0 : txring_numa[port_id] = socket_id;
419 : 0 : break;
420 : 0 : case RXTX_RING:
421 : 0 : rxring_numa[port_id] = socket_id;
422 : 0 : txring_numa[port_id] = socket_id;
423 : 0 : break;
424 : : default:
425 : : fprintf(stderr,
426 : : "Invalid ring-flag=%d config for port=%d\n",
427 : : ring_flag,port_id);
428 : : break;
429 : : }
430 : : }
431 : :
432 : : return 0;
433 : : }
434 : :
435 : : static int
436 : 0 : parse_event_printing_config(const char *optarg, int enable)
437 : : {
438 : : uint32_t mask = 0;
439 : :
440 : 0 : if (!strcmp(optarg, "unknown"))
441 : : mask = UINT32_C(1) << RTE_ETH_EVENT_UNKNOWN;
442 : 0 : else if (!strcmp(optarg, "intr_lsc"))
443 : : mask = UINT32_C(1) << RTE_ETH_EVENT_INTR_LSC;
444 : 0 : else if (!strcmp(optarg, "queue_state"))
445 : : mask = UINT32_C(1) << RTE_ETH_EVENT_QUEUE_STATE;
446 : 0 : else if (!strcmp(optarg, "intr_reset"))
447 : : mask = UINT32_C(1) << RTE_ETH_EVENT_INTR_RESET;
448 : 0 : else if (!strcmp(optarg, "vf_mbox"))
449 : : mask = UINT32_C(1) << RTE_ETH_EVENT_VF_MBOX;
450 : 0 : else if (!strcmp(optarg, "ipsec"))
451 : : mask = UINT32_C(1) << RTE_ETH_EVENT_IPSEC;
452 : 0 : else if (!strcmp(optarg, "macsec"))
453 : : mask = UINT32_C(1) << RTE_ETH_EVENT_MACSEC;
454 : 0 : else if (!strcmp(optarg, "intr_rmv"))
455 : : mask = UINT32_C(1) << RTE_ETH_EVENT_INTR_RMV;
456 : 0 : else if (!strcmp(optarg, "dev_probed"))
457 : : mask = UINT32_C(1) << RTE_ETH_EVENT_NEW;
458 : 0 : else if (!strcmp(optarg, "dev_released"))
459 : : mask = UINT32_C(1) << RTE_ETH_EVENT_DESTROY;
460 : 0 : else if (!strcmp(optarg, "flow_aged"))
461 : : mask = UINT32_C(1) << RTE_ETH_EVENT_FLOW_AGED;
462 : 0 : else if (!strcmp(optarg, "err_recovering"))
463 : : mask = UINT32_C(1) << RTE_ETH_EVENT_ERR_RECOVERING;
464 : 0 : else if (!strcmp(optarg, "recovery_success"))
465 : : mask = UINT32_C(1) << RTE_ETH_EVENT_RECOVERY_SUCCESS;
466 : 0 : else if (!strcmp(optarg, "recovery_failed"))
467 : : mask = UINT32_C(1) << RTE_ETH_EVENT_RECOVERY_FAILED;
468 : 0 : else if (!strcmp(optarg, "all"))
469 : : mask = ~UINT32_C(0);
470 : : else {
471 : 0 : fprintf(stderr, "Invalid event: %s\n", optarg);
472 : 0 : return -1;
473 : : }
474 : 0 : if (enable)
475 : 0 : event_print_mask |= mask;
476 : : else
477 : 0 : event_print_mask &= ~mask;
478 : : return 0;
479 : : }
480 : :
481 : : static int
482 : 0 : parse_xstats_list(const char *in_str, struct rte_eth_xstat_name **xstats,
483 : : unsigned int *xstats_num)
484 : : {
485 : : int max_names_nb, names_nb, nonempty_names_nb;
486 : : int name, nonempty_name;
487 : : int stringlen;
488 : : char **names;
489 : : char *str;
490 : : int ret;
491 : : int i;
492 : :
493 : : names = NULL;
494 : 0 : str = strdup(in_str);
495 : 0 : if (str == NULL) {
496 : : ret = -ENOMEM;
497 : 0 : goto out;
498 : : }
499 : 0 : stringlen = strlen(str);
500 : :
501 : 0 : for (i = 0, max_names_nb = 1; str[i] != '\0'; i++) {
502 : 0 : if (str[i] == ',')
503 : 0 : max_names_nb++;
504 : : }
505 : :
506 : 0 : names = calloc(max_names_nb, sizeof(*names));
507 : 0 : if (names == NULL) {
508 : : ret = -ENOMEM;
509 : 0 : goto out;
510 : : }
511 : :
512 : 0 : names_nb = rte_strsplit(str, stringlen, names, max_names_nb, ',');
513 : 0 : if (names_nb < 0) {
514 : : ret = -EINVAL;
515 : 0 : goto out;
516 : : }
517 : :
518 : : nonempty_names_nb = 0;
519 : 0 : for (i = 0; i < names_nb; i++) {
520 : 0 : if (names[i][0] == '\0')
521 : 0 : continue;
522 : 0 : nonempty_names_nb++;
523 : : }
524 : 0 : *xstats = calloc(nonempty_names_nb, sizeof(**xstats));
525 : 0 : if (*xstats == NULL) {
526 : : ret = -ENOMEM;
527 : 0 : goto out;
528 : : }
529 : :
530 : 0 : for (name = nonempty_name = 0; name < names_nb; name++) {
531 : 0 : if (names[name][0] == '\0')
532 : 0 : continue;
533 : 0 : rte_strscpy((*xstats)[nonempty_name].name, names[name],
534 : : sizeof((*xstats)[nonempty_name].name));
535 : 0 : nonempty_name++;
536 : : }
537 : :
538 : 0 : *xstats_num = nonempty_names_nb;
539 : : ret = 0;
540 : :
541 : 0 : out:
542 : 0 : free(names);
543 : 0 : free(str);
544 : 0 : return ret;
545 : : }
546 : :
547 : : static int
548 : 0 : parse_link_speed(int n)
549 : : {
550 : : uint32_t speed = RTE_ETH_LINK_SPEED_FIXED;
551 : :
552 : 0 : switch (n) {
553 : : case 1000:
554 : : speed |= RTE_ETH_LINK_SPEED_1G;
555 : : break;
556 : 0 : case 2500:
557 : : speed |= RTE_ETH_LINK_SPEED_2_5G;
558 : 0 : break;
559 : 0 : case 5000:
560 : : speed |= RTE_ETH_LINK_SPEED_5G;
561 : 0 : break;
562 : 0 : case 10000:
563 : : speed |= RTE_ETH_LINK_SPEED_10G;
564 : 0 : break;
565 : 0 : case 25000:
566 : : speed |= RTE_ETH_LINK_SPEED_25G;
567 : 0 : break;
568 : 0 : case 40000:
569 : : speed |= RTE_ETH_LINK_SPEED_40G;
570 : 0 : break;
571 : 0 : case 50000:
572 : : speed |= RTE_ETH_LINK_SPEED_50G;
573 : 0 : break;
574 : 0 : case 100000:
575 : : speed |= RTE_ETH_LINK_SPEED_100G;
576 : 0 : break;
577 : 0 : case 200000:
578 : : speed |= RTE_ETH_LINK_SPEED_200G;
579 : 0 : break;
580 : 0 : case 400000:
581 : : speed |= RTE_ETH_LINK_SPEED_400G;
582 : 0 : break;
583 : 0 : case 100:
584 : : case 10:
585 : : default:
586 : 0 : fprintf(stderr, "Unsupported fixed speed\n");
587 : 0 : return 0;
588 : : }
589 : :
590 : 0 : return speed;
591 : : }
592 : :
593 : : void
594 : 0 : launch_args_parse(int argc, char** argv)
595 : : {
596 : : #define PARAM_PROC_ID "proc-id"
597 : : #define PARAM_NUM_PROCS "num-procs"
598 : :
599 : : int n, opt;
600 : : char **argvopt;
601 : : int opt_idx;
602 : : portid_t pid;
603 : : enum { TX, RX };
604 : : /* Default offloads for all ports. */
605 : 0 : uint64_t rx_offloads = rx_mode.offloads;
606 : 0 : uint64_t tx_offloads = tx_mode.offloads;
607 : : struct rte_eth_dev_info dev_info;
608 : : uint16_t rec_nb_pkts;
609 : : int ret;
610 : :
611 : : static struct option lgopts[] = {
612 : : { "help", 0, 0, 0 },
613 : : #ifdef RTE_LIB_CMDLINE
614 : : { "interactive", 0, 0, 0 },
615 : : { "cmdline-file", 1, 0, 0 },
616 : : { "auto-start", 0, 0, 0 },
617 : : { "eth-peers-configfile", 1, 0, 0 },
618 : : { "eth-peer", 1, 0, 0 },
619 : : #endif
620 : : { "tx-first", 0, 0, 0 },
621 : : { "stats-period", 1, 0, 0 },
622 : : { "display-xstats", 1, 0, 0 },
623 : : { "nb-cores", 1, 0, 0 },
624 : : { "nb-ports", 1, 0, 0 },
625 : : { "coremask", 1, 0, 0 },
626 : : { "portmask", 1, 0, 0 },
627 : : { "portlist", 1, 0, 0 },
628 : : { "numa", 0, 0, 0 },
629 : : { "no-numa", 0, 0, 0 },
630 : : { "mp-anon", 0, 0, 0 }, /* deprecated */
631 : : { "port-numa-config", 1, 0, 0 },
632 : : { "ring-numa-config", 1, 0, 0 },
633 : : { "socket-num", 1, 0, 0 },
634 : : { "mbuf-size", 1, 0, 0 },
635 : : { "total-num-mbufs", 1, 0, 0 },
636 : : { "max-pkt-len", 1, 0, 0 },
637 : : { "max-lro-pkt-size", 1, 0, 0 },
638 : : #ifdef RTE_LIB_LATENCYSTATS
639 : : { "latencystats", 1, 0, 0 },
640 : : #endif
641 : : #ifdef RTE_LIB_BITRATESTATS
642 : : { "bitrate-stats", 1, 0, 0 },
643 : : #endif
644 : : { "disable-crc-strip", 0, 0, 0 },
645 : : { "enable-lro", 0, 0, 0 },
646 : : { "enable-rx-cksum", 0, 0, 0 },
647 : : { "enable-rx-timestamp", 0, 0, 0 },
648 : : { "enable-scatter", 0, 0, 0 },
649 : : { "enable-hw-vlan", 0, 0, 0 },
650 : : { "enable-hw-vlan-filter", 0, 0, 0 },
651 : : { "enable-hw-vlan-strip", 0, 0, 0 },
652 : : { "enable-hw-vlan-extend", 0, 0, 0 },
653 : : { "enable-hw-qinq-strip", 0, 0, 0 },
654 : : { "enable-drop-en", 0, 0, 0 },
655 : : { "disable-rss", 0, 0, 0 },
656 : : { "port-topology", 1, 0, 0 },
657 : : { "forward-mode", 1, 0, 0 },
658 : : { "rss-ip", 0, 0, 0 },
659 : : { "rss-udp", 0, 0, 0 },
660 : : { "rss-level-outer", 0, 0, 0 },
661 : : { "rss-level-inner", 0, 0, 0 },
662 : : { "rxq", 1, 0, 0 },
663 : : { "txq", 1, 0, 0 },
664 : : { "rxd", 1, 0, 0 },
665 : : { "txd", 1, 0, 0 },
666 : : { "hairpinq", 1, 0, 0 },
667 : : { "hairpin-mode", 1, 0, 0 },
668 : : { "burst", 1, 0, 0 },
669 : : { "flowgen-clones", 1, 0, 0 },
670 : : { "flowgen-flows", 1, 0, 0 },
671 : : { "mbcache", 1, 0, 0 },
672 : : { "txpt", 1, 0, 0 },
673 : : { "txht", 1, 0, 0 },
674 : : { "txwt", 1, 0, 0 },
675 : : { "txfreet", 1, 0, 0 },
676 : : { "txrst", 1, 0, 0 },
677 : : { "rxpt", 1, 0, 0 },
678 : : { "rxht", 1, 0, 0 },
679 : : { "rxwt", 1, 0, 0 },
680 : : { "rxfreet", 1, 0, 0 },
681 : : { "no-flush-rx", 0, 0, 0 },
682 : : { "flow-isolate-all", 0, 0, 0 },
683 : : { "disable-flow-flush", 0, 0, 0 },
684 : : { "rxoffs", 1, 0, 0 },
685 : : { "rxpkts", 1, 0, 0 },
686 : : { "rxhdrs", 1, 0, 0 },
687 : : { "txpkts", 1, 0, 0 },
688 : : { "multi-rx-mempool", 0, 0, 0 },
689 : : { "txonly-multi-flow", 0, 0, 0 },
690 : : { "rxq-share", 2, 0, 0 },
691 : : { "eth-link-speed", 1, 0, 0 },
692 : : { "disable-link-check", 0, 0, 0 },
693 : : { "disable-device-start", 0, 0, 0 },
694 : : { "no-lsc-interrupt", 0, 0, 0 },
695 : : { "no-rmv-interrupt", 0, 0, 0 },
696 : : { "print-event", 1, 0, 0 },
697 : : { "mask-event", 1, 0, 0 },
698 : : { "tx-offloads", 1, 0, 0 },
699 : : { "rx-offloads", 1, 0, 0 },
700 : : { "hot-plug", 0, 0, 0 },
701 : : { "vxlan-gpe-port", 1, 0, 0 },
702 : : { "geneve-parsed-port", 1, 0, 0 },
703 : : #ifndef RTE_EXEC_ENV_WINDOWS
704 : : { "mlockall", 0, 0, 0 },
705 : : { "no-mlockall", 0, 0, 0 },
706 : : #endif
707 : : { "mp-alloc", 1, 0, 0 },
708 : : { "tx-ip", 1, 0, 0 },
709 : : { "tx-udp", 1, 0, 0 },
710 : : { "noisy-forward-mode", 1, 0, 0 },
711 : : { "noisy-tx-sw-buffer-size", 1, 0, 0 },
712 : : { "noisy-tx-sw-buffer-flushtime", 1, 0, 0 },
713 : : { "noisy-lkup-memory", 1, 0, 0 },
714 : : { "noisy-lkup-num-writes", 1, 0, 0 },
715 : : { "noisy-lkup-num-reads", 1, 0, 0 },
716 : : { "noisy-lkup-num-reads-writes", 1, 0, 0 },
717 : : { "no-iova-contig", 0, 0, 0 },
718 : : { "rx-mq-mode", 1, 0, 0 },
719 : : { "record-core-cycles", 0, 0, 0 },
720 : : { "record-burst-stats", 0, 0, 0 },
721 : : { PARAM_NUM_PROCS, 1, 0, 0 },
722 : : { PARAM_PROC_ID, 1, 0, 0 },
723 : : { 0, 0, 0, 0 },
724 : : };
725 : :
726 : : argvopt = argv;
727 : :
728 : : #ifdef RTE_LIB_CMDLINE
729 : : #define SHORTOPTS "i"
730 : : #else
731 : : #define SHORTOPTS ""
732 : : #endif
733 : 0 : while ((opt = getopt_long(argc, argvopt, SHORTOPTS "ah",
734 : 0 : lgopts, &opt_idx)) != EOF) {
735 : 0 : switch (opt) {
736 : : #ifdef RTE_LIB_CMDLINE
737 : : case 'i':
738 : : printf("Interactive-mode selected\n");
739 : 0 : interactive = 1;
740 : 0 : break;
741 : : #endif
742 : : case 'a':
743 : : printf("Auto-start selected\n");
744 : 0 : auto_start = 1;
745 : 0 : break;
746 : :
747 : 0 : case 0: /*long options */
748 : 0 : if (!strcmp(lgopts[opt_idx].name, "help")) {
749 : 0 : usage(argv[0]);
750 : 0 : exit(EXIT_SUCCESS);
751 : : }
752 : : #ifdef RTE_LIB_CMDLINE
753 : 0 : if (!strcmp(lgopts[opt_idx].name, "interactive")) {
754 : : printf("Interactive-mode selected\n");
755 : 0 : interactive = 1;
756 : : }
757 : 0 : if (!strcmp(lgopts[opt_idx].name, "cmdline-file")) {
758 : 0 : printf("CLI commands to be read from %s\n",
759 : : optarg);
760 : 0 : strlcpy(cmdline_filename, optarg,
761 : : sizeof(cmdline_filename));
762 : : }
763 : 0 : if (!strcmp(lgopts[opt_idx].name, "auto-start")) {
764 : : printf("Auto-start selected\n");
765 : 0 : auto_start = 1;
766 : : }
767 : 0 : if (!strcmp(lgopts[opt_idx].name, "tx-first")) {
768 : : printf("Ports to start sending a burst of "
769 : : "packets first\n");
770 : 0 : tx_first = 1;
771 : : }
772 : 0 : if (!strcmp(lgopts[opt_idx].name, "stats-period")) {
773 : 0 : char *end = NULL;
774 : : unsigned int n;
775 : :
776 : 0 : n = strtoul(optarg, &end, 10);
777 : 0 : if ((optarg[0] == '\0') || (end == NULL) ||
778 : 0 : (*end != '\0'))
779 : : break;
780 : :
781 : 0 : stats_period = n;
782 : 0 : break;
783 : : }
784 : 0 : if (!strcmp(lgopts[opt_idx].name, "display-xstats")) {
785 : : char rc;
786 : :
787 : 0 : rc = parse_xstats_list(optarg, &xstats_display,
788 : : &xstats_display_num);
789 : 0 : if (rc != 0)
790 : 0 : rte_exit(EXIT_FAILURE,
791 : : "Failed to parse display-xstats argument: %d\n",
792 : : rc);
793 : : }
794 : 0 : if (!strcmp(lgopts[opt_idx].name,
795 : : "eth-peers-configfile")) {
796 : 0 : if (init_peer_eth_addrs(optarg) != 0)
797 : 0 : rte_exit(EXIT_FAILURE,
798 : : "Cannot open logfile\n");
799 : : }
800 : 0 : if (!strcmp(lgopts[opt_idx].name, "eth-peer")) {
801 : : char *port_end;
802 : :
803 : 0 : errno = 0;
804 : 0 : n = strtoul(optarg, &port_end, 10);
805 : 0 : if (errno != 0 || port_end == optarg || *port_end++ != ',')
806 : 0 : rte_exit(EXIT_FAILURE,
807 : : "Invalid eth-peer: %s", optarg);
808 : 0 : if (n >= RTE_MAX_ETHPORTS)
809 : 0 : rte_exit(EXIT_FAILURE,
810 : : "eth-peer: port %d >= RTE_MAX_ETHPORTS(%d)\n",
811 : : n, RTE_MAX_ETHPORTS);
812 : :
813 : 0 : if (rte_ether_unformat_addr(port_end,
814 : : &peer_eth_addrs[n]) < 0)
815 : 0 : rte_exit(EXIT_FAILURE,
816 : : "Invalid ethernet address: %s\n",
817 : : port_end);
818 : 0 : nb_peer_eth_addrs++;
819 : : }
820 : : #endif
821 : 0 : if (!strcmp(lgopts[opt_idx].name, "tx-ip")) {
822 : : struct in_addr in;
823 : : char *end;
824 : :
825 : 0 : end = strchr(optarg, ',');
826 : 0 : if (end == optarg || !end)
827 : 0 : rte_exit(EXIT_FAILURE,
828 : : "Invalid tx-ip: %s", optarg);
829 : :
830 : 0 : *end++ = 0;
831 : 0 : if (inet_pton(AF_INET, optarg, &in) == 0)
832 : 0 : rte_exit(EXIT_FAILURE,
833 : : "Invalid source IP address: %s\n",
834 : : optarg);
835 : 0 : tx_ip_src_addr = rte_be_to_cpu_32(in.s_addr);
836 : :
837 : 0 : if (inet_pton(AF_INET, end, &in) == 0)
838 : 0 : rte_exit(EXIT_FAILURE,
839 : : "Invalid destination IP address: %s\n",
840 : : optarg);
841 : 0 : tx_ip_dst_addr = rte_be_to_cpu_32(in.s_addr);
842 : : }
843 : 0 : if (!strcmp(lgopts[opt_idx].name, "tx-udp")) {
844 : 0 : char *end = NULL;
845 : :
846 : 0 : errno = 0;
847 : 0 : n = strtoul(optarg, &end, 10);
848 : 0 : if (errno != 0 || end == optarg ||
849 : 0 : n > UINT16_MAX ||
850 : 0 : !(*end == '\0' || *end == ','))
851 : 0 : rte_exit(EXIT_FAILURE,
852 : : "Invalid UDP port: %s\n",
853 : : optarg);
854 : 0 : tx_udp_src_port = n;
855 : 0 : if (*end == ',') {
856 : 0 : char *dst = end + 1;
857 : :
858 : 0 : n = strtoul(dst, &end, 10);
859 : 0 : if (errno != 0 || end == dst ||
860 : 0 : n > UINT16_MAX || *end)
861 : 0 : rte_exit(EXIT_FAILURE,
862 : : "Invalid destination UDP port: %s\n",
863 : : dst);
864 : 0 : tx_udp_dst_port = n;
865 : : } else {
866 : 0 : tx_udp_dst_port = n;
867 : : }
868 : :
869 : : }
870 : 0 : if (!strcmp(lgopts[opt_idx].name, "nb-ports")) {
871 : 0 : n = atoi(optarg);
872 : 0 : if (n > 0 && n <= nb_ports)
873 : 0 : nb_fwd_ports = n;
874 : : else
875 : 0 : rte_exit(EXIT_FAILURE,
876 : : "Invalid port %d\n", n);
877 : : }
878 : 0 : if (!strcmp(lgopts[opt_idx].name, "nb-cores")) {
879 : 0 : n = atoi(optarg);
880 : 0 : if (n > 0 && n <= nb_lcores)
881 : 0 : nb_fwd_lcores = (uint8_t) n;
882 : : else
883 : 0 : rte_exit(EXIT_FAILURE,
884 : : "nb-cores should be > 0 and <= %d\n",
885 : : nb_lcores);
886 : : }
887 : 0 : if (!strcmp(lgopts[opt_idx].name, "coremask"))
888 : 0 : parse_fwd_coremask(optarg);
889 : 0 : if (!strcmp(lgopts[opt_idx].name, "portmask"))
890 : 0 : parse_fwd_portmask(optarg);
891 : 0 : if (!strcmp(lgopts[opt_idx].name, "portlist"))
892 : 0 : parse_fwd_portlist(optarg);
893 : 0 : if (!strcmp(lgopts[opt_idx].name, "no-numa"))
894 : 0 : numa_support = 0;
895 : 0 : if (!strcmp(lgopts[opt_idx].name, "numa"))
896 : 0 : numa_support = 1;
897 : 0 : if (!strcmp(lgopts[opt_idx].name, "mp-anon")) {
898 : 0 : mp_alloc_type = MP_ALLOC_ANON;
899 : : }
900 : 0 : if (!strcmp(lgopts[opt_idx].name, "mp-alloc")) {
901 : 0 : if (!strcmp(optarg, "native"))
902 : 0 : mp_alloc_type = MP_ALLOC_NATIVE;
903 : 0 : else if (!strcmp(optarg, "anon"))
904 : 0 : mp_alloc_type = MP_ALLOC_ANON;
905 : 0 : else if (!strcmp(optarg, "xmem"))
906 : 0 : mp_alloc_type = MP_ALLOC_XMEM;
907 : 0 : else if (!strcmp(optarg, "xmemhuge"))
908 : 0 : mp_alloc_type = MP_ALLOC_XMEM_HUGE;
909 : 0 : else if (!strcmp(optarg, "xbuf"))
910 : 0 : mp_alloc_type = MP_ALLOC_XBUF;
911 : : else
912 : 0 : rte_exit(EXIT_FAILURE,
913 : : "mp-alloc %s invalid - must be: "
914 : : "native, anon, xmem or xmemhuge\n",
915 : : optarg);
916 : : }
917 : 0 : if (!strcmp(lgopts[opt_idx].name, "port-numa-config")) {
918 : 0 : if (parse_portnuma_config(optarg))
919 : 0 : rte_exit(EXIT_FAILURE,
920 : : "invalid port-numa configuration\n");
921 : : }
922 : 0 : if (!strcmp(lgopts[opt_idx].name, "ring-numa-config"))
923 : 0 : if (parse_ringnuma_config(optarg))
924 : 0 : rte_exit(EXIT_FAILURE,
925 : : "invalid ring-numa configuration\n");
926 : 0 : if (!strcmp(lgopts[opt_idx].name, "socket-num")) {
927 : 0 : n = atoi(optarg);
928 : 0 : if (!new_socket_id((uint8_t)n)) {
929 : 0 : socket_num = (uint8_t)n;
930 : : } else {
931 : 0 : print_invalid_socket_id_error();
932 : 0 : rte_exit(EXIT_FAILURE,
933 : : "Invalid socket id");
934 : : }
935 : : }
936 : 0 : if (!strcmp(lgopts[opt_idx].name, "mbuf-size")) {
937 : : unsigned int mb_sz[MAX_SEGS_BUFFER_SPLIT];
938 : : unsigned int nb_segs, i;
939 : :
940 : 0 : nb_segs = parse_item_list(optarg, "mbuf-size",
941 : : MAX_SEGS_BUFFER_SPLIT, mb_sz, 0);
942 : 0 : if (nb_segs <= 0)
943 : 0 : rte_exit(EXIT_FAILURE,
944 : : "bad mbuf-size\n");
945 : 0 : for (i = 0; i < nb_segs; i++) {
946 : 0 : if (mb_sz[i] <= 0 || mb_sz[i] > 0xFFFF)
947 : 0 : rte_exit(EXIT_FAILURE,
948 : : "mbuf-size should be "
949 : : "> 0 and < 65536\n");
950 : 0 : mbuf_data_size[i] = (uint16_t) mb_sz[i];
951 : : }
952 : 0 : mbuf_data_size_n = nb_segs;
953 : : }
954 : 0 : if (!strcmp(lgopts[opt_idx].name, "total-num-mbufs")) {
955 : 0 : n = atoi(optarg);
956 : 0 : if (n > MIN_TOTAL_NUM_MBUFS)
957 : 0 : param_total_num_mbufs = (unsigned)n;
958 : : else
959 : 0 : rte_exit(EXIT_FAILURE,
960 : : "total-num-mbufs should be > %d\n",
961 : : MIN_TOTAL_NUM_MBUFS);
962 : : }
963 : 0 : if (!strcmp(lgopts[opt_idx].name, "max-pkt-len")) {
964 : 0 : n = atoi(optarg);
965 : 0 : if (n >= RTE_ETHER_MIN_LEN)
966 : 0 : max_rx_pkt_len = n;
967 : : else
968 : 0 : rte_exit(EXIT_FAILURE,
969 : : "Invalid max-pkt-len=%d - should be > %d\n",
970 : : n, RTE_ETHER_MIN_LEN);
971 : : }
972 : 0 : if (!strcmp(lgopts[opt_idx].name, "max-lro-pkt-size")) {
973 : 0 : n = atoi(optarg);
974 : 0 : rx_mode.max_lro_pkt_size = (uint32_t) n;
975 : : }
976 : : #ifdef RTE_LIB_LATENCYSTATS
977 : 0 : if (!strcmp(lgopts[opt_idx].name,
978 : : "latencystats")) {
979 : 0 : n = atoi(optarg);
980 : 0 : if (n >= 0) {
981 : 0 : latencystats_lcore_id = (lcoreid_t) n;
982 : 0 : latencystats_enabled = 1;
983 : : } else
984 : 0 : rte_exit(EXIT_FAILURE,
985 : : "invalid lcore id %d for latencystats"
986 : : " must be >= 0\n", n);
987 : : }
988 : : #endif
989 : : #ifdef RTE_LIB_BITRATESTATS
990 : 0 : if (!strcmp(lgopts[opt_idx].name, "bitrate-stats")) {
991 : 0 : n = atoi(optarg);
992 : 0 : if (n >= 0) {
993 : 0 : bitrate_lcore_id = (lcoreid_t) n;
994 : 0 : bitrate_enabled = 1;
995 : : } else
996 : 0 : rte_exit(EXIT_FAILURE,
997 : : "invalid lcore id %d for bitrate stats"
998 : : " must be >= 0\n", n);
999 : : }
1000 : : #endif
1001 : 0 : if (!strcmp(lgopts[opt_idx].name, "disable-crc-strip"))
1002 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_KEEP_CRC;
1003 : 0 : if (!strcmp(lgopts[opt_idx].name, "enable-lro"))
1004 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_TCP_LRO;
1005 : 0 : if (!strcmp(lgopts[opt_idx].name, "enable-scatter"))
1006 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_SCATTER;
1007 : 0 : if (!strcmp(lgopts[opt_idx].name, "enable-rx-cksum"))
1008 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_CHECKSUM;
1009 : 0 : if (!strcmp(lgopts[opt_idx].name,
1010 : : "enable-rx-timestamp"))
1011 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_TIMESTAMP;
1012 : 0 : if (!strcmp(lgopts[opt_idx].name, "enable-hw-vlan"))
1013 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_VLAN;
1014 : :
1015 : 0 : if (!strcmp(lgopts[opt_idx].name,
1016 : : "enable-hw-vlan-filter"))
1017 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_FILTER;
1018 : :
1019 : 0 : if (!strcmp(lgopts[opt_idx].name,
1020 : : "enable-hw-vlan-strip"))
1021 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_STRIP;
1022 : :
1023 : 0 : if (!strcmp(lgopts[opt_idx].name,
1024 : : "enable-hw-vlan-extend"))
1025 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_VLAN_EXTEND;
1026 : :
1027 : 0 : if (!strcmp(lgopts[opt_idx].name,
1028 : : "enable-hw-qinq-strip"))
1029 : 0 : rx_offloads |= RTE_ETH_RX_OFFLOAD_QINQ_STRIP;
1030 : :
1031 : 0 : if (!strcmp(lgopts[opt_idx].name, "enable-drop-en"))
1032 : 0 : rx_drop_en = 1;
1033 : :
1034 : 0 : if (!strcmp(lgopts[opt_idx].name, "disable-rss"))
1035 : 0 : rss_hf = 0;
1036 : 0 : if (!strcmp(lgopts[opt_idx].name, "port-topology")) {
1037 : 0 : if (!strcmp(optarg, "paired"))
1038 : 0 : port_topology = PORT_TOPOLOGY_PAIRED;
1039 : 0 : else if (!strcmp(optarg, "chained"))
1040 : 0 : port_topology = PORT_TOPOLOGY_CHAINED;
1041 : 0 : else if (!strcmp(optarg, "loop"))
1042 : 0 : port_topology = PORT_TOPOLOGY_LOOP;
1043 : : else
1044 : 0 : rte_exit(EXIT_FAILURE, "port-topology %s invalid -"
1045 : : " must be: paired, chained or loop\n",
1046 : : optarg);
1047 : : }
1048 : 0 : if (!strcmp(lgopts[opt_idx].name, "forward-mode"))
1049 : 0 : set_pkt_forwarding_mode(optarg);
1050 : 0 : if (!strcmp(lgopts[opt_idx].name, "rss-ip"))
1051 : 0 : rss_hf = RTE_ETH_RSS_IP;
1052 : 0 : if (!strcmp(lgopts[opt_idx].name, "rss-udp"))
1053 : 0 : rss_hf = RTE_ETH_RSS_UDP;
1054 : 0 : if (!strcmp(lgopts[opt_idx].name, "rss-level-inner"))
1055 : 0 : rss_hf |= RTE_ETH_RSS_LEVEL_INNERMOST;
1056 : 0 : if (!strcmp(lgopts[opt_idx].name, "rss-level-outer"))
1057 : 0 : rss_hf |= RTE_ETH_RSS_LEVEL_OUTERMOST;
1058 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxq")) {
1059 : 0 : n = atoi(optarg);
1060 : 0 : if (n >= 0 && check_nb_rxq((queueid_t)n) == 0)
1061 : 0 : nb_rxq = (queueid_t) n;
1062 : : else
1063 : 0 : rte_exit(EXIT_FAILURE, "rxq %d invalid - must be"
1064 : : " >= 0 && <= %u\n", n,
1065 : 0 : get_allowed_max_nb_rxq(&pid));
1066 : : }
1067 : 0 : if (!strcmp(lgopts[opt_idx].name, "txq")) {
1068 : 0 : n = atoi(optarg);
1069 : 0 : if (n >= 0 && check_nb_txq((queueid_t)n) == 0)
1070 : 0 : nb_txq = (queueid_t) n;
1071 : : else
1072 : 0 : rte_exit(EXIT_FAILURE, "txq %d invalid - must be"
1073 : : " >= 0 && <= %u\n", n,
1074 : 0 : get_allowed_max_nb_txq(&pid));
1075 : : }
1076 : 0 : if (!strcmp(lgopts[opt_idx].name, "hairpinq")) {
1077 : 0 : n = atoi(optarg);
1078 : 0 : if (n >= 0 &&
1079 : 0 : check_nb_hairpinq((queueid_t)n) == 0)
1080 : 0 : nb_hairpinq = (queueid_t) n;
1081 : : else
1082 : 0 : rte_exit(EXIT_FAILURE, "txq %d invalid - must be"
1083 : : " >= 0 && <= %u\n", n,
1084 : 0 : get_allowed_max_nb_hairpinq
1085 : : (&pid));
1086 : 0 : if ((n + nb_txq) < 0 ||
1087 : 0 : check_nb_txq((queueid_t)(n + nb_txq)) != 0)
1088 : 0 : rte_exit(EXIT_FAILURE, "txq + hairpinq "
1089 : : "%d invalid - must be"
1090 : : " >= 0 && <= %u\n",
1091 : : n + nb_txq,
1092 : 0 : get_allowed_max_nb_txq(&pid));
1093 : 0 : if ((n + nb_rxq) < 0 ||
1094 : 0 : check_nb_rxq((queueid_t)(n + nb_rxq)) != 0)
1095 : 0 : rte_exit(EXIT_FAILURE, "rxq + hairpinq "
1096 : : "%d invalid - must be"
1097 : : " >= 0 && <= %u\n",
1098 : : n + nb_rxq,
1099 : 0 : get_allowed_max_nb_rxq(&pid));
1100 : : }
1101 : 0 : if (!nb_rxq && !nb_txq) {
1102 : 0 : rte_exit(EXIT_FAILURE, "Either rx or tx queues should "
1103 : : "be non-zero\n");
1104 : : }
1105 : 0 : if (!strcmp(lgopts[opt_idx].name, "hairpin-mode")) {
1106 : 0 : char *end = NULL;
1107 : : unsigned int n;
1108 : :
1109 : 0 : errno = 0;
1110 : 0 : n = strtoul(optarg, &end, 0);
1111 : 0 : if (errno != 0 || end == optarg)
1112 : 0 : rte_exit(EXIT_FAILURE, "hairpin mode invalid\n");
1113 : : else
1114 : 0 : hairpin_mode = (uint32_t)n;
1115 : : }
1116 : 0 : if (!strcmp(lgopts[opt_idx].name, "burst")) {
1117 : 0 : n = atoi(optarg);
1118 : 0 : if (n == 0) {
1119 : : /* A burst size of zero means that the
1120 : : * PMD should be queried for
1121 : : * recommended Rx burst size. Since
1122 : : * testpmd uses a single size for all
1123 : : * ports, port 0 is queried for the
1124 : : * value, on the assumption that all
1125 : : * ports are of the same NIC model.
1126 : : */
1127 : 0 : ret = eth_dev_info_get_print_err(
1128 : : 0,
1129 : : &dev_info);
1130 : 0 : if (ret != 0)
1131 : 0 : return;
1132 : :
1133 : 0 : rec_nb_pkts = dev_info
1134 : : .default_rxportconf.burst_size;
1135 : :
1136 : 0 : if (rec_nb_pkts == 0)
1137 : 0 : rte_exit(EXIT_FAILURE,
1138 : : "PMD does not recommend a burst size. "
1139 : : "Provided value must be between "
1140 : : "1 and %d\n", MAX_PKT_BURST);
1141 : 0 : else if (rec_nb_pkts > MAX_PKT_BURST)
1142 : 0 : rte_exit(EXIT_FAILURE,
1143 : : "PMD recommended burst size of %d"
1144 : : " exceeds maximum value of %d\n",
1145 : : rec_nb_pkts, MAX_PKT_BURST);
1146 : 0 : printf("Using PMD-provided burst value of %d\n",
1147 : : rec_nb_pkts);
1148 : 0 : nb_pkt_per_burst = rec_nb_pkts;
1149 : 0 : } else if (n > MAX_PKT_BURST)
1150 : 0 : rte_exit(EXIT_FAILURE,
1151 : : "burst must be between1 and %d\n",
1152 : : MAX_PKT_BURST);
1153 : : else
1154 : 0 : nb_pkt_per_burst = (uint16_t) n;
1155 : : }
1156 : 0 : if (!strcmp(lgopts[opt_idx].name, "flowgen-clones")) {
1157 : 0 : n = atoi(optarg);
1158 : 0 : if (n >= 0)
1159 : 0 : nb_pkt_flowgen_clones = (uint16_t) n;
1160 : : else
1161 : 0 : rte_exit(EXIT_FAILURE,
1162 : : "clones must be >= 0 and <= current burst\n");
1163 : : }
1164 : 0 : if (!strcmp(lgopts[opt_idx].name, "flowgen-flows")) {
1165 : 0 : n = atoi(optarg);
1166 : 0 : if (n > 0)
1167 : 0 : nb_flows_flowgen = (int) n;
1168 : : else
1169 : 0 : rte_exit(EXIT_FAILURE,
1170 : : "flows must be >= 1\n");
1171 : : }
1172 : 0 : if (!strcmp(lgopts[opt_idx].name, "mbcache")) {
1173 : 0 : n = atoi(optarg);
1174 : 0 : if ((n >= 0) &&
1175 : : (n <= RTE_MEMPOOL_CACHE_MAX_SIZE))
1176 : 0 : mb_mempool_cache = (uint16_t) n;
1177 : : else
1178 : 0 : rte_exit(EXIT_FAILURE,
1179 : : "mbcache must be >= 0 and <= %d\n",
1180 : : RTE_MEMPOOL_CACHE_MAX_SIZE);
1181 : : }
1182 : 0 : if (!strcmp(lgopts[opt_idx].name, "txfreet")) {
1183 : 0 : n = atoi(optarg);
1184 : 0 : if (n >= 0)
1185 : 0 : tx_free_thresh = (int16_t)n;
1186 : : else
1187 : 0 : rte_exit(EXIT_FAILURE, "txfreet must be >= 0\n");
1188 : : }
1189 : 0 : if (!strcmp(lgopts[opt_idx].name, "txrst")) {
1190 : 0 : n = atoi(optarg);
1191 : 0 : if (n >= 0)
1192 : 0 : tx_rs_thresh = (int16_t)n;
1193 : : else
1194 : 0 : rte_exit(EXIT_FAILURE, "txrst must be >= 0\n");
1195 : : }
1196 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxd")) {
1197 : 0 : n = atoi(optarg);
1198 : 0 : if (n > 0) {
1199 : 0 : if (rx_free_thresh >= n)
1200 : 0 : rte_exit(EXIT_FAILURE,
1201 : : "rxd must be > "
1202 : : "rx_free_thresh(%d)\n",
1203 : : (int)rx_free_thresh);
1204 : : else
1205 : 0 : nb_rxd = (uint16_t) n;
1206 : : } else
1207 : 0 : rte_exit(EXIT_FAILURE,
1208 : : "rxd(%d) invalid - must be > 0\n",
1209 : : n);
1210 : : }
1211 : 0 : if (!strcmp(lgopts[opt_idx].name, "txd")) {
1212 : 0 : n = atoi(optarg);
1213 : 0 : if (n > 0)
1214 : 0 : nb_txd = (uint16_t) n;
1215 : : else
1216 : 0 : rte_exit(EXIT_FAILURE, "txd must be in > 0\n");
1217 : : }
1218 : 0 : if (!strcmp(lgopts[opt_idx].name, "txpt")) {
1219 : 0 : n = atoi(optarg);
1220 : 0 : if (n >= 0)
1221 : 0 : tx_pthresh = (int8_t)n;
1222 : : else
1223 : 0 : rte_exit(EXIT_FAILURE, "txpt must be >= 0\n");
1224 : : }
1225 : 0 : if (!strcmp(lgopts[opt_idx].name, "txht")) {
1226 : 0 : n = atoi(optarg);
1227 : 0 : if (n >= 0)
1228 : 0 : tx_hthresh = (int8_t)n;
1229 : : else
1230 : 0 : rte_exit(EXIT_FAILURE, "txht must be >= 0\n");
1231 : : }
1232 : 0 : if (!strcmp(lgopts[opt_idx].name, "txwt")) {
1233 : 0 : n = atoi(optarg);
1234 : 0 : if (n >= 0)
1235 : 0 : tx_wthresh = (int8_t)n;
1236 : : else
1237 : 0 : rte_exit(EXIT_FAILURE, "txwt must be >= 0\n");
1238 : : }
1239 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxpt")) {
1240 : 0 : n = atoi(optarg);
1241 : 0 : if (n >= 0)
1242 : 0 : rx_pthresh = (int8_t)n;
1243 : : else
1244 : 0 : rte_exit(EXIT_FAILURE, "rxpt must be >= 0\n");
1245 : : }
1246 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxht")) {
1247 : 0 : n = atoi(optarg);
1248 : 0 : if (n >= 0)
1249 : 0 : rx_hthresh = (int8_t)n;
1250 : : else
1251 : 0 : rte_exit(EXIT_FAILURE, "rxht must be >= 0\n");
1252 : : }
1253 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxwt")) {
1254 : 0 : n = atoi(optarg);
1255 : 0 : if (n >= 0)
1256 : 0 : rx_wthresh = (int8_t)n;
1257 : : else
1258 : 0 : rte_exit(EXIT_FAILURE, "rxwt must be >= 0\n");
1259 : : }
1260 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxfreet")) {
1261 : 0 : n = atoi(optarg);
1262 : 0 : if (n >= 0)
1263 : 0 : rx_free_thresh = (int16_t)n;
1264 : : else
1265 : 0 : rte_exit(EXIT_FAILURE, "rxfreet must be >= 0\n");
1266 : : }
1267 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxoffs")) {
1268 : : unsigned int seg_off[MAX_SEGS_BUFFER_SPLIT];
1269 : : unsigned int nb_offs;
1270 : :
1271 : 0 : nb_offs = parse_item_list
1272 : : (optarg, "rxpkt offsets",
1273 : : MAX_SEGS_BUFFER_SPLIT,
1274 : : seg_off, 0);
1275 : 0 : if (nb_offs > 0)
1276 : 0 : set_rx_pkt_offsets(seg_off, nb_offs);
1277 : : else
1278 : 0 : rte_exit(EXIT_FAILURE, "bad rxoffs\n");
1279 : : }
1280 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxpkts")) {
1281 : : unsigned int seg_len[MAX_SEGS_BUFFER_SPLIT];
1282 : : unsigned int nb_segs;
1283 : 0 : nb_segs = parse_item_list
1284 : : (optarg, "rxpkt segments",
1285 : : MAX_SEGS_BUFFER_SPLIT,
1286 : : seg_len, 0);
1287 : 0 : if (nb_segs > 0)
1288 : 0 : set_rx_pkt_segments(seg_len, nb_segs);
1289 : : else
1290 : 0 : rte_exit(EXIT_FAILURE, "bad rxpkts\n");
1291 : : }
1292 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxhdrs")) {
1293 : : unsigned int seg_hdrs[MAX_SEGS_BUFFER_SPLIT];
1294 : : unsigned int nb_segs;
1295 : :
1296 : 0 : nb_segs = parse_hdrs_list
1297 : : (optarg, "rxpkt segments",
1298 : : MAX_SEGS_BUFFER_SPLIT,
1299 : : seg_hdrs);
1300 : 0 : if (nb_segs > 0)
1301 : 0 : set_rx_pkt_hdrs(seg_hdrs, nb_segs);
1302 : : else
1303 : 0 : rte_exit(EXIT_FAILURE, "bad rxpkts\n");
1304 : : }
1305 : 0 : if (!strcmp(lgopts[opt_idx].name, "txpkts")) {
1306 : : unsigned seg_lengths[RTE_MAX_SEGS_PER_PKT];
1307 : : unsigned int nb_segs;
1308 : :
1309 : 0 : nb_segs = parse_item_list(optarg, "txpkt segments",
1310 : : RTE_MAX_SEGS_PER_PKT, seg_lengths, 0);
1311 : 0 : if (nb_segs > 0)
1312 : 0 : set_tx_pkt_segments(seg_lengths, nb_segs);
1313 : : else
1314 : 0 : rte_exit(EXIT_FAILURE, "bad txpkts\n");
1315 : : }
1316 : 0 : if (!strcmp(lgopts[opt_idx].name, "multi-rx-mempool"))
1317 : 0 : multi_rx_mempool = 1;
1318 : 0 : if (!strcmp(lgopts[opt_idx].name, "txonly-multi-flow"))
1319 : 0 : txonly_multi_flow = 1;
1320 : 0 : if (!strcmp(lgopts[opt_idx].name, "rxq-share")) {
1321 : 0 : if (optarg == NULL) {
1322 : 0 : rxq_share = UINT32_MAX;
1323 : : } else {
1324 : : n = atoi(optarg);
1325 : 0 : if (n >= 0)
1326 : 0 : rxq_share = (uint32_t)n;
1327 : : else
1328 : 0 : rte_exit(EXIT_FAILURE, "rxq-share must be >= 0\n");
1329 : : }
1330 : : }
1331 : 0 : if (!strcmp(lgopts[opt_idx].name, "no-flush-rx"))
1332 : 0 : no_flush_rx = 1;
1333 : 0 : if (!strcmp(lgopts[opt_idx].name, "eth-link-speed")) {
1334 : 0 : n = atoi(optarg);
1335 : 0 : if (n >= 0 && parse_link_speed(n) > 0)
1336 : 0 : eth_link_speed = parse_link_speed(n);
1337 : : }
1338 : 0 : if (!strcmp(lgopts[opt_idx].name, "disable-link-check"))
1339 : 0 : no_link_check = 1;
1340 : 0 : if (!strcmp(lgopts[opt_idx].name, "disable-device-start"))
1341 : 0 : no_device_start = 1;
1342 : 0 : if (!strcmp(lgopts[opt_idx].name, "no-lsc-interrupt"))
1343 : 0 : lsc_interrupt = 0;
1344 : 0 : if (!strcmp(lgopts[opt_idx].name, "no-rmv-interrupt"))
1345 : 0 : rmv_interrupt = 0;
1346 : 0 : if (!strcmp(lgopts[opt_idx].name, "flow-isolate-all"))
1347 : 0 : flow_isolate_all = 1;
1348 : 0 : if (!strcmp(lgopts[opt_idx].name, "disable-flow-flush"))
1349 : 0 : no_flow_flush = 1;
1350 : 0 : if (!strcmp(lgopts[opt_idx].name, "tx-offloads")) {
1351 : 0 : char *end = NULL;
1352 : 0 : n = strtoull(optarg, &end, 16);
1353 : 0 : if (n >= 0)
1354 : 0 : tx_offloads = (uint64_t)n;
1355 : : else
1356 : 0 : rte_exit(EXIT_FAILURE,
1357 : : "tx-offloads must be >= 0\n");
1358 : : }
1359 : :
1360 : 0 : if (!strcmp(lgopts[opt_idx].name, "rx-offloads")) {
1361 : 0 : char *end = NULL;
1362 : 0 : n = strtoull(optarg, &end, 16);
1363 : 0 : if (n >= 0)
1364 : 0 : rx_offloads = (uint64_t)n;
1365 : : else
1366 : 0 : rte_exit(EXIT_FAILURE,
1367 : : "rx-offloads must be >= 0\n");
1368 : : }
1369 : :
1370 : 0 : if (!strcmp(lgopts[opt_idx].name, "vxlan-gpe-port")) {
1371 : 0 : n = atoi(optarg);
1372 : 0 : if (n >= 0)
1373 : 0 : vxlan_gpe_udp_port = (uint16_t)n;
1374 : : else
1375 : 0 : rte_exit(EXIT_FAILURE,
1376 : : "vxlan-gpe-port must be >= 0\n");
1377 : : }
1378 : 0 : if (!strcmp(lgopts[opt_idx].name,
1379 : : "geneve-parsed-port")) {
1380 : 0 : n = atoi(optarg);
1381 : 0 : if (n >= 0)
1382 : 0 : geneve_udp_port = (uint16_t)n;
1383 : : else
1384 : 0 : rte_exit(EXIT_FAILURE,
1385 : : "geneve-parsed-port must be >= 0\n");
1386 : : }
1387 : 0 : if (!strcmp(lgopts[opt_idx].name, "print-event"))
1388 : 0 : if (parse_event_printing_config(optarg, 1)) {
1389 : 0 : rte_exit(EXIT_FAILURE,
1390 : : "invalid print-event argument\n");
1391 : : }
1392 : 0 : if (!strcmp(lgopts[opt_idx].name, "mask-event"))
1393 : 0 : if (parse_event_printing_config(optarg, 0)) {
1394 : 0 : rte_exit(EXIT_FAILURE,
1395 : : "invalid mask-event argument\n");
1396 : : }
1397 : 0 : if (!strcmp(lgopts[opt_idx].name, "hot-plug"))
1398 : 0 : hot_plug = 1;
1399 : 0 : if (!strcmp(lgopts[opt_idx].name, "mlockall"))
1400 : 0 : do_mlockall = 1;
1401 : 0 : if (!strcmp(lgopts[opt_idx].name, "no-mlockall"))
1402 : 0 : do_mlockall = 0;
1403 : 0 : if (!strcmp(lgopts[opt_idx].name,
1404 : : "noisy-tx-sw-buffer-size")) {
1405 : 0 : n = atoi(optarg);
1406 : 0 : if (n >= 0)
1407 : 0 : noisy_tx_sw_bufsz = n;
1408 : : else
1409 : 0 : rte_exit(EXIT_FAILURE,
1410 : : "noisy-tx-sw-buffer-size must be >= 0\n");
1411 : : }
1412 : 0 : if (!strcmp(lgopts[opt_idx].name,
1413 : : "noisy-tx-sw-buffer-flushtime")) {
1414 : 0 : n = atoi(optarg);
1415 : 0 : if (n >= 0)
1416 : 0 : noisy_tx_sw_buf_flush_time = n;
1417 : : else
1418 : 0 : rte_exit(EXIT_FAILURE,
1419 : : "noisy-tx-sw-buffer-flushtime must be >= 0\n");
1420 : : }
1421 : 0 : if (!strcmp(lgopts[opt_idx].name,
1422 : : "noisy-lkup-memory")) {
1423 : 0 : n = atoi(optarg);
1424 : 0 : if (n >= 0)
1425 : 0 : noisy_lkup_mem_sz = n;
1426 : : else
1427 : 0 : rte_exit(EXIT_FAILURE,
1428 : : "noisy-lkup-memory must be >= 0\n");
1429 : : }
1430 : 0 : if (!strcmp(lgopts[opt_idx].name,
1431 : : "noisy-lkup-num-writes")) {
1432 : 0 : n = atoi(optarg);
1433 : 0 : if (n >= 0)
1434 : 0 : noisy_lkup_num_writes = n;
1435 : : else
1436 : 0 : rte_exit(EXIT_FAILURE,
1437 : : "noisy-lkup-num-writes must be >= 0\n");
1438 : : }
1439 : 0 : if (!strcmp(lgopts[opt_idx].name,
1440 : : "noisy-lkup-num-reads")) {
1441 : 0 : n = atoi(optarg);
1442 : 0 : if (n >= 0)
1443 : 0 : noisy_lkup_num_reads = n;
1444 : : else
1445 : 0 : rte_exit(EXIT_FAILURE,
1446 : : "noisy-lkup-num-reads must be >= 0\n");
1447 : : }
1448 : 0 : if (!strcmp(lgopts[opt_idx].name,
1449 : : "noisy-lkup-num-reads-writes")) {
1450 : 0 : n = atoi(optarg);
1451 : 0 : if (n >= 0)
1452 : 0 : noisy_lkup_num_reads_writes = n;
1453 : : else
1454 : 0 : rte_exit(EXIT_FAILURE,
1455 : : "noisy-lkup-num-reads-writes must be >= 0\n");
1456 : : }
1457 : 0 : if (!strcmp(lgopts[opt_idx].name,
1458 : : "noisy-forward-mode")) {
1459 : : int i;
1460 : 0 : for (i = 0; i < NOISY_FWD_MODE_MAX; i++)
1461 : 0 : if (!strcmp(optarg, noisy_fwd_mode_desc[i])) {
1462 : 0 : noisy_fwd_mode = i;
1463 : 0 : break;
1464 : : }
1465 : 0 : if (i == NOISY_FWD_MODE_MAX)
1466 : 0 : rte_exit(EXIT_FAILURE, "noisy-forward-mode %s invalid,"
1467 : : " must be a valid noisy-forward-mode value\n",
1468 : : optarg);
1469 : : }
1470 : 0 : if (!strcmp(lgopts[opt_idx].name, "no-iova-contig"))
1471 : 0 : mempool_flags = RTE_MEMPOOL_F_NO_IOVA_CONTIG;
1472 : :
1473 : 0 : if (!strcmp(lgopts[opt_idx].name, "rx-mq-mode")) {
1474 : 0 : char *end = NULL;
1475 : 0 : n = strtoul(optarg, &end, 16);
1476 : 0 : if (n >= 0 && n <= RTE_ETH_MQ_RX_VMDQ_DCB_RSS)
1477 : 0 : rx_mq_mode = (enum rte_eth_rx_mq_mode)n;
1478 : : else
1479 : 0 : rte_exit(EXIT_FAILURE,
1480 : : "rx-mq-mode must be >= 0 and <= %d\n",
1481 : : RTE_ETH_MQ_RX_VMDQ_DCB_RSS);
1482 : : }
1483 : 0 : if (!strcmp(lgopts[opt_idx].name, "record-core-cycles"))
1484 : 0 : record_core_cycles = 1;
1485 : 0 : if (!strcmp(lgopts[opt_idx].name, "record-burst-stats"))
1486 : 0 : record_burst_stats = 1;
1487 : 0 : if (!strcmp(lgopts[opt_idx].name, PARAM_NUM_PROCS))
1488 : 0 : num_procs = atoi(optarg);
1489 : 0 : if (!strcmp(lgopts[opt_idx].name, PARAM_PROC_ID))
1490 : 0 : proc_id = atoi(optarg);
1491 : : break;
1492 : 0 : case 'h':
1493 : 0 : usage(argv[0]);
1494 : 0 : exit(EXIT_SUCCESS);
1495 : : break;
1496 : 0 : default:
1497 : 0 : usage(argv[0]);
1498 : 0 : fprintf(stderr, "Invalid option: %s\n", argv[optind]);
1499 : 0 : rte_exit(EXIT_FAILURE,
1500 : : "Command line is incomplete or incorrect\n");
1501 : : break;
1502 : : }
1503 : : }
1504 : :
1505 : 0 : if (optind != argc) {
1506 : 0 : usage(argv[0]);
1507 : 0 : fprintf(stderr, "Invalid parameter: %s\n", argv[optind]);
1508 : 0 : rte_exit(EXIT_FAILURE, "Command line is incorrect\n");
1509 : : }
1510 : :
1511 : 0 : if (proc_id >= (int)num_procs)
1512 : 0 : rte_exit(EXIT_FAILURE,
1513 : : "The multi-process option '%s(%d)' should be less than '%s(%u)'\n",
1514 : : PARAM_PROC_ID, proc_id,
1515 : : PARAM_NUM_PROCS, num_procs);
1516 : :
1517 : : /* Set offload configuration from command line parameters. */
1518 : 0 : rx_mode.offloads = rx_offloads;
1519 : 0 : tx_mode.offloads = tx_offloads;
1520 : :
1521 : 0 : if (mempool_flags & RTE_MEMPOOL_F_NO_IOVA_CONTIG &&
1522 : 0 : mp_alloc_type != MP_ALLOC_ANON) {
1523 : 0 : TESTPMD_LOG(WARNING, "cannot use no-iova-contig without "
1524 : : "mp-alloc=anon. mempool no-iova-contig is "
1525 : : "ignored\n");
1526 : 0 : mempool_flags = 0;
1527 : : }
1528 : : }
|