bgpd: Move evpn_overlay to a pointer

Before this convertion:

```
	/* --- cacheline 3 boundary (192 bytes) --- */
	struct bgp_attr_encap_subtlv * encap_subtlvs;    /*   192     8 */
	struct bgp_attr_encap_subtlv * vnc_subtlvs;      /*   200     8 */
	struct bgp_route_evpn      evpn_overlay;         /*   208    36 */
```

After this convertion:

```
	/* --- cacheline 3 boundary (192 bytes) --- */
	struct bgp_attr_encap_subtlv * encap_subtlvs;    /*   192     8 */
	struct bgp_attr_encap_subtlv * vnc_subtlvs;      /*   200     8 */
	struct bgp_route_evpn *    evpn_overlay;         /*   208     8 */
```

Saving 28 bytes when EVPN is not used.

Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
This commit is contained in:
Donatas Abraitis 2024-08-11 13:59:13 +03:00
parent 423e8076b5
commit 4ace11d010
19 changed files with 265 additions and 145 deletions

View file

@ -198,6 +198,7 @@ static struct hash *vnc_hash = NULL;
#endif #endif
static struct hash *srv6_l3vpn_hash; static struct hash *srv6_l3vpn_hash;
static struct hash *srv6_vpn_hash; static struct hash *srv6_vpn_hash;
static struct hash *evpn_overlay_hash;
struct bgp_attr_encap_subtlv *encap_tlv_dup(struct bgp_attr_encap_subtlv *orig) struct bgp_attr_encap_subtlv *encap_tlv_dup(struct bgp_attr_encap_subtlv *orig)
{ {
@ -549,6 +550,81 @@ static bool bgp_attr_aigp_valid(uint8_t *pnt, int length)
return true; return true;
} }
static void *evpn_overlay_hash_alloc(void *p)
{
return p;
}
static void evpn_overlay_free(struct bgp_route_evpn *bre)
{
XFREE(MTYPE_BGP_EVPN_OVERLAY, bre);
}
static struct bgp_route_evpn *evpn_overlay_intern(struct bgp_route_evpn *bre)
{
struct bgp_route_evpn *find;
find = hash_get(evpn_overlay_hash, bre, evpn_overlay_hash_alloc);
if (find != bre)
evpn_overlay_free(bre);
find->refcnt++;
return find;
}
static void evpn_overlay_unintern(struct bgp_route_evpn **brep)
{
struct bgp_route_evpn *bre = *brep;
if (!*brep)
return;
if (bre->refcnt)
bre->refcnt--;
if (bre->refcnt == 0) {
hash_release(evpn_overlay_hash, bre);
evpn_overlay_free(bre);
*brep = NULL;
}
}
static uint32_t evpn_overlay_hash_key_make(const void *p)
{
const struct bgp_route_evpn *bre = p;
uint32_t key = 0;
if (IS_IPADDR_V4(&bre->gw_ip))
key = jhash_1word(bre->gw_ip.ipaddr_v4.s_addr, 0);
else
key = jhash2(bre->gw_ip.ipaddr_v6.s6_addr32,
array_size(bre->gw_ip.ipaddr_v6.s6_addr32), 0);
key = jhash_1word(bre->type, key);
key = jhash(bre->eth_s_id.val, sizeof(bre->eth_s_id.val), 0);
return key;
}
static bool evpn_overlay_hash_cmp(const void *p1, const void *p2)
{
const struct bgp_route_evpn *bre1 = p1;
const struct bgp_route_evpn *bre2 = p2;
return bgp_route_evpn_same(bre1, bre2);
}
static void evpn_overlay_init(void)
{
evpn_overlay_hash = hash_create(evpn_overlay_hash_key_make,
evpn_overlay_hash_cmp,
"BGP EVPN Overlay");
}
static void evpn_overlay_finish(void)
{
hash_clean_and_free(&evpn_overlay_hash,
(void (*)(void *))evpn_overlay_free);
}
static void *srv6_l3vpn_hash_alloc(void *p) static void *srv6_l3vpn_hash_alloc(void *p)
{ {
return p; return p;
@ -788,6 +864,8 @@ unsigned int attrhash_key_make(const void *p)
MIX(encap_hash_key_make(attr->encap_subtlvs)); MIX(encap_hash_key_make(attr->encap_subtlvs));
if (attr->srv6_l3vpn) if (attr->srv6_l3vpn)
MIX(srv6_l3vpn_hash_key_make(attr->srv6_l3vpn)); MIX(srv6_l3vpn_hash_key_make(attr->srv6_l3vpn));
if (bgp_attr_get_evpn_overlay(attr))
MIX(evpn_overlay_hash_key_make(bgp_attr_get_evpn_overlay(attr)));
if (attr->srv6_vpn) if (attr->srv6_vpn)
MIX(srv6_vpn_hash_key_make(attr->srv6_vpn)); MIX(srv6_vpn_hash_key_make(attr->srv6_vpn));
#ifdef ENABLE_BGP_VNC #ifdef ENABLE_BGP_VNC
@ -961,6 +1039,7 @@ struct attr *bgp_attr_intern(struct attr *attr)
struct ecommunity *ipv6_ecomm = NULL; struct ecommunity *ipv6_ecomm = NULL;
struct lcommunity *lcomm = NULL; struct lcommunity *lcomm = NULL;
struct community *comm = NULL; struct community *comm = NULL;
struct bgp_route_evpn *bre = NULL;
/* Intern referenced structure. */ /* Intern referenced structure. */
if (attr->aspath) { if (attr->aspath) {
@ -1027,6 +1106,16 @@ struct attr *bgp_attr_intern(struct attr *attr)
else else
attr->encap_subtlvs->refcnt++; attr->encap_subtlvs->refcnt++;
} }
bre = bgp_attr_get_evpn_overlay(attr);
if (bre) {
if (!bre->refcnt)
bgp_attr_set_evpn_overlay(attr,
evpn_overlay_intern(bre));
else
bre->refcnt++;
}
if (attr->srv6_l3vpn) { if (attr->srv6_l3vpn) {
if (!attr->srv6_l3vpn->refcnt) if (!attr->srv6_l3vpn->refcnt)
attr->srv6_l3vpn = srv6_l3vpn_intern(attr->srv6_l3vpn); attr->srv6_l3vpn = srv6_l3vpn_intern(attr->srv6_l3vpn);
@ -1216,6 +1305,7 @@ void bgp_attr_unintern_sub(struct attr *attr)
struct lcommunity *lcomm = NULL; struct lcommunity *lcomm = NULL;
struct community *comm = NULL; struct community *comm = NULL;
struct transit *transit; struct transit *transit;
struct bgp_route_evpn *bre;
/* aspath refcount shoud be decrement. */ /* aspath refcount shoud be decrement. */
aspath_unintern(&attr->aspath); aspath_unintern(&attr->aspath);
@ -1257,6 +1347,10 @@ void bgp_attr_unintern_sub(struct attr *attr)
srv6_l3vpn_unintern(&attr->srv6_l3vpn); srv6_l3vpn_unintern(&attr->srv6_l3vpn);
srv6_vpn_unintern(&attr->srv6_vpn); srv6_vpn_unintern(&attr->srv6_vpn);
bre = bgp_attr_get_evpn_overlay(attr);
evpn_overlay_unintern(&bre);
bgp_attr_set_evpn_overlay(attr, NULL);
} }
/* Free bgp attribute and aspath. */ /* Free bgp attribute and aspath. */
@ -1289,6 +1383,7 @@ void bgp_attr_flush(struct attr *attr)
struct cluster_list *cluster; struct cluster_list *cluster;
struct lcommunity *lcomm; struct lcommunity *lcomm;
struct community *comm; struct community *comm;
struct bgp_route_evpn *bre;
if (attr->aspath && !attr->aspath->refcnt) { if (attr->aspath && !attr->aspath->refcnt) {
aspath_free(attr->aspath); aspath_free(attr->aspath);
@ -1347,6 +1442,11 @@ void bgp_attr_flush(struct attr *attr)
bgp_attr_set_vnc_subtlvs(attr, NULL); bgp_attr_set_vnc_subtlvs(attr, NULL);
} }
#endif #endif
bre = bgp_attr_get_evpn_overlay(attr);
if (bre && !bre->refcnt) {
evpn_overlay_free(bre);
bgp_attr_set_evpn_overlay(attr, NULL);
}
} }
/* Implement draft-scudder-idr-optional-transitive behaviour and /* Implement draft-scudder-idr-optional-transitive behaviour and
@ -5006,6 +5106,7 @@ void bgp_attr_init(void)
transit_init(); transit_init();
encap_init(); encap_init();
srv6_init(); srv6_init();
evpn_overlay_init();
} }
void bgp_attr_finish(void) void bgp_attr_finish(void)
@ -5019,6 +5120,7 @@ void bgp_attr_finish(void)
transit_finish(); transit_finish();
encap_finish(); encap_finish();
srv6_finish(); srv6_finish();
evpn_overlay_finish();
} }
/* Make attribute packet. */ /* Make attribute packet. */

