]> git.proxmox.com Git - mirror_iproute2.git/blob - lib/mpls_pton.c
tc: m_tunnel_key: Allow key-less tunnels
[mirror_iproute2.git] / lib / mpls_pton.c
1 /* SPDX-License-Identifier: GPL-2.0 */
2
3 #include <errno.h>
4 #include <string.h>
5 #include <sys/types.h>
6 #include <netinet/in.h>
7 #include <linux/mpls.h>
8
9 #include "utils.h"
10
11
12 static int mpls_pton1(const char *name, struct mpls_label *addr,
13 unsigned int maxlabels)
14 {
15 char *endp;
16 unsigned count;
17
18 for (count = 0; count < maxlabels; count++) {
19 unsigned long label;
20
21 label = strtoul(name, &endp, 0);
22 /* Fail when the label value is out or range */
23 if (label >= (1 << 20))
24 return 0;
25
26 if (endp == name) /* no digits */
27 return 0;
28
29 addr->entry = htonl(label << MPLS_LS_LABEL_SHIFT);
30 if (*endp == '\0') {
31 addr->entry |= htonl(1 << MPLS_LS_S_SHIFT);
32 return 1;
33 }
34
35 /* Bad character in the address */
36 if (*endp != '/')
37 return 0;
38
39 name = endp + 1;
40 addr += 1;
41 }
42 /* The address was too long */
43 fprintf(stderr, "Error: too many labels.\n");
44 return 0;
45 }
46
47 int mpls_pton(int af, const char *src, void *addr, size_t alen)
48 {
49 unsigned int maxlabels = alen / sizeof(struct mpls_label);
50 int err;
51
52 switch(af) {
53 case AF_MPLS:
54 errno = 0;
55 err = mpls_pton1(src, (struct mpls_label *)addr, maxlabels);
56 break;
57 default:
58 errno = EAFNOSUPPORT;
59 err = -1;
60 }
61
62 return err;
63 }