]> git.proxmox.com Git - mirror_frr.git/blame - lib/mpls.c
Merge pull request #13649 from donaldsharp/unlock_the_node_or_else
[mirror_frr.git] / lib / mpls.c
CommitLineData
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 */
24int 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 69char *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}