]> git.proxmox.com Git - mirror_frr.git/blob - lib/mpls.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / lib / mpls.c
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 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 */
69 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 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)
80 label2str(labels[i], type, label_buf,
81 sizeof(label_buf));
82 else
83 snprintf(label_buf, sizeof(label_buf), "%u",
84 ((type == ZEBRA_LSP_EVPN)
85 ? label2vni(&labels[i])
86 : labels[i]));
87
88 strlcat(buf, label_buf, len);
89 }
90
91 return buf;
92 }