]> git.puffer.fish Git - matthieu/frr.git/commitdiff
bgpd: carry two MPLS labels in EVPN NLRIs
authorMitesh Kanjariya <mitesh@marvel-07.cumulusnetworks.com>
Tue, 21 Nov 2017 10:42:05 +0000 (02:42 -0800)
committermitesh <mitesh@cumulusnetworks.com>
Tue, 23 Jan 2018 23:58:53 +0000 (15:58 -0800)
When doing symmetric routing,
EVPN type-2 (MACIP) routes need to be advertised with two labels (VNIs)
the first being the L2 VNI (identifying the VLAN) and
the second being the L3 VNI (identifying the VRF).
The receive processing needs to handle one or two labels too.

Ticket: CM-18489
Review: CCR-6949
Testing: manual and bgp/evpn/mpls smoke

Signed-off-by: Vivek Venkatraman <vivek@cumulusnetworks.com>
15 files changed:
bgpd/bgp_attr.c
bgpd/bgp_attr.h
bgpd/bgp_debug.c
bgpd/bgp_debug.h
bgpd/bgp_evpn.c
bgpd/bgp_evpn.h
bgpd/bgp_evpn_private.h
bgpd/bgp_label.c
bgpd/bgp_mplsvpn.c
bgpd/bgp_route.c
bgpd/bgp_route.h
bgpd/bgp_routemap.c
bgpd/bgp_updgrp_packet.c
bgpd/bgp_zebra.c
bgpd/rfapi/vnc_export_bgp.c

index f197ad16a381a3ad4a9e76c4e2febbbb410caa78..3f3acbe0e2923db2638035a707dc494883508cb5 100644 (file)
@@ -2701,8 +2701,9 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi,
 
 void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
                              struct prefix *p, struct prefix_rd *prd,
-                             mpls_label_t *label, int addpath_encode,
-                             u_int32_t addpath_tx_id, struct attr *attr)
+                             mpls_label_t *label, u_int32_t num_labels,
+                             int addpath_encode, u_int32_t addpath_tx_id,
+                             struct attr *attr)
 {
        if (safi == SAFI_MPLS_VPN) {
                if (addpath_encode)
@@ -2714,8 +2715,8 @@ void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
                stream_put(s, &p->u.prefix, PSIZE(p->prefixlen));
        } else if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
                /* EVPN prefix - contents depend on type */
-               bgp_evpn_encode_prefix(s, p, prd, label, attr, addpath_encode,
-                                      addpath_tx_id);
+               bgp_evpn_encode_prefix(s, p, prd, label, num_labels,
+                                      attr, addpath_encode, addpath_tx_id);
        } else if (safi == SAFI_LABELED_UNICAST) {
                /* Prefix write with label. */
                stream_put_labeled_prefix(s, p, label);
@@ -2843,8 +2844,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
                                struct bpacket_attr_vec_arr *vecarr,
                                struct prefix *p, afi_t afi, safi_t safi,
                                struct peer *from, struct prefix_rd *prd,
-                               mpls_label_t *label, int addpath_encode,
-                               u_int32_t addpath_tx_id)
+                               mpls_label_t *label, u_int32_t num_labels,
+                               int addpath_encode, u_int32_t addpath_tx_id)
 {
        size_t cp;
        size_t aspath_sizep;
@@ -2866,7 +2867,8 @@ bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *peer,
 
                mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi,
                                                        vecarr, attr);
-               bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label,
+               bgp_packet_mpattr_prefix(s, afi, safi, p, prd,
+                                        label, num_labels,
                                         addpath_encode, addpath_tx_id, attr);
                bgp_packet_mpattr_end(s, mpattrlen_pos);
        }
@@ -3298,15 +3300,19 @@ size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi, safi_t safi)
 
 void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p, afi_t afi,
                                 safi_t safi, struct prefix_rd *prd,
-                                mpls_label_t *label, int addpath_encode,
-                                u_int32_t addpath_tx_id, struct attr *attr)
+                                mpls_label_t *label, u_int32_t num_labels,
+                                int addpath_encode, u_int32_t addpath_tx_id,
+                                struct attr *attr)
 {
        u_char wlabel[3] = {0x80, 0x00, 0x00};
 
-       if (safi == SAFI_LABELED_UNICAST)
+       if (safi == SAFI_LABELED_UNICAST) {
                label = (mpls_label_t *)wlabel;
+               num_labels = 1;
+       }
 
-       return bgp_packet_mpattr_prefix(s, afi, safi, p, prd, label,
+       return bgp_packet_mpattr_prefix(s, afi, safi, p, prd,
+                                       label, num_labels,
                                        addpath_encode, addpath_tx_id, attr);
 }
 
index ebe14a7ceb42c2f8ad9a66e5b3a02ffed244d9eb..1b1471a198974cdb7e4de38639225e1ba1a6bad4 100644 (file)
@@ -260,7 +260,8 @@ extern bgp_size_t bgp_packet_attribute(struct bgp *bgp, struct peer *,
                                       struct bpacket_attr_vec_arr *vecarr,
                                       struct prefix *, afi_t, safi_t,
                                       struct peer *, struct prefix_rd *,
-                                      mpls_label_t *, int, u_int32_t);
+                                      mpls_label_t *, u_int32_t,
+                                      int, u_int32_t);
 extern void bgp_dump_routes_attr(struct stream *, struct attr *,
                                 struct prefix *);
 extern int attrhash_cmp(const void *, const void *);
@@ -308,7 +309,8 @@ extern size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer,
                                      struct attr *attr);
 extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
                                     struct prefix *p, struct prefix_rd *prd,
-                                    mpls_label_t *label, int addpath_encode,
+                                    mpls_label_t *label, u_int32_t num_labels,
+                                    int addpath_encode,
                                     u_int32_t addpath_tx_id, struct attr *);
 extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
                                            struct prefix *p);
@@ -318,7 +320,8 @@ extern size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi,
                                         safi_t safi);
 extern void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p,
                                        afi_t afi, safi_t safi,
-                                       struct prefix_rd *prd, mpls_label_t *,
+                                       struct prefix_rd *prd,
+                                       mpls_label_t *, u_int32_t,
                                        int, u_int32_t, struct attr *);
 extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt);
 
index 45ac8e68597fbf1ccabf712d5c77d0270acbc503..b08522b68bd67e08884cd2f78ead7d262033896f 100644 (file)
@@ -2017,8 +2017,9 @@ int bgp_debug_zebra(struct prefix *p)
 const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
                                    struct prefix_rd *prd,
                                    union prefixconstptr pu,
-                                   mpls_label_t *label, int addpath_valid,
-                                   u_int32_t addpath_id, char *str, int size)
+                                   mpls_label_t *label, u_int32_t num_labels,
+                                   int addpath_valid, u_int32_t addpath_id,
+                                   char *str, int size)
 {
        char rd_buf[RD_ADDRSTRLEN];
        char pfx_buf[PREFIX_STRLEN];
@@ -2041,11 +2042,19 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
                         addpath_id);
 
        tag_buf[0] = '\0';
-       if (bgp_labeled_safi(safi) && label) {
-               u_int32_t label_value;
+       if (bgp_labeled_safi(safi) && num_labels) {
 
-               label_value = decode_label(label);
-               sprintf(tag_buf, " label %u", label_value);
+               if (safi == SAFI_EVPN) {
+                       char tag_buf2[20];
+
+                       bgp_evpn_label2str(label, num_labels, tag_buf2, 20);
+                       sprintf(tag_buf, " label %s", tag_buf2);
+               } else {
+                       u_int32_t label_value;
+
+                       label_value = decode_label(label);
+                       sprintf(tag_buf, " label %u", label_value);
+               }
        }
 
        if (prd)
index 5fe19b162b88d80c25f18a5d6cac5b685e1c4dca..7c773cfafbf42f6d0e1e52ae137e108b950d6673 100644 (file)
@@ -153,7 +153,8 @@ extern int bgp_debug_zebra(struct prefix *p);
 
 extern int bgp_debug_count(void);
 extern const char *bgp_debug_rdpfxpath2str(afi_t, safi_t, struct prefix_rd *,
-                                          union prefixconstptr, mpls_label_t *,
+                                          union prefixconstptr,
+                                          mpls_label_t *, u_int32_t,
                                           int, u_int32_t, char *, int);
 const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data,
                                     size_t datalen);
index 46a983a880ab4fbe6d512d89fa65ed9ce55a4472..b20076d471950765eb24d1a66dee42aa84d4f802 100644 (file)
@@ -1034,10 +1034,11 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_def,
                               bgp_def->peer_self, attr_new, rn);
                SET_FLAG(ri->flags, BGP_INFO_VALID);
 
-               /* L3-VNI goes in the label2 field */
+               /* Type-5 routes advertise the L3-VNI */
                bgp_info_extra_get(ri);
                vni2label(bgp_vrf->l3vni, &label);
-               memcpy(&ri->extra->label2, &label, BGP_LABEL_BYTES);
+               memcpy(&ri->extra->label, &label, sizeof(label));
+               ri->extra->num_labels = 1;
 
                /* add the route entry to route node*/
                bgp_info_add(rn, ri);
@@ -1127,11 +1128,15 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
        struct bgp_info *tmp_ri;
        struct bgp_info *local_ri, *remote_ri;
        struct attr *attr_new;
-       mpls_label_t label = MPLS_INVALID_LABEL;
+       mpls_label_t label[BGP_MAX_LABELS];
+       u_int32_t num_labels = 1;
        int route_change = 1;
        u_char sticky = 0;
+       struct prefix_evpn *evp;
 
        *ri = NULL;
+       evp = (struct prefix_evpn *)&rn->p;
+       memset(&label, 0, sizeof(label));
 
        /* See if this is an update of an existing route, or a new add. Also,
         * identify if already known from remote, and if so, the one with the
@@ -1196,9 +1201,20 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
                bgp_info_extra_get(tmp_ri);
 
                /* The VNI goes into the 'label' field of the route */
-               vni2label(vpn->vni, &label);
+               vni2label(vpn->vni, &label[0]);
+               /* Type-2 routes may carry a second VNI - the L3-VNI */
+               if (evp->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE) {
+                       vni_t l3vni;
+
+                       l3vni = bgpevpn_get_l3vni(vpn);
+                       if (l3vni) {
+                               vni2label(l3vni, &label[1]);
+                               num_labels++;
+                       }
+               }
 
