back to topotato report
topotato coverage report
Current view: top level - lib - mpls.h (source / functions) Hit Total Coverage
Test: test_bgp_ecmp_enhe.py::BGP_Unnumbered_ECMP Lines: 0 60 0.0 %
Date: 2023-11-16 17:19:14 Functions: 0 6 0.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: GPL-2.0-or-later
       2             : /*
       3             :  * MPLS definitions
       4             :  * Copyright 2015 Cumulus Networks, Inc.
       5             :  */
       6             : 
       7             : #ifndef _QUAGGA_MPLS_H
       8             : #define _QUAGGA_MPLS_H
       9             : 
      10             : #include <zebra.h>
      11             : #include <vxlan.h>
      12             : #include <arpa/inet.h>
      13             : 
      14             : #ifdef __cplusplus
      15             : extern "C" {
      16             : #endif
      17             : 
      18             : #ifdef MPLS_LABEL_MAX
      19             : #undef MPLS_LABEL_MAX
      20             : #endif
      21             : 
      22             : #define MPLS_LABEL_HELPSTR                                                     \
      23             :         "Specify label(s) for this route\nOne or more "                        \
      24             :         "labels in the range (16-1048575) separated by '/'\n"
      25             : 
      26             : /* Well-known MPLS label values (RFC 3032 etc). */
      27             : #define MPLS_LABEL_IPV4_EXPLICIT_NULL  0       /* [RFC3032] */
      28             : #define MPLS_LABEL_ROUTER_ALERT        1       /* [RFC3032] */
      29             : #define MPLS_LABEL_IPV6_EXPLICIT_NULL  2       /* [RFC3032] */
      30             : #define MPLS_LABEL_IMPLICIT_NULL       3       /* [RFC3032] */
      31             : #define MPLS_LABEL_ELI                 7       /* [RFC6790] */
      32             : #define MPLS_LABEL_GAL                 13      /* [RFC5586] */
      33             : #define MPLS_LABEL_OAM_ALERT           14      /* [RFC3429] */
      34             : #define MPLS_LABEL_EXTENSION           15      /* [RFC7274] */
      35             : #define MPLS_LABEL_MAX                 1048575
      36             : #define MPLS_LABEL_VALUE_MASK          0x000FFFFF
      37             : #define MPLS_LABEL_NONE                0xFFFFFFFF /* for internal use only */
      38             : 
      39             : /* Minimum and maximum label values */
      40             : #define MPLS_LABEL_RESERVED_MIN            0
      41             : #define MPLS_LABEL_RESERVED_MAX            15
      42             : #define MPLS_LABEL_UNRESERVED_MIN          16
      43             : #define MPLS_LABEL_UNRESERVED_MAX          1048575
      44             : #define MPLS_LABEL_BASE_ANY                0
      45             : 
      46             : /* Default min and max SRGB label range */
      47             : /* Even if the SRGB allows to manage different Label space between routers,
      48             :  * if an operator want to use the same SRGB for all its router, we must fix
      49             :  * a common range. However, Cisco start its SRGB at 16000 and Juniper ends
      50             :  * its SRGB at 16384 for OSPF. Thus, by fixing the minimum SRGB label to
      51             :  * 8000 we could deal with both Cisco and Juniper.
      52             :  */
      53             : #define MPLS_DEFAULT_MIN_SRGB_LABEL        8000
      54             : #define MPLS_DEFAULT_MAX_SRGB_LABEL        50000
      55             : #define MPLS_DEFAULT_MIN_SRGB_SIZE         5000
      56             : #define MPLS_DEFAULT_MAX_SRGB_SIZE         20000
      57             : 
      58             : /* Maximum # labels that can be pushed. */
      59             : #define MPLS_MAX_LABELS                    16
      60             : 
      61             : #define IS_MPLS_RESERVED_LABEL(label) (label <= MPLS_LABEL_RESERVED_MAX)
      62             : 
      63             : #define IS_MPLS_UNRESERVED_LABEL(label)                                        \
      64             :         (label >= MPLS_LABEL_UNRESERVED_MIN                                    \
      65             :          && label <= MPLS_LABEL_UNRESERVED_MAX)
      66             : 
      67             : /* Definitions for a MPLS label stack entry (RFC 3032). This encodes the
      68             :  * label, EXP, BOS and TTL fields.
      69             :  */
      70             : typedef unsigned int mpls_lse_t;
      71             : 
      72             : #define MPLS_LS_LABEL_MASK             0xFFFFF000
      73             : #define MPLS_LS_LABEL_SHIFT            12
      74             : #define MPLS_LS_EXP_MASK               0x00000E00
      75             : #define MPLS_LS_EXP_SHIFT              9
      76             : #define MPLS_LS_S_MASK                 0x00000100
      77             : #define MPLS_LS_S_SHIFT                8
      78             : #define MPLS_LS_TTL_MASK               0x000000FF
      79             : #define MPLS_LS_TTL_SHIFT              0
      80             : 
      81             : #define MPLS_LABEL_VALUE(lse)                                                  \
      82             :         ((lse & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT)
      83             : #define MPLS_LABEL_EXP(lse) ((lse & MPLS_LS_EXP_MASK) >> MPLS_LS_EXP_SHIFT)
      84             : #define MPLS_LABEL_BOS(lse) ((lse & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT)
      85             : #define MPLS_LABEL_TTL(lse) ((lse & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT)
      86             : 
      87             : #define IS_MPLS_LABEL_BOS(ls)          (MPLS_LABEL_BOS(ls) == 1)
      88             : 
      89             : #define MPLS_LABEL_LEN_BITS            20
      90             : 
      91             : /* MPLS label value as a 32-bit (mostly we only care about the label value). */
      92             : typedef unsigned int mpls_label_t;
      93             : 
      94             : struct mpls_label_stack {
      95             :         uint8_t num_labels;
      96             :         uint8_t reserved[3];
      97             :         mpls_label_t label[0]; /* 1 or more labels */
      98             : };
      99             : 
     100             : /* The MPLS explicit-null label is 0 which means when you memset a mpls_label_t
     101             :  * to zero you have set that variable to explicit-null which was probably not
     102             :  * your intent. The work-around is to use one bit to indicate if the
     103             :  * mpls_label_t has been set by the user. MPLS_INVALID_LABEL has this bit clear
     104             :  * so that we can use MPLS_INVALID_LABEL to initialize mpls_label_t variables.
     105             :  */
     106             : #define MPLS_INVALID_LABEL                 0xFFFDFFFF
     107             : 
     108             : /* LSP types. */
     109             : enum lsp_types_t {
     110             :         ZEBRA_LSP_NONE = 0,   /* No LSP. */
     111             :         ZEBRA_LSP_STATIC = 1, /* Static LSP. */
     112             :         ZEBRA_LSP_LDP = 2,    /* LDP LSP. */
     113             :         ZEBRA_LSP_BGP = 3,    /* BGP LSP. */
     114             :         ZEBRA_LSP_OSPF_SR = 4,/* OSPF Segment Routing LSP. */
     115             :         ZEBRA_LSP_ISIS_SR = 5,/* IS-IS Segment Routing LSP. */
     116             :         ZEBRA_LSP_SHARP = 6,  /* Identifier for test protocol */
     117             :         ZEBRA_LSP_SRTE = 7,   /* SR-TE LSP */
     118             :         ZEBRA_LSP_EVPN = 8,  /* EVPN VNI Label */
     119             : };
     120             : 
     121             : /* Functions for basic label operations. */
     122             : 
     123           0 : static inline void vni2label(vni_t vni, mpls_label_t *label)
     124             : {
     125           0 :         uint8_t *tag = (uint8_t *)label;
     126             : 
     127           0 :         assert(tag);
     128             : 
     129           0 :         tag[0] = (vni >> 16) & 0xFF;
     130           0 :         tag[1] = (vni >> 8) & 0xFF;
     131           0 :         tag[2] = vni & 0xFF;
     132           0 : }
     133             : 
     134           0 : static inline vni_t label2vni(const mpls_label_t *label)
     135             : {
     136           0 :         uint8_t *tag = (uint8_t *)label;
     137           0 :         vni_t vni;
     138             : 
     139           0 :         assert(tag);
     140             : 
     141           0 :         vni = ((uint32_t)*tag++ << 16);
     142           0 :         vni |= (uint32_t)*tag++ << 8;
     143           0 :         vni |= (uint32_t)(*tag & 0xFF);
     144             : 
     145           0 :         return vni;
     146             : }
     147             : 
     148             : /* Encode a label stack entry from fields; convert to network byte-order as
     149             :  * the Netlink interface expects MPLS labels to be in this format.
     150             :  */
     151           0 : static inline mpls_lse_t mpls_lse_encode(mpls_label_t label, uint32_t ttl,
     152             :                                          uint32_t exp, uint32_t bos)
     153             : {
     154           0 :         mpls_lse_t lse;
     155           0 :         lse = htonl((label << MPLS_LS_LABEL_SHIFT) | (exp << MPLS_LS_EXP_SHIFT)
     156             :                     | (bos ? (1 << MPLS_LS_S_SHIFT) : 0)
     157             :                     | (ttl << MPLS_LS_TTL_SHIFT));
     158           0 :         return lse;
     159             : }
     160             : 
     161             : /* Extract the fields from a label stack entry after converting to host-byte
     162             :  * order. This is expected to be called only for messages received over the
     163             :  * Netlink interface.
     164             :  */
     165           0 : static inline void mpls_lse_decode(mpls_lse_t lse, mpls_label_t *label,
     166             :                                    uint32_t *ttl, uint32_t *exp, uint32_t *bos)
     167             : {
     168           0 :         mpls_lse_t local_lse;
     169             : 
     170           0 :         local_lse = ntohl(lse);
     171           0 :         *label = MPLS_LABEL_VALUE(local_lse);
     172           0 :         *exp = MPLS_LABEL_EXP(local_lse);
     173           0 :         *bos = MPLS_LABEL_BOS(local_lse);
     174           0 :         *ttl = MPLS_LABEL_TTL(local_lse);
     175           0 : }
     176             : 
     177             : /* Invalid label index value (when used with BGP Prefix-SID). Should
     178             :  * match the BGP definition.
     179             :  */
     180             : #define MPLS_INVALID_LABEL_INDEX   0xFFFFFFFF
     181             : 
     182             : /* Printable string for labels (with consideration for reserved values). */
     183           0 : static inline char *label2str(mpls_label_t label, enum lsp_types_t type,
     184             :                               char *buf, size_t len)
     185             : {
     186           0 :         if (type == ZEBRA_LSP_EVPN) {
     187           0 :                 snprintf(buf, len, "%u", label2vni(&label));
     188           0 :                 return (buf);
     189             :         }
     190             : 
     191           0 :         switch (label) {
     192           0 :         case MPLS_LABEL_IPV4_EXPLICIT_NULL:
     193           0 :                 strlcpy(buf, "IPv4 Explicit Null", len);
     194           0 :                 return (buf);
     195           0 :         case MPLS_LABEL_ROUTER_ALERT:
     196           0 :                 strlcpy(buf, "Router Alert", len);
     197           0 :                 return (buf);
     198           0 :         case MPLS_LABEL_IPV6_EXPLICIT_NULL:
     199           0 :                 strlcpy(buf, "IPv6 Explicit Null", len);
     200           0 :                 return (buf);
     201           0 :         case MPLS_LABEL_IMPLICIT_NULL:
     202           0 :                 strlcpy(buf, "implicit-null", len);
     203           0 :                 return (buf);
     204           0 :         case MPLS_LABEL_ELI:
     205           0 :                 strlcpy(buf, "Entropy Label Indicator", len);
     206           0 :                 return (buf);
     207           0 :         case MPLS_LABEL_GAL:
     208           0 :                 strlcpy(buf, "Generic Associated Channel", len);
     209           0 :                 return (buf);
     210           0 :         case MPLS_LABEL_OAM_ALERT:
     211           0 :                 strlcpy(buf, "OAM Alert", len);
     212           0 :                 return (buf);
     213           0 :         case MPLS_LABEL_EXTENSION:
     214           0 :                 strlcpy(buf, "Extension", len);
     215           0 :                 return (buf);
     216           0 :         default:
     217           0 :                 if (label < 16)
     218           0 :                         snprintf(buf, len, "Reserved (%u)", label);
     219             :                 else
     220           0 :                         snprintf(buf, len, "%u", label);
     221             :                 return buf;
     222             :         }
     223             : }
     224             : 
     225             : /*
     226             :  * String to label conversion, labels separated by '/'.
     227             :  */
     228             : int mpls_str2label(const char *label_str, uint8_t *num_labels,
     229             :                    mpls_label_t *labels);
     230             : 
     231             : /* Generic string buffer for label-stack-to-str */
     232             : #define MPLS_LABEL_STRLEN 1024
     233             : 
     234             : /*
     235             :  * Label to string conversion, labels in string separated by '/'.
     236             :  */
     237             : char *mpls_label2str(uint8_t num_labels, const mpls_label_t *labels, char *buf,
     238             :                      int len, enum lsp_types_t type, int pretty);
     239             : 
     240             : #ifdef __cplusplus
     241             : }
     242             : #endif
     243             : 
     244             : #endif

Generated by: LCOV version v1.16-topotato