View file

@ -278,7 +278,7 @@ struct attr {
struct bgp_attr_encap_subtlv *vnc_subtlvs; /* VNC-specific */ struct bgp_attr_encap_subtlv *vnc_subtlvs; /* VNC-specific */
#endif #endif
/* EVPN */ /* EVPN */
struct bgp_route_evpn evpn_overlay; struct bgp_route_evpn *evpn_overlay;
/* EVPN MAC Mobility sequence number, if any. */ /* EVPN MAC Mobility sequence number, if any. */
uint32_t mm_seqnum; uint32_t mm_seqnum;
@ -614,16 +614,16 @@ static inline void bgp_attr_set_cluster(struct attr *attr,
UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST)); UNSET_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_CLUSTER_LIST));
} }
static inline const struct bgp_route_evpn * static inline struct bgp_route_evpn *
bgp_attr_get_evpn_overlay(const struct attr *attr) bgp_attr_get_evpn_overlay(const struct attr *attr)
{ {
return &attr->evpn_overlay; return attr->evpn_overlay;
} }
static inline void bgp_attr_set_evpn_overlay(struct attr *attr, static inline void bgp_attr_set_evpn_overlay(struct attr *attr,
struct bgp_route_evpn *eo) struct bgp_route_evpn *bre)
{ {
memcpy(&attr->evpn_overlay, eo, sizeof(struct bgp_route_evpn)); attr->evpn_overlay = bre;
} }
static inline struct bgp_attr_encap_subtlv * static inline struct bgp_attr_encap_subtlv *

View file