-               memcpy(&tmp_ri->extra->label, &label, BGP_LABEL_BYTES);
+               memcpy(&tmp_ri->extra->label, label, sizeof(label));
+               tmp_ri->extra->num_labels = num_labels;
                bgp_info_add(rn, tmp_ri);
        } else {
                tmp_ri = local_ri;
@@ -1814,9 +1830,11 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
                SET_FLAG(ri->flags, BGP_INFO_VALID);
                bgp_info_extra_get(ri);
                ri->extra->parent = parent_ri;
-               if (parent_ri->extra)
+               if (parent_ri->extra) {
                        memcpy(&ri->extra->label, &parent_ri->extra->label,
-                              BGP_LABEL_BYTES);
+                              sizeof(ri->extra->label));
+                       ri->extra->num_labels = parent_ri->extra->num_labels;
+               }
                bgp_info_add(rn, ri);
        } else {
                if (attrhash_cmp(ri->attr, parent_ri->attr)
@@ -1880,9 +1898,11 @@ static int install_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
                SET_FLAG(ri->flags, BGP_INFO_VALID);
                bgp_info_extra_get(ri);
                ri->extra->parent = parent_ri;
-               if (parent_ri->extra)
+               if (parent_ri->extra) {
                        memcpy(&ri->extra->label, &parent_ri->extra->label,
-                              BGP_LABEL_BYTES);
+                              sizeof(ri->extra->label));
+                       ri->extra->num_labels = parent_ri->extra->num_labels;
+               }
                bgp_info_add(rn, ri);
        } else {
                if (attrhash_cmp(ri->attr, parent_ri->attr)
@@ -2772,7 +2792,8 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
        struct prefix_evpn p;
        u_char ipaddr_len;
        u_char macaddr_len;
-       mpls_label_t *label_pnt;
+       mpls_label_t label[BGP_MAX_LABELS]; /* holds the VNI(s) as in packet */
+       u_int32_t num_labels = 0;
        int ret;
 
        /* Type-2 route should be either 33, 37 or 49 bytes or an
@@ -2840,19 +2861,28 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
        }
        pfx += ipaddr_len;
 
-       /* Get the VNI (in MPLS label field). */
-       /* Note: We ignore the second VNI, if any. */
-       label_pnt = (mpls_label_t *)pfx;
+       /* Get the VNI(s). Stored as bytes here. */
+       num_labels++;
+       memset(label, 0, sizeof(label));
+       memcpy(&label[0], pfx, BGP_LABEL_BYTES);
+       pfx += 3;
+       psize -= (33 + ipaddr_len);
+       /* Do we have a second VNI? */
+       if (psize) {
+               num_labels++;
+               memcpy(&label[1], pfx, BGP_LABEL_BYTES);
+               pfx += 3;
+       }
 
        /* Process the route. */
        if (attr)
                ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
                                 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
-                                &prd, label_pnt, 0, NULL);
+                                &prd, &label[0], num_labels, 0, NULL);
        else
                ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
                                   afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
-                                  &prd, label_pnt, NULL);
+                                  &prd, &label[0], num_labels, NULL);
        return ret;
 }
 
@@ -2908,11 +2938,11 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
        if (attr)
                ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
                                 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
-                                &prd, NULL, 0, NULL);
+                                &prd, NULL, 0, 0, NULL);
        else
                ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
                                   afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
-                                  &prd, NULL, NULL);
+                                  &prd, NULL, 0, NULL);
        return ret;
 }
 
@@ -2928,7 +2958,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
        struct bgp_route_evpn evpn;
        u_char ippfx_len;
        u_int32_t eth_tag;
-       mpls_label_t *label_pnt;
+       mpls_label_t label; /* holds the VNI as in the packet */
        int ret;
 
        /* Type-5 route should be 34 or 58 bytes:
@@ -2994,23 +3024,27 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
                pfx += 16;
        }
 
-       label_pnt = (mpls_label_t *)pfx;
+       /* Get the VNI (in MPLS label field). Stored as bytes here. */
+       memset(&label, 0, sizeof(label));
+       memcpy(&label, pfx, BGP_LABEL_BYTES);
+       pfx += 3;
 
        /* Process the route. */
        if (!withdraw)
                ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
                                 afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
-                                &prd, label_pnt, 0, &evpn);
+                                &prd, &label, 1, 0, &evpn);
        else
                ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
                                   afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
-                                  &prd, label_pnt, &evpn);
+                                  &prd, &label, 1, &evpn);
 
        return ret;
 }
 
 static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
-                                    struct prefix_rd *prd, mpls_label_t *label,
+                                    struct prefix_rd *prd,
+                                    mpls_label_t *label, u_int32_t num_labels,
                                     struct attr *attr)
 {
        int len;
@@ -3055,7 +3089,7 @@ static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
                        stream_put(s, &temp, 16);
        }
 
-       if (label)
+       if (num_labels)
                stream_put(s, label, 3);
        else
                stream_put3(s, 0);
@@ -3447,14 +3481,20 @@ int bgp_evpn_uninstall_routes(struct bgp *bgp, struct bgpevpn *vpn)
 }
 
 /*
- * Function to display "tag" in route as a VNI.
+ * TODO: Hardcoded for a maximum of 2 VNIs right now
  */
-char *bgp_evpn_label2str(mpls_label_t *label, char *buf, int len)
+char *bgp_evpn_label2str(mpls_label_t *label, u_int32_t num_labels,
+                        char *buf, int len)
 {
        vni_t vni;
+       vni_t vni1, vni2;
 
-       vni = label2vni(label);
-       snprintf(buf, len, "%u", vni);
+       vni1 = label2vni(label);
+       if (num_labels == 2) {
+               vni2 = label2vni(label+1);
+               snprintf(buf, len, "%u/%u", vni1, vni2);
+       } else
+               snprintf(buf, len, "%u", vni1);
        return buf;
 }
 
@@ -3577,12 +3617,13 @@ char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len)
  * Encode EVPN prefix in Update (MP_REACH)
  */
 void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
