summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--bgpd/bgp_attr.c28
-rw-r--r--bgpd/bgp_attr.h9
-rw-r--r--bgpd/bgp_debug.c21
-rw-r--r--bgpd/bgp_debug.h3
-rw-r--r--bgpd/bgp_evpn.c119
-rw-r--r--bgpd/bgp_evpn.h27
-rw-r--r--bgpd/bgp_evpn_private.h20
-rw-r--r--bgpd/bgp_label.c6
-rw-r--r--bgpd/bgp_mplsvpn.c4
-rw-r--r--bgpd/bgp_route.c116
-rw-r--r--bgpd/bgp_route.h17
-rw-r--r--bgpd/bgp_routemap.c2
-rw-r--r--bgpd/bgp_updgrp_packet.c31
-rw-r--r--bgpd/bgp_zebra.c5
-rw-r--r--bgpd/rfapi/vnc_export_bgp.c2
15 files changed, 261 insertions, 149 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c
index f197ad16a3..3f3acbe0e2 100644
--- a/bgpd/bgp_attr.c
+++ b/bgpd/bgp_attr.c
@@ -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);
}
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h
index ebe14a7ceb..1b1471a198 100644
--- a/bgpd/bgp_attr.h
+++ b/bgpd/bgp_attr.h
@@ -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);
diff --git a/bgpd/bgp_debug.c b/bgpd/bgp_debug.c
index 45ac8e6859..b08522b68b 100644
--- a/bgpd/bgp_debug.c
+++ b/bgpd/bgp_debug.c
@@ -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)
diff --git a/bgpd/bgp_debug.h b/bgpd/bgp_debug.h
index 5fe19b162b..7c773cfafb 100644
--- a/bgpd/bgp_debug.h
+++ b/bgpd/bgp_debug.h
@@ -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);
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 46a983a880..b20076d471 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -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:
diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h
index 9400916845..b3b61db141 100644
--- a/bgpd/bgp_evpn.h
+++ b/bgpd/bgp_evpn.h
@@ -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,
diff --git a/bgpd/bgp_evpn_private.h b/bgpd/bgp_evpn_private.h
index f5a0998f62..6003e03f35 100644
--- a/bgpd/bgp_evpn_private.h
+++ b/bgpd/bgp_evpn_private.h
@@ -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)
{
diff --git a/bgpd/bgp_label.c b/bgpd/bgp_label.c
index 60250513b6..38b39075be 100644
--- a/bgpd/bgp_label.c
+++ b/bgpd/bgp_label.c
@@ -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);
}
}
diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c
index 472b9d200a..0e2594ba8a 100644
--- a/bgpd/bgp_mplsvpn.c
+++ b/bgpd/bgp_mplsvpn.c
@@ -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. */
diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c
index fdc7f22ae8..234bde418b 100644
--- a/bgpd/bgp_route.c
+++ b/bgpd/bgp_route.c
@@ -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);
diff --git a/bgpd/bgp_route.h b/bgpd/bgp_route.h
index ae4759aad0..cd4d027c6e 100644
--- a/bgpd/bgp_route.h
+++ b/bgpd/bgp_route.h
@@ -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 */
diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c
index 8c9f9f65ca..de2410e009 100644
--- a/bgpd/bgp_routemap.c
+++ b/bgpd/bgp_routemap.c
@@ -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;
}
diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c
index b63dfbed0a..9fa733a720 100644
--- a/bgpd/bgp_updgrp_packet.c
+++ b/bgpd/bgp_updgrp_packet.c
@@ -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 */
diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c
index de170fdd01..2a35645ee8 100644
--- a/bgpd/bgp_zebra.c
+++ b/bgpd/bgp_zebra.c
@@ -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;
diff --git a/bgpd/rfapi/vnc_export_bgp.c b/bgpd/rfapi/vnc_export_bgp.c
index d4921ce40a..a37e705612 100644
--- a/bgpd/rfapi/vnc_export_bgp.c
+++ b/bgpd/rfapi/vnc_export_bgp.c
@@ -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);
}