@ -24,6 +24,13 @@
bool bgp_route_evpn_same(const struct bgp_route_evpn *e1, bool bgp_route_evpn_same(const struct bgp_route_evpn *e1,
const struct bgp_route_evpn *e2) const struct bgp_route_evpn *e2)
{ {
if (!e1 && e2)
return false;
if (!e2 && e1)
return false;
if (!e1 && !e2)
return true;
return (e1->type == e2->type && return (e1->type == e2->type &&
!memcmp(&(e1->eth_s_id), &(e2->eth_s_id), sizeof(esi_t)) && !memcmp(&(e1->eth_s_id), &(e2->eth_s_id), sizeof(esi_t)) &&
!ipaddr_cmp(&(e1->gw_ip), &(e2->gw_ip))); !ipaddr_cmp(&(e1->gw_ip), &(e2->gw_ip)));

View file

@ -23,6 +23,7 @@ enum overlay_index_type {
* MAC overlay index is stored in the RMAC attribute. * MAC overlay index is stored in the RMAC attribute.
*/ */
struct bgp_route_evpn { struct bgp_route_evpn {
unsigned long refcnt;
enum overlay_index_type type; enum overlay_index_type type;
esi_t eth_s_id; esi_t eth_s_id;
struct ipaddr gw_ip; struct ipaddr gw_ip;

View file

@ -1741,20 +1741,30 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp,
BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP)) { BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP)) {
if (src_attr && if (src_attr &&
!IN6_IS_ADDR_UNSPECIFIED(&src_attr->mp_nexthop_global)) { !IN6_IS_ADDR_UNSPECIFIED(&src_attr->mp_nexthop_global)) {
attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP; struct bgp_route_evpn *bre =
SET_IPADDR_V6(&attr.evpn_overlay.gw_ip); XCALLOC(MTYPE_BGP_EVPN_OVERLAY,
memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6, sizeof(struct bgp_route_evpn));
bre->type = OVERLAY_INDEX_GATEWAY_IP;
SET_IPADDR_V6(&bre->gw_ip);
memcpy(&bre->gw_ip.ipaddr_v6,
&src_attr->mp_nexthop_global, &src_attr->mp_nexthop_global,
sizeof(struct in6_addr)); sizeof(struct in6_addr));
bgp_attr_set_evpn_overlay(&attr, bre);
} }
} else if (src_afi == AFI_IP && } else if (src_afi == AFI_IP &&
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN], CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP)) { BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP)) {
if (src_attr && src_attr->nexthop.s_addr != 0) { if (src_attr && src_attr->nexthop.s_addr != 0) {
attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP; struct bgp_route_evpn *bre =
SET_IPADDR_V4(&attr.evpn_overlay.gw_ip); XCALLOC(MTYPE_BGP_EVPN_OVERLAY,
memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4, sizeof(struct bgp_route_evpn));
&src_attr->nexthop, sizeof(struct in_addr));
bre->type = OVERLAY_INDEX_GATEWAY_IP;
SET_IPADDR_V4(&bre->gw_ip);
memcpy(&bre->gw_ip.ipaddr_v4, &src_attr->nexthop,
sizeof(struct in_addr));
bgp_attr_set_evpn_overlay(&attr, bre);
} }
} }
@ -3031,6 +3041,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
bool use_l3nhg = false; bool use_l3nhg = false;
bool is_l3nhg_active = false; bool is_l3nhg_active = false;
char buf1[INET6_ADDRSTRLEN]; char buf1[INET6_ADDRSTRLEN];
struct bgp_route_evpn *bre;
memset(pp, 0, sizeof(struct prefix)); memset(pp, 0, sizeof(struct prefix));
ip_prefix_from_evpn_prefix(evp, pp); ip_prefix_from_evpn_prefix(evp, pp);
@ -3064,35 +3075,33 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
* make sure to set the flag for next hop attribute. * make sure to set the flag for next hop attribute.
*/ */
attr = *parent_pi->attr; attr = *parent_pi->attr;
if (attr.evpn_overlay.type != OVERLAY_INDEX_GATEWAY_IP) { bre = bgp_attr_get_evpn_overlay(&attr);
if (afi == AFI_IP6) if (bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) {
evpn_convert_nexthop_to_ipv6(&attr);
else {
attr.nexthop = attr.mp_nexthop_global_in;
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
}
} else {
/* /*
* If gateway IP overlay index is specified in the NLRI of * If gateway IP overlay index is specified in the NLRI of
* EVPN RT-5, this gateway IP should be used as the nexthop * EVPN RT-5, this gateway IP should be used as the nexthop
* for the prefix in the VRF * for the prefix in the VRF
*/ */
if (bgp_debug_zebra(NULL)) { if (bgp_debug_zebra(NULL)) {
zlog_debug( zlog_debug("Install gateway IP %s as nexthop for prefix %pFX in vrf %s",
"Install gateway IP %s as nexthop for prefix %pFX in vrf %s", inet_ntop(pp->family, &bre->gw_ip, buf1,
inet_ntop(pp->family, &attr.evpn_overlay.gw_ip, sizeof(buf1)),
buf1, sizeof(buf1)), pp, pp, vrf_id_to_name(bgp_vrf->vrf_id));
vrf_id_to_name(bgp_vrf->vrf_id));
} }
if (afi == AFI_IP6) { if (afi == AFI_IP6) {
memcpy(&attr.mp_nexthop_global, memcpy(&attr.mp_nexthop_global, &bre->gw_ip.ipaddr_v6,
&attr.evpn_overlay.gw_ip.ipaddr_v6,
sizeof(struct in6_addr)); sizeof(struct in6_addr));
attr.mp_nexthop_len = IPV6_MAX_BYTELEN; attr.mp_nexthop_len = IPV6_MAX_BYTELEN;
} else { } else {
attr.nexthop = attr.evpn_overlay.gw_ip.ipaddr_v4; attr.nexthop = bre->gw_ip.ipaddr_v4;
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
}
} else {
if (afi == AFI_IP6)
evpn_convert_nexthop_to_ipv6(&attr);
else {
attr.nexthop = attr.mp_nexthop_global_in;
attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP); attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
} }
} }
@ -3144,22 +3153,20 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
} }
/* Gateway IP nexthop should be resolved */ /* Gateway IP nexthop should be resolved */
if (attr.evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) { if (bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) {
if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi, if (bgp_find_or_add_nexthop(bgp_vrf, bgp_vrf, afi, safi, pi,
NULL, 0, NULL)) NULL, 0, NULL))
bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID); bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
else { else {
if (BGP_DEBUG(nht, NHT)) { if (BGP_DEBUG(nht, NHT)) {
inet_ntop(pp->family, inet_ntop(pp->family, &bre->gw_ip, buf1,
&attr.evpn_overlay.gw_ip, sizeof(buf1));
buf1, sizeof(buf1));
zlog_debug("%s: gateway IP NH unresolved", zlog_debug("%s: gateway IP NH unresolved",
buf1); buf1);
} }
bgp_path_info_unset_flag(dest, pi, BGP_PATH_VALID); bgp_path_info_unset_flag(dest, pi, BGP_PATH_VALID);
} }
} else { } else {
/* as it is an importation, change nexthop */ /* as it is an importation, change nexthop */
bgp_path_info_set_flag(dest, pi, BGP_PATH_ANNC_NH_SELF); bgp_path_info_set_flag(dest, pi, BGP_PATH_ANNC_NH_SELF);
} }
@ -4690,7 +4697,6 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
{ {
struct prefix_rd prd; struct prefix_rd prd;
struct prefix_evpn p = {}; struct prefix_evpn p = {};
struct bgp_route_evpn evpn = {};
uint8_t ipaddr_len; uint8_t ipaddr_len;
uint8_t macaddr_len; uint8_t macaddr_len;
/* holds the VNI(s) as in packet */ /* holds the VNI(s) as in packet */
@ -4792,11 +4798,11 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
if (attr) if (attr)
bgp_update(peer, (struct prefix *)&p, addpath_id, attr, afi, bgp_update(peer, (struct prefix *)&p, addpath_id, attr, afi,
safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd,
&label[0], num_labels, 0, &evpn); &label[0], num_labels, 0, NULL);
else else
bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi, bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label[0], ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label[0],
num_labels, &evpn); num_labels);
goto done; goto done;
fail: fail:
@ -4886,8 +4892,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
0, 0, NULL); 0, 0, NULL);
else else
bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi, bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0);
NULL);
return 0; return 0;
} }
@ -4900,7 +4905,8 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
{ {
struct prefix_rd prd; struct prefix_rd prd;
struct prefix_evpn p; struct prefix_evpn p;
struct bgp_route_evpn evpn; struct bgp_route_evpn *evpn = XCALLOC(MTYPE_BGP_EVPN_OVERLAY,
sizeof(struct bgp_route_evpn));
uint8_t ippfx_len; uint8_t ippfx_len;
uint32_t eth_tag; uint32_t eth_tag;
mpls_label_t label; /* holds the VNI as in the packet */ mpls_label_t label; /* holds the VNI as in the packet */
@ -4930,12 +4936,9 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
p.prefixlen = EVPN_ROUTE_PREFIXLEN; p.prefixlen = EVPN_ROUTE_PREFIXLEN;
p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE; p.prefix.route_type = BGP_EVPN_IP_PREFIX_ROUTE;
/* Additional information outside of prefix - ESI and GW IP */
memset(&evpn, 0, sizeof(evpn));
/* Fetch ESI overlay index */ /* Fetch ESI overlay index */
if (attr) if (attr)
memcpy(&evpn.eth_s_id, pfx, sizeof(esi_t)); memcpy(&evpn->eth_s_id, pfx, sizeof(esi_t));
pfx += ESI_BYTES; pfx += ESI_BYTES;
/* Fetch Ethernet Tag. */ /* Fetch Ethernet Tag. */
@ -4962,16 +4965,16 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
SET_IPADDR_V4(&p.prefix.prefix_addr.ip); SET_IPADDR_V4(&p.prefix.prefix_addr.ip);
memcpy(&p.prefix.prefix_addr.ip.ipaddr_v4, pfx, 4); memcpy(&p.prefix.prefix_addr.ip.ipaddr_v4, pfx, 4);
pfx += 4; pfx += 4;
SET_IPADDR_V4(&evpn.gw_ip); SET_IPADDR_V4(&evpn->gw_ip);
memcpy(&evpn.gw_ip.ipaddr_v4, pfx, 4); memcpy(&evpn->gw_ip.ipaddr_v4, pfx, 4);
pfx += 4; pfx += 4;
} else { } else {
SET_IPADDR_V6(&p.prefix.prefix_addr.ip); SET_IPADDR_V6(&p.prefix.prefix_addr.ip);
memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx, memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx,
IPV6_MAX_BYTELEN); IPV6_MAX_BYTELEN);
pfx += IPV6_MAX_BYTELEN; pfx += IPV6_MAX_BYTELEN;
SET_IPADDR_V6(&evpn.gw_ip); SET_IPADDR_V6(&evpn->gw_ip);
memcpy(&evpn.gw_ip.ipaddr_v6, pfx, IPV6_MAX_BYTELEN); memcpy(&evpn->gw_ip.ipaddr_v6, pfx, IPV6_MAX_BYTELEN);
pfx += IPV6_MAX_BYTELEN; pfx += IPV6_MAX_BYTELEN;
} }
@ -4989,20 +4992,20 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
* An update containing a non-zero gateway IP and a non-zero ESI * An update containing a non-zero gateway IP and a non-zero ESI
* at the same time is should be treated as withdraw * at the same time is should be treated as withdraw
*/ */
if (bgp_evpn_is_esi_valid(&evpn.eth_s_id) && if (bgp_evpn_is_esi_valid(&evpn->eth_s_id) &&
!ipaddr_is_zero(&evpn.gw_ip)) { !ipaddr_is_zero(&evpn->gw_ip)) {
flog_err(EC_BGP_EVPN_ROUTE_INVALID, flog_err(EC_BGP_EVPN_ROUTE_INVALID,
"%s - Rx EVPN Type-5 ESI and gateway-IP both non-zero.", "%s - Rx EVPN Type-5 ESI and gateway-IP both non-zero.",
peer->host); peer->host);
is_valid_update = false; is_valid_update = false;
} else if (bgp_evpn_is_esi_valid(&evpn.eth_s_id)) } else if (bgp_evpn_is_esi_valid(&evpn->eth_s_id))
evpn.type = OVERLAY_INDEX_ESI; evpn->type = OVERLAY_INDEX_ESI;
else if (!ipaddr_is_zero(&evpn.gw_ip)) else if (!ipaddr_is_zero(&evpn->gw_ip))
evpn.type = OVERLAY_INDEX_GATEWAY_IP; evpn->type = OVERLAY_INDEX_GATEWAY_IP;
if (attr) { if (attr) {
if (is_zero_mac(&attr->rmac) && if (is_zero_mac(&attr->rmac) &&
!bgp_evpn_is_esi_valid(&evpn.eth_s_id) && !bgp_evpn_is_esi_valid(&evpn->eth_s_id) &&
ipaddr_is_zero(&evpn.gw_ip) && label == 0) { ipaddr_is_zero(&evpn->gw_ip) && label == 0) {
flog_err(EC_BGP_EVPN_ROUTE_INVALID, flog_err(EC_BGP_EVPN_ROUTE_INVALID,
"%s - Rx EVPN Type-5 ESI, gateway-IP, RMAC and label all zero", "%s - Rx EVPN Type-5 ESI, gateway-IP, RMAC and label all zero",
peer->host); peer->host);
@ -5017,7 +5020,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
if (attr && is_valid_update) if (attr && is_valid_update)
bgp_update(peer, (struct prefix *)&p, addpath_id, attr, afi, bgp_update(peer, (struct prefix *)&p, addpath_id, attr, afi,
safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd,
&label, 1, 0, &evpn); &label, 1, 0, evpn);
else { else {
if (!is_valid_update) { if (!is_valid_update) {
char attr_str[BUFSIZ] = {0}; char attr_str[BUFSIZ] = {0};
@ -5029,8 +5032,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
attr_str); attr_str);
} }
bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi, bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, 1, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, 1);
&evpn);
} }
return 0; return 0;
@ -5044,12 +5046,16 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p,
int len; int len;
char temp[16]; char temp[16];
const struct evpn_addr *p_evpn_p; const struct evpn_addr *p_evpn_p;
struct bgp_route_evpn *bre = NULL;
memset(&temp, 0, sizeof(temp)); memset(&temp, 0, sizeof(temp));
if (p->family != AF_EVPN) if (p->family != AF_EVPN)
return; return;
p_evpn_p = &(p->u.prefix_evpn); p_evpn_p = &(p->u.prefix_evpn);
if (attr)
bre = bgp_attr_get_evpn_overlay(attr);
/* len denites the total len of IP and GW-IP in the route /* len denites the total len of IP and GW-IP in the route
IP and GW-IP have to be both ipv4 or ipv6 IP and GW-IP have to be both ipv4 or ipv6
*/ */
@ -5060,7 +5066,7 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p,
/* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */ /* Prefix contains RD, ESI, EthTag, IP length, IP, GWIP and VNI */
stream_putc(s, 8 + 10 + 4 + 1 + len + 3); stream_putc(s, 8 + 10 + 4 + 1 + len + 3);
stream_put(s, prd->val, 8); stream_put(s, prd->val, 8);
if (attr && attr->evpn_overlay.type == OVERLAY_INDEX_ESI) if (attr && bre && bre->type == OVERLAY_INDEX_ESI)
stream_put(s, &attr->esi, sizeof(esi_t)); stream_put(s, &attr->esi, sizeof(esi_t));
else else
stream_put(s, 0, sizeof(esi_t)); stream_put(s, 0, sizeof(esi_t));
@ -5070,15 +5076,11 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p,
stream_put_ipv4(s, p_evpn_p->prefix_addr.ip.ipaddr_v4.s_addr); stream_put_ipv4(s, p_evpn_p->prefix_addr.ip.ipaddr_v4.s_addr);
else else
stream_put(s, &p_evpn_p->prefix_addr.ip.ipaddr_v6, 16); stream_put(s, &p_evpn_p->prefix_addr.ip.ipaddr_v6, 16);
if (attr && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) { if (attr && bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) {
const struct bgp_route_evpn *evpn_overlay =
bgp_attr_get_evpn_overlay(attr);
if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip)) if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip))
stream_put_ipv4(s, stream_put_ipv4(s, bre->gw_ip.ipaddr_v4.s_addr);
evpn_overlay->gw_ip.ipaddr_v4.s_addr);
else else
stream_put(s, &(evpn_overlay->gw_ip.ipaddr_v6), 16); stream_put(s, &(bre->gw_ip.ipaddr_v6), 16);
} else { } else {
if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip)) if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip))
stream_put_ipv4(s, 0); stream_put_ipv4(s, 0);

