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,
|
void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
|
||||||
struct prefix *p, struct prefix_rd *prd,
|
struct prefix *p, struct prefix_rd *prd,
|
||||||
mpls_label_t *label, int addpath_encode,
|
mpls_label_t *label, u_int32_t num_labels,
|
||||||
u_int32_t addpath_tx_id, struct attr *attr)
|
int addpath_encode, u_int32_t addpath_tx_id,
|
||||||
|
struct attr *attr)
|
||||||
{
|
{
|
||||||
if (safi == SAFI_MPLS_VPN) {
|
if (safi == SAFI_MPLS_VPN) {
|
||||||
if (addpath_encode)
|
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));
|
stream_put(s, &p->u.prefix, PSIZE(p->prefixlen));
|
||||||
} else if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
|
} else if (afi == AFI_L2VPN && safi == SAFI_EVPN) {
|
||||||
/* EVPN prefix - contents depend on type */
|
/* EVPN prefix - contents depend on type */
|
||||||
bgp_evpn_encode_prefix(s, p, prd, label, attr, addpath_encode,
|
bgp_evpn_encode_prefix(s, p, prd, label, num_labels,
|
||||||
addpath_tx_id);
|
attr, addpath_encode, addpath_tx_id);
|
||||||
} else if (safi == SAFI_LABELED_UNICAST) {
|
} else if (safi == SAFI_LABELED_UNICAST) {
|
||||||
/* Prefix write with label. */
|
/* Prefix write with label. */
|
||||||
stream_put_labeled_prefix(s, p, 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 bpacket_attr_vec_arr *vecarr,
|
||||||
struct prefix *p, afi_t afi, safi_t safi,
|
struct prefix *p, afi_t afi, safi_t safi,
|
||||||
struct peer *from, struct prefix_rd *prd,
|
struct peer *from, struct prefix_rd *prd,
|
||||||
mpls_label_t *label, int addpath_encode,
|
mpls_label_t *label, u_int32_t num_labels,
|
||||||
u_int32_t addpath_tx_id)
|
int addpath_encode, u_int32_t addpath_tx_id)
|
||||||
{
|
{
|
||||||
size_t cp;
|
size_t cp;
|
||||||
size_t aspath_sizep;
|
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,
|
mpattrlen_pos = bgp_packet_mpattr_start(s, peer, afi, safi,
|
||||||
vecarr, attr);
|
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);
|
addpath_encode, addpath_tx_id, attr);
|
||||||
bgp_packet_mpattr_end(s, mpattrlen_pos);
|
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,
|
void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p, afi_t afi,
|
||||||
safi_t safi, struct prefix_rd *prd,
|
safi_t safi, struct prefix_rd *prd,
|
||||||
mpls_label_t *label, int addpath_encode,
|
mpls_label_t *label, u_int32_t num_labels,
|
||||||
u_int32_t addpath_tx_id, struct attr *attr)
|
int addpath_encode, u_int32_t addpath_tx_id,
|
||||||
|
struct attr *attr)
|
||||||
{
|
{
|
||||||
u_char wlabel[3] = {0x80, 0x00, 0x00};
|
u_char wlabel[3] = {0x80, 0x00, 0x00};
|
||||||
|
|
||||||
if (safi == SAFI_LABELED_UNICAST)
|
if (safi == SAFI_LABELED_UNICAST) {
|
||||||
label = (mpls_label_t *)wlabel;
|
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);
|
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 bpacket_attr_vec_arr *vecarr,
|
||||||
struct prefix *, afi_t, safi_t,
|
struct prefix *, afi_t, safi_t,
|
||||||
struct peer *, struct prefix_rd *,
|
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 *,
|
extern void bgp_dump_routes_attr(struct stream *, struct attr *,
|
||||||
struct prefix *);
|
struct prefix *);
|
||||||
extern int attrhash_cmp(const void *, const void *);
|
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);
|
struct attr *attr);
|
||||||
extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
|
extern void bgp_packet_mpattr_prefix(struct stream *s, afi_t afi, safi_t safi,
|
||||||
struct prefix *p, struct prefix_rd *prd,
|
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 *);
|
u_int32_t addpath_tx_id, struct attr *);
|
||||||
extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
|
extern size_t bgp_packet_mpattr_prefix_size(afi_t afi, safi_t safi,
|
||||||
struct prefix *p);
|
struct prefix *p);
|
||||||
|
@ -318,7 +320,8 @@ extern size_t bgp_packet_mpunreach_start(struct stream *s, afi_t afi,
|
||||||
safi_t safi);
|
safi_t safi);
|
||||||
extern void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p,
|
extern void bgp_packet_mpunreach_prefix(struct stream *s, struct prefix *p,
|
||||||
afi_t afi, safi_t safi,
|
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 *);
|
int, u_int32_t, struct attr *);
|
||||||
extern void bgp_packet_mpunreach_end(struct stream *s, size_t attrlen_pnt);
|
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,
|
const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
|
||||||
struct prefix_rd *prd,
|
struct prefix_rd *prd,
|
||||||
union prefixconstptr pu,
|
union prefixconstptr pu,
|
||||||
mpls_label_t *label, int addpath_valid,
|
mpls_label_t *label, u_int32_t num_labels,
|
||||||
u_int32_t addpath_id, char *str, int size)
|
int addpath_valid, u_int32_t addpath_id,
|
||||||
|
char *str, int size)
|
||||||
{
|
{
|
||||||
char rd_buf[RD_ADDRSTRLEN];
|
char rd_buf[RD_ADDRSTRLEN];
|
||||||
char pfx_buf[PREFIX_STRLEN];
|
char pfx_buf[PREFIX_STRLEN];
|
||||||
|
@ -2041,12 +2042,20 @@ const char *bgp_debug_rdpfxpath2str(afi_t afi, safi_t safi,
|
||||||
addpath_id);
|
addpath_id);
|
||||||
|
|
||||||
tag_buf[0] = '\0';
|
tag_buf[0] = '\0';
|
||||||
if (bgp_labeled_safi(safi) && label) {
|
if (bgp_labeled_safi(safi) && num_labels) {
|
||||||
|
|
||||||
|
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;
|
u_int32_t label_value;
|
||||||
|
|
||||||
label_value = decode_label(label);
|
label_value = decode_label(label);
|
||||||
sprintf(tag_buf, " label %u", label_value);
|
sprintf(tag_buf, " label %u", label_value);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (prd)
|
if (prd)
|
||||||
snprintf(str, size, "RD %s %s%s%s %s %s",
|
snprintf(str, size, "RD %s %s%s%s %s %s",
|
||||||
|
|
|
@ -153,7 +153,8 @@ extern int bgp_debug_zebra(struct prefix *p);
|
||||||
|
|
||||||
extern int bgp_debug_count(void);
|
extern int bgp_debug_count(void);
|
||||||
extern const char *bgp_debug_rdpfxpath2str(afi_t, safi_t, struct prefix_rd *,
|
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);
|
int, u_int32_t, char *, int);
|
||||||
const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data,
|
const char *bgp_notify_admin_message(char *buf, size_t bufsz, u_char *data,
|
||||||
size_t datalen);
|
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);
|
bgp_def->peer_self, attr_new, rn);
|
||||||
SET_FLAG(ri->flags, BGP_INFO_VALID);
|
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);
|
bgp_info_extra_get(ri);
|
||||||
vni2label(bgp_vrf->l3vni, &label);
|
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*/
|
/* add the route entry to route node*/
|
||||||
bgp_info_add(rn, ri);
|
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 *tmp_ri;
|
||||||
struct bgp_info *local_ri, *remote_ri;
|
struct bgp_info *local_ri, *remote_ri;
|
||||||
struct attr *attr_new;
|
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;
|
int route_change = 1;
|
||||||
u_char sticky = 0;
|
u_char sticky = 0;
|
||||||
|
struct prefix_evpn *evp;
|
||||||
|
|
||||||
*ri = NULL;
|
*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,
|
/* 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
|
* 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);
|
bgp_info_extra_get(tmp_ri);
|
||||||
|
|
||||||
/* The VNI goes into the 'label' field of the route */
|
/* 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);
|
bgp_info_add(rn, tmp_ri);
|
||||||
} else {
|
} else {
|
||||||
tmp_ri = local_ri;
|
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);
|
SET_FLAG(ri->flags, BGP_INFO_VALID);
|
||||||
bgp_info_extra_get(ri);
|
bgp_info_extra_get(ri);
|
||||||
ri->extra->parent = parent_ri;
|
ri->extra->parent = parent_ri;
|
||||||
if (parent_ri->extra)
|
if (parent_ri->extra) {
|
||||||
memcpy(&ri->extra->label, &parent_ri->extra->label,
|
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);
|
bgp_info_add(rn, ri);
|
||||||
} else {
|
} else {
|
||||||
if (attrhash_cmp(ri->attr, parent_ri->attr)
|
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);
|
SET_FLAG(ri->flags, BGP_INFO_VALID);
|
||||||
bgp_info_extra_get(ri);
|
bgp_info_extra_get(ri);
|
||||||
ri->extra->parent = parent_ri;
|
ri->extra->parent = parent_ri;
|
||||||
if (parent_ri->extra)
|
if (parent_ri->extra) {
|
||||||
memcpy(&ri->extra->label, &parent_ri->extra->label,
|
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);
|
bgp_info_add(rn, ri);
|
||||||
} else {
|
} else {
|
||||||
if (attrhash_cmp(ri->attr, parent_ri->attr)
|
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;
|
struct prefix_evpn p;
|
||||||
u_char ipaddr_len;
|
u_char ipaddr_len;
|
||||||
u_char macaddr_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;
|
int ret;
|
||||||
|
|
||||||
/* Type-2 route should be either 33, 37 or 49 bytes or an
|
/* 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;
|
pfx += ipaddr_len;
|
||||||
|
|
||||||
/* Get the VNI (in MPLS label field). */
|
/* Get the VNI(s). Stored as bytes here. */
|
||||||
/* Note: We ignore the second VNI, if any. */
|
num_labels++;
|
||||||
label_pnt = (mpls_label_t *)pfx;
|
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. */
|
/* Process the route. */
|
||||||
if (attr)
|
if (attr)
|
||||||
ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
|
ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
|
||||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||||
&prd, label_pnt, 0, NULL);
|
&prd, &label[0], num_labels, 0, NULL);
|
||||||
else
|
else
|
||||||
ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
|
ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
|
||||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||||
&prd, label_pnt, NULL);
|
&prd, &label[0], num_labels, NULL);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2908,11 +2938,11 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
|
||||||
if (attr)
|
if (attr)
|
||||||
ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
|
ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
|
||||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||||
&prd, NULL, 0, NULL);
|
&prd, NULL, 0, 0, NULL);
|
||||||
else
|
else
|
||||||
ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
|
ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
|
||||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||||
&prd, NULL, NULL);
|
&prd, NULL, 0, NULL);
|
||||||
return ret;
|
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;
|
struct bgp_route_evpn evpn;
|
||||||
u_char ippfx_len;
|
u_char ippfx_len;
|
||||||
u_int32_t eth_tag;
|
u_int32_t eth_tag;
|
||||||
mpls_label_t *label_pnt;
|
mpls_label_t label; /* holds the VNI as in the packet */
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/* Type-5 route should be 34 or 58 bytes:
|
/* 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;
|
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. */
|
/* Process the route. */
|
||||||
if (!withdraw)
|
if (!withdraw)
|
||||||
ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
|
ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr,
|
||||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||||
&prd, label_pnt, 0, &evpn);
|
&prd, &label, 1, 0, &evpn);
|
||||||
else
|
else
|
||||||
ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
|
ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr,
|
||||||
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||||
&prd, label_pnt, &evpn);
|
&prd, &label, 1, &evpn);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
|
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)
|
struct attr *attr)
|
||||||
{
|
{
|
||||||
int len;
|
int len;
|
||||||
|
@ -3055,7 +3089,7 @@ static void evpn_mpattr_encode_type5(struct stream *s, struct prefix *p,
|
||||||
stream_put(s, &temp, 16);
|
stream_put(s, &temp, 16);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (label)
|
if (num_labels)
|
||||||
stream_put(s, label, 3);
|
stream_put(s, label, 3);
|
||||||
else
|
else
|
||||||
stream_put3(s, 0);
|
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 vni;
|
||||||
|
vni_t vni1, vni2;
|
||||||
|
|
||||||
vni = label2vni(label);
|
vni1 = label2vni(label);
|
||||||
snprintf(buf, len, "%u", vni);
|
if (num_labels == 2) {
|
||||||
|
vni2 = label2vni(label+1);
|
||||||
|
snprintf(buf, len, "%u/%u", vni1, vni2);
|
||||||
|
} else
|
||||||
|
snprintf(buf, len, "%u", vni1);
|
||||||
return buf;
|
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)
|
* Encode EVPN prefix in Update (MP_REACH)
|
||||||
*/
|
*/
|
||||||
void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
|
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,
|
struct attr *attr, int addpath_encode,
|
||||||
u_int32_t addpath_tx_id)
|
u_int32_t addpath_tx_id)
|
||||||
{
|
{
|
||||||
struct prefix_evpn *evp = (struct prefix_evpn *)p;
|
struct prefix_evpn *evp = (struct prefix_evpn *)p;
|
||||||
int ipa_len = 0;
|
int len, ipa_len = 0;
|
||||||
|
|
||||||
if (addpath_encode)
|
if (addpath_encode)
|
||||||
stream_putl(s, addpath_tx_id);
|
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;
|
ipa_len = IPV4_MAX_BYTELEN;
|
||||||
else if (IS_EVPN_PREFIX_IPADDR_V6(evp))
|
else if (IS_EVPN_PREFIX_IPADDR_V6(evp))
|
||||||
ipa_len = IPV6_MAX_BYTELEN;
|
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, prd->val, 8); /* RD */
|
||||||
stream_put(s, 0, 10); /* ESI */
|
stream_put(s, 0, 10); /* ESI */
|
||||||
stream_putl(s, 0); /* Ethernet Tag ID */
|
stream_putl(s, 0); /* Ethernet Tag ID */
|
||||||
stream_putc(s, 8 * ETH_ALEN); /* Mac Addr Len - bits */
|
stream_putc(s, 8 * ETH_ALEN); /* Mac Addr Len - bits */
|
||||||
stream_put(s, evp->prefix.mac.octet, 6); /* Mac Addr */
|
stream_put(s, evp->prefix.mac.octet, 6); /* Mac Addr */
|
||||||
stream_putc(s, 8 * ipa_len); /* IP address Length */
|
stream_putc(s, 8 * ipa_len); /* IP address Length */
|
||||||
if (ipa_len)
|
if (ipa_len) /* IP */
|
||||||
stream_put(s, &evp->prefix.ip.ip.addr,
|
stream_put(s, &evp->prefix.ip.ip.addr, ipa_len);
|
||||||
ipa_len); /* IP */
|
/* 1st label is the L2 VNI */
|
||||||
stream_put(s, label,
|
stream_put(s, label, BGP_LABEL_BYTES);
|
||||||
BGP_LABEL_BYTES); /* VNI is contained in 'tag' */
|
/* Include 2nd label (L3 VNI) if advertising MAC+IP */
|
||||||
|
if (ipa_len && num_labels > 1)
|
||||||
|
stream_put(s, label+1, BGP_LABEL_BYTES);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BGP_EVPN_IMET_ROUTE:
|
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:
|
case BGP_EVPN_IP_PREFIX_ROUTE:
|
||||||
/* TODO: AddPath support. */
|
/* TODO: AddPath support. */
|
||||||
evpn_mpattr_encode_type5(s, p, prd, label, attr);
|
evpn_mpattr_encode_type5(s, p, prd, label, num_labels, attr);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -34,6 +34,27 @@ static inline int is_evpn_enabled(void)
|
||||||
return bgp ? bgp->advertise_all_vni : 0;
|
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,
|
extern void bgp_evpn_advertise_type5_route(struct bgp *bgp_vrf,
|
||||||
struct bgp_node *rn,
|
struct bgp_node *rn,
|
||||||
afi_t afi, safi_t safi);
|
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);
|
safi_t safi);
|
||||||
extern void bgp_evpn_vrf_delete(struct bgp *bgp_vrf);
|
extern void bgp_evpn_vrf_delete(struct bgp *bgp_vrf);
|
||||||
extern void bgp_evpn_handle_router_id_update(struct bgp *bgp, int withdraw);
|
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 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_route2json(struct prefix_evpn *p, json_object *json);
|
||||||
extern void bgp_evpn_encode_prefix(struct stream *s, struct prefix *p,
|
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,
|
struct attr *attr, int addpath_encode,
|
||||||
u_int32_t addpath_tx_id);
|
u_int32_t addpath_tx_id);
|
||||||
extern int bgp_nlri_parse_evpn(struct peer *peer, struct attr *attr,
|
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));
|
|| 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,
|
static inline void encode_rmac_extcomm(struct ecommunity_val *eval,
|
||||||
struct ethaddr *rmac)
|
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)
|
if (!rn || !ri || !to)
|
||||||
return MPLS_INVALID_LABEL;
|
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;
|
from = ri->peer;
|
||||||
reflect =
|
reflect =
|
||||||
((from->sort == BGP_PEER_IBGP) && (to->sort == BGP_PEER_IBGP));
|
((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) {
|
if (attr) {
|
||||||
bgp_update(peer, &p, addpath_id, attr, packet->afi,
|
bgp_update(peer, &p, addpath_id, attr, packet->afi,
|
||||||
SAFI_UNICAST, ZEBRA_ROUTE_BGP,
|
SAFI_UNICAST, ZEBRA_ROUTE_BGP,
|
||||||
BGP_ROUTE_NORMAL, NULL, &label, 0, NULL);
|
BGP_ROUTE_NORMAL, NULL, &label, 1, 0, NULL);
|
||||||
} else {
|
} else {
|
||||||
bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
|
bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
|
||||||
SAFI_UNICAST, ZEBRA_ROUTE_BGP,
|
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) {
|
if (attr) {
|
||||||
bgp_update(peer, &p, addpath_id, attr, packet->afi,
|
bgp_update(peer, &p, addpath_id, attr, packet->afi,
|
||||||
SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
|
SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
|
||||||
BGP_ROUTE_NORMAL, &prd, &label, 0, NULL);
|
BGP_ROUTE_NORMAL, &prd, &label, 1, 0, NULL);
|
||||||
} else {
|
} else {
|
||||||
bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
|
bgp_withdraw(peer, &p, addpath_id, attr, packet->afi,
|
||||||
SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
|
SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
|
||||||
BGP_ROUTE_NORMAL, &prd, &label, NULL);
|
BGP_ROUTE_NORMAL, &prd, &label, 1, NULL);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* Packet length consistency check. */
|
/* Packet length consistency check. */
|
||||||
|
|
114
bgpd/bgp_route.c
114
bgpd/bgp_route.c
|
@ -147,7 +147,8 @@ static struct bgp_info_extra *bgp_info_extra_new(void)
|
||||||
{
|
{
|
||||||
struct bgp_info_extra *new;
|
struct bgp_info_extra *new;
|
||||||
new = XCALLOC(MTYPE_BGP_ROUTE_EXTRA, sizeof(struct bgp_info_extra));
|
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;
|
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
|
/* If one path has a label but the other does not, do not treat
|
||||||
* them as equals for multipath
|
* 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
|
!= (exist->extra
|
||||||
&& bgp_is_valid_label(&exist->extra->label))) {
|
&& bgp_is_valid_label(&exist->extra->label[0]))) {
|
||||||
if (debug)
|
if (debug)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: %s and %s cannot be multipath, one has a label while the other does not",
|
"%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,
|
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,
|
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 soft_reconfig, struct bgp_route_evpn *evpn)
|
||||||
{
|
{
|
||||||
int ret;
|
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 attr *attr_new;
|
||||||
struct bgp_info *ri;
|
struct bgp_info *ri;
|
||||||
struct bgp_info *new;
|
struct bgp_info *new;
|
||||||
|
struct bgp_info_extra *extra;
|
||||||
const char *reason;
|
const char *reason;
|
||||||
char pfx_buf[BGP_PRD_PATH_STRLEN];
|
char pfx_buf[BGP_PRD_PATH_STRLEN];
|
||||||
char label_buf[20];
|
|
||||||
int connected = 0;
|
int connected = 0;
|
||||||
int do_loop_check = 1;
|
int do_loop_check = 1;
|
||||||
int has_valid_label = 0;
|
int has_valid_label = 0;
|
||||||
|
@ -2698,11 +2700,12 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||||
|
|
||||||
bgp = peer->bgp;
|
bgp = peer->bgp;
|
||||||
rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
|
rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p, prd);
|
||||||
|
/* 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);
|
has_valid_label = bgp_is_valid_label(label);
|
||||||
|
|
||||||
if (has_valid_label)
|
|
||||||
sprintf(label_buf, "label %u", label_pton(label));
|
|
||||||
|
|
||||||
/* When peer's soft reconfiguration enabled. Record input packet in
|
/* When peer's soft reconfiguration enabled. Record input packet in
|
||||||
Adj-RIBs-In. */
|
Adj-RIBs-In. */
|
||||||
if (!soft_reconfig
|
if (!soft_reconfig
|
||||||
|
@ -2821,7 +2824,7 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||||
&& attrhash_cmp(ri->attr, attr_new)
|
&& attrhash_cmp(ri->attr, attr_new)
|
||||||
&& (!has_valid_label
|
&& (!has_valid_label
|
||||||
|| memcmp(&(bgp_info_extra_get(ri))->label, label,
|
|| memcmp(&(bgp_info_extra_get(ri))->label, label,
|
||||||
BGP_LABEL_BYTES)
|
num_labels * sizeof(mpls_label_t))
|
||||||
== 0)
|
== 0)
|
||||||
&& (overlay_index_equal(
|
&& (overlay_index_equal(
|
||||||
afi, ri, evpn == NULL ? NULL : &evpn->eth_s_id,
|
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)) {
|
&& CHECK_FLAG(ri->flags, BGP_INFO_HISTORY)) {
|
||||||
if (bgp_debug_update(peer, p, NULL, 1)) {
|
if (bgp_debug_update(peer, p, NULL, 1)) {
|
||||||
bgp_debug_rdpfxpath2str(
|
bgp_debug_rdpfxpath2str(
|
||||||
afi, safi, prd, p, label,
|
afi, safi, prd, p,
|
||||||
|
label, num_labels,
|
||||||
addpath_id ? 1 : 0, addpath_id,
|
addpath_id ? 1 : 0, addpath_id,
|
||||||
pfx_buf, sizeof(pfx_buf));
|
pfx_buf, sizeof(pfx_buf));
|
||||||
zlog_debug("%s rcvd %s", peer->host,
|
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(
|
bgp_debug_rdpfxpath2str(
|
||||||
afi, safi, prd, p, label,
|
afi, safi, prd, p,
|
||||||
|
label, num_labels,
|
||||||
addpath_id ? 1 : 0, addpath_id,
|
addpath_id ? 1 : 0, addpath_id,
|
||||||
pfx_buf, sizeof(pfx_buf));
|
pfx_buf, sizeof(pfx_buf));
|
||||||
zlog_debug(
|
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 (CHECK_FLAG(ri->flags, BGP_INFO_REMOVED)) {
|
||||||
if (bgp_debug_update(peer, p, NULL, 1)) {
|
if (bgp_debug_update(peer, p, NULL, 1)) {
|
||||||
bgp_debug_rdpfxpath2str(
|
bgp_debug_rdpfxpath2str(
|
||||||
afi, safi, prd, p, label,
|
afi, safi, prd, p,
|
||||||
|
label, num_labels,
|
||||||
addpath_id ? 1 : 0, addpath_id, pfx_buf,
|
addpath_id ? 1 : 0, addpath_id, pfx_buf,
|
||||||
sizeof(pfx_buf));
|
sizeof(pfx_buf));
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
|
@ -2896,7 +2902,8 @@ int bgp_update(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||||
|
|
||||||
/* Received Logging. */
|
/* Received Logging. */
|
||||||
if (bgp_debug_update(peer, p, NULL, 1)) {
|
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,
|
addpath_id ? 1 : 0, addpath_id,
|
||||||
pfx_buf, sizeof(pfx_buf));
|
pfx_buf, sizeof(pfx_buf));
|
||||||
zlog_debug("%s rcvd %s", peer->host, 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 */
|
/* Update MPLS label */
|
||||||
if (has_valid_label) {
|
if (has_valid_label) {
|
||||||
memcpy(&(bgp_info_extra_get(ri))->label, label,
|
extra = bgp_info_extra_get(ri);
|
||||||
BGP_LABEL_BYTES);
|
memcpy(&extra->label, label,
|
||||||
bgp_set_valid_label(&(bgp_info_extra_get(ri))->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
|
#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;
|
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,
|
addpath_id ? 1 : 0, addpath_id, pfx_buf,
|
||||||
sizeof(pfx_buf));
|
sizeof(pfx_buf));
|
||||||
zlog_debug("%s rcvd %s", peer->host, 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 */
|
/* Update MPLS label */
|
||||||
if (has_valid_label) {
|
if (has_valid_label) {
|
||||||
memcpy(&(bgp_info_extra_get(new))->label, label,
|
extra = bgp_info_extra_get(new);
|
||||||
BGP_LABEL_BYTES);
|
memcpy(&extra->label, label,
|
||||||
bgp_set_valid_label(&(bgp_info_extra_get(new))->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 */
|
/* Update Overlay Index */
|
||||||
|
@ -3241,7 +3255,8 @@ filtered:
|
||||||
peer->rcvd_attr_printed = 1;
|
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,
|
addpath_id ? 1 : 0, addpath_id, pfx_buf,
|
||||||
sizeof(pfx_buf));
|
sizeof(pfx_buf));
|
||||||
zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s",
|
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,
|
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,
|
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_route_evpn *evpn)
|
||||||
{
|
{
|
||||||
struct bgp *bgp;
|
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_adj_in_unset(rn, peer, addpath_id)) {
|
||||||
if (bgp_debug_update(peer, p, NULL, 1)) {
|
if (bgp_debug_update(peer, p, NULL, 1)) {
|
||||||
bgp_debug_rdpfxpath2str(
|
bgp_debug_rdpfxpath2str(
|
||||||
afi, safi, prd, p, label,
|
afi, safi, prd, p,
|
||||||
|
label, num_labels,
|
||||||
addpath_id ? 1 : 0, addpath_id, pfx_buf,
|
addpath_id ? 1 : 0, addpath_id, pfx_buf,
|
||||||
sizeof(pfx_buf));
|
sizeof(pfx_buf));
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
|
@ -3332,7 +3349,8 @@ int bgp_withdraw(struct peer *peer, struct prefix *p, u_int32_t addpath_id,
|
||||||
|
|
||||||
/* Logging. */
|
/* Logging. */
|
||||||
if (bgp_debug_update(peer, p, NULL, 1)) {
|
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,
|
addpath_id ? 1 : 0, addpath_id, pfx_buf,
|
||||||
sizeof(pfx_buf));
|
sizeof(pfx_buf));
|
||||||
zlog_debug("%s rcvd UPDATE about %s -- withdrawn", peer->host,
|
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))
|
if (ri && !CHECK_FLAG(ri->flags, BGP_INFO_HISTORY))
|
||||||
bgp_rib_withdraw(rn, ri, peer, afi, safi, prd);
|
bgp_rib_withdraw(rn, ri, peer, afi, safi, prd);
|
||||||
else if (bgp_debug_update(peer, p, NULL, 1)) {
|
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,
|
addpath_id ? 1 : 0, addpath_id, pfx_buf,
|
||||||
sizeof(pfx_buf));
|
sizeof(pfx_buf));
|
||||||
zlog_debug("%s Can't find the route %s", peer->host, 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;
|
continue;
|
||||||
|
|
||||||
struct bgp_info *ri = rn->info;
|
struct bgp_info *ri = rn->info;
|
||||||
mpls_label_t label = (ri && ri->extra)
|
u_int32_t num_labels = 0;
|
||||||
? ri->extra->label
|
mpls_label_t *label_pnt = NULL;
|
||||||
: MPLS_INVALID_LABEL;
|
|
||||||
|
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,
|
ret = bgp_update(peer, &rn->p, ain->addpath_rx_id,
|
||||||
ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
|
ain->attr, afi, safi, ZEBRA_ROUTE_BGP,
|
||||||
BGP_ROUTE_NORMAL, prd, &label, 1,
|
BGP_ROUTE_NORMAL, prd,
|
||||||
NULL);
|
label_pnt, num_labels, 1, NULL);
|
||||||
|
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
bgp_unlock_node(rn);
|
bgp_unlock_node(rn);
|
||||||
|
@ -4029,11 +4052,12 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
|
||||||
if (attr)
|
if (attr)
|
||||||
ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
|
ret = bgp_update(peer, &p, addpath_id, attr, afi, safi,
|
||||||
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL,
|
||||||
NULL, NULL, 0, NULL);
|
NULL, NULL, 0, 0, NULL);
|
||||||
else
|
else
|
||||||
ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
|
ret = bgp_withdraw(peer, &p, addpath_id, attr, afi,
|
||||||
safi, ZEBRA_ROUTE_BGP,
|
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
|
/* Address family configuration mismatch or maximum-prefix count
|
||||||
overflow. */
|
overflow. */
|
||||||
|
@ -4345,10 +4369,13 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
|
||||||
#if ENABLE_BGP_VNC
|
#if ENABLE_BGP_VNC
|
||||||
mpls_label_t label = 0;
|
mpls_label_t label = 0;
|
||||||
#endif
|
#endif
|
||||||
|
u_int32_t num_labels = 0;
|
||||||
union gw_addr add;
|
union gw_addr add;
|
||||||
|
|
||||||
assert(bgp_static);
|
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,
|
rn = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, p,
|
||||||
&bgp_static->prd);
|
&bgp_static->prd);
|
||||||
|
|
||||||
|
@ -4466,7 +4493,10 @@ static void bgp_static_update_safi(struct bgp *bgp, struct prefix *p,
|
||||||
attr_new, rn);
|
attr_new, rn);
|
||||||
SET_FLAG(new->flags, BGP_INFO_VALID);
|
SET_FLAG(new->flags, BGP_INFO_VALID);
|
||||||
new->extra = bgp_info_extra_new();
|
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
|
#if ENABLE_BGP_VNC
|
||||||
label = decode_label(&bgp_static->label);
|
label = decode_label(&bgp_static->label);
|
||||||
#endif
|
#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 (bgp_is_valid_label(&label)) {
|
||||||
if (json) {
|
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 defined(HAVE_CUMULUS)
|
||||||
if (!json_paths && safi == SAFI_EVPN) {
|
if (!json_paths && safi == SAFI_EVPN) {
|
||||||
char tag_buf[20];
|
char tag_buf[30];
|
||||||
|
|
||||||
bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2));
|
bgp_evpn_route2str((struct prefix_evpn *)p, buf2, sizeof(buf2));
|
||||||
vty_out(vty, " Route %s", buf2);
|
vty_out(vty, " Route %s", buf2);
|
||||||
tag_buf[0] = '\0';
|
tag_buf[0] = '\0';
|
||||||
if (binfo->extra) {
|
if (binfo->extra && binfo->extra->num_labels) {
|
||||||
bgp_evpn_label2str(&binfo->extra->label, tag_buf,
|
bgp_evpn_label2str(binfo->extra->label,
|
||||||
sizeof(tag_buf));
|
binfo->extra->num_labels,
|
||||||
|
tag_buf, sizeof(tag_buf));
|
||||||
vty_out(vty, " VNI %s", tag_buf);
|
vty_out(vty, " VNI %s", tag_buf);
|
||||||
}
|
}
|
||||||
vty_out(vty, "\n");
|
vty_out(vty, "\n");
|
||||||
|
@ -7692,13 +7723,14 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct prefix *p,
|
||||||
|
|
||||||
/* Remote Label */
|
/* Remote Label */
|
||||||
#if defined(HAVE_CUMULUS)
|
#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)
|
&& safi != SAFI_EVPN)
|
||||||
#else
|
#else
|
||||||
if (binfo->extra && bgp_is_valid_label(&binfo->extra->label))
|
if (binfo->extra && bgp_is_valid_label(&binfo->extra->label[0]))
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
mpls_label_t label = label_pton(&binfo->extra->label);
|
mpls_label_t label = label_pton(
|
||||||
|
&binfo->extra->label[0]);
|
||||||
if (json_paths)
|
if (json_paths)
|
||||||
json_object_int_add(json_path, "remoteLabel",
|
json_object_int_add(json_path, "remoteLabel",
|
||||||
label);
|
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_OCODE_HEADER "Origin codes: i - IGP, e - EGP, ? - incomplete\n\n"
|
||||||
#define BGP_SHOW_HEADER " Network Next Hop Metric LocPrf Weight Path\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,
|
/* Ancillary information to struct bgp_info,
|
||||||
* used for uncommonly used data (aggregation, MPLS, etc.)
|
* used for uncommonly used data (aggregation, MPLS, etc.)
|
||||||
* and lazily allocated to save memory.
|
* and lazily allocated to save memory.
|
||||||
|
@ -73,11 +78,9 @@ struct bgp_info_extra {
|
||||||
/* Nexthop reachability check. */
|
/* Nexthop reachability check. */
|
||||||
u_int32_t igpmetric;
|
u_int32_t igpmetric;
|
||||||
|
|
||||||
/* MPLS label - L2VNI */
|
/* MPLS label(s) - VNI(s) for EVPN-VxLAN */
|
||||||
mpls_label_t label;
|
mpls_label_t label[BGP_MAX_LABELS];
|
||||||
|
u_int32_t num_labels;
|
||||||
/* MPLS label - L3-VNI */
|
|
||||||
mpls_label_t label2;
|
|
||||||
|
|
||||||
#if ENABLE_BGP_VNC
|
#if ENABLE_BGP_VNC
|
||||||
union {
|
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 */
|
/* this is primarily for MPLS-VPN */
|
||||||
extern int bgp_update(struct peer *, struct prefix *, u_int32_t, struct attr *,
|
extern int bgp_update(struct peer *, struct prefix *, u_int32_t, struct attr *,
|
||||||
afi_t, safi_t, int, int, struct prefix_rd *,
|
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,
|
extern int bgp_withdraw(struct peer *, struct prefix *, u_int32_t,
|
||||||
struct attr *, afi_t, safi_t, int, int,
|
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 *);
|
struct bgp_route_evpn *);
|
||||||
|
|
||||||
/* for bgp_nexthop and bgp_damp */
|
/* 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);
|
vni = *((vni_t *)rule);
|
||||||
bgp_info = (struct bgp_info *)object;
|
bgp_info = (struct bgp_info *)object;
|
||||||
|
|
||||||
if (vni == label2vni(&bgp_info->extra->label))
|
if (vni == label2vni(&bgp_info->extra->label[0]))
|
||||||
return RMAP_MATCH;
|
return RMAP_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -701,7 +701,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
||||||
int addpath_overhead = 0;
|
int addpath_overhead = 0;
|
||||||
u_int32_t addpath_tx_id = 0;
|
u_int32_t addpath_tx_id = 0;
|
||||||
struct prefix_rd *prd = NULL;
|
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)
|
if (!subgrp)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -772,7 +773,7 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
||||||
* attr. */
|
* attr. */
|
||||||
total_attr_len = bgp_packet_attribute(
|
total_attr_len = bgp_packet_attribute(
|
||||||
NULL, peer, s, adv->baa->attr, &vecarr, NULL,
|
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 =
|
space_remaining =
|
||||||
STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
STREAM_CONCAT_REMAIN(s, snlri, STREAM_SIZE(s))
|
||||||
|
@ -815,11 +816,15 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
||||||
if (rn->prn)
|
if (rn->prn)
|
||||||
prd = (struct prefix_rd *)&rn->prn->p;
|
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,
|
label = bgp_adv_label(rn, binfo, peer, afi,
|
||||||
safi);
|
safi);
|
||||||
else if (binfo && binfo->extra)
|
label_pnt = &label;
|
||||||
label = binfo->extra->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))
|
if (stream_empty(snlri))
|
||||||
mpattrlen_pos = bgp_packet_mpattr_start(
|
mpattrlen_pos = bgp_packet_mpattr_start(
|
||||||
|
@ -827,8 +832,9 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
||||||
adv->baa->attr);
|
adv->baa->attr);
|
||||||
|
|
||||||
bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd,
|
bgp_packet_mpattr_prefix(snlri, afi, safi, &rn->p, prd,
|
||||||
&label, addpath_encode,
|
label_pnt, num_labels,
|
||||||
addpath_tx_id, adv->baa->attr);
|
addpath_encode, addpath_tx_id,
|
||||||
|
adv->baa->attr);
|
||||||
}
|
}
|
||||||
|
|
||||||
num_pfx++;
|
num_pfx++;
|
||||||
|
@ -857,7 +863,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
|
||||||
send_attr_printed = 1;
|
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,
|
addpath_encode, addpath_tx_id,
|
||||||
pfx_buf, sizeof(pfx_buf));
|
pfx_buf, sizeof(pfx_buf));
|
||||||
zlog_debug("u%" PRIu64 ":s%" PRIu64 " send UPDATE %s",
|
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,
|
bgp_packet_mpunreach_prefix(s, &rn->p, afi, safi, prd,
|
||||||
NULL, addpath_encode,
|
NULL, 0, addpath_encode,
|
||||||
addpath_tx_id, NULL);
|
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)) {
|
if (bgp_debug_update(NULL, &rn->p, subgrp->update_group, 0)) {
|
||||||
char pfx_buf[BGP_PRD_PATH_STRLEN];
|
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,
|
addpath_encode, addpath_tx_id,
|
||||||
pfx_buf, sizeof(pfx_buf));
|
pfx_buf, sizeof(pfx_buf));
|
||||||
zlog_debug("u%" PRIu64 ":s%" PRIu64
|
zlog_debug("u%" PRIu64 ":s%" PRIu64
|
||||||
|
@ -1132,7 +1139,7 @@ void subgroup_default_update_packet(struct update_subgroup *subgrp,
|
||||||
stream_putw(s, 0);
|
stream_putw(s, 0);
|
||||||
total_attr_len = bgp_packet_attribute(
|
total_attr_len = bgp_packet_attribute(
|
||||||
NULL, peer, s, attr, &vecarr, &p, afi, safi, from, NULL, NULL,
|
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. */
|
/* Set Total Path Attribute Length. */
|
||||||
stream_putw_at(s, pos, total_attr_len);
|
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);
|
mp_start = stream_get_endp(s);
|
||||||
mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
|
mplen_pos = bgp_packet_mpunreach_start(s, afi, safi);
|
||||||
bgp_packet_mpunreach_prefix(
|
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);
|
BGP_ADDPATH_TX_ID_FOR_DEFAULT_ORIGINATE, NULL);
|
||||||
|
|
||||||
/* Set the mp_unreach attr's length */
|
/* 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;
|
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)) {
|
&& !CHECK_FLAG(api.flags, ZEBRA_FLAG_EVPN_ROUTE)) {
|
||||||
has_valid_label = 1;
|
has_valid_label = 1;
|
||||||
label = label_pton(&mpinfo->extra->label);
|
label = label_pton(&mpinfo->extra->label[0]);
|
||||||
|
|
||||||
api_nh->label_num = 1;
|
api_nh->label_num = 1;
|
||||||
api_nh->labels[0] = label;
|
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 */
|
iattr, /* bgp_update copies this attr */
|
||||||
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
|
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
|
||||||
BGP_ROUTE_REDISTRIBUTE, NULL, /* RD not used for unicast */
|
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 */
|
0, NULL); /* EVPN not used */
|
||||||
bgp_attr_unintern(&iattr);
|
bgp_attr_unintern(&iattr);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue