]>
git.proxmox.com Git - ceph.git/blob - ceph/src/dpdk/examples/ip_pipeline/parser.c
4 * Copyright(c) 2016 Intel Corporation. All rights reserved.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 * * Redistributions in binary form must reproduce the above copyright
14 * notice, this list of conditions and the following disclaimer in
15 * the documentation and/or other materials provided with the
17 * * Neither the name of Intel Corporation nor the names of its
18 * contributors may be used to endorse or promote products derived
19 * from this software without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
35 * For my_ether_aton() function:
37 * Copyright (c) 2009, Olivier MATZ <zer0@droids-corp.org>
38 * All rights reserved.
39 * Redistribution and use in source and binary forms, with or without
40 * modification, are permitted provided that the following conditions are met:
42 * * Redistributions of source code must retain the above copyright
43 * notice, this list of conditions and the following disclaimer.
44 * * Redistributions in binary form must reproduce the above copyright
45 * notice, this list of conditions and the following disclaimer in the
46 * documentation and/or other materials provided with the distribution.
47 * * Neither the name of the University of California, Berkeley nor the
48 * names of its contributors may be used to endorse or promote products
49 * derived from this software without specific prior written permission.
51 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND ANY
52 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
53 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
54 * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
55 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
56 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
57 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
58 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
59 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
60 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
64 * For inet_pton4() and inet_pton6() functions:
66 * Copyright (c) 1996 by Internet Software Consortium.
68 * Permission to use, copy, modify, and distribute this software for any
69 * purpose with or without fee is hereby granted, provided that the above
70 * copyright notice and this permission notice appear in all copies.
72 * THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
73 * ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
74 * OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
75 * CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
76 * DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
77 * PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
78 * ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
94 #include <rte_errno.h>
95 #include <rte_cfgfile.h>
96 #include <rte_string_fns.h>
105 case '0': case '1': case '2': case '3': case '4': case '5':
106 case '6': case '7': case '8': case '9':
108 case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
110 case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
118 parser_read_arg_bool(const char *p
)
120 p
= skip_white_spaces(p
);
121 int result
= -EINVAL
;
123 if (((p
[0] == 'y') && (p
[1] == 'e') && (p
[2] == 's')) ||
124 ((p
[0] == 'Y') && (p
[1] == 'E') && (p
[2] == 'S'))) {
129 if (((p
[0] == 'o') && (p
[1] == 'n')) ||
130 ((p
[0] == 'O') && (p
[1] == 'N'))) {
135 if (((p
[0] == 'n') && (p
[1] == 'o')) ||
136 ((p
[0] == 'N') && (p
[1] == 'O'))) {
141 if (((p
[0] == 'o') && (p
[1] == 'f') && (p
[2] == 'f')) ||
142 ((p
[0] == 'O') && (p
[1] == 'F') && (p
[2] == 'F'))) {
147 p
= skip_white_spaces(p
);
156 parser_read_uint64(uint64_t *value
, const char *p
)
161 p
= skip_white_spaces(p
);
165 val
= strtoul(p
, &next
, 10);
187 p
= skip_white_spaces(p
);
196 parser_read_uint64_hex(uint64_t *value
, const char *p
)
201 p
= skip_white_spaces(p
);
203 val
= strtoul(p
, &next
, 16);
207 p
= skip_white_spaces(next
);
216 parser_read_uint32(uint32_t *value
, const char *p
)
219 int ret
= parser_read_uint64(&val
, p
);
224 if (val
> UINT32_MAX
)
232 parser_read_uint32_hex(uint32_t *value
, const char *p
)
235 int ret
= parser_read_uint64_hex(&val
, p
);
240 if (val
> UINT32_MAX
)
248 parser_read_uint16(uint16_t *value
, const char *p
)
251 int ret
= parser_read_uint64(&val
, p
);
256 if (val
> UINT16_MAX
)
264 parser_read_uint16_hex(uint16_t *value
, const char *p
)
267 int ret
= parser_read_uint64_hex(&val
, p
);
272 if (val
> UINT16_MAX
)
280 parser_read_uint8(uint8_t *value
, const char *p
)
283 int ret
= parser_read_uint64(&val
, p
);
296 parser_read_uint8_hex(uint8_t *value
, const char *p
)
299 int ret
= parser_read_uint64_hex(&val
, p
);
312 parse_tokenize_string(char *string
, char *tokens
[], uint32_t *n_tokens
)
316 if ((string
== NULL
) ||
321 for (i
= 0; i
< *n_tokens
; i
++) {
322 tokens
[i
] = strtok_r(string
, PARSE_DELIMITER
, &string
);
323 if (tokens
[i
] == NULL
)
327 if ((i
== *n_tokens
) &&
328 (NULL
!= strtok_r(string
, PARSE_DELIMITER
, &string
)))
336 parse_hex_string(char *src
, uint8_t *dst
, uint32_t *size
)
341 /* Check input parameters */
349 if (((len
& 3) != 0) ||
354 for (c
= src
; *c
!= 0; c
++) {
355 if ((((*c
) >= '0') && ((*c
) <= '9')) ||
356 (((*c
) >= 'A') && ((*c
) <= 'F')) ||
357 (((*c
) >= 'a') && ((*c
) <= 'f')))
363 /* Convert chars to bytes */
364 for (i
= 0; i
< *size
; i
++)
365 dst
[i
] = get_hex_val(src
[2 * i
]) * 16 +
366 get_hex_val(src
[2 * i
+ 1]);
372 parse_mpls_labels(char *string
, uint32_t *labels
, uint32_t *n_labels
)
374 uint32_t n_max_labels
= *n_labels
, count
= 0;
376 /* Check for void list of labels */
377 if (strcmp(string
, "<void>") == 0) {
382 /* At least one label should be present */
383 for ( ; (*string
!= '\0'); ) {
387 if (count
>= n_max_labels
)
391 if (string
[0] != ':')
397 value
= strtol(string
, &next
, 10);
402 labels
[count
++] = (uint32_t) value
;
413 * inet_pton4(src, dst)
414 * like inet_aton() but without all the hexadecimal and shorthand.
416 * 1 if `src' is a valid dotted quad, else 0.
418 * does not touch `dst' unless it's returning 1.
423 inet_pton4(const char *src
, unsigned char *dst
)
425 static const char digits
[] = "0123456789";
426 int saw_digit
, octets
, ch
;
427 unsigned char tmp
[INADDRSZ
], *tp
;
432 while ((ch
= *src
++) != '\0') {
435 pch
= strchr(digits
, ch
);
437 unsigned int new = *tp
* 10 + (pch
- digits
);
446 *tp
= (unsigned char)new;
447 } else if (ch
== '.' && saw_digit
) {
458 memcpy(dst
, tmp
, INADDRSZ
);
463 * inet_pton6(src, dst)
464 * convert presentation level address to network order binary form.
466 * 1 if `src' is a valid [RFC1884 2.2] address, else 0.
468 * (1) does not touch `dst' unless it's returning 1.
469 * (2) :: in a full address is silently ignored.
471 * inspired by Mark Andrews.
476 inet_pton6(const char *src
, unsigned char *dst
)
478 static const char xdigits_l
[] = "0123456789abcdef",
479 xdigits_u
[] = "0123456789ABCDEF";
480 unsigned char tmp
[IN6ADDRSZ
], *tp
= 0, *endp
= 0, *colonp
= 0;
481 const char *xdigits
= 0, *curtok
= 0;
482 int ch
= 0, saw_xdigit
= 0, count_xdigit
= 0;
483 unsigned int val
= 0;
484 unsigned dbloct_count
= 0;
486 memset((tp
= tmp
), '\0', IN6ADDRSZ
);
487 endp
= tp
+ IN6ADDRSZ
;
489 /* Leading :: requires some special handling. */
494 saw_xdigit
= count_xdigit
= 0;
497 while ((ch
= *src
++) != '\0') {
500 pch
= strchr((xdigits
= xdigits_l
), ch
);
502 pch
= strchr((xdigits
= xdigits_u
), ch
);
504 if (count_xdigit
>= 4)
507 val
|= (pch
- xdigits
);
521 } else if (*src
== '\0') {
524 if (tp
+ sizeof(int16_t) > endp
)
526 *tp
++ = (unsigned char) ((val
>> 8) & 0xff);
527 *tp
++ = (unsigned char) (val
& 0xff);
534 if (ch
== '.' && ((tp
+ INADDRSZ
) <= endp
) &&
535 inet_pton4(curtok
, tp
) > 0) {
539 break; /* '\0' was seen by inet_pton4(). */
544 if (tp
+ sizeof(int16_t) > endp
)
546 *tp
++ = (unsigned char) ((val
>> 8) & 0xff);
547 *tp
++ = (unsigned char) (val
& 0xff);
550 if (colonp
!= NULL
) {
551 /* if we already have 8 double octets, having a colon means error */
552 if (dbloct_count
== 8)
556 * Since some memmove()'s erroneously fail to handle
557 * overlapping regions, we'll do the shift by hand.
559 const int n
= tp
- colonp
;
562 for (i
= 1; i
<= n
; i
++) {
563 endp
[-i
] = colonp
[n
- i
];
570 memcpy(dst
, tmp
, IN6ADDRSZ
);
574 static struct ether_addr
*
575 my_ether_aton(const char *a
)
579 unsigned long o
[ETHER_ADDR_LEN
];
580 static struct ether_addr ether_addr
;
585 o
[i
] = strtoul(a
, &end
, 16);
586 if (errno
!= 0 || end
== a
|| (end
[0] != ':' && end
[0] != 0))
589 } while (++i
!= sizeof(o
) / sizeof(o
[0]) && end
[0] != 0);
591 /* Junk at the end of line */
595 /* Support the format XX:XX:XX:XX:XX:XX */
596 if (i
== ETHER_ADDR_LEN
) {
598 if (o
[i
] > UINT8_MAX
)
600 ether_addr
.addr_bytes
[i
] = (uint8_t)o
[i
];
602 /* Support the format XXXX:XXXX:XXXX */
603 } else if (i
== ETHER_ADDR_LEN
/ 2) {
605 if (o
[i
] > UINT16_MAX
)
607 ether_addr
.addr_bytes
[i
* 2] = (uint8_t)(o
[i
] >> 8);
608 ether_addr
.addr_bytes
[i
* 2 + 1] = (uint8_t)(o
[i
] & 0xff);
614 return (struct ether_addr
*)ðer_addr
;
618 parse_ipv4_addr(const char *token
, struct in_addr
*ipv4
)
620 if (strlen(token
) >= INET_ADDRSTRLEN
)
623 if (inet_pton4(token
, (unsigned char *)ipv4
) != 1)
630 parse_ipv6_addr(const char *token
, struct in6_addr
*ipv6
)
632 if (strlen(token
) >= INET6_ADDRSTRLEN
)
635 if (inet_pton6(token
, (unsigned char *)ipv6
) != 1)
642 parse_mac_addr(const char *token
, struct ether_addr
*addr
)
644 struct ether_addr
*tmp
;
646 tmp
= my_ether_aton(token
);
650 memcpy(addr
, tmp
, sizeof(struct ether_addr
));
655 parse_pipeline_core(uint32_t *socket
,
663 uint32_t s
= 0, c
= 0, h
= 0, val
;
664 uint8_t s_parsed
= 0, c_parsed
= 0, h_parsed
= 0;
665 const char *next
= skip_white_spaces(entry
);
668 /* Expect <CORE> or [sX][cY][h]. At least one parameter is required. */
669 while (*next
!= '\0') {
670 /* If everything parsed nothing should left */
671 if (s_parsed
&& c_parsed
&& h_parsed
)
678 if (s_parsed
|| c_parsed
|| h_parsed
)
685 if (c_parsed
|| h_parsed
)
698 /* If it start from digit it must be only core id. */
699 if (!isdigit(*next
) || s_parsed
|| c_parsed
|| h_parsed
)
705 for (num_len
= 0; *next
!= '\0'; next
++, num_len
++) {
706 if (num_len
== RTE_DIM(num
))
712 num
[num_len
] = *next
;
715 if (num_len
== 0 && type
!= 'h' && type
!= 'H')
718 if (num_len
!= 0 && (type
== 'h' || type
== 'H'))
722 val
= strtol(num
, NULL
, 10);