examples/multi_process: check server port validity
[dpdk.git] / examples / multi_process / client_server_mp / mp_server / args.c
1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2010-2014 Intel Corporation
3  */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <stdint.h>
8 #include <getopt.h>
9 #include <stdarg.h>
10 #include <errno.h>
11
12 #include <rte_memory.h>
13 #include <rte_ethdev.h>
14 #include <rte_string_fns.h>
15
16 #include "common.h"
17 #include "args.h"
18 #include "init.h"
19
20 /* global var for number of clients - extern in header */
21 uint8_t num_clients;
22
23 static const char *progname;
24
25 /**
26  * Prints out usage information to stdout
27  */
28 static void
29 usage(void)
30 {
31         printf(
32             "%s [EAL options] -- -p PORTMASK -n NUM_CLIENTS [-s NUM_SOCKETS]\n"
33             " -p PORTMASK: hexadecimal bitmask of ports to use\n"
34             " -n NUM_CLIENTS: number of client processes to use\n"
35             , progname);
36 }
37
38 /**
39  * The ports to be used by the application are passed in
40  * the form of a bitmask. This function parses the bitmask
41  * and places the port numbers to be used into the port[]
42  * array variable
43  */
44 static int
45 parse_portmask(const char *portmask)
46 {
47         char *end = NULL;
48         unsigned long long pm;
49         uint16_t id;
50
51         if (portmask == NULL || *portmask == '\0')
52                 return -1;
53
54         /* convert parameter to a number and verify */
55         errno = 0;
56         pm = strtoull(portmask, &end, 16);
57         if (errno != 0 || end == NULL || *end != '\0')
58                 return -1;
59
60         RTE_ETH_FOREACH_DEV(id) {
61                 unsigned long msk = 1u << id;
62
63                 if ((pm & msk) == 0)
64                         continue;
65
66                 pm &= ~msk;
67                 ports->id[ports->num_ports++] = id;
68         }
69
70         if (pm != 0) {
71                 printf("WARNING: leftover ports in mask %#llx - ignoring\n",
72                        pm);
73         }
74
75         return 0;
76 }
77
78 /**
79  * Take the number of clients parameter passed to the app
80  * and convert to a number to store in the num_clients variable
81  */
82 static int
83 parse_num_clients(const char *clients)
84 {
85         char *end = NULL;
86         unsigned long temp;
87
88         if (clients == NULL || *clients == '\0')
89                 return -1;
90
91         temp = strtoul(clients, &end, 10);
92         if (end == NULL || *end != '\0' || temp == 0)
93                 return -1;
94
95         num_clients = (uint8_t)temp;
96         return 0;
97 }
98
99 /**
100  * The application specific arguments follow the DPDK-specific
101  * arguments which are stripped by the DPDK init. This function
102  * processes these application arguments, printing usage info
103  * on error.
104  */
105 int
106 parse_app_args(int argc, char *argv[])
107 {
108         int option_index, opt;
109         char **argvopt = argv;
110         static struct option lgopts[] = { /* no long options */
111                 {NULL, 0, 0, 0 }
112         };
113         progname = argv[0];
114
115         while ((opt = getopt_long(argc, argvopt, "n:p:", lgopts,
116                 &option_index)) != EOF){
117                 switch (opt){
118                         case 'p':
119                                 if (parse_portmask(optarg) != 0) {
120                                         usage();
121                                         return -1;
122                                 }
123                                 break;
124                         case 'n':
125                                 if (parse_num_clients(optarg) != 0){
126                                         usage();
127                                         return -1;
128                                 }
129                                 break;
130                         default:
131                                 printf("ERROR: Unknown option '%c'\n", opt);
132                                 usage();
133                                 return -1;
134                 }
135         }
136
137         if (ports->num_ports == 0 || num_clients == 0){
138                 usage();
139                 return -1;
140         }
141
142         if (ports->num_ports % 2 != 0){
143                 printf("ERROR: application requires an even number of ports to use\n");
144                 return -1;
145         }
146         return 0;
147 }