]>
Commit | Line | Data |
---|---|---|
acddc0ed | 1 | // SPDX-License-Identifier: GPL-2.0-or-later |
036fdaad DS |
2 | /* |
3 | * mpls functions | |
4 | * | |
5 | * Copyright (C) 2018 Cumulus Networks, Inc. | |
6 | * Donald Sharp | |
036fdaad DS |
7 | */ |
8 | #include <zebra.h> | |
9 | #include <mpls.h> | |
10 | #include <memory.h> | |
11 | ||
12 | /* | |
13 | * String to label conversion, labels separated by '/'. | |
14 | * | |
15 | * @param label_str labels separated by / | |
16 | * @param num_labels number of labels; zero if conversion was unsuccessful | |
17 | * @param labels preallocated mpls_label_t array of size MPLS_MAX_LABELS; only | |
18 | * modified if the conversion succeeded | |
19 | * @return 0 on success | |
20 | * -1 if the string could not be parsed as integers | |
21 | * -2 if a label was inside the reserved range (0-15) | |
22 | * -3 if the number of labels given exceeds MPLS_MAX_LABELS | |
23 | */ | |
24 | int mpls_str2label(const char *label_str, uint8_t *num_labels, | |
25 | mpls_label_t *labels) | |
26 | { | |
27 | char *ostr; // copy of label string (start) | |
28 | char *lstr; // copy of label string | |
29 | char *nump; // pointer to next segment | |
30 | char *endp; // end pointer | |
31 | int i; // for iterating label_str | |
32 | int rc; // return code | |
33 | mpls_label_t pl[MPLS_MAX_LABELS]; // parsed labels | |
34 | ||
35 | /* labels to zero until we have a successful parse */ | |
36 | ostr = lstr = XSTRDUP(MTYPE_TMP, label_str); | |
37 | *num_labels = 0; | |
38 | rc = 0; | |
39 | ||
40 | for (i = 0; i < MPLS_MAX_LABELS && lstr && !rc; i++) { | |
41 | nump = strsep(&lstr, "/"); | |
42 | pl[i] = strtoul(nump, &endp, 10); | |
43 | ||
44 | /* format check */ | |
45 | if (*endp != '\0') | |
46 | rc = -1; | |
47 | /* validity check */ | |
48 | else if (!IS_MPLS_UNRESERVED_LABEL(pl[i])) | |
49 | rc = -2; | |
50 | } | |
51 | ||
52 | /* excess labels */ | |
53 | if (!rc && i == MPLS_MAX_LABELS && lstr) | |
54 | rc = -3; | |
55 | ||
56 | if (!rc) { | |
57 | *num_labels = i; | |
58 | memcpy(labels, pl, *num_labels * sizeof(mpls_label_t)); | |
59 | } | |
60 | ||
61 | XFREE(MTYPE_TMP, ostr); | |
62 | ||
63 | return rc; | |
64 | } | |
65 | ||
66 | /* | |
67 | * Label to string conversion, labels in string separated by '/'. | |
68 | */ | |
e4a1ec74 | 69 | char *mpls_label2str(uint8_t num_labels, const mpls_label_t *labels, char *buf, |
4645cb6b | 70 | int len, enum lsp_types_t type, int pretty) |
036fdaad DS |
71 | { |
72 | char label_buf[BUFSIZ]; | |
73 | int i; | |
74 | ||
75 | buf[0] = '\0'; | |
76 | for (i = 0; i < num_labels; i++) { | |
77 | if (i != 0) | |
78 | strlcat(buf, "/", len); | |
79 | if (pretty) | |
4645cb6b SW |
80 | label2str(labels[i], type, label_buf, |
81 | sizeof(label_buf)); | |
036fdaad | 82 | else |
4645cb6b SW |
83 | snprintf(label_buf, sizeof(label_buf), "%u", |
84 | ((type == ZEBRA_LSP_EVPN) | |
85 | ? label2vni(&labels[i]) | |
86 | : labels[i])); | |
87 | ||
036fdaad DS |
88 | strlcat(buf, label_buf, len); |
89 | } | |
90 | ||
91 | return buf; | |
92 | } |