-                           struct prefix_rd *prd, mpls_label_t *label,
+                           struct prefix_rd *prd,
+                           mpls_label_t *label, u_int32_t num_labels,
                            struct attr *attr, int addpath_encode,
                            u_int32_t addpath_tx_id)
 {
        struct prefix_evpn *evp = (struct prefix_evpn *)p;
-       int ipa_len = 0;
+       int len, ipa_len = 0;
 
        if (addpath_encode)
                stream_putl(s, addpath_tx_id);
@@ -3596,18 +3637,24 @@ void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
                        ipa_len = IPV4_MAX_BYTELEN;
                else if (IS_EVPN_PREFIX_IPADDR_V6(evp))
                        ipa_len = IPV6_MAX_BYTELEN;
-               stream_putc(s, 33 + ipa_len);       // 1 VNI
+               /* RD, ESI, EthTag, MAC+len, IP len, [IP], 1 VNI */
+               len = 8 + 10 + 4 + 1 + 6 + 1 + ipa_len + 3;
+               if (ipa_len && num_labels > 1) /* There are 2 VNIs */
+                       len += 3;
+               stream_putc(s, len);
                stream_put(s, prd->val, 8);      /* RD */
                stream_put(s, 0, 10);               /* ESI */
                stream_putl(s, 0);                  /* Ethernet Tag ID */
                stream_putc(s, 8 * ETH_ALEN); /* Mac Addr Len - bits */
                stream_put(s, evp->prefix.mac.octet, 6); /* Mac Addr */
                stream_putc(s, 8 * ipa_len);             /* IP address Length */
-               if (ipa_len)
-                       stream_put(s, &evp->prefix.ip.ip.addr,
-                                  ipa_len); /* IP */
-               stream_put(s, label,
-                          BGP_LABEL_BYTES); /* VNI is contained in 'tag' */
+               if (ipa_len) /* IP */
+                       stream_put(s, &evp->prefix.ip.ip.addr, ipa_len);
+               /* 1st label is the L2 VNI */
+               stream_put(s, label, BGP_LABEL_BYTES);
+               /* Include 2nd label (L3 VNI) if advertising MAC+IP */
+               if (ipa_len && num_labels > 1)
+                       stream_put(s, label+1, BGP_LABEL_BYTES);
                break;
 
        case BGP_EVPN_IMET_ROUTE:
@@ -3621,7 +3668,7 @@ void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
 
        case BGP_EVPN_IP_PREFIX_ROUTE:
                /* TODO: AddPath support. */
-               evpn_mpattr_encode_type5(s, p, prd, label, attr);
+               evpn_mpattr_encode_type5(s, p, prd, label, num_labels, attr);
                break;
 
        default:
index 9400916845b04374263de3772f004e1077860110..b3b61db141d4204d13e8e4cd40b2b738f47cd2d8 100644 (file)
@@ -34,6 +34,27 @@ static inline int is_evpn_enabled(void)
        return bgp ? bgp->advertise_all_vni : 0;
 }
 
+static inline void vni2label(vni_t vni, mpls_label_t *label)
+{
+       u_char *tag = (u_char *)label;
+
+       tag[0] = (vni >> 16) & 0xFF;
+       tag[1] = (vni >> 8) & 0xFF;
+       tag[2] = vni & 0xFF;
+}
+
+static inline vni_t label2vni(mpls_label_t *label)
+{
+       u_char *tag = (u_char *)label;
+       vni_t vni;
+
+       vni = ((u_int32_t)*tag++ << 16);
+       vni |= (u_int32_t)*tag++ << 8;
+       vni |= (u_int32_t)(*tag & 0xFF);
+
+       return vni;
+}
+
 extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
                                           struct bgp_node *rn,
                                           afi_t afi, safi_t safi);
@@ -46,11 +67,13 @@ extern void bgp_evpn_advertise_type5_routes(struct bgp *bgp_vrf, afi_t afi,
                                            safi_t safi);
 extern void bgp_evpn_vrf_delete(struct bgp *bgp_vrf);
 extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
-extern char *bgp_evpn_label2str(mpls_label_t *label, char *buf, int len);
+extern char *bgp_evpn_label2str(mpls_label_t *label, u_int32_t num_labels,
+                               char *buf, int len);
 extern char *bgp_evpn_route2str(struct prefix_evpn *p, char *buf, int len);
 extern void bgp_evpn_route2json(struct prefix_evpn *p, json_object *json);
 extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
-                                  struct prefix_rd *prd, mpls_label_t *label,
+                                  struct prefix_rd *prd,
+                                  mpls_label_t *label, u_int32_t num_labels,
                                   struct attr *attr, int addpath_encode,
                                   u_int32_t addpath_tx_id);
 extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
index f5a0998f62adb6c675da9b5940e4fcfa1bf2e4fa..6003e03f356955f91181c4988906991094825f63 100644 (file)
@@ -228,26 +228,6 @@ static inline int is_vni_param_configured(struct bgpevpn *vpn)
                || is_export_rt_configured(vpn));
 }
 
-static inline void vni2label(vni_t vni, mpls_label_t *label)
-{
-       u_char *tag = (u_char *)label;
-       tag[0] = (vni >> 16) & 0xFF;
-       tag[1] = (vni >> 8) & 0xFF;
-       tag[2] = vni & 0xFF;
-}
-
-static inline vni_t label2vni(mpls_label_t *label)
-{
-       u_char *tag = (u_char *)label;
-       vni_t vni;
-
-       vni = ((u_int32_t)*tag++ << 16);
-       vni |= (u_int32_t)*tag++ << 8;
-       vni |= (u_int32_t)(*tag & 0xFF);
-
-       return vni;
-}
-
 static inline void encode_rmac_extcomm(struct ecommunity_val *eval,
                                       struct ethaddr *rmac)
 {
index 60250513b678eeff506b0bb8e0a14ac48a17703b..38b39075be376b51aecdc46d1f61050b0274175e 100644 (file)
@@ -103,7 +103,7 @@ mpls_label_t bgp_adv_label(struct bgp_node *rn, struct bgp_info *ri,
        if (!rn || !ri || !to)
                return MPLS_INVALID_LABEL;
 
-       remote_label = ri->extra ? ri->extra->label : MPLS_INVALID_LABEL;
+       remote_label = ri->extra ? ri->extra->label[0] : MPLS_INVALID_LABEL;
        from = ri->peer;
        reflect =
                ((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
@@ -325,11 +325,11 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
                if (attr) {
                        bgp_update(peer, &p, addpath_id, attr, packet->afi,
                                   SAFI_UNICAST, ZEBRA_ROUTE_BGP,
-                                  BGP_ROUTE_NORMAL, NULL, &label, 0, NULL);
+                                  BGP_ROUTE_NORMAL, NULL, &label, 1, 0, NULL);
                } else {
                        bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
                                     SAFI_UNICAST, ZEBRA_ROUTE_BGP,
-                                    BGP_ROUTE_NORMAL, NULL, &label, NULL);
+                                    BGP_ROUTE_NORMAL, NULL, &label, 1, NULL);
                }
        }
 
