Line | Count | Source |
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 | 0 | { |
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 | 0 | rc = -1; |
47 | | /* validity check */ |
48 | 0 | else if (!IS_MPLS_UNRESERVED_LABEL(pl[i])) |
49 | 0 | rc = -2; |
50 | 0 | } |
51 | | |
52 | | /* excess labels */ |
53 | 0 | if (!rc && i == MPLS_MAX_LABELS && lstr) |
54 | 0 | rc = -3; |
55 | |
|
56 | 0 | if (!rc) { |
57 | 0 | *num_labels = i; |
58 | 0 | memcpy(labels, pl, *num_labels * sizeof(mpls_label_t)); |
59 | 0 | } |
60 | |
|
61 | 0 | XFREE(MTYPE_TMP, ostr); |
62 | |
|
63 | 0 | return rc; |
64 | 0 | } |
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 | 0 | { |
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 | 0 | sizeof(label_buf)); |
82 | 0 | else |
83 | 0 | snprintf(label_buf, sizeof(label_buf), "%u", |
84 | 0 | ((type == ZEBRA_LSP_EVPN) |
85 | 0 | ? label2vni(&labels[i]) |
86 | 0 | : labels[i])); |
87 | |
|
88 | 0 | strlcat(buf, label_buf, len); |
89 | 0 | } |
90 | |
|
91 | 0 | return buf; |
92 | 0 | } |