1d30ea906Sjfb8856606 /* SPDX-License-Identifier: BSD-3-Clause
2d30ea906Sjfb8856606 * Copyright(c) 2016 Intel Corporation.
3d30ea906Sjfb8856606 * Copyright (c) 2009, Olivier MATZ <[email protected]>
4d30ea906Sjfb8856606 * All rights reserved.
5d30ea906Sjfb8856606 */
6d30ea906Sjfb8856606
7d30ea906Sjfb8856606 #include <stdint.h>
8d30ea906Sjfb8856606 #include <stdlib.h>
9d30ea906Sjfb8856606 #include <stdio.h>
10d30ea906Sjfb8856606 #include <ctype.h>
11d30ea906Sjfb8856606 #include <getopt.h>
12d30ea906Sjfb8856606 #include <errno.h>
13d30ea906Sjfb8856606 #include <stdarg.h>
14d30ea906Sjfb8856606 #include <string.h>
15d30ea906Sjfb8856606 #include <libgen.h>
16d30ea906Sjfb8856606 #include <unistd.h>
17d30ea906Sjfb8856606 #include <sys/wait.h>
18*0c6bd470Sfengbojiang #include <arpa/inet.h>
19*0c6bd470Sfengbojiang #include <sys/socket.h>
20d30ea906Sjfb8856606
21d30ea906Sjfb8856606 #include <rte_errno.h>
22d30ea906Sjfb8856606
23d30ea906Sjfb8856606 #include "parser.h"
24d30ea906Sjfb8856606
25d30ea906Sjfb8856606 static uint32_t
get_hex_val(char c)26d30ea906Sjfb8856606 get_hex_val(char c)
27d30ea906Sjfb8856606 {
28d30ea906Sjfb8856606 switch (c) {
29d30ea906Sjfb8856606 case '0': case '1': case '2': case '3': case '4': case '5':
30d30ea906Sjfb8856606 case '6': case '7': case '8': case '9':
31d30ea906Sjfb8856606 return c - '0';
32d30ea906Sjfb8856606 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
33d30ea906Sjfb8856606 return c - 'A' + 10;
34d30ea906Sjfb8856606 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
35d30ea906Sjfb8856606 return c - 'a' + 10;
36d30ea906Sjfb8856606 default:
37d30ea906Sjfb8856606 return 0;
38d30ea906Sjfb8856606 }
39d30ea906Sjfb8856606 }
40d30ea906Sjfb8856606
41d30ea906Sjfb8856606 int
softnic_parser_read_arg_bool(const char * p)42d30ea906Sjfb8856606 softnic_parser_read_arg_bool(const char *p)
43d30ea906Sjfb8856606 {
44d30ea906Sjfb8856606 p = skip_white_spaces(p);
45d30ea906Sjfb8856606 int result = -EINVAL;
46d30ea906Sjfb8856606
47d30ea906Sjfb8856606 if (((p[0] == 'y') && (p[1] == 'e') && (p[2] == 's')) ||
48d30ea906Sjfb8856606 ((p[0] == 'Y') && (p[1] == 'E') && (p[2] == 'S'))) {
49d30ea906Sjfb8856606 p += 3;
50d30ea906Sjfb8856606 result = 1;
51d30ea906Sjfb8856606 }
52d30ea906Sjfb8856606
53d30ea906Sjfb8856606 if (((p[0] == 'o') && (p[1] == 'n')) ||
54d30ea906Sjfb8856606 ((p[0] == 'O') && (p[1] == 'N'))) {
55d30ea906Sjfb8856606 p += 2;
56d30ea906Sjfb8856606 result = 1;
57d30ea906Sjfb8856606 }
58d30ea906Sjfb8856606
59d30ea906Sjfb8856606 if (((p[0] == 'n') && (p[1] == 'o')) ||
60d30ea906Sjfb8856606 ((p[0] == 'N') && (p[1] == 'O'))) {
61d30ea906Sjfb8856606 p += 2;
62d30ea906Sjfb8856606 result = 0;
63d30ea906Sjfb8856606 }
64d30ea906Sjfb8856606
65d30ea906Sjfb8856606 if (((p[0] == 'o') && (p[1] == 'f') && (p[2] == 'f')) ||
66d30ea906Sjfb8856606 ((p[0] == 'O') && (p[1] == 'F') && (p[2] == 'F'))) {
67d30ea906Sjfb8856606 p += 3;
68d30ea906Sjfb8856606 result = 0;
69d30ea906Sjfb8856606 }
70d30ea906Sjfb8856606
71d30ea906Sjfb8856606 p = skip_white_spaces(p);
72d30ea906Sjfb8856606
73d30ea906Sjfb8856606 if (p[0] != '\0')
74d30ea906Sjfb8856606 return -EINVAL;
75d30ea906Sjfb8856606
76d30ea906Sjfb8856606 return result;
77d30ea906Sjfb8856606 }
78d30ea906Sjfb8856606
79d30ea906Sjfb8856606 int
softnic_parser_read_int32(int32_t * value,const char * p)80d30ea906Sjfb8856606 softnic_parser_read_int32(int32_t *value, const char *p)
81d30ea906Sjfb8856606 {
82d30ea906Sjfb8856606 char *next;
83d30ea906Sjfb8856606 int32_t val;
84d30ea906Sjfb8856606
85d30ea906Sjfb8856606 p = skip_white_spaces(p);
86d30ea906Sjfb8856606 if (!isdigit(*p))
87d30ea906Sjfb8856606 return -EINVAL;
88d30ea906Sjfb8856606
89d30ea906Sjfb8856606 val = strtol(p, &next, 10);
90d30ea906Sjfb8856606 if (p == next)
91d30ea906Sjfb8856606 return -EINVAL;
92d30ea906Sjfb8856606
93d30ea906Sjfb8856606 *value = val;
94d30ea906Sjfb8856606 return 0;
95d30ea906Sjfb8856606 }
96d30ea906Sjfb8856606
97d30ea906Sjfb8856606 int
softnic_parser_read_uint64(uint64_t * value,const char * p)98d30ea906Sjfb8856606 softnic_parser_read_uint64(uint64_t *value, const char *p)
99d30ea906Sjfb8856606 {
100d30ea906Sjfb8856606 char *next;
101d30ea906Sjfb8856606 uint64_t val;
102d30ea906Sjfb8856606
103d30ea906Sjfb8856606 p = skip_white_spaces(p);
104d30ea906Sjfb8856606 if (!isdigit(*p))
105d30ea906Sjfb8856606 return -EINVAL;
106d30ea906Sjfb8856606
107d30ea906Sjfb8856606 val = strtoul(p, &next, 10);
108d30ea906Sjfb8856606 if (p == next)
109d30ea906Sjfb8856606 return -EINVAL;
110d30ea906Sjfb8856606
111d30ea906Sjfb8856606 p = next;
112d30ea906Sjfb8856606 switch (*p) {
113d30ea906Sjfb8856606 case 'T':
114d30ea906Sjfb8856606 val *= 1024ULL;
115d30ea906Sjfb8856606 /* fall through */
116d30ea906Sjfb8856606 case 'G':
117d30ea906Sjfb8856606 val *= 1024ULL;
118d30ea906Sjfb8856606 /* fall through */
119d30ea906Sjfb8856606 case 'M':
120d30ea906Sjfb8856606 val *= 1024ULL;
121d30ea906Sjfb8856606 /* fall through */
122d30ea906Sjfb8856606 case 'k':
123d30ea906Sjfb8856606 case 'K':
124d30ea906Sjfb8856606 val *= 1024ULL;
125d30ea906Sjfb8856606 p++;
126d30ea906Sjfb8856606 break;
127d30ea906Sjfb8856606 }
128d30ea906Sjfb8856606
129d30ea906Sjfb8856606 p = skip_white_spaces(p);
130d30ea906Sjfb8856606 if (*p != '\0')
131d30ea906Sjfb8856606 return -EINVAL;
132d30ea906Sjfb8856606
133d30ea906Sjfb8856606 *value = val;
134d30ea906Sjfb8856606 return 0;
135d30ea906Sjfb8856606 }
136d30ea906Sjfb8856606
137d30ea906Sjfb8856606 int
softnic_parser_read_uint64_hex(uint64_t * value,const char * p)138d30ea906Sjfb8856606 softnic_parser_read_uint64_hex(uint64_t *value, const char *p)
139d30ea906Sjfb8856606 {
140d30ea906Sjfb8856606 char *next;
141d30ea906Sjfb8856606 uint64_t val;
142d30ea906Sjfb8856606
143d30ea906Sjfb8856606 p = skip_white_spaces(p);
144d30ea906Sjfb8856606
145d30ea906Sjfb8856606 val = strtoul(p, &next, 16);
146d30ea906Sjfb8856606 if (p == next)
147d30ea906Sjfb8856606 return -EINVAL;
148d30ea906Sjfb8856606
149d30ea906Sjfb8856606 p = skip_white_spaces(next);
150d30ea906Sjfb8856606 if (*p != '\0')
151d30ea906Sjfb8856606 return -EINVAL;
152d30ea906Sjfb8856606
153d30ea906Sjfb8856606 *value = val;
154d30ea906Sjfb8856606 return 0;
155d30ea906Sjfb8856606 }
156d30ea906Sjfb8856606
157d30ea906Sjfb8856606 int
softnic_parser_read_uint32(uint32_t * value,const char * p)158d30ea906Sjfb8856606 softnic_parser_read_uint32(uint32_t *value, const char *p)
159d30ea906Sjfb8856606 {
160d30ea906Sjfb8856606 uint64_t val = 0;
161d30ea906Sjfb8856606 int ret = softnic_parser_read_uint64(&val, p);
162d30ea906Sjfb8856606
163d30ea906Sjfb8856606 if (ret < 0)
164d30ea906Sjfb8856606 return ret;
165d30ea906Sjfb8856606
166d30ea906Sjfb8856606 if (val > UINT32_MAX)
167d30ea906Sjfb8856606 return -ERANGE;
168d30ea906Sjfb8856606
169d30ea906Sjfb8856606 *value = val;
170d30ea906Sjfb8856606 return 0;
171d30ea906Sjfb8856606 }
172d30ea906Sjfb8856606
173d30ea906Sjfb8856606 int
softnic_parser_read_uint32_hex(uint32_t * value,const char * p)174d30ea906Sjfb8856606 softnic_parser_read_uint32_hex(uint32_t *value, const char *p)
175d30ea906Sjfb8856606 {
176d30ea906Sjfb8856606 uint64_t val = 0;
177d30ea906Sjfb8856606 int ret = softnic_parser_read_uint64_hex(&val, p);
178d30ea906Sjfb8856606
179d30ea906Sjfb8856606 if (ret < 0)
180d30ea906Sjfb8856606 return ret;
181d30ea906Sjfb8856606
182d30ea906Sjfb8856606 if (val > UINT32_MAX)
183d30ea906Sjfb8856606 return -ERANGE;
184d30ea906Sjfb8856606
185d30ea906Sjfb8856606 *value = val;
186d30ea906Sjfb8856606 return 0;
187d30ea906Sjfb8856606 }
188d30ea906Sjfb8856606
189d30ea906Sjfb8856606 int
softnic_parser_read_uint16(uint16_t * value,const char * p)190d30ea906Sjfb8856606 softnic_parser_read_uint16(uint16_t *value, const char *p)
191d30ea906Sjfb8856606 {
192d30ea906Sjfb8856606 uint64_t val = 0;
193d30ea906Sjfb8856606 int ret = softnic_parser_read_uint64(&val, p);
194d30ea906Sjfb8856606
195d30ea906Sjfb8856606 if (ret < 0)
196d30ea906Sjfb8856606 return ret;
197d30ea906Sjfb8856606
198d30ea906Sjfb8856606 if (val > UINT16_MAX)
199d30ea906Sjfb8856606 return -ERANGE;
200d30ea906Sjfb8856606
201d30ea906Sjfb8856606 *value = val;
202d30ea906Sjfb8856606 return 0;
203d30ea906Sjfb8856606 }
204d30ea906Sjfb8856606
205d30ea906Sjfb8856606 int
softnic_parser_read_uint16_hex(uint16_t * value,const char * p)206d30ea906Sjfb8856606 softnic_parser_read_uint16_hex(uint16_t *value, const char *p)
207d30ea906Sjfb8856606 {
208d30ea906Sjfb8856606 uint64_t val = 0;
209d30ea906Sjfb8856606 int ret = softnic_parser_read_uint64_hex(&val, p);
210d30ea906Sjfb8856606
211d30ea906Sjfb8856606 if (ret < 0)
212d30ea906Sjfb8856606 return ret;
213d30ea906Sjfb8856606
214d30ea906Sjfb8856606 if (val > UINT16_MAX)
215d30ea906Sjfb8856606 return -ERANGE;
216d30ea906Sjfb8856606
217d30ea906Sjfb8856606 *value = val;
218d30ea906Sjfb8856606 return 0;
219d30ea906Sjfb8856606 }
220d30ea906Sjfb8856606
221d30ea906Sjfb8856606 int
softnic_parser_read_uint8(uint8_t * value,const char * p)222d30ea906Sjfb8856606 softnic_parser_read_uint8(uint8_t *value, const char *p)
223d30ea906Sjfb8856606 {
224d30ea906Sjfb8856606 uint64_t val = 0;
225d30ea906Sjfb8856606 int ret = softnic_parser_read_uint64(&val, p);
226d30ea906Sjfb8856606
227d30ea906Sjfb8856606 if (ret < 0)
228d30ea906Sjfb8856606 return ret;
229d30ea906Sjfb8856606
230d30ea906Sjfb8856606 if (val > UINT8_MAX)
231d30ea906Sjfb8856606 return -ERANGE;
232d30ea906Sjfb8856606
233d30ea906Sjfb8856606 *value = val;
234d30ea906Sjfb8856606 return 0;
235d30ea906Sjfb8856606 }
236d30ea906Sjfb8856606
237d30ea906Sjfb8856606 int
softnic_parser_read_uint8_hex(uint8_t * value,const char * p)238d30ea906Sjfb8856606 softnic_parser_read_uint8_hex(uint8_t *value, const char *p)
239d30ea906Sjfb8856606 {
240d30ea906Sjfb8856606 uint64_t val = 0;
241d30ea906Sjfb8856606 int ret = softnic_parser_read_uint64_hex(&val, p);
242d30ea906Sjfb8856606
243d30ea906Sjfb8856606 if (ret < 0)
244d30ea906Sjfb8856606 return ret;
245d30ea906Sjfb8856606
246d30ea906Sjfb8856606 if (val > UINT8_MAX)
247d30ea906Sjfb8856606 return -ERANGE;
248d30ea906Sjfb8856606
249d30ea906Sjfb8856606 *value = val;
250d30ea906Sjfb8856606 return 0;
251d30ea906Sjfb8856606 }
252d30ea906Sjfb8856606
253d30ea906Sjfb8856606 int
softnic_parse_tokenize_string(char * string,char * tokens[],uint32_t * n_tokens)254d30ea906Sjfb8856606 softnic_parse_tokenize_string(char *string, char *tokens[], uint32_t *n_tokens)
255d30ea906Sjfb8856606 {
256d30ea906Sjfb8856606 uint32_t i;
257d30ea906Sjfb8856606
258d30ea906Sjfb8856606 if (string == NULL ||
259d30ea906Sjfb8856606 tokens == NULL ||
260d30ea906Sjfb8856606 (*n_tokens < 1))
261d30ea906Sjfb8856606 return -EINVAL;
262d30ea906Sjfb8856606
263d30ea906Sjfb8856606 for (i = 0; i < *n_tokens; i++) {
264d30ea906Sjfb8856606 tokens[i] = strtok_r(string, PARSE_DELIMITER, &string);
265d30ea906Sjfb8856606 if (tokens[i] == NULL)
266d30ea906Sjfb8856606 break;
267d30ea906Sjfb8856606 }
268d30ea906Sjfb8856606
269d30ea906Sjfb8856606 if (i == *n_tokens &&
270d30ea906Sjfb8856606 strtok_r(string, PARSE_DELIMITER, &string) != NULL)
271d30ea906Sjfb8856606 return -E2BIG;
272d30ea906Sjfb8856606
273d30ea906Sjfb8856606 *n_tokens = i;
274d30ea906Sjfb8856606 return 0;
275d30ea906Sjfb8856606 }
276d30ea906Sjfb8856606
277d30ea906Sjfb8856606 int
softnic_parse_hex_string(char * src,uint8_t * dst,uint32_t * size)278d30ea906Sjfb8856606 softnic_parse_hex_string(char *src, uint8_t *dst, uint32_t *size)
279d30ea906Sjfb8856606 {
280d30ea906Sjfb8856606 char *c;
281d30ea906Sjfb8856606 uint32_t len, i;
282d30ea906Sjfb8856606
283d30ea906Sjfb8856606 /* Check input parameters */
284d30ea906Sjfb8856606 if (src == NULL ||
285d30ea906Sjfb8856606 dst == NULL ||
286d30ea906Sjfb8856606 size == NULL ||
287d30ea906Sjfb8856606 (*size == 0))
288d30ea906Sjfb8856606 return -1;
289d30ea906Sjfb8856606
290d30ea906Sjfb8856606 len = strlen(src);
291d30ea906Sjfb8856606 if (((len & 3) != 0) ||
292d30ea906Sjfb8856606 (len > (*size) * 2))
293d30ea906Sjfb8856606 return -1;
294d30ea906Sjfb8856606 *size = len / 2;
295d30ea906Sjfb8856606
296d30ea906Sjfb8856606 for (c = src; *c != 0; c++) {
297d30ea906Sjfb8856606 if ((((*c) >= '0') && ((*c) <= '9')) ||
298d30ea906Sjfb8856606 (((*c) >= 'A') && ((*c) <= 'F')) ||
299d30ea906Sjfb8856606 (((*c) >= 'a') && ((*c) <= 'f')))
300d30ea906Sjfb8856606 continue;
301d30ea906Sjfb8856606
302d30ea906Sjfb8856606 return -1;
303d30ea906Sjfb8856606 }
304d30ea906Sjfb8856606
305d30ea906Sjfb8856606 /* Convert chars to bytes */
306d30ea906Sjfb8856606 for (i = 0; i < *size; i++)
307d30ea906Sjfb8856606 dst[i] = get_hex_val(src[2 * i]) * 16 +
308d30ea906Sjfb8856606 get_hex_val(src[2 * i + 1]);
309d30ea906Sjfb8856606
310d30ea906Sjfb8856606 return 0;
311d30ea906Sjfb8856606 }
312d30ea906Sjfb8856606
313d30ea906Sjfb8856606 int
softnic_parse_mpls_labels(char * string,uint32_t * labels,uint32_t * n_labels)314d30ea906Sjfb8856606 softnic_parse_mpls_labels(char *string, uint32_t *labels, uint32_t *n_labels)
315d30ea906Sjfb8856606 {
316d30ea906Sjfb8856606 uint32_t n_max_labels = *n_labels, count = 0;
317d30ea906Sjfb8856606
318d30ea906Sjfb8856606 /* Check for void list of labels */
319d30ea906Sjfb8856606 if (strcmp(string, "<void>") == 0) {
320d30ea906Sjfb8856606 *n_labels = 0;
321d30ea906Sjfb8856606 return 0;
322d30ea906Sjfb8856606 }
323d30ea906Sjfb8856606
324d30ea906Sjfb8856606 /* At least one label should be present */
325d30ea906Sjfb8856606 for ( ; (*string != '\0'); ) {
326d30ea906Sjfb8856606 char *next;
327d30ea906Sjfb8856606 int value;
328d30ea906Sjfb8856606
329d30ea906Sjfb8856606 if (count >= n_max_labels)
330d30ea906Sjfb8856606 return -1;
331d30ea906Sjfb8856606
332d30ea906Sjfb8856606 if (count > 0) {
333d30ea906Sjfb8856606 if (string[0] != ':')
334d30ea906Sjfb8856606 return -1;
335d30ea906Sjfb8856606
336d30ea906Sjfb8856606 string++;
337d30ea906Sjfb8856606 }
338d30ea906Sjfb8856606
339d30ea906Sjfb8856606 value = strtol(string, &next, 10);
340d30ea906Sjfb8856606 if (next == string)
341d30ea906Sjfb8856606 return -1;
342d30ea906Sjfb8856606 string = next;
343d30ea906Sjfb8856606
344d30ea906Sjfb8856606 labels[count++] = (uint32_t)value;
345d30ea906Sjfb8856606 }
346d30ea906Sjfb8856606
347d30ea906Sjfb8856606 *n_labels = count;
348d30ea906Sjfb8856606 return 0;
349d30ea906Sjfb8856606 }
350d30ea906Sjfb8856606
3514418919fSjohnjiang static struct rte_ether_addr *
my_ether_aton(const char * a)352d30ea906Sjfb8856606 my_ether_aton(const char *a)
353d30ea906Sjfb8856606 {
354d30ea906Sjfb8856606 int i;
355d30ea906Sjfb8856606 char *end;
3564418919fSjohnjiang unsigned long o[RTE_ETHER_ADDR_LEN];
3574418919fSjohnjiang static struct rte_ether_addr ether_addr;
358d30ea906Sjfb8856606
359d30ea906Sjfb8856606 i = 0;
360d30ea906Sjfb8856606 do {
361d30ea906Sjfb8856606 errno = 0;
362d30ea906Sjfb8856606 o[i] = strtoul(a, &end, 16);
363d30ea906Sjfb8856606 if (errno != 0 || end == a || (end[0] != ':' && end[0] != 0))
364d30ea906Sjfb8856606 return NULL;
365d30ea906Sjfb8856606 a = end + 1;
366d30ea906Sjfb8856606 } while (++i != sizeof(o) / sizeof(o[0]) && end[0] != 0);
367d30ea906Sjfb8856606
368d30ea906Sjfb8856606 /* Junk at the end of line */
369d30ea906Sjfb8856606 if (end[0] != 0)
370d30ea906Sjfb8856606 return NULL;
371d30ea906Sjfb8856606
372d30ea906Sjfb8856606 /* Support the format XX:XX:XX:XX:XX:XX */
3734418919fSjohnjiang if (i == RTE_ETHER_ADDR_LEN) {
374d30ea906Sjfb8856606 while (i-- != 0) {
375d30ea906Sjfb8856606 if (o[i] > UINT8_MAX)
376d30ea906Sjfb8856606 return NULL;
377d30ea906Sjfb8856606 ether_addr.addr_bytes[i] = (uint8_t)o[i];
378d30ea906Sjfb8856606 }
379d30ea906Sjfb8856606 /* Support the format XXXX:XXXX:XXXX */
3804418919fSjohnjiang } else if (i == RTE_ETHER_ADDR_LEN / 2) {
381d30ea906Sjfb8856606 while (i-- != 0) {
382d30ea906Sjfb8856606 if (o[i] > UINT16_MAX)
383d30ea906Sjfb8856606 return NULL;
384d30ea906Sjfb8856606 ether_addr.addr_bytes[i * 2] = (uint8_t)(o[i] >> 8);
385d30ea906Sjfb8856606 ether_addr.addr_bytes[i * 2 + 1] = (uint8_t)(o[i] & 0xff);
386d30ea906Sjfb8856606 }
387d30ea906Sjfb8856606 /* unknown format */
388d30ea906Sjfb8856606 } else
389d30ea906Sjfb8856606 return NULL;
390d30ea906Sjfb8856606
3914418919fSjohnjiang return (struct rte_ether_addr *)ðer_addr;
392d30ea906Sjfb8856606 }
393d30ea906Sjfb8856606
394d30ea906Sjfb8856606 int
softnic_parse_ipv4_addr(const char * token,struct in_addr * ipv4)395d30ea906Sjfb8856606 softnic_parse_ipv4_addr(const char *token, struct in_addr *ipv4)
396d30ea906Sjfb8856606 {
397d30ea906Sjfb8856606 if (strlen(token) >= INET_ADDRSTRLEN)
398d30ea906Sjfb8856606 return -EINVAL;
399d30ea906Sjfb8856606
400*0c6bd470Sfengbojiang if (inet_pton(AF_INET, token, ipv4) != 1)
401d30ea906Sjfb8856606 return -EINVAL;
402d30ea906Sjfb8856606
403d30ea906Sjfb8856606 return 0;
404d30ea906Sjfb8856606 }
405d30ea906Sjfb8856606
406d30ea906Sjfb8856606 int
softnic_parse_ipv6_addr(const char * token,struct in6_addr * ipv6)407d30ea906Sjfb8856606 softnic_parse_ipv6_addr(const char *token, struct in6_addr *ipv6)
408d30ea906Sjfb8856606 {
409d30ea906Sjfb8856606 if (strlen(token) >= INET6_ADDRSTRLEN)
410d30ea906Sjfb8856606 return -EINVAL;
411d30ea906Sjfb8856606
412*0c6bd470Sfengbojiang if (inet_pton(AF_INET6, token, ipv6) != 1)
413d30ea906Sjfb8856606 return -EINVAL;
414d30ea906Sjfb8856606
415d30ea906Sjfb8856606 return 0;
416d30ea906Sjfb8856606 }
417d30ea906Sjfb8856606
418d30ea906Sjfb8856606 int
softnic_parse_mac_addr(const char * token,struct rte_ether_addr * addr)4194418919fSjohnjiang softnic_parse_mac_addr(const char *token, struct rte_ether_addr *addr)
420d30ea906Sjfb8856606 {
4214418919fSjohnjiang struct rte_ether_addr *tmp;
422d30ea906Sjfb8856606
423d30ea906Sjfb8856606 tmp = my_ether_aton(token);
424d30ea906Sjfb8856606 if (tmp == NULL)
425d30ea906Sjfb8856606 return -1;
426d30ea906Sjfb8856606
4274418919fSjohnjiang memcpy(addr, tmp, sizeof(struct rte_ether_addr));
428d30ea906Sjfb8856606 return 0;
429d30ea906Sjfb8856606 }
430d30ea906Sjfb8856606
431d30ea906Sjfb8856606 int
softnic_parse_cpu_core(const char * entry,struct softnic_cpu_core_params * p)432d30ea906Sjfb8856606 softnic_parse_cpu_core(const char *entry,
433d30ea906Sjfb8856606 struct softnic_cpu_core_params *p)
434d30ea906Sjfb8856606 {
435d30ea906Sjfb8856606 size_t num_len;
436d30ea906Sjfb8856606 char num[8];
437d30ea906Sjfb8856606
438d30ea906Sjfb8856606 uint32_t s = 0, c = 0, h = 0, val;
439d30ea906Sjfb8856606 uint8_t s_parsed = 0, c_parsed = 0, h_parsed = 0;
440d30ea906Sjfb8856606 const char *next = skip_white_spaces(entry);
441d30ea906Sjfb8856606 char type;
442d30ea906Sjfb8856606
443d30ea906Sjfb8856606 if (p == NULL)
444d30ea906Sjfb8856606 return -EINVAL;
445d30ea906Sjfb8856606
446d30ea906Sjfb8856606 /* Expect <CORE> or [sX][cY][h]. At least one parameter is required. */
447d30ea906Sjfb8856606 while (*next != '\0') {
448d30ea906Sjfb8856606 /* If everything parsed nothing should left */
449d30ea906Sjfb8856606 if (s_parsed && c_parsed && h_parsed)
450d30ea906Sjfb8856606 return -EINVAL;
451d30ea906Sjfb8856606
452d30ea906Sjfb8856606 type = *next;
453d30ea906Sjfb8856606 switch (type) {
454d30ea906Sjfb8856606 case 's':
455d30ea906Sjfb8856606 case 'S':
456d30ea906Sjfb8856606 if (s_parsed || c_parsed || h_parsed)
457d30ea906Sjfb8856606 return -EINVAL;
458d30ea906Sjfb8856606 s_parsed = 1;
459d30ea906Sjfb8856606 next++;
460d30ea906Sjfb8856606 break;
461d30ea906Sjfb8856606 case 'c':
462d30ea906Sjfb8856606 case 'C':
463d30ea906Sjfb8856606 if (c_parsed || h_parsed)
464d30ea906Sjfb8856606 return -EINVAL;
465d30ea906Sjfb8856606 c_parsed = 1;
466d30ea906Sjfb8856606 next++;
467d30ea906Sjfb8856606 break;
468d30ea906Sjfb8856606 case 'h':
469d30ea906Sjfb8856606 case 'H':
470d30ea906Sjfb8856606 if (h_parsed)
471d30ea906Sjfb8856606 return -EINVAL;
472d30ea906Sjfb8856606 h_parsed = 1;
473d30ea906Sjfb8856606 next++;
474d30ea906Sjfb8856606 break;
475d30ea906Sjfb8856606 default:
476d30ea906Sjfb8856606 /* If it start from digit it must be only core id. */
477d30ea906Sjfb8856606 if (!isdigit(*next) || s_parsed || c_parsed || h_parsed)
478d30ea906Sjfb8856606 return -EINVAL;
479d30ea906Sjfb8856606
480d30ea906Sjfb8856606 type = 'C';
481d30ea906Sjfb8856606 }
482d30ea906Sjfb8856606
483d30ea906Sjfb8856606 for (num_len = 0; *next != '\0'; next++, num_len++) {
484d30ea906Sjfb8856606 if (num_len == RTE_DIM(num))
485d30ea906Sjfb8856606 return -EINVAL;
486d30ea906Sjfb8856606
487d30ea906Sjfb8856606 if (!isdigit(*next))
488d30ea906Sjfb8856606 break;
489d30ea906Sjfb8856606
490d30ea906Sjfb8856606 num[num_len] = *next;
491d30ea906Sjfb8856606 }
492d30ea906Sjfb8856606
493d30ea906Sjfb8856606 if (num_len == 0 && type != 'h' && type != 'H')
494d30ea906Sjfb8856606 return -EINVAL;
495d30ea906Sjfb8856606
496d30ea906Sjfb8856606 if (num_len != 0 && (type == 'h' || type == 'H'))
497d30ea906Sjfb8856606 return -EINVAL;
498d30ea906Sjfb8856606
499d30ea906Sjfb8856606 num[num_len] = '\0';
500d30ea906Sjfb8856606 val = strtol(num, NULL, 10);
501d30ea906Sjfb8856606
502d30ea906Sjfb8856606 h = 0;
503d30ea906Sjfb8856606 switch (type) {
504d30ea906Sjfb8856606 case 's':
505d30ea906Sjfb8856606 case 'S':
506d30ea906Sjfb8856606 s = val;
507d30ea906Sjfb8856606 break;
508d30ea906Sjfb8856606 case 'c':
509d30ea906Sjfb8856606 case 'C':
510d30ea906Sjfb8856606 c = val;
511d30ea906Sjfb8856606 break;
512d30ea906Sjfb8856606 case 'h':
513d30ea906Sjfb8856606 case 'H':
514d30ea906Sjfb8856606 h = 1;
515d30ea906Sjfb8856606 break;
516d30ea906Sjfb8856606 }
517d30ea906Sjfb8856606 }
518d30ea906Sjfb8856606
519d30ea906Sjfb8856606 p->socket_id = s;
520d30ea906Sjfb8856606 p->core_id = c;
521d30ea906Sjfb8856606 p->thread_id = h;
522d30ea906Sjfb8856606 return 0;
523d30ea906Sjfb8856606 }
524