View file

@ -770,8 +770,7 @@ int bgp_evpn_type4_route_process(struct peer *peer, afi_t afi, safi_t safi,
0, 0, NULL); 0, 0, NULL);
} else { } else {
bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi, bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0);
NULL);
} }
return 0; return 0;
} }
@ -1239,8 +1238,7 @@ int bgp_evpn_type1_route_process(struct peer *peer, afi_t afi, safi_t safi,
0, 0, NULL); 0, 0, NULL);
} else { } else {
bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi, bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0);
NULL);
} }
return 0; return 0;
} }

View file

@ -195,7 +195,7 @@ int bgp_nlri_parse_flowspec(struct peer *peer, struct attr *attr,
NULL, 0, 0, NULL); NULL, 0, 0, NULL);
} else { } else {
bgp_withdraw(peer, &p, 0, afi, safi, ZEBRA_ROUTE_BGP, bgp_withdraw(peer, &p, 0, afi, safi, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, NULL, NULL, 0, NULL); BGP_ROUTE_NORMAL, NULL, NULL, 0);
} }
XFREE(MTYPE_TMP, temp); XFREE(MTYPE_TMP, temp);

View file

@ -576,7 +576,7 @@ int bgp_nlri_parse_label(struct peer *peer, struct attr *attr,
} else { } else {
bgp_withdraw(peer, &p, addpath_id, packet->afi, bgp_withdraw(peer, &p, addpath_id, packet->afi,
SAFI_UNICAST, ZEBRA_ROUTE_BGP, SAFI_UNICAST, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, NULL, &label, 1, NULL); BGP_ROUTE_NORMAL, NULL, &label, 1);
} }
} }

