]> git.proxmox.com Git - mirror_iproute2.git/blame - lib/mpls_pton.c
rdma: Properly mark RDMAtool license
[mirror_iproute2.git] / lib / mpls_pton.c
CommitLineData
6054c1eb
SH
1/* SPDX-License-Identifier: GPL-2.0 */
2
dacc5d41
EB
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
4af44716
DA
12static int mpls_pton1(const char *name, struct mpls_label *addr,
13 unsigned int maxlabels)
dacc5d41
EB
14{
15 char *endp;
16 unsigned count;
17
4af44716 18 for (count = 0; count < maxlabels; count++) {
dacc5d41
EB
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 */
4af44716 43 fprintf(stderr, "Error: too many labels.\n");
dacc5d41
EB
44 return 0;
45}
46
4af44716 47int mpls_pton(int af, const char *src, void *addr, size_t alen)
dacc5d41 48{
4af44716 49 unsigned int maxlabels = alen / sizeof(struct mpls_label);
dacc5d41
EB
50 int err;
51
52 switch(af) {
53 case AF_MPLS:
54 errno = 0;
4af44716 55 err = mpls_pton1(src, (struct mpls_label *)addr, maxlabels);
dacc5d41
EB
56 break;
57 default:
58 errno = EAFNOSUPPORT;
59 err = -1;
60 }
61
62 return err;
63}