#include <arpa/inet.h>
+#ifdef MPLS_LABEL_MAX
+#undef MPLS_LABEL_MAX
+#endif
+
/* Well-known MPLS label values (RFC 3032 etc). */
-#define MPLS_V4_EXP_NULL_LABEL 0
-#define MPLS_RA_LABEL 1
-#define MPLS_V6_EXP_NULL_LABEL 2
-#define MPLS_IMP_NULL_LABEL 3
-#define MPLS_ENTROPY_LABEL_INDICATOR 7
-#define MPLS_GAL_LABEL 13
-#define MPLS_OAM_ALERT_LABEL 14
-#define MPLS_EXTENSION_LABEL 15
+#define MPLS_LABEL_IPV4_EXPLICIT_NULL 0 /* [RFC3032] */
+#define MPLS_LABEL_ROUTER_ALERT 1 /* [RFC3032] */
+#define MPLS_LABEL_IPV6_EXPLICIT_NULL 2 /* [RFC3032] */
+#define MPLS_LABEL_IMPLICIT_NULL 3 /* [RFC3032] */
+#define MPLS_LABEL_ELI 7 /* [RFC6790] */
+#define MPLS_LABEL_GAL 13 /* [RFC5586] */
+#define MPLS_LABEL_OAM_ALERT 14 /* [RFC3429] */
+#define MPLS_LABEL_EXTENSION 15 /* [RFC7274] */
+#define MPLS_LABEL_MAX 1048575
+#define MPLS_LABEL_NONE 0xFFFFFFFF /* for internal use only */
/* Minimum and maximum label values */
-#define MPLS_MIN_RESERVED_LABEL 0
-#define MPLS_MAX_RESERVED_LABEL 15
-#define MPLS_MIN_UNRESERVED_LABEL 16
-#define MPLS_MAX_UNRESERVED_LABEL 1048575
+#define MPLS_LABEL_RESERVED_MIN 0
+#define MPLS_LABEL_RESERVED_MAX 15
+#define MPLS_LABEL_UNRESERVED_MIN 16
+#define MPLS_LABEL_UNRESERVED_MAX 1048575
/* Default min and max SRGB label range */
-#define MPLS_DEFAULT_MIN_SRGB_LABEL 16000
-#define MPLS_DEFAULT_MAX_SRGB_LABEL 23999
+/* Even if the SRGB allows to manage different Label space between routers,
+ * if an operator want to use the same SRGB for all its router, we must fix
+ * a common range. However, Cisco start its SRGB at 16000 and Juniper ends
+ * its SRGB at 16384 for OSPF. Thus, by fixing the minimum SRGB label to
+ * 8000 we could deal with both Cisco and Juniper.
+ */
+#define MPLS_DEFAULT_MIN_SRGB_LABEL 8000
+#define MPLS_DEFAULT_MAX_SRGB_LABEL 50000
+#define MPLS_DEFAULT_MIN_SRGB_SIZE 5000
+#define MPLS_DEFAULT_MAX_SRGB_SIZE 20000
+
+/* Maximum # labels that can be pushed. */
+#define MPLS_MAX_LABELS 16
-#define IS_MPLS_RESERVED_LABEL(label) \
- (label >= MPLS_MIN_RESERVED_LABEL && label <= MPLS_MAX_RESERVED_LABEL)
+#define IS_MPLS_RESERVED_LABEL(label) \
+ (label >= MPLS_LABEL_RESERVED_MIN && label <= MPLS_LABEL_RESERVED_MAX)
-#define IS_MPLS_UNRESERVED_LABEL(label) \
- (label >= MPLS_MIN_UNRESERVED_LABEL && label <= MPLS_MAX_UNRESERVED_LABEL)
+#define IS_MPLS_UNRESERVED_LABEL(label) \
+ (label >= MPLS_LABEL_UNRESERVED_MIN \
+ && label <= MPLS_LABEL_UNRESERVED_MAX)
/* Definitions for a MPLS label stack entry (RFC 3032). This encodes the
* label, EXP, BOS and TTL fields.
#define MPLS_LS_TTL_MASK 0x000000FF
#define MPLS_LS_TTL_SHIFT 0
-#define MPLS_LABEL_VALUE(lse) \
- ((lse & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT)
-#define MPLS_LABEL_EXP(lse) \
- ((lse & MPLS_LS_EXP_MASK) >> MPLS_LS_EXP_SHIFT)
-#define MPLS_LABEL_BOS(lse) \
- ((lse & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT)
-#define MPLS_LABEL_TTL(lse) \
- ((lse & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT)
+#define MPLS_LABEL_VALUE(lse) \
+ ((lse & MPLS_LS_LABEL_MASK) >> MPLS_LS_LABEL_SHIFT)
+#define MPLS_LABEL_EXP(lse) ((lse & MPLS_LS_EXP_MASK) >> MPLS_LS_EXP_SHIFT)
+#define MPLS_LABEL_BOS(lse) ((lse & MPLS_LS_S_MASK) >> MPLS_LS_S_SHIFT)
+#define MPLS_LABEL_TTL(lse) ((lse & MPLS_LS_TTL_MASK) >> MPLS_LS_TTL_SHIFT)
#define IS_MPLS_LABEL_BOS(ls) (MPLS_LABEL_BOS(ls) == 1)
/* MPLS label value as a 32-bit (mostly we only care about the label value). */
typedef unsigned int mpls_label_t;
+struct mpls_label_stack {
+ uint8_t num_labels;
+ uint8_t reserved[3];
+ mpls_label_t label[0]; /* 1 or more labels */
+};
+
/* The MPLS explicit-null label is 0 which means when you memset a mpls_label_t
* to zero you have set that variable to explicit-null which was probably not
* your intent. The work-around is to use one bit to indicate if the
#define MPLS_INVALID_LABEL 0xFFFDFFFF
/* LSP types. */
-enum lsp_types_t
-{
- ZEBRA_LSP_NONE = 0, /* No LSP. */
- ZEBRA_LSP_STATIC = 1, /* Static LSP. */
- ZEBRA_LSP_LDP = 2, /* LDP LSP. */
- ZEBRA_LSP_BGP = 3 /* BGP LSP. */
+enum lsp_types_t {
+ ZEBRA_LSP_NONE = 0, /* No LSP. */
+ ZEBRA_LSP_STATIC = 1, /* Static LSP. */
+ ZEBRA_LSP_LDP = 2, /* LDP LSP. */
+ ZEBRA_LSP_BGP = 3, /* BGP LSP. */
+ ZEBRA_LSP_SR = 4, /* Segment Routing LSP. */
+ ZEBRA_LSP_SHARP = 5, /* Identifier for test protocol */
};
/* Functions for basic label operations. */
/* Encode a label stack entry from fields; convert to network byte-order as
* the Netlink interface expects MPLS labels to be in this format.
*/
-static inline mpls_lse_t
-mpls_lse_encode (mpls_label_t label, u_int32_t ttl,
- u_int32_t exp, u_int32_t bos)
+static inline mpls_lse_t mpls_lse_encode(mpls_label_t label, uint32_t ttl,
+ uint32_t exp, uint32_t bos)
{
- mpls_lse_t lse;
- lse = htonl ((label << MPLS_LS_LABEL_SHIFT) |
- (exp << MPLS_LS_EXP_SHIFT) |
- (bos ? (1 << MPLS_LS_S_SHIFT) : 0) |
- (ttl << MPLS_LS_TTL_SHIFT));
- return lse;
+ mpls_lse_t lse;
+ lse = htonl((label << MPLS_LS_LABEL_SHIFT) | (exp << MPLS_LS_EXP_SHIFT)
+ | (bos ? (1 << MPLS_LS_S_SHIFT) : 0)
+ | (ttl << MPLS_LS_TTL_SHIFT));
+ return lse;
}
/* Extract the fields from a label stack entry after converting to host-byte
* order. This is expected to be called only for messages received over the
* Netlink interface.
*/
-static inline void
-mpls_lse_decode (mpls_lse_t lse, mpls_label_t *label,
- u_int32_t *ttl, u_int32_t *exp, u_int32_t *bos)
+static inline void mpls_lse_decode(mpls_lse_t lse, mpls_label_t *label,
+ uint32_t *ttl, uint32_t *exp, uint32_t *bos)
{
- mpls_lse_t local_lse;
+ mpls_lse_t local_lse;
- local_lse = ntohl (lse);
- *label = MPLS_LABEL_VALUE(local_lse);
- *exp = MPLS_LABEL_EXP(local_lse);
- *bos = MPLS_LABEL_BOS(local_lse);
- *ttl = MPLS_LABEL_TTL(local_lse);
+ local_lse = ntohl(lse);
+ *label = MPLS_LABEL_VALUE(local_lse);
+ *exp = MPLS_LABEL_EXP(local_lse);
+ *bos = MPLS_LABEL_BOS(local_lse);
+ *ttl = MPLS_LABEL_TTL(local_lse);
}
/* Invalid label index value (when used with BGP Prefix-SID). Should
*/
#define MPLS_INVALID_LABEL_INDEX 0xFFFFFFFF
-
/* Printable string for labels (with consideration for reserved values). */
-static inline char *
-label2str (mpls_label_t label, char *buf, size_t len)
+static inline char *label2str(mpls_label_t label, char *buf, size_t len)
{
- switch(label) {
- case MPLS_V4_EXP_NULL_LABEL:
- strlcpy(buf, "IPv4 Explicit Null", len);
- return(buf);
- case MPLS_RA_LABEL:
- strlcpy(buf, "Router Alert", len);
- return(buf);
- case MPLS_V6_EXP_NULL_LABEL:
- strlcpy(buf, "IPv6 Explict Null", len);
- return(buf);
- case MPLS_IMP_NULL_LABEL:
- strlcpy(buf, "implicit-null", len);
- return(buf);
- case MPLS_ENTROPY_LABEL_INDICATOR:
- strlcpy(buf, "Entropy Label Indicator", len);
- return(buf);
- case MPLS_GAL_LABEL:
- strlcpy(buf, "Generic Associated Channel", len);
- return(buf);
- case MPLS_OAM_ALERT_LABEL:
- strlcpy(buf, "OAM Alert", len);
- return(buf);
- case MPLS_EXTENSION_LABEL:
- strlcpy(buf, "Extension", len);
- return(buf);
- default:
- if (label < 16)
- snprintf(buf, len, "Reserved (%u)", label);
- else
- snprintf(buf, len, "%u", label);
- return(buf);
- }
+ switch (label) {
+ case MPLS_LABEL_IPV4_EXPLICIT_NULL:
+ strlcpy(buf, "IPv4 Explicit Null", len);
+ return (buf);
+ case MPLS_LABEL_ROUTER_ALERT:
+ strlcpy(buf, "Router Alert", len);
+ return (buf);
+ case MPLS_LABEL_IPV6_EXPLICIT_NULL:
+ strlcpy(buf, "IPv6 Explict Null", len);
+ return (buf);
+ case MPLS_LABEL_IMPLICIT_NULL:
+ strlcpy(buf, "implicit-null", len);
+ return (buf);
+ case MPLS_LABEL_ELI:
+ strlcpy(buf, "Entropy Label Indicator", len);
+ return (buf);
+ case MPLS_LABEL_GAL:
+ strlcpy(buf, "Generic Associated Channel", len);
+ return (buf);
+ case MPLS_LABEL_OAM_ALERT:
+ strlcpy(buf, "OAM Alert", len);
+ return (buf);
+ case MPLS_LABEL_EXTENSION:
+ strlcpy(buf, "Extension", len);
+ return (buf);
+ default:
+ if (label < 16)
+ snprintf(buf, len, "Reserved (%u)", label);
+ else
+ snprintf(buf, len, "%u", label);
+ return (buf);
+ }
}
-/* constants used by ldpd */
-#define MPLS_LABEL_IPV4NULL 0 /* IPv4 Explicit NULL Label */
-#define MPLS_LABEL_RTALERT 1 /* Router Alert Label */
-#define MPLS_LABEL_IPV6NULL 2 /* IPv6 Explicit NULL Label */
-#define MPLS_LABEL_IMPLNULL 3 /* Implicit NULL Label */
-/* MPLS_LABEL_RESERVED 4-15 */ /* Values 4-15 are reserved */
-#define MPLS_LABEL_RESERVED_MAX 15
-#define MPLS_LABEL_MAX ((1 << 20) - 1)
#endif