diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/mpls.c | 11 | ||||
| -rw-r--r-- | lib/mpls.h | 39 | ||||
| -rw-r--r-- | lib/nexthop_group.c | 51 | ||||
| -rw-r--r-- | lib/nexthop_group.h | 2 | ||||
| -rw-r--r-- | lib/zclient.c | 3 | ||||
| -rw-r--r-- | lib/zclient.h | 1 | ||||
| -rw-r--r-- | lib/zebra.h | 8 |
7 files changed, 95 insertions, 20 deletions
diff --git a/lib/mpls.c b/lib/mpls.c index ac5792a686..1b21dd29ff 100644 --- a/lib/mpls.c +++ b/lib/mpls.c @@ -80,7 +80,7 @@ int mpls_str2label(const char *label_str, uint8_t *num_labels, * Label to string conversion, labels in string separated by '/'. */ char *mpls_label2str(uint8_t num_labels, const mpls_label_t *labels, char *buf, - int len, int pretty) + int len, enum lsp_types_t type, int pretty) { char label_buf[BUFSIZ]; int i; @@ -90,9 +90,14 @@ char *mpls_label2str(uint8_t num_labels, const mpls_label_t *labels, char *buf, if (i != 0) strlcat(buf, "/", len); if (pretty) - label2str(labels[i], label_buf, sizeof(label_buf)); + label2str(labels[i], type, label_buf, + sizeof(label_buf)); else - snprintf(label_buf, sizeof(label_buf), "%u", labels[i]); + snprintf(label_buf, sizeof(label_buf), "%u", + ((type == ZEBRA_LSP_EVPN) + ? label2vni(&labels[i]) + : labels[i])); + strlcat(buf, label_buf, len); } diff --git a/lib/mpls.h b/lib/mpls.h index 74bd7aae3e..069e560f80 100644 --- a/lib/mpls.h +++ b/lib/mpls.h @@ -23,6 +23,7 @@ #define _QUAGGA_MPLS_H #include <zebra.h> +#include <vxlan.h> #include <arpa/inet.h> #ifdef __cplusplus @@ -129,10 +130,36 @@ enum lsp_types_t { ZEBRA_LSP_ISIS_SR = 5,/* IS-IS Segment Routing LSP. */ ZEBRA_LSP_SHARP = 6, /* Identifier for test protocol */ ZEBRA_LSP_SRTE = 7, /* SR-TE LSP */ + ZEBRA_LSP_EVPN = 8, /* EVPN VNI Label */ }; /* Functions for basic label operations. */ +static inline void vni2label(vni_t vni, mpls_label_t *label) +{ + uint8_t *tag = (uint8_t *)label; + + assert(tag); + + tag[0] = (vni >> 16) & 0xFF; + tag[1] = (vni >> 8) & 0xFF; + tag[2] = vni & 0xFF; +} + +static inline vni_t label2vni(const mpls_label_t *label) +{ + uint8_t *tag = (uint8_t *)label; + vni_t vni; + + assert(tag); + + vni = ((uint32_t)*tag++ << 16); + vni |= (uint32_t)*tag++ << 8; + vni |= (uint32_t)(*tag & 0xFF); + + return vni; +} + /* Encode a label stack entry from fields; convert to network byte-order as * the Netlink interface expects MPLS labels to be in this format. */ @@ -168,8 +195,14 @@ static inline void mpls_lse_decode(mpls_lse_t lse, mpls_label_t *label, #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, enum lsp_types_t type, + char *buf, size_t len) { + if (type == ZEBRA_LSP_EVPN) { + snprintf(buf, len, "%u", label2vni(&label)); + return (buf); + } + switch (label) { case MPLS_LABEL_IPV4_EXPLICIT_NULL: strlcpy(buf, "IPv4 Explicit Null", len); @@ -200,7 +233,7 @@ static inline char *label2str(mpls_label_t label, char *buf, size_t len) snprintf(buf, len, "Reserved (%u)", label); else snprintf(buf, len, "%u", label); - return (buf); + return buf; } } @@ -217,7 +250,7 @@ int mpls_str2label(const char *label_str, uint8_t *num_labels, * Label to string conversion, labels in string separated by '/'. */ char *mpls_label2str(uint8_t num_labels, const mpls_label_t *labels, char *buf, - int len, int pretty); + int len, enum lsp_types_t type, int pretty); #ifdef __cplusplus } diff --git a/lib/nexthop_group.c b/lib/nexthop_group.c index 41fe64606b..fd7eee213c 100644 --- a/lib/nexthop_group.c +++ b/lib/nexthop_group.c @@ -41,6 +41,7 @@ struct nexthop_hold { char *intf; bool onlink; char *labels; + vni_t vni; uint32_t weight; char *backup_str; }; @@ -131,6 +132,18 @@ nexthop_group_active_nexthop_num_no_recurse(const struct nexthop_group *nhg) return num; } +bool nexthop_group_has_label(const struct nexthop_group *nhg) +{ + struct nexthop *nhop; + + for (ALL_NEXTHOPS_PTR(nhg, nhop)) { + if (nhop->nh_label) + return true; + } + + return false; +} + struct nexthop *nexthop_exists(const struct nexthop_group *nhg, const struct nexthop *nh) { @@ -791,12 +804,13 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, const union sockunion *addr, const char *intf, bool onlink, const char *name, const char *labels, - int *lbl_ret, uint32_t weight, - const char *backup_str) + vni_t vni, int *lbl_ret, + uint32_t weight, const char *backup_str) { int ret = 0; struct vrf *vrf; int num; + uint8_t labelnum = 0; memset(nhop, 0, sizeof(*nhop)); @@ -837,10 +851,9 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, nhop->type = NEXTHOP_TYPE_IFINDEX; if (labels) { - uint8_t num = 0; mpls_label_t larray[MPLS_MAX_LABELS]; - ret = mpls_str2label(labels, &num, larray); + ret = mpls_str2label(labels, &labelnum, larray); /* Return label parse result */ if (lbl_ret) @@ -848,9 +861,14 @@ static bool nexthop_group_parse_nexthop(struct nexthop *nhop, if (ret < 0) return false; - else if (num > 0) - nexthop_add_labels(nhop, ZEBRA_LSP_NONE, - num, larray); + else if (labelnum > 0) + nexthop_add_labels(nhop, ZEBRA_LSP_NONE, labelnum, + larray); + } else if (vni) { + mpls_label_t label = MPLS_INVALID_LABEL; + + vni2label(vni, &label); + nexthop_add_labels(nhop, ZEBRA_LSP_EVPN, 1, &label); } nhop->weight = weight; @@ -877,7 +895,7 @@ static bool nexthop_group_parse_nhh(struct nexthop *nhop, { return (nexthop_group_parse_nexthop( nhop, nhh->addr, nhh->intf, nhh->onlink, nhh->nhvrf_name, - nhh->labels, NULL, nhh->weight, nhh->backup_str)); + nhh->labels, nhh->vni, NULL, nhh->weight, nhh->backup_str)); } DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, @@ -889,6 +907,7 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, [{ \ nexthop-vrf NAME$vrf_name \ |label WORD \ + |vni (1-16777215) \ |weight (1-255) \ |backup-idx WORD \ }]", @@ -903,6 +922,8 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, "The nexthop-vrf Name\n" "Specify label(s) for this nexthop\n" "One or more labels in the range (16-1048575) separated by '/'\n" + "Specify VNI(s) for this nexthop\n" + "VNI in the range (1-16777215)\n" "Weight to be used by the nexthop for purposes of ECMP\n" "Weight value to be used\n" "Specify backup nexthop indexes in another group\n" @@ -927,8 +948,8 @@ DEFPY(ecmp_nexthops, ecmp_nexthops_cmd, } legal = nexthop_group_parse_nexthop(&nhop, addr, intf, !!onlink, - vrf_name, label, &lbl_ret, weight, - backup_idx); + vrf_name, label, vni, &lbl_ret, + weight, backup_idx); if (nhop.type == NEXTHOP_TYPE_IPV6 && IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6)) { @@ -1058,9 +1079,8 @@ void nexthop_group_write_nexthop(struct vty *vty, const struct nexthop *nh) if (nh->nh_label && nh->nh_label->num_labels > 0) { char buf[200]; - mpls_label2str(nh->nh_label->num_labels, - nh->nh_label->label, - buf, sizeof(buf), 0); + mpls_label2str(nh->nh_label->num_labels, nh->nh_label->label, + buf, sizeof(buf), nh->nh_label_type, 0); vty_out(vty, " label %s", buf); } @@ -1117,7 +1137,7 @@ void nexthop_group_json_nexthop(json_object *j, const struct nexthop *nh) char buf[200]; mpls_label2str(nh->nh_label->num_labels, nh->nh_label->label, - buf, sizeof(buf), 0); + buf, sizeof(buf), nh->nh_label_type, 0); json_object_string_add(j, "label", buf); } @@ -1155,6 +1175,9 @@ static void nexthop_group_write_nexthop_internal(struct vty *vty, if (nh->labels) vty_out(vty, " label %s", nh->labels); + if (nh->vni) + vty_out(vty, " vni %u", nh->vni); + if (nh->weight) vty_out(vty, " weight %u", nh->weight); diff --git a/lib/nexthop_group.h b/lib/nexthop_group.h index 0ea0b7c185..4d560fc438 100644 --- a/lib/nexthop_group.h +++ b/lib/nexthop_group.h @@ -170,6 +170,8 @@ nexthop_group_active_nexthop_num(const struct nexthop_group *nhg); extern uint8_t nexthop_group_active_nexthop_num_no_recurse(const struct nexthop_group *nhg); +extern bool nexthop_group_has_label(const struct nexthop_group *nhg); + #ifdef __cplusplus } #endif diff --git a/lib/zclient.c b/lib/zclient.c index d748bef335..42d5c33a1b 100644 --- a/lib/zclient.c +++ b/lib/zclient.c @@ -1035,6 +1035,7 @@ int zapi_nexthop_encode(struct stream *s, const struct zapi_nexthop *api_nh, */ if (api_nh->label_num > 0) { stream_putc(s, api_nh->label_num); + stream_putc(s, api_nh->label_type); stream_put(s, &api_nh->labels[0], api_nh->label_num * sizeof(mpls_label_t)); } @@ -1397,6 +1398,7 @@ int zapi_nexthop_decode(struct stream *s, struct zapi_nexthop *api_nh, /* MPLS labels for BGP-LU or Segment Routing */ if (CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_LABEL)) { STREAM_GETC(s, api_nh->label_num); + STREAM_GETC(s, api_nh->label_type); if (api_nh->label_num > MPLS_MAX_LABELS) { flog_err( EC_LIB_ZAPI_ENCODE, @@ -1948,6 +1950,7 @@ int zapi_nexthop_from_nexthop(struct zapi_nexthop *znh, znh->labels[i] = nh->nh_label->label[i]; znh->label_num = i; + znh->label_type = nh->nh_label_type; SET_FLAG(znh->flags, ZAPI_NEXTHOP_FLAG_LABEL); } diff --git a/lib/zclient.h b/lib/zclient.h index 8c4ce1b777..55957e4bee 100644 --- a/lib/zclient.h +++ b/lib/zclient.h @@ -427,6 +427,7 @@ struct zapi_nexthop { /* MPLS labels for BGP-LU or Segment Routing */ uint8_t label_num; + enum lsp_types_t label_type; mpls_label_t labels[MPLS_MAX_LABELS]; struct ethaddr rmac; diff --git a/lib/zebra.h b/lib/zebra.h index b2f5e5a848..a87398a237 100644 --- a/lib/zebra.h +++ b/lib/zebra.h @@ -338,6 +338,14 @@ struct in_pktinfo { #define strmatch(a,b) (!strcmp((a), (b))) +#if BYTE_ORDER == LITTLE_ENDIAN +#define htonll(x) (((uint64_t)htonl((x)&0xFFFFFFFF) << 32) | htonl((x) >> 32)) +#define ntohll(x) (((uint64_t)ntohl((x)&0xFFFFFFFF) << 32) | ntohl((x) >> 32)) +#else +#define htonll(x) (x) +#define ntohll(x) (x) +#endif + #ifndef INADDR_LOOPBACK #define INADDR_LOOPBACK 0x7f000001 /* Internet address 127.0.0.1. */ #endif |
