Coverage Report

Created: 2025-12-12 06:43

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/lib/mpls.c
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
}