Line data Source code
1 : // SPDX-License-Identifier: GPL-2.0-or-later
2 : /*
3 : * mpls functions
4 : *
5 : * Copyright (C) 2018 Cumulus Networks, Inc.
6 : * Donald Sharp
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 0 : int mpls_str2label(const char *label_str, uint8_t *num_labels,
25 : mpls_label_t *labels)
26 : {
27 0 : char *ostr; // copy of label string (start)
28 0 : char *lstr; // copy of label string
29 0 : char *nump; // pointer to next segment
30 0 : char *endp; // end pointer
31 0 : int i; // for iterating label_str
32 0 : int rc; // return code
33 0 : mpls_label_t pl[MPLS_MAX_LABELS]; // parsed labels
34 :
35 : /* labels to zero until we have a successful parse */
36 0 : ostr = lstr = XSTRDUP(MTYPE_TMP, label_str);
37 0 : *num_labels = 0;
38 0 : rc = 0;
39 :
40 0 : for (i = 0; i < MPLS_MAX_LABELS && lstr && !rc; i++) {
41 0 : nump = strsep(&lstr, "/");
42 0 : pl[i] = strtoul(nump, &endp, 10);
43 :
44 : /* format check */
45 0 : if (*endp != '\0')
46 : rc = -1;
47 : /* validity check */
48 0 : else if (!IS_MPLS_UNRESERVED_LABEL(pl[i]))
49 0 : rc = -2;
50 : }
51 :
52 : /* excess labels */
53 0 : if (!rc && i == MPLS_MAX_LABELS && lstr)
54 : rc = -3;
55 :
56 0 : if (!rc) {
57 0 : *num_labels = i;
58 0 : memcpy(labels, pl, *num_labels * sizeof(mpls_label_t));
59 : }
60 :
61 0 : XFREE(MTYPE_TMP, ostr);
62 :
63 0 : return rc;
64 : }
65 :
66 : /*
67 : * Label to string conversion, labels in string separated by '/'.
68 : */
69 0 : char *mpls_label2str(uint8_t num_labels, const mpls_label_t *labels, char *buf,
70 : int len, enum lsp_types_t type, int pretty)
71 : {
72 0 : char label_buf[BUFSIZ];
73 0 : int i;
74 :
75 0 : buf[0] = '\0';
76 0 : for (i = 0; i < num_labels; i++) {
77 0 : if (i != 0)
78 0 : strlcat(buf, "/", len);
79 0 : if (pretty)
80 0 : label2str(labels[i], type, label_buf,
81 : sizeof(label_buf));
82 : else
83 0 : snprintf(label_buf, sizeof(label_buf), "%u",
84 : ((type == ZEBRA_LSP_EVPN)
85 0 : ? label2vni(&labels[i])
86 0 : : labels[i]));
87 :
88 0 : strlcat(buf, label_buf, len);
89 : }
90 :
91 0 : return buf;
92 : }
|