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