index 472b9d200a4bca98930065baefb5910d4a111b24..0e2594ba8a5adf44a6363bcaed305819c3d7621b 100644 (file)
@@ -214,11 +214,11 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
                if (attr) {
                        bgp_update(peer, &p, addpath_id, attr, packet->afi,
                                   SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
-                                  BGP_ROUTE_NORMAL, &prd, &label, 0, NULL);
+                                  BGP_ROUTE_NORMAL, &prd, &label, 1, 0, NULL);
                } else {
                        bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
                                     SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
-                                    BGP_ROUTE_NORMAL, &prd, &label, NULL);
+                                    BGP_ROUTE_NORMAL, &prd, &label, 1, NULL);
                }
        }
        /* Packet length consistency check. */
index fdc7f22ae859ed3b1d9220a47950e9ef4e3db9de..234bde418b735c1f69621d18dde3c1a7c01dde2e 100644 (file)
@@ -147,7 +147,8 @@ static struct bgp_info_extra *bgp_info_extra_new(void)
 {
        struct bgp_info_extra *new;
        new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA, sizeof(struct bgp_info_extra));
-       new->label = MPLS_INVALID_LABEL;
+       new->label[0] = MPLS_INVALID_LABEL;
+       new->num_labels = 0;
        return new;
 }
 