View file

@ -143,7 +143,6 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
const struct prefix *p = bgp_dest_get_prefix(dest); const struct prefix *p = bgp_dest_get_prefix(dest);
struct prefix_evpn *pevpn = (struct prefix_evpn *)dest; struct prefix_evpn *pevpn = (struct prefix_evpn *)dest;
struct prefix_rd prd; struct prefix_rd prd;
struct bgp_route_evpn *evpn;
if (pevpn->family == AF_EVPN if (pevpn->family == AF_EVPN
&& pevpn->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE && pevpn->prefix.route_type == BGP_EVPN_MAC_IP_ROUTE
@ -195,12 +194,10 @@ static void bgp_process_mac_rescan_table(struct bgp *bgp, struct peer *peer,
continue; continue;
} }
memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr),
sizeof(evpn));
bgp_update(peer, p, pi->addpath_rx_id, pi->attr, bgp_update(peer, p, pi->addpath_rx_id, pi->attr,
AFI_L2VPN, SAFI_EVPN, ZEBRA_ROUTE_BGP, AFI_L2VPN, SAFI_EVPN, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, &prd, label_pnt, BGP_ROUTE_NORMAL, &prd, label_pnt, num_labels,
num_labels, 1, evpn); 1, bgp_attr_get_evpn_overlay(pi->attr));
} }
} }
} }

View file

@ -135,3 +135,5 @@ DEFINE_MTYPE(BGPD, EVPN_REMOTE_IP, "BGP EVPN Remote IP hash entry");
DEFINE_MTYPE(BGPD, BGP_NOTIFICATION, "BGP Notification Message"); DEFINE_MTYPE(BGPD, BGP_NOTIFICATION, "BGP Notification Message");
DEFINE_MTYPE(BGPD, BGP_SOFT_VERSION, "Software Version"); DEFINE_MTYPE(BGPD, BGP_SOFT_VERSION, "Software Version");
DEFINE_MTYPE(BGPD, BGP_EVPN_OVERLAY, "BGP EVPN Overlay");

View file

@ -134,4 +134,6 @@ DECLARE_MTYPE(BGP_NOTIFICATION);
DECLARE_MTYPE(BGP_SOFT_VERSION); DECLARE_MTYPE(BGP_SOFT_VERSION);
DECLARE_MTYPE(BGP_EVPN_OVERLAY);
#endif /* _QUAGGA_BGP_MEMORY_H */ #endif /* _QUAGGA_BGP_MEMORY_H */

View file

@ -245,7 +245,7 @@ int bgp_nlri_parse_vpn(struct peer *peer, struct attr *attr,
} else { } else {
bgp_withdraw(peer, &p, addpath_id, packet->afi, bgp_withdraw(peer, &p, addpath_id, packet->afi,
SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP, SAFI_MPLS_VPN, ZEBRA_ROUTE_BGP,
BGP_ROUTE_NORMAL, &prd, &label, 1, NULL); BGP_ROUTE_NORMAL, &prd, &label, 1);
} }
} }
/* Packet length consistency check. */ /* Packet length consistency check. */

View file

