Line data Source code
1 : /*
2 : * mpls functions
3 : *
4 : * Copyright (C) 2018 Cumulus Networks, Inc.
5 : * Donald Sharp
6 : *
7 : * This program is free software; you can redistribute it and/or modify it
8 : * under the terms of the GNU General Public License as published by the Free
9 : * Software Foundation; either version 2 of the License, or (at your option)
10 : * any later version.
11 : *
12 : * This program is distributed in the hope that it will be useful, but WITHOUT
13 : * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 : * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 : * more details.
16 : *
17 : * You should have received a copy of the GNU General Public License along
18 : * with this program; see the file COPYING; if not, write to the Free Software
19 : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20 : */
21 : #include <zebra.h>
22 : #include <mpls.h>
23 : #include <memory.h>
24 :
25 : /*
26 : * String to label conversion, labels separated by '/'.
27 : *
28 : * @param label_str labels separated by /
29 : * @param num_labels number of labels; zero if conversion was unsuccessful
30 : * @param labels preallocated mpls_label_t array of size MPLS_MAX_LABELS; only
31 : * modified if the conversion succeeded
32 : * @return 0 on success
33 : * -1 if the string could not be parsed as integers
34 : * -2 if a label was inside the reserved range (0-15)
35 : * -3 if the number of labels given exceeds MPLS_MAX_LABELS
36 : */
37 0 : int mpls_str2label(const char *label_str, uint8_t *num_labels,
38 : mpls_label_t *labels)
39 : {
40 0 : char *ostr; // copy of label string (start)
41 0 : char *lstr; // copy of label string
42 0 : char *nump; // pointer to next segment
43 0 : char *endp; // end pointer
44 0 : int i; // for iterating label_str
45 0 : int rc; // return code
46 0 : mpls_label_t pl[MPLS_MAX_LABELS]; // parsed labels
47 :
48 : /* labels to zero until we have a successful parse */
49 0 : ostr = lstr = XSTRDUP(MTYPE_TMP, label_str);
50 0 : *num_labels = 0;
51 0 : rc = 0;
52 :
53 0 : for (i = 0; i < MPLS_MAX_LABELS && lstr && !rc; i++) {
54 0 : nump = strsep(&lstr, "/");
55 0 : pl[i] = strtoul(nump, &endp, 10);
56 :
57 : /* format check */
58 0 : if (*endp != '\0')
59 : rc = -1;
60 : /* validity check */
61 0 : else if (!IS_MPLS_UNRESERVED_LABEL(pl[i]))
62 0 : rc = -2;
63 : }
64 :
65 : /* excess labels */
66 0 : if (!rc && i == MPLS_MAX_LABELS && lstr)
67 : rc = -3;
68 :
69 0 : if (!rc) {
70 0 : *num_labels = i;
71 0 : memcpy(labels, pl, *num_labels * sizeof(mpls_label_t));
72 : }
73 :
74 0 : XFREE(MTYPE_TMP, ostr);
75 :
76 0 : return rc;
77 : }
78 :
79 : /*
80 : * Label to string conversion, labels in string separated by '/'.
81 : */
82 0 : char *mpls_label2str(uint8_t num_labels, const mpls_label_t *labels, char *buf,
83 : int len, int pretty)
84 : {
85 0 : char label_buf[BUFSIZ];
86 0 : int i;
87 :
88 0 : buf[0] = '\0';
89 0 : for (i = 0; i < num_labels; i++) {
90 0 : if (i != 0)
91 0 : strlcat(buf, "/", len);
92 0 : if (pretty)
93 0 : label2str(labels[i], label_buf, sizeof(label_buf));
94 : else
95 0 : snprintf(label_buf, sizeof(label_buf), "%u", labels[i]);
96 0 : strlcat(buf, label_buf, len);
97 : }
98 :
99 0 : return buf;
100 : }
|