@@ -770,9 +771,9 @@ static int bgp_info_cmp(struct bgp *bgp, struct bgp_info *new,
                /* If one path has a label but the other does not, do not treat
                 * them as equals for multipath
                 */
-               if ((new->extra &&bgp_is_valid_label(&new->extra->label))
+               if ((new->extra && bgp_is_valid_label(&new->extra->label[0]))
                    != (exist->extra
-                       && bgp_is_valid_label(&exist->extra->label))) {
+                       && bgp_is_valid_label(&exist->extra->label[0]))) {
                        if (debug)
                                zlog_debug(
                                        "%s: %s and %s cannot be multipath, one has a label while the other does not",
@@ -2670,7 +2671,8 @@ static int bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
 
 int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
               struct attr *attr, afi_t afi, safi_t safi, int type,
-              int sub_type, struct prefix_rd *prd, mpls_label_t *label,
+              int sub_type, struct prefix_rd *prd,
+              mpls_label_t *label, u_int32_t num_labels,
               int soft_reconfig, struct bgp_route_evpn *evpn)
 {
        int ret;
@@ -2681,9 +2683,9 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
        struct attr *attr_new;
        struct bgp_info *ri;
        struct bgp_info *new;
+       struct bgp_info_extra *extra;
        const char *reason;
        char pfx_buf[BGP_PRD_PATH_STRLEN];
-       char label_buf[20];
        int connected = 0;
        int do_loop_check = 1;
        int has_valid_label = 0;
@@ -2698,10 +2700,11 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
 
        bgp = peer->bgp;
        rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
-       has_valid_label = bgp_is_valid_label(label);
-
-       if (has_valid_label)
-               sprintf(label_buf, "label %u", label_pton(label));
+       /* TODO: Check to see if we can get rid of "is_valid_label" */
+       if (afi == AFI_L2VPN && safi == SAFI_EVPN)
+               has_valid_label = (num_labels > 0) ? 1 : 0;
+       else
+               has_valid_label = bgp_is_valid_label(label);
 
        /* When peer's soft reconfiguration enabled.  Record input packet in
           Adj-RIBs-In.  */
@@ -2821,7 +2824,7 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
                    && attrhash_cmp(ri->attr, attr_new)
                    && (!has_valid_label
                        || memcmp(&(bgp_info_extra_get(ri))->label, label,
-                                 BGP_LABEL_BYTES)
+                                 num_labels * sizeof(mpls_label_t))
                                   == 0)
                    && (overlay_index_equal(
                               afi, ri, evpn == NULL ? NULL : &evpn->eth_s_id,
@@ -2832,7 +2835,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
                            && CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) {
                                if (bgp_debug_update(peer, p, NULL, 1)) {
                                        bgp_debug_rdpfxpath2str(
-                                               afi, safi, prd, p, label,
+                                               afi, safi, prd, p,
+                                               label, num_labels,
                                                addpath_id ? 1 : 0, addpath_id,
                                                pfx_buf, sizeof(pfx_buf));
                                        zlog_debug("%s rcvd %s", peer->host,
@@ -2857,7 +2861,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
                                        }
 
                                        bgp_debug_rdpfxpath2str(
-                                               afi, safi, prd, p, label,
+                                               afi, safi, prd, p,
+                                               label, num_labels,
                                                addpath_id ? 1 : 0, addpath_id,
                                                pfx_buf, sizeof(pfx_buf));
                                        zlog_debug(
@@ -2883,7 +2888,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
                if (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
                        if (bgp_debug_update(peer, p, NULL, 1)) {
                                bgp_debug_rdpfxpath2str(
-                                       afi, safi, prd, p, label,
+                                       afi, safi, prd, p,
+                                       label, num_labels,
                                        addpath_id ? 1 : 0, addpath_id, pfx_buf,
                                        sizeof(pfx_buf));
                                zlog_debug(
@@ -2896,7 +2902,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
 
                /* Received Logging. */
                if (bgp_debug_update(peer, p, NULL, 1)) {
-                       bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
+                       bgp_debug_rdpfxpath2str(afi, safi, prd, p,
+                                               label, num_labels,
                                                addpath_id ? 1 : 0, addpath_id,
                                                pfx_buf, sizeof(pfx_buf));
                        zlog_debug("%s rcvd %s", peer->host, pfx_buf);
@@ -2987,9 +2994,12 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
 
                /* Update MPLS label */
                if (has_valid_label) {
-                       memcpy(&(bgp_info_extra_get(ri))->label, label,
-                              BGP_LABEL_BYTES);
-                       bgp_set_valid_label(&(bgp_info_extra_get(ri))->label);
+                       extra = bgp_info_extra_get(ri);
+                       memcpy(&extra->label, label,
+                              num_labels * sizeof(mpls_label_t));
+                       extra->num_labels = num_labels;
+                       if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
+                               bgp_set_valid_label(&extra->label[0]);
                }
 
 #if ENABLE_BGP_VNC
@@ -3126,7 +3136,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
                        peer->rcvd_attr_printed = 1;
                }
 
-               bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
+               bgp_debug_rdpfxpath2str(afi, safi, prd, p,
+                                       label, num_labels,
                                        addpath_id ? 1 : 0, addpath_id, pfx_buf,
                                        sizeof(pfx_buf));
                zlog_debug("%s rcvd %s", peer->host, pfx_buf);
@@ -3137,9 +3148,12 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
 
        /* Update MPLS label */
        if (has_valid_label) {
-               memcpy(&(bgp_info_extra_get(new))->label, label,
-                      BGP_LABEL_BYTES);
-               bgp_set_valid_label(&(bgp_info_extra_get(new))->label);
+               extra = bgp_info_extra_get(new);
+               memcpy(&extra->label, label,
+                      num_labels * sizeof(mpls_label_t));
+               extra->num_labels = num_labels;
+               if (!(afi == AFI_L2VPN && safi == SAFI_EVPN))
+                       bgp_set_valid_label(&extra->label[0]);
        }
 
        /* Update Overlay Index */
@@ -3241,7 +3255,8 @@ filtered:
                        peer->rcvd_attr_printed = 1;
                }
 
-               bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
+               bgp_debug_rdpfxpath2str(afi, safi, prd, p,
+                                       label, num_labels,
                                        addpath_id ? 1 : 0, addpath_id, pfx_buf,
                                        sizeof(pfx_buf));
                zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
@@ -3276,7 +3291,8 @@ filtered:
 
 int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
                 struct attr *attr, afi_t afi, safi_t safi, int type,
-                int sub_type, struct prefix_rd *prd, mpls_label_t *label,
+                int sub_type, struct prefix_rd *prd,
+                mpls_label_t *label, u_int32_t num_labels,
                 struct bgp_route_evpn *evpn)
 {
        struct bgp *bgp;
@@ -3312,7 +3328,8 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
                if (!bgp_adj_in_unset(rn, peer, addpath_id)) {
                        if (bgp_debug_update(peer, p, NULL, 1)) {
                                bgp_debug_rdpfxpath2str(
-                                       afi, safi, prd, p, label,
+                                       afi, safi, prd, p,
+                                       label, num_labels,
                                        addpath_id ? 1 : 0, addpath_id, pfx_buf,
                                        sizeof(pfx_buf));
                                zlog_debug(
@@ -3332,7 +3349,8 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
 
        /* Logging. */
        if (bgp_debug_update(peer, p, NULL, 1)) {
-               bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
+               bgp_debug_rdpfxpath2str(afi, safi, prd, p,
+                                       label, num_labels,
                                        addpath_id ? 1 : 0, addpath_id, pfx_buf,
                                        sizeof(pfx_buf));
                zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
@@ -3343,7 +3361,8 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
        if (ri && !CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
                bgp_rib_withdraw(rn, ri, peer, afi, safi, prd);
        else if (bgp_debug_update(peer, p, NULL, 1)) {
-               bgp_debug_rdpfxpath2str(afi, safi, prd, p, label,
+               bgp_debug_rdpfxpath2str(afi, safi, prd, p,
+                                       label, num_labels,
                                        addpath_id ? 1 : 0, addpath_id, pfx_buf,
                                        sizeof(pfx_buf));
                zlog_debug("%s Can't find the route %s", peer->host, pfx_buf);
@@ -3469,14 +3488,18 @@ static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
                                continue;
 
                        struct bgp_info *ri = rn->info;
-                       mpls_label_t label = (ri && ri->extra)
-                                                    ? ri->extra->label
-                                                    : MPLS_INVALID_LABEL;
+                       u_int32_t num_labels = 0;
+                       mpls_label_t *label_pnt = NULL;
+
+                       if (ri && ri->extra)
+                               num_labels = ri->extra->num_labels;
+                       if (num_labels)
+                               label_pnt = &ri->extra->label[0];
 
                        ret = bgp_update(peer, &rn->p, ain->addpath_rx_id,
                                         ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
-                                        BGP_ROUTE_NORMAL, prd, &label, 1,
-                                        NULL);
+                                        BGP_ROUTE_NORMAL, prd,
+                                        label_pnt, num_labels, 1, NULL);
 
                        if (ret < 0) {
                                bgp_unlock_node(rn);
@@ -4029,11 +4052,12 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
                if (attr)
                        ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
                                         ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
-                                        NULL, NULL, 0, NULL);
+                                        NULL, NULL, 0, 0, NULL);
                else
                        ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
                                           safi, ZEBRA_ROUTE_BGP,
-                                          BGP_ROUTE_NORMAL, NULL, NULL, NULL);
+                                          BGP_ROUTE_NORMAL, NULL,
+                                          NULL, 0, NULL);
 
                /* Address family configuration mismatch or maximum-prefix count
                   overflow. */
@@ -4345,10 +4369,13 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
 #if ENABLE_BGP_VNC
        mpls_label_t label = 0;
 #endif
+       u_int32_t num_labels = 0;
        union gw_addr add;
 
        assert(bgp_static);
 
+       if (bgp_static->label != MPLS_INVALID_LABEL)
+               num_labels = 1;
        rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
                              &bgp_static->prd);
 
@@ -4466,7 +4493,10 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
                        attr_new, rn);
        SET_FLAG(new->flags, BGP_INFO_VALID);
        new->extra = bgp_info_extra_new();
-       new->extra->label = bgp_static->label;
+       if (num_labels) {
+               new->extra->label[0] = bgp_static->label;
+               new->extra->num_labels = num_labels;
+       }
 #if ENABLE_BGP_VNC
        label = decode_label(&bgp_static->label);
 #endif
@@ -6713,7 +6743,7 @@ void route_vty_out_tag(struct vty *vty, struct prefix *p,
                }
        }
 
-       label = decode_label(&binfo->extra->label);
+       label = decode_label(&binfo->extra->label[0]);
 
        if (bgp_is_valid_label(&label)) {
                if (json) {
@@ -7051,14 +7081,15 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
 
 #if defined(HAVE_CUMULUS)
        if (!json_paths && safi == SAFI_EVPN) {
-               char tag_buf[20];
+               char tag_buf[30];
 
                bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2));
                vty_out(vty, "  Route %s", buf2);
                tag_buf[0] = '\0';
-               if (binfo->extra) {
-                       bgp_evpn_label2str(&binfo->extra->label, tag_buf,
-                                          sizeof(tag_buf));
+               if (binfo->extra && binfo->extra->num_labels) {
+                       bgp_evpn_label2str(binfo->extra->label,
+                                          binfo->extra->num_labels,
+                                          tag_buf, sizeof(tag_buf));
                        vty_out(vty, " VNI %s", tag_buf);
                }
                vty_out(vty, "\n");
@@ -7692,13 +7723,14 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
 
 /* Remote Label */
 #if defined(HAVE_CUMULUS)
-               if (binfo->extra && bgp_is_valid_label(&binfo->extra->label)
+               if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0])
                    && safi != SAFI_EVPN)
 #else
-               if (binfo->extra && bgp_is_valid_label(&binfo->extra->label))
+               if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0]))
 #endif
                {
-                       mpls_label_t label = label_pton(&binfo->extra->label);
+                       mpls_label_t label = label_pton(
+                                               &binfo->extra->label[0]);
                        if (json_paths)
                                json_object_int_add(json_path, "remoteLabel",
                                                    label);
index ae4759aad0dbc848b6a3e05f9463d77cb972a38e..cd4d027c6e6409b59bbcecef87168782683d6b03 100644 (file)
@@ -59,6 +59,11 @@ enum bgp_show_type {
 #define BGP_SHOW_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"
 #define BGP_SHOW_HEADER "   Network          Next Hop            Metric LocPrf Weight Path\n"
 
+/* Maximum number of labels we can process or send with a prefix. We
+ * really do only 1 for MPLS (BGP-LU) but we can do 2 for EVPN-VxLAN.
+ */
+#define BGP_MAX_LABELS 2
+
 /* Ancillary information to struct bgp_info,
  * used for uncommonly used data (aggregation, MPLS, etc.)
  * and lazily allocated to save memory.
@@ -73,11 +78,9 @@ struct bgp_info_extra {
        /* Nexthop reachability check.  */
        u_int32_t igpmetric;
 
-       /* MPLS label - L2VNI  */
-       mpls_label_t label;
-
-       /* MPLS label - L3-VNI */
-       mpls_label_t label2;
+       /* MPLS label(s) - VNI(s) for EVPN-VxLAN  */
+       mpls_label_t label[BGP_MAX_LABELS];
+       u_int32_t num_labels;
 
 #if ENABLE_BGP_VNC
        union {
@@ -360,10 +363,10 @@ extern int bgp_static_unset_safi(afi_t afi, safi_t safi, struct vty *,
 /* this is primarily for MPLS-VPN */
 extern int bgp_update(struct peer *, struct prefix *, u_int32_t, struct attr *,
                      afi_t, safi_t, int, int, struct prefix_rd *,
-                     mpls_label_t *, int, struct bgp_route_evpn *);
+                     mpls_label_t *, u_int32_t, int, struct bgp_route_evpn *);
 extern int bgp_withdraw(struct peer *, struct prefix *, u_int32_t,
                        struct attr *, afi_t, safi_t, int, int,
-                       struct prefix_rd *, mpls_label_t *,
+                       struct prefix_rd *, mpls_label_t *, u_int32_t,
                        struct bgp_route_evpn *);
 
 /* for bgp_nexthop and bgp_damp */
index 8c9f9f65ca4e4b3894e6d27ae7d2435b41ecaca1..de2410e009f00475d2403c9097b1496faaa5f5a8 100644 (file)
@@ -659,7 +659,7 @@ static route_map_result_t route_match_vni(void *rule, struct prefix *prefix,
                vni = *((vni_t *)rule);
                bgp_info = (struct bgp_info *)object;
 
-               if (vni == label2vni(&bgp_info->extra->label))
+               if (vni == label2vni(&bgp_info->extra->label[0]))
                        return RMAP_MATCH;
        }
 
index b63dfbed0ac240cacdcb6277ff13be46527f3fd5..9fa733a720e993108972fe2d9a2ad8596492d1d3 100644 (file)
@@ -701,7 +701,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
        int addpath_overhead = 0;
        u_int32_t addpath_tx_id = 0;
        struct prefix_rd *prd = NULL;
-       mpls_label_t label = MPLS_INVALID_LABEL;
+       mpls_label_t label = MPLS_INVALID_LABEL, *label_pnt = NULL;
+       u_int32_t num_labels = 0;
 
        if (!subgrp)
                return NULL;
@@ -772,7 +773,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
                         * attr. */
                        total_attr_len = bgp_packet_attribute(
                                NULL, peer, s, adv->baa->attr, &vecarr, NULL,
-                               afi, safi, from, NULL, NULL, 0, 0);
+                               afi, safi, from, NULL, NULL, 0, 0, 0);
 
                        space_remaining =
                                STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
@@ -815,11 +816,15 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
                        if (rn->prn)
                                prd = (struct prefix_rd *)&rn->prn->p;
 
-                       if (safi == SAFI_LABELED_UNICAST)
+                       if (safi == SAFI_LABELED_UNICAST) {
                                label = bgp_adv_label(rn, binfo, peer, afi,
                                                      safi);
-                       else if (binfo && binfo->extra)
-                               label = binfo->extra->label;
+                               label_pnt = &label;
+                               num_labels = 1;
+                       } else if (binfo && binfo->extra) {
+                               label_pnt = &binfo->extra->label[0];
+                               num_labels = binfo->extra->num_labels;
+                       }
 
                        if (stream_empty(snlri))
                                mpattrlen_pos = bgp_packet_mpattr_start(
@@ -827,8 +832,9 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
                                        adv->baa->attr);
 
                        bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd,
-                                                &label, addpath_encode,
-                                                addpath_tx_id, adv->baa->attr);
+                                                label_pnt, num_labels,
+                                                addpath_encode, addpath_tx_id,
+                                                adv->baa->attr);
                }
 
                num_pfx++;
@@ -857,7 +863,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
                                send_attr_printed = 1;
                        }
 
-                       bgp_debug_rdpfxpath2str(afi, safi, prd, &rn->p, &label,
+                       bgp_debug_rdpfxpath2str(afi, safi, prd, &rn->p,
+                                               label_pnt, num_labels,
                                                addpath_encode, addpath_tx_id,
                                                pfx_buf, sizeof(pfx_buf));
                        zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s",
@@ -1009,7 +1016,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
                        }
 
                        bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd,
-                                                   NULL, addpath_encode,
+                                                   NULL, 0, addpath_encode,
                                                    addpath_tx_id, NULL);
                }
 
@@ -1018,7 +1025,7 @@ struct bpacket *subgroup_withdraw_packet(struct update_subgroup *subgrp)
                if (bgp_debug_update(NULL, &rn->p, subgrp->update_group, 0)) {
                        char pfx_buf[BGP_PRD_PATH_STRLEN];
 
-                       bgp_debug_rdpfxpath2str(afi, safi, prd, &rn->p, NULL,
+                       bgp_debug_rdpfxpath2str(afi, safi, prd, &rn->p, NULL, 0,
                                                addpath_encode, addpath_tx_id,
                                                pfx_buf, sizeof(pfx_buf));
                        zlog_debug("u%" PRIu64 ":s%" PRIu64
@@ -1132,7 +1139,7 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
        stream_putw(s, 0);
        total_attr_len = bgp_packet_attribute(
                NULL, peer, s, attr, &vecarr, &p, afi, safi, from, NULL, NULL,
-               addpath_encode, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
+               0, addpath_encode, BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE);
 
        /* Set Total Path Attribute Length. */
        stream_putw_at(s, pos, total_attr_len);
@@ -1227,7 +1234,7 @@ void subgroup_default_withdraw_packet(struct update_subgroup *subgrp)
                mp_start = stream_get_endp(s);
                mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
                bgp_packet_mpunreach_prefix(
-                       s, &p, afi, safi, NULL, NULL, addpath_encode,
+                       s, &p, afi, safi, NULL, NULL, 0, addpath_encode,
                        BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, NULL);
 
                /* Set the mp_unreach attr's length */
index de170fdd0135b274369fae45ccb9afade18b1402..2a35645ee83b32eb590cd086a33e6aeaa123f740 100644 (file)
@@ -1142,10 +1142,11 @@ void bgp_zebra_announce(struct bgp_node *rn, struct prefix *p,
                        api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
                }
 
-               if (mpinfo->extra && bgp_is_valid_label(&mpinfo->extra->label)
+               if (mpinfo->extra &&
+                   bgp_is_valid_label(&mpinfo->extra->label[0])
                    && !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
                        has_valid_label = 1;
-                       label = label_pton(&mpinfo->extra->label);
+                       label = label_pton(&mpinfo->extra->label[0]);
 
                        api_nh->label_num = 1;
                        api_nh->labels[0] = label;
index d4921ce40a80ec6d49c05a81313a1c664544bc83..a37e7056126028244ce7024dac9cb4b3109446b2 100644 (file)
@@ -317,7 +317,7 @@ void vnc_direct_bgp_add_route_ce(struct bgp *bgp, struct route_node *rn,
                   iattr,          /* bgp_update copies this attr */
                   afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
                   BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
-                  NULL,                         /* tag not used for unicast */
+                  NULL, 0,                      /* tag not used for unicast */
                   0, NULL);                     /* EVPN not used */
        bgp_attr_unintern(&iattr);
 }