@ -1300,11 +1300,13 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
bool bnc_is_valid_nexthop = false; bool bnc_is_valid_nexthop = false;
bool path_valid = false; bool path_valid = false;
struct bgp_route_evpn *bre =
bgp_attr_get_evpn_overlay(path->attr);
if (safi == SAFI_UNICAST && if (safi == SAFI_UNICAST &&
path->sub_type == BGP_ROUTE_IMPORTED && path->sub_type == BGP_ROUTE_IMPORTED &&
bgp_path_info_num_labels(path) && bgp_path_info_num_labels(path) &&
(path->attr->evpn_overlay.type != OVERLAY_INDEX_GATEWAY_IP)) { !(bre && bre->type == OVERLAY_INDEX_GATEWAY_IP)) {
bnc_is_valid_nexthop = bnc_is_valid_nexthop =
bgp_isvalid_nexthop_for_l3vpn(bnc, path) bgp_isvalid_nexthop_for_l3vpn(bnc, path)
? true ? true

View file

@ -4608,10 +4608,8 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
* will not be interned. In which case, it is ok to update the * will not be interned. In which case, it is ok to update the
* attr->evpn_overlay, so that, this can be stored in adj_in. * attr->evpn_overlay, so that, this can be stored in adj_in.
*/ */
if ((afi == AFI_L2VPN) && evpn) { if ((afi == AFI_L2VPN) && evpn)
memcpy(&attr->evpn_overlay, evpn, bgp_attr_set_evpn_overlay(attr, evpn);
sizeof(struct bgp_route_evpn));
}
bgp_adj_in_set(dest, peer, attr, addpath_id, &bgp_labels); bgp_adj_in_set(dest, peer, attr, addpath_id, &bgp_labels);
} }
@ -4773,8 +4771,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
* evpn to new_atr.evpn_overlay before it is interned. * evpn to new_atr.evpn_overlay before it is interned.
*/ */
if (soft_reconfig && (afi == AFI_L2VPN) && evpn) if (soft_reconfig && (afi == AFI_L2VPN) && evpn)
memcpy(&new_attr.evpn_overlay, evpn, bgp_attr_set_evpn_overlay(&new_attr, evpn);
sizeof(struct bgp_route_evpn));
/* Apply incoming route-map. /* Apply incoming route-map.
* NB: new_attr may now contain newly allocated values from route-map * NB: new_attr may now contain newly allocated values from route-map
@ -5450,7 +5447,7 @@ filtered:
void bgp_withdraw(struct peer *peer, const struct prefix *p, void bgp_withdraw(struct peer *peer, const struct prefix *p,
uint32_t addpath_id, afi_t afi, safi_t safi, int type, uint32_t addpath_id, 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,
uint8_t num_labels, struct bgp_route_evpn *evpn) uint8_t num_labels)
{ {
struct bgp *bgp; struct bgp *bgp;
char pfx_buf[BGP_PRD_PATH_STRLEN]; char pfx_buf[BGP_PRD_PATH_STRLEN];
@ -5679,7 +5676,7 @@ static void bgp_soft_reconfig_table_update(struct peer *peer,
struct bgp_path_info *pi; struct bgp_path_info *pi;
uint8_t num_labels; uint8_t num_labels;
mpls_label_t *label_pnt; mpls_label_t *label_pnt;
struct bgp_route_evpn evpn; struct bgp_route_evpn *bre = NULL;
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next) for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
if (pi->peer == peer) if (pi->peer == peer)
@ -5687,15 +5684,13 @@ static void bgp_soft_reconfig_table_update(struct peer *peer,
num_labels = ain->labels ? ain->labels->num_labels : 0; num_labels = ain->labels ? ain->labels->num_labels : 0;
label_pnt = num_labels ? &ain->labels->label[0] : NULL; label_pnt = num_labels ? &ain->labels->label[0] : NULL;
if (pi) if (pi)
memcpy(&evpn, bgp_attr_get_evpn_overlay(pi->attr), bre = bgp_attr_get_evpn_overlay(pi->attr);
sizeof(evpn));
else
memset(&evpn, 0, sizeof(evpn));
bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id, bgp_update(peer, bgp_dest_get_prefix(dest), ain->addpath_rx_id,
ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd, ain->attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, prd,
label_pnt, num_labels, 1, &evpn); label_pnt, num_labels, 1, bre);
} }
static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi, static void bgp_soft_reconfig_table(struct peer *peer, afi_t afi, safi_t safi,
@ -6614,7 +6609,7 @@ int bgp_nlri_parse_ip(struct peer *peer, struct attr *attr,
else else
bgp_withdraw(peer, &p, addpath_id, afi, safi, bgp_withdraw(peer, &p, addpath_id, afi, safi,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, NULL,
NULL, 0, NULL); NULL, 0);
/* Do not send BGP notification twice when maximum-prefix count /* Do not send BGP notification twice when maximum-prefix count
* overflow. */ * overflow. */
@ -6745,15 +6740,25 @@ void bgp_static_update(struct bgp *bgp, const struct prefix *p,
if (afi == AFI_L2VPN) { if (afi == AFI_L2VPN) {
if (bgp_static->gatewayIp.family == AF_INET) { if (bgp_static->gatewayIp.family == AF_INET) {
SET_IPADDR_V4(&attr.evpn_overlay.gw_ip); struct bgp_route_evpn *bre =
memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4, XCALLOC(MTYPE_BGP_EVPN_OVERLAY,
sizeof(struct bgp_route_evpn));
SET_IPADDR_V4(&bre->gw_ip);
memcpy(&bre->gw_ip.ipaddr_v4,
&bgp_static->gatewayIp.u.prefix4, &bgp_static->gatewayIp.u.prefix4,
IPV4_MAX_BYTELEN); IPV4_MAX_BYTELEN);
bgp_attr_set_evpn_overlay(&attr, bre);
} else if (bgp_static->gatewayIp.family == AF_INET6) { } else if (bgp_static->gatewayIp.family == AF_INET6) {
SET_IPADDR_V6(&attr.evpn_overlay.gw_ip); struct bgp_route_evpn *bre =
memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6, XCALLOC(MTYPE_BGP_EVPN_OVERLAY,
sizeof(struct bgp_route_evpn));
SET_IPADDR_V6(&bre->gw_ip);
memcpy(&bre->gw_ip.ipaddr_v6,
&bgp_static->gatewayIp.u.prefix6, &bgp_static->gatewayIp.u.prefix6,
IPV6_MAX_BYTELEN); IPV6_MAX_BYTELEN);
bgp_attr_set_evpn_overlay(&attr, bre);
} }
memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t)); memcpy(&attr.esi, bgp_static->eth_s_id, sizeof(esi_t));
if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) { if (bgp_static->encap_tunneltype == BGP_ENCAP_TYPE_VXLAN) {
@ -10114,6 +10119,7 @@ void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
json_object *json_path = NULL; json_object *json_path = NULL;
json_object *json_nexthop = NULL; json_object *json_nexthop = NULL;
json_object *json_overlay = NULL; json_object *json_overlay = NULL;
struct bgp_route_evpn *bre = NULL;
if (!path->extra) if (!path->extra)
return; return;
@ -10179,12 +10185,14 @@ void route_vty_out_overlay(struct vty *vty, const struct prefix *p,
} }
} }
const struct bgp_route_evpn *eo = bgp_attr_get_evpn_overlay(attr); bre = bgp_attr_get_evpn_overlay(attr);
if (bre) {
if (!json_path) if (!json_path)
vty_out(vty, "/%pIA", &eo->gw_ip); vty_out(vty, "/%pIA", &bre->gw_ip);
else else
json_object_string_addf(json_overlay, "gw", "%pIA", &eo->gw_ip); json_object_string_addf(json_overlay, "gw", "%pIA",
&bre->gw_ip);
}
if (bgp_attr_get_ecommunity(attr)) { if (bgp_attr_get_ecommunity(attr)) {
char *mac = NULL; char *mac = NULL;
@ -10519,6 +10527,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
mpls_label_t label = MPLS_INVALID_LABEL; mpls_label_t label = MPLS_INVALID_LABEL;
struct bgp_path_info *bpi_ultimate = struct bgp_path_info *bpi_ultimate =
bgp_get_imported_bpi_ultimate(path); bgp_get_imported_bpi_ultimate(path);
struct bgp_route_evpn *bre = bgp_attr_get_evpn_overlay(attr);
if (json_paths) { if (json_paths) {
json_path = json_object_new_object(); json_path = json_object_new_object();
@ -10545,12 +10554,10 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
} }
} }
if (safi == SAFI_EVPN if (safi == SAFI_EVPN && bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) {
&& attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
char gwip_buf[INET6_ADDRSTRLEN]; char gwip_buf[INET6_ADDRSTRLEN];
ipaddr2str(&attr->evpn_overlay.gw_ip, gwip_buf, ipaddr2str(&bre->gw_ip, gwip_buf, sizeof(gwip_buf));
sizeof(gwip_buf));
if (json_paths) if (json_paths)
json_object_string_add(json_path, "gatewayIP", json_object_string_add(json_path, "gatewayIP",

View file

@ -798,8 +798,7 @@ extern void bgp_update(struct peer *peer, const struct prefix *p,
extern void bgp_withdraw(struct peer *peer, const struct prefix *p, extern void bgp_withdraw(struct peer *peer, const struct prefix *p,
uint32_t addpath_id, afi_t afi, safi_t safi, int type, uint32_t addpath_id, afi_t afi, safi_t safi, int type,
int sub_type, struct prefix_rd *prd, int sub_type, struct prefix_rd *prd,
mpls_label_t *label, uint8_t num_labels, mpls_label_t *label, uint8_t num_labels);
struct bgp_route_evpn *evpn);
/* for bgp_nexthop and bgp_damp */ /* for bgp_nexthop and bgp_damp */
extern void bgp_process(struct bgp *bgp, struct bgp_dest *dest, extern void bgp_process(struct bgp *bgp, struct bgp_dest *dest,

View file

@ -1236,6 +1236,8 @@ route_set_evpn_gateway_ip(void *rule, const struct prefix *prefix, void *object)
struct ipaddr *gw_ip = rule; struct ipaddr *gw_ip = rule;
struct bgp_path_info *path; struct bgp_path_info *path;
struct prefix_evpn *evp; struct prefix_evpn *evp;
struct bgp_route_evpn *bre = XCALLOC(MTYPE_BGP_EVPN_OVERLAY,
sizeof(struct bgp_route_evpn));
if (prefix->family != AF_EVPN) if (prefix->family != AF_EVPN)
return RMAP_OKAY; return RMAP_OKAY;
@ -1251,9 +1253,9 @@ route_set_evpn_gateway_ip(void *rule, const struct prefix *prefix, void *object)
path = object; path = object;
/* Set gateway-ip value. */ /* Set gateway-ip value. */
path->attr->evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP; bre->type = OVERLAY_INDEX_GATEWAY_IP;
memcpy(&path->attr->evpn_overlay.gw_ip, &gw_ip->ip.addr, memcpy(&bre->gw_ip, &gw_ip->ip.addr, IPADDRSZ(gw_ip));
IPADDRSZ(gw_ip)); bgp_attr_set_evpn_overlay(path->attr, bre);
return RMAP_OKAY; return RMAP_OKAY;
} }

View file

@ -863,7 +863,8 @@ struct bpacket *subgroup_update_packet(struct update_subgroup *subgrp)
bgp_debug_rdpfxpath2str(afi, safi, prd, dest_p, bgp_debug_rdpfxpath2str(afi, safi, prd, dest_p,
label_pnt, num_labels, label_pnt, num_labels,
addpath_capable, addpath_tx_id, addpath_capable, addpath_tx_id,
&adv->baa->attr->evpn_overlay, bgp_attr_get_evpn_overlay(
adv->baa->attr),
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",
subgrp->update_group->id, subgrp->id, subgrp->update_group->id, subgrp->id,

View file

@ -1128,6 +1128,8 @@ static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
struct attr *attr, bool is_evpn, struct attr *attr, bool is_evpn,
struct zapi_nexthop *api_nh) struct zapi_nexthop *api_nh)
{ {
struct bgp_route_evpn *bre = bgp_attr_get_evpn_overlay(attr);
api_nh->gate.ipv4 = *nexthop; api_nh->gate.ipv4 = *nexthop;
api_nh->vrf_id = nh_bgp->vrf_id; api_nh->vrf_id = nh_bgp->vrf_id;
@ -1144,7 +1146,7 @@ static bool update_ipv4nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
* treat the nexthop as NEXTHOP_TYPE_IPV4 * treat the nexthop as NEXTHOP_TYPE_IPV4
* Else, mark the nexthop as onlink. * Else, mark the nexthop as onlink.
*/ */
if (attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) if (bre && bre->type == OVERLAY_INDEX_GATEWAY_IP)
api_nh->type = NEXTHOP_TYPE_IPV4; api_nh->type = NEXTHOP_TYPE_IPV4;
else { else {
api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX; api_nh->type = NEXTHOP_TYPE_IPV4_IFINDEX;
@ -1170,9 +1172,11 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
struct zapi_nexthop *api_nh) struct zapi_nexthop *api_nh)
{ {
struct attr *attr; struct attr *attr;
struct bgp_route_evpn *bre;
attr = pi->attr; attr = pi->attr;
api_nh->vrf_id = nh_bgp->vrf_id; api_nh->vrf_id = nh_bgp->vrf_id;
bre = bgp_attr_get_evpn_overlay(attr);
if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) { if (attr->nh_type == NEXTHOP_TYPE_BLACKHOLE) {
api_nh->type = attr->nh_type; api_nh->type = attr->nh_type;
@ -1183,7 +1187,7 @@ static bool update_ipv6nh_for_route_install(int nh_othervrf, struct bgp *nh_bgp,
* treat the nexthop as NEXTHOP_TYPE_IPV4 * treat the nexthop as NEXTHOP_TYPE_IPV4
* Else, mark the nexthop as onlink. * Else, mark the nexthop as onlink.
*/ */
if (attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) if (bre && bre->type == OVERLAY_INDEX_GATEWAY_IP)
api_nh->type = NEXTHOP_TYPE_IPV6; api_nh->type = NEXTHOP_TYPE_IPV6;
else { else {
api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX; api_nh->type = NEXTHOP_TYPE_IPV6_IFINDEX;
@ -1281,6 +1285,7 @@ static void bgp_zebra_announce_parse_nexthop(
uint32_t ttl = 0; uint32_t ttl = 0;
uint32_t bos = 0; uint32_t bos = 0;
uint32_t exp = 0; uint32_t exp = 0;
struct bgp_route_evpn *bre = NULL;
/* Determine if we're doing weighted ECMP or not */ /* Determine if we're doing weighted ECMP or not */
do_wt_ecmp = bgp_path_info_mpath_chkwtd(bgp, info); do_wt_ecmp = bgp_path_info_mpath_chkwtd(bgp, info);
@ -1395,6 +1400,7 @@ static void bgp_zebra_announce_parse_nexthop(
} }
is_evpn = !!CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN); is_evpn = !!CHECK_FLAG(api_nh->flags, ZAPI_NEXTHOP_FLAG_EVPN);
bre = bgp_attr_get_evpn_overlay(mpinfo->attr);
/* Did we get proper nexthop info to update zebra? */ /* Did we get proper nexthop info to update zebra? */
if (!nh_updated) if (!nh_updated)
@ -1430,9 +1436,7 @@ static void bgp_zebra_announce_parse_nexthop(
api_nh->labels[0] = nh_label; api_nh->labels[0] = nh_label;
} }
if (is_evpn if (is_evpn && !(bre && bre->type == OVERLAY_INDEX_GATEWAY_IP))
&& mpinfo->attr->evpn_overlay.type
!= OVERLAY_INDEX_GATEWAY_IP)
memcpy(&api_nh->rmac, &(mpinfo->attr->rmac), memcpy(&api_nh->rmac, &(mpinfo->attr->rmac),
sizeof(struct ethaddr)); sizeof(struct ethaddr));

View file

@ -388,7 +388,7 @@ void vnc_direct_bgp_del_route_ce(struct bgp *bgp, struct agg_node *rn,
bgp_withdraw(bpi->peer, p, 0, /* addpath_id */ bgp_withdraw(bpi->peer, p, 0, /* addpath_id */
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, 0, NULL); /* tag not used for unicast */ NULL, 0); /* tag not used for unicast */
} }
static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi) static void vnc_direct_bgp_vpn_enable_ce(struct bgp *bgp, afi_t afi)
@ -473,16 +473,14 @@ static void vnc_direct_bgp_vpn_disable_ce(struct bgp *bgp, afi_t afi)
if (ri->type == ZEBRA_ROUTE_VNC_DIRECT if (ri->type == ZEBRA_ROUTE_VNC_DIRECT
&& ri->sub_type == BGP_ROUTE_REDISTRIBUTE) { && ri->sub_type == BGP_ROUTE_REDISTRIBUTE) {
bgp_withdraw(ri->peer, bgp_dest_get_prefix(dest),
bgp_withdraw(
ri->peer, bgp_dest_get_prefix(dest),
0, /* addpath_id */ 0, /* addpath_id */
AFI_IP, SAFI_UNICAST, AFI_IP, SAFI_UNICAST,
ZEBRA_ROUTE_VNC_DIRECT, ZEBRA_ROUTE_VNC_DIRECT,
BGP_ROUTE_REDISTRIBUTE, BGP_ROUTE_REDISTRIBUTE,
NULL, /* RD not used for unicast */ NULL, /* RD not used for unicast */
NULL, 0, NULL,
NULL); /* tag not used for unicast */ 0); /* tag not used for unicast */
} }
} }
} }
@ -864,8 +862,7 @@ void vnc_direct_bgp_del_prefix(struct bgp *bgp,
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
BGP_ROUTE_REDISTRIBUTE, BGP_ROUTE_REDISTRIBUTE,
NULL, /* RD not used for unicast */ NULL, /* RD not used for unicast */
NULL, 0, NULL, 0); /* tag not used for unicast */
NULL); /* tag not used for unicast */
/* /*
* yuck! * yuck!
* - but consistent with rest of function * - but consistent with rest of function
@ -893,8 +890,7 @@ void vnc_direct_bgp_del_prefix(struct bgp *bgp,
afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT, afi, SAFI_UNICAST, ZEBRA_ROUTE_VNC_DIRECT,
BGP_ROUTE_REDISTRIBUTE, BGP_ROUTE_REDISTRIBUTE,
NULL, /* RD not used for unicast */ NULL, /* RD not used for unicast */
NULL, 0, NULL, 0); /* tag not used for unicast */
NULL); /* tag not used for unicast */
} }
} }
} }
@ -1131,7 +1127,7 @@ void vnc_direct_bgp_del_nve(struct bgp *bgp, struct rfapi_descriptor *rfd)
BGP_ROUTE_REDISTRIBUTE, BGP_ROUTE_REDISTRIBUTE,
NULL, /* RD not used for NULL, /* RD not used for
unicast */ unicast */
NULL, 0, NULL); /* tag not NULL, 0); /* tag not
used for used for
unicast */ unicast */
} }
@ -1359,7 +1355,7 @@ static void vnc_direct_del_rn_group_rd(struct bgp *bgp,
0, /* addpath_id */ 0, /* addpath_id */
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, 0, NULL); /* tag not used for unicast */ NULL, 0); /* tag not used for unicast */
return; return;
} }
@ -1471,7 +1467,6 @@ static void vnc_direct_bgp_unexport_table(afi_t afi, struct agg_table *rt,
for (ALL_LIST_ELEMENTS_RO(nve_list, hln, for (ALL_LIST_ELEMENTS_RO(nve_list, hln,
irfd)) { irfd)) {
bgp_withdraw(irfd->peer, bgp_withdraw(irfd->peer,
agg_node_get_prefix(rn), agg_node_get_prefix(rn),
0, /* addpath_id */ 0, /* addpath_id */
@ -1480,7 +1475,7 @@ static void vnc_direct_bgp_unexport_table(afi_t afi, struct agg_table *rt,
BGP_ROUTE_REDISTRIBUTE, BGP_ROUTE_REDISTRIBUTE,
NULL, /* RD not used for NULL, /* RD not used for
unicast */ unicast */
NULL, 0, NULL); /* tag not NULL, 0); /* tag not
used for used for
unicast, unicast,
EVPN EVPN
@ -1715,8 +1710,7 @@ static void vncExportWithdrawTimer(struct event *t)
bgp_withdraw(eti->peer, p, 0, /* addpath_id */ bgp_withdraw(eti->peer, p, 0, /* addpath_id */
family2afi(p->family), SAFI_UNICAST, eti->type, family2afi(p->family), SAFI_UNICAST, eti->type,
eti->subtype, NULL, /* RD not used for unicast */ eti->subtype, NULL, /* RD not used for unicast */
NULL, 0, NULL, 0); /* tag not used for unicast, EVPN neither */
NULL); /* tag not used for unicast, EVPN neither */
/* /*
* Free the eti * Free the eti
@ -2001,7 +1995,7 @@ void vnc_direct_bgp_rh_vpn_disable(struct bgp *bgp, afi_t afi)
ZEBRA_ROUTE_VNC_DIRECT_RH, ZEBRA_ROUTE_VNC_DIRECT_RH,
BGP_ROUTE_REDISTRIBUTE, BGP_ROUTE_REDISTRIBUTE,
NULL, /* RD not used for unicast */ NULL, /* RD not used for unicast */
NULL, 0, NULL); /* tag not used for NULL, 0); /* tag not used for
unicast, EVPN unicast, EVPN
neither */ neither */
} }