forked from Mirror/frr
bgpd: carry two MPLS labels in EVPN NLRIs
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>
This commit is contained in:
parent
a6ad0a4183
commit
b57ba6d2a8
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
119
bgpd/bgp_evpn.c
119
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;
|
||||
|
||||
memcpy(&tmp_ri->extra->label, &label, BGP_LABEL_BYTES);
|
||||
l3vni = bgpevpn_get_l3vni(vpn);
|
||||
if (l3vni) {
|
||||
vni2label(l3vni, &label[1]);
|
||||
num_labels++;
|
||||
}
|
||||
}
|
||||
|
||||
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:
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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. */
|
||||
|
|
116
bgpd/bgp_route.c
116
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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue