summaryrefslogtreecommitdiffstats
path: root/bgpd/bgp_evpn.c
diff options
context:
space:
mode:
Diffstat (limited to 'bgpd/bgp_evpn.c')
-rw-r--r--bgpd/bgp_evpn.c362
1 files changed, 191 insertions, 171 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c
index 7af6ff7c..0a8ce615 100644
--- a/bgpd/bgp_evpn.c
+++ b/bgpd/bgp_evpn.c
@@ -117,7 +117,7 @@ int vni_list_cmp(void *p1, void *p2)
static unsigned int vrf_import_rt_hash_key_make(const void *p)
{
const struct vrf_irt_node *irt = p;
- const char *pnt = irt->rt.val;
+ const uint8_t *pnt = irt->rt.val;
return jhash(pnt, 8, 0x5abc1234);
}
@@ -229,7 +229,7 @@ static int is_vrf_present_in_irt_vrfs(struct list *vrfs, struct bgp *bgp_vrf)
static unsigned int import_rt_hash_key_make(const void *p)
{
const struct irt_node *irt = p;
- const char *pnt = irt->rt.val;
+ const uint8_t *pnt = irt->rt.val;
return jhash(pnt, 8, 0xdeadbeef);
}
@@ -621,7 +621,7 @@ static void form_auto_rt(struct bgp *bgp, vni_t vni, struct list *rtl,
struct listnode *node;
if (bgp->advertise_autort_rfc8365)
- vni |= EVPN_AUTORT_VXLAN;
+ SET_FLAG(vni, EVPN_AUTORT_VXLAN);
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true);
ecomadd = ecommunity_new();
@@ -1159,9 +1159,8 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
}
/* Add MAC mobility (sticky) if needed. */
- if (attr->sticky) {
+ if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_STICKY)) {
seqnum = 0;
- memset(&ecom_sticky, 0, sizeof(ecom_sticky));
encode_mac_mobility_extcomm(1, seqnum, &eval_sticky);
ecom_sticky.size = 1;
ecom_sticky.unit_size = ECOMMUNITY_SIZE;
@@ -1179,8 +1178,7 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
}
/* Add default gateway, if needed. */
- if (attr->default_gw) {
- memset(&ecom_default_gw, 0, sizeof(ecom_default_gw));
+ if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW)) {
encode_default_gw_extcomm(&eval_default_gw);
ecom_default_gw.size = 1;
ecom_default_gw.unit_size = ECOMMUNITY_SIZE;
@@ -1191,9 +1189,11 @@ static void build_evpn_route_extcomm(struct bgpevpn *vpn, struct attr *attr,
}
proxy = !!(attr->es_flags & ATTR_ES_PROXY_ADVERT);
- if (attr->router_flag || proxy) {
- memset(&ecom_na, 0, sizeof(ecom_na));
- encode_na_flag_extcomm(&eval_na, attr->router_flag, proxy);
+ if (CHECK_FLAG(attr->evpn_flags, ATTR_EVPN_FLAG_ROUTER) || proxy) {
+ encode_na_flag_extcomm(&eval_na,
+ CHECK_FLAG(attr->evpn_flags,
+ ATTR_EVPN_FLAG_ROUTER),
+ proxy);
ecom_na.size = 1;
ecom_na.unit_size = ECOMMUNITY_SIZE;
ecom_na.val = (uint8_t *)eval_na.val;
@@ -1278,12 +1278,15 @@ enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn
flags = 0;
if (pi->sub_type == BGP_ROUTE_IMPORTED) {
- if (pi->attr->sticky)
+ if (CHECK_FLAG(pi->attr->evpn_flags,
+ ATTR_EVPN_FLAG_STICKY))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY);
- if (pi->attr->default_gw)
+ if (CHECK_FLAG(pi->attr->evpn_flags,
+ ATTR_EVPN_FLAG_DEFAULT_GW))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_GW);
if (is_evpn_prefix_ipaddr_v6(p) &&
- pi->attr->router_flag)
+ CHECK_FLAG(pi->attr->evpn_flags,
+ ATTR_EVPN_FLAG_ROUTER))
SET_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG);
seq = mac_mobility_seqnum(pi->attr);
@@ -1311,12 +1314,11 @@ enum zclient_send_status evpn_zebra_install(struct bgp *bgp, struct bgpevpn *vpn
* flag set install the local entry as a router entry
*/
if (is_evpn_prefix_ipaddr_v6(p) &&
- (pi->attr->es_flags &
- ATTR_ES_PEER_ROUTER))
+ CHECK_FLAG(pi->attr->es_flags, ATTR_ES_PEER_ROUTER))
SET_FLAG(flags,
ZEBRA_MACIP_TYPE_ROUTER_FLAG);
- if (!(pi->attr->es_flags & ATTR_ES_PEER_ACTIVE))
+ if (!CHECK_FLAG(pi->attr->es_flags, ATTR_ES_PEER_ACTIVE))
SET_FLAG(flags,
ZEBRA_MACIP_TYPE_PROXY_ADVERT);
}
@@ -1608,12 +1610,16 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn,
struct bgp_labels bgp_labels = {};
struct bgp_path_info *local_pi = NULL;
struct bgp_path_info *tmp_pi = NULL;
+ struct aspath *new_aspath;
+ struct attr static_attr = { 0 };
*route_changed = 0;
/* See if this is an update of an existing route, or a new add. */
local_pi = bgp_evpn_route_get_local_path(bgp_evpn, dest);
+ static_attr = *attr;
+
/*
* create a new route entry if one doesn't exist.
* Otherwise see if route attr has changed
@@ -1623,8 +1629,19 @@ static int update_evpn_type5_route_entry(struct bgp *bgp_evpn,
/* route has changed as this is the first entry */
*route_changed = 1;
+ /*
+ * if the asn values are different, copy the as of
+ * source vrf to the target entry
+ */
+ if (bgp_vrf->as != bgp_evpn->as) {
+ new_aspath = aspath_dup(static_attr.aspath);
+ new_aspath = aspath_add_seq(new_aspath, bgp_vrf->as);
+ static_attr.aspath = new_aspath;
+ }
+
/* Add (or update) attribute to hash. */
- attr_new = bgp_attr_intern(attr);
+ attr_new = bgp_attr_intern(&static_attr);
+ bgp_attr_flush(&static_attr);
/* create the route info from attribute */
pi = info_make(ZEBRA_ROUTE_BGP, BGP_ROUTE_STATIC, 0,
@@ -1738,20 +1755,30 @@ static int update_evpn_type5_route(struct bgp *bgp_vrf, struct prefix_evpn *evp,
BGP_L2VPN_EVPN_ADV_IPV6_UNICAST_GW_IP)) {
if (src_attr &&
!IN6_IS_ADDR_UNSPECIFIED(&src_attr->mp_nexthop_global)) {
- attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP;
- SET_IPADDR_V6(&attr.evpn_overlay.gw_ip);
- memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v6,
+ struct bgp_route_evpn *bre =
+ XCALLOC(MTYPE_BGP_EVPN_OVERLAY,
+ 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,
sizeof(struct in6_addr));
+ bgp_attr_set_evpn_overlay(&attr, bre);
}
} else if (src_afi == AFI_IP &&
CHECK_FLAG(bgp_vrf->af_flags[AFI_L2VPN][SAFI_EVPN],
BGP_L2VPN_EVPN_ADV_IPV4_UNICAST_GW_IP)) {
if (src_attr && src_attr->nexthop.s_addr != 0) {
- attr.evpn_overlay.type = OVERLAY_INDEX_GATEWAY_IP;
- SET_IPADDR_V4(&attr.evpn_overlay.gw_ip);
- memcpy(&attr.evpn_overlay.gw_ip.ipaddr_v4,
- &src_attr->nexthop, sizeof(struct in_addr));
+ struct bgp_route_evpn *bre =
+ XCALLOC(MTYPE_BGP_EVPN_OVERLAY,
+ sizeof(struct bgp_route_evpn));
+
+ 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);
}
}
@@ -1840,7 +1867,8 @@ static void bgp_evpn_get_sync_info(struct bgp *bgp, esi_t *esi,
*active_on_peer = true;
}
- if (second_best_path->attr->router_flag)
+ if (CHECK_FLAG(second_best_path->attr->evpn_flags,
+ ATTR_EVPN_FLAG_ROUTER))
*peer_router = true;
/* we use both proxy and non-proxy imports to
@@ -1883,42 +1911,44 @@ static void update_evpn_route_entry_sync_info(struct bgp *bgp,
mac);
attr->mm_sync_seqnum = max_sync_seq;
if (active_on_peer)
- attr->es_flags |= ATTR_ES_PEER_ACTIVE;
+ SET_FLAG(attr->es_flags, ATTR_ES_PEER_ACTIVE);
else
- attr->es_flags &= ~ATTR_ES_PEER_ACTIVE;
+ UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_ACTIVE);
if (proxy_from_peer)
- attr->es_flags |= ATTR_ES_PEER_PROXY;
+ SET_FLAG(attr->es_flags, ATTR_ES_PEER_PROXY);
else
- attr->es_flags &= ~ATTR_ES_PEER_PROXY;
+ UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_PROXY);
if (peer_router)
- attr->es_flags |= ATTR_ES_PEER_ROUTER;
+ SET_FLAG(attr->es_flags, ATTR_ES_PEER_ROUTER);
else
- attr->es_flags &= ~ATTR_ES_PEER_ROUTER;
+ UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_ROUTER);
if (BGP_DEBUG(evpn_mh, EVPN_MH_RT)) {
char esi_buf[ESI_STR_LEN];
- zlog_debug(
- "setup sync info for %pFX es %s max_seq %d %s%s%s",
- evp,
- esi_to_str(esi, esi_buf,
- sizeof(esi_buf)),
- max_sync_seq,
- (attr->es_flags & ATTR_ES_PEER_ACTIVE)
- ? "peer-active "
- : "",
- (attr->es_flags & ATTR_ES_PEER_PROXY)
- ? "peer-proxy "
- : "",
- (attr->es_flags & ATTR_ES_PEER_ROUTER)
- ? "peer-router "
- : "");
+ zlog_debug("setup sync info for %pFX es %s max_seq %d %s%s%s",
+ evp,
+ esi_to_str(esi, esi_buf,
+ sizeof(esi_buf)),
+ max_sync_seq,
+ CHECK_FLAG(attr->es_flags,
+ ATTR_ES_PEER_ACTIVE)
+ ? "peer-active "
+ : "",
+ CHECK_FLAG(attr->es_flags,
+ ATTR_ES_PEER_PROXY)
+ ? "peer-proxy "
+ : "",
+ CHECK_FLAG(attr->es_flags,
+ ATTR_ES_PEER_ROUTER)
+ ? "peer-router "
+ : "");
}
}
} else {
attr->mm_sync_seqnum = 0;
- attr->es_flags &= ~ATTR_ES_PEER_ACTIVE;
- attr->es_flags &= ~ATTR_ES_PEER_PROXY;
+ UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_ACTIVE);
+ UNSET_FLAG(attr->es_flags, ATTR_ES_PEER_PROXY);
}
}
@@ -1940,7 +1970,6 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
struct attr local_attr;
struct bgp_labels bgp_labels = {};
int route_change = 1;
- uint8_t sticky = 0;
const struct prefix_evpn *evp;
*pi = NULL;
@@ -1972,9 +2001,7 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
local_attr = *attr;
/* Extract MAC mobility sequence number, if any. */
- local_attr.mm_seqnum =
- bgp_attr_mac_mobility_seqnum(&local_attr, &sticky);
- local_attr.sticky = sticky;
+ local_attr.mm_seqnum = bgp_attr_mac_mobility_seqnum(&local_attr);
/* Add (or update) attribute to hash. */
attr_new = bgp_attr_intern(&local_attr);
@@ -2069,9 +2096,8 @@ static int update_evpn_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
BGP_PATH_ATTR_CHANGED);
/* Extract MAC mobility sequence number, if any. */
- local_attr.mm_seqnum = bgp_attr_mac_mobility_seqnum(
- &local_attr, &sticky);
- local_attr.sticky = sticky;
+ local_attr.mm_seqnum =
+ bgp_attr_mac_mobility_seqnum(&local_attr);
attr_new = bgp_attr_intern(&local_attr);
@@ -2114,22 +2140,18 @@ static void evpn_zebra_reinstall_best_route(struct bgp *bgp,
}
}
- if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP
- && (curr_select->sub_type == BGP_ROUTE_IMPORTED ||
- bgp_evpn_attr_is_sync(curr_select->attr)))
- if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP &&
- (curr_select->sub_type == BGP_ROUTE_IMPORTED ||
- bgp_evpn_attr_is_sync(curr_select->attr))) {
- if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS))
- evpn_zebra_install(bgp, vpn,
- (const struct prefix_evpn *)
- bgp_dest_get_prefix(
- dest),
- curr_select);
- else
- bgp_zebra_route_install(dest, curr_select, bgp,
- true, vpn, false);
- }
+ if (curr_select && curr_select->type == ZEBRA_ROUTE_BGP &&
+ (curr_select->sub_type == BGP_ROUTE_IMPORTED ||
+ bgp_evpn_attr_is_sync(curr_select->attr))) {
+ if (CHECK_FLAG(bgp->flags, BGP_FLAG_DELETE_IN_PROGRESS))
+ evpn_zebra_install(bgp, vpn,
+ (const struct prefix_evpn *)
+ bgp_dest_get_prefix(dest),
+ curr_select);
+ else
+ bgp_zebra_route_install(dest, curr_select, bgp, true,
+ vpn, false);
+ }
}
/*
@@ -2204,21 +2226,23 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
attr.nexthop = vpn->originator_ip;
attr.mp_nexthop_global_in = vpn->originator_ip;
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
- attr.sticky = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY) ? 1 : 0;
- attr.default_gw = CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW) ? 1 : 0;
- attr.router_flag = CHECK_FLAG(flags,
- ZEBRA_MACIP_TYPE_ROUTER_FLAG) ? 1 : 0;
+ if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_STICKY))
+ SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_STICKY);
+ if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_GW))
+ SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW);
+ if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_ROUTER_FLAG))
+ SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_ROUTER);
if (CHECK_FLAG(flags, ZEBRA_MACIP_TYPE_PROXY_ADVERT))
- attr.es_flags |= ATTR_ES_PROXY_ADVERT;
+ SET_FLAG(attr.es_flags, ATTR_ES_PROXY_ADVERT);
if (esi && bgp_evpn_is_esi_valid(esi)) {
memcpy(&attr.esi, esi, sizeof(esi_t));
- attr.es_flags |= ATTR_ES_IS_LOCAL;
+ SET_FLAG(attr.es_flags, ATTR_ES_IS_LOCAL);
}
/* PMSI is only needed for type-3 routes */
if (p->prefix.route_type == BGP_EVPN_IMET_ROUTE) {
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL);
+ SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL));
bgp_attr_set_pmsi_tnl_type(&attr, PMSI_TNLTYPE_INGR_REPL);
}
@@ -2250,8 +2274,12 @@ static int update_evpn_route(struct bgp *bgp, struct bgpevpn *vpn,
* IPv4 or IPv6 global addresses and we're advertising L3VNI with
* these routes.
*/
- add_l3_ecomm = bgp_evpn_route_add_l3_ecomm_ok(
- vpn, p, (attr.es_flags & ATTR_ES_IS_LOCAL) ? &attr.esi : NULL);
+ add_l3_ecomm =
+ bgp_evpn_route_add_l3_ecomm_ok(vpn, p,
+ CHECK_FLAG(attr.es_flags,
+ ATTR_ES_IS_LOCAL)
+ ? &attr.esi
+ : NULL);
if (bgp->evpn_info)
macvrf_soo = bgp->evpn_info->soo;
@@ -2509,13 +2537,12 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
attr.nexthop = vpn->originator_ip;
attr.mp_nexthop_global_in = vpn->originator_ip;
attr.mp_nexthop_len = BGP_ATTR_NHLEN_IPV4;
- attr.sticky = (local_pi->attr->sticky) ? 1 : 0;
- attr.router_flag = (local_pi->attr->router_flag) ? 1 : 0;
+ attr.evpn_flags = local_pi->attr->evpn_flags;
attr.es_flags = local_pi->attr->es_flags;
- if (local_pi->attr->default_gw) {
- attr.default_gw = 1;
+ if (CHECK_FLAG(local_pi->attr->evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW)) {
+ SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_DEFAULT_GW);
if (is_evpn_prefix_ipaddr_v6(&evp))
- attr.router_flag = 1;
+ SET_FLAG(attr.evpn_flags, ATTR_EVPN_FLAG_ROUTER);
}
memcpy(&attr.esi, &local_pi->attr->esi, sizeof(esi_t));
bgp_evpn_get_rmac_nexthop(vpn, &evp, &attr,
@@ -2524,9 +2551,12 @@ void bgp_evpn_update_type2_route_entry(struct bgp *bgp, struct bgpevpn *vpn,
/* Add L3 VNI RTs and RMAC for non IPv6 link-local if
* using L3 VNI for type-2 routes also.
*/
- add_l3_ecomm = bgp_evpn_route_add_l3_ecomm_ok(
- vpn, &evp,
- (attr.es_flags & ATTR_ES_IS_LOCAL) ? &attr.esi : NULL);
+ add_l3_ecomm =
+ bgp_evpn_route_add_l3_ecomm_ok(vpn, &evp,
+ CHECK_FLAG(attr.es_flags,
+ ATTR_ES_IS_LOCAL)
+ ? &attr.esi
+ : NULL);
if (bgp->evpn_info)
macvrf_soo = bgp->evpn_info->soo;
@@ -3030,6 +3060,7 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
bool use_l3nhg = false;
bool is_l3nhg_active = false;
char buf1[INET6_ADDRSTRLEN];
+ struct bgp_route_evpn *bre;
memset(pp, 0, sizeof(struct prefix));
ip_prefix_from_evpn_prefix(evp, pp);
@@ -3063,45 +3094,43 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
* make sure to set the flag for next hop attribute.
*/
attr = *parent_pi->attr;
- if (attr.evpn_overlay.type != OVERLAY_INDEX_GATEWAY_IP) {
- 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);
- }
- } else {
-
+ bre = bgp_attr_get_evpn_overlay(&attr);
+ if (bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) {
/*
* If gateway IP overlay index is specified in the NLRI of
* EVPN RT-5, this gateway IP should be used as the nexthop
* for the prefix in the VRF
*/
if (bgp_debug_zebra(NULL)) {
- zlog_debug(
- "Install gateway IP %s as nexthop for prefix %pFX in vrf %s",
- inet_ntop(pp->family, &attr.evpn_overlay.gw_ip,
- buf1, sizeof(buf1)), pp,
- vrf_id_to_name(bgp_vrf->vrf_id));
+ zlog_debug("Install gateway IP %s as nexthop for prefix %pFX in vrf %s",
+ inet_ntop(pp->family, &bre->gw_ip, buf1,
+ sizeof(buf1)),
+ pp, vrf_id_to_name(bgp_vrf->vrf_id));
}
if (afi == AFI_IP6) {
- memcpy(&attr.mp_nexthop_global,
- &attr.evpn_overlay.gw_ip.ipaddr_v6,
+ memcpy(&attr.mp_nexthop_global, &bre->gw_ip.ipaddr_v6,
sizeof(struct in6_addr));
attr.mp_nexthop_len = IPV6_MAX_BYTELEN;
} else {
- attr.nexthop = attr.evpn_overlay.gw_ip.ipaddr_v4;
- attr.flag |= ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP);
+ attr.nexthop = bre->gw_ip.ipaddr_v4;
+ SET_FLAG(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;
+ SET_FLAG(attr.flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP));
}
}
bgp_evpn_es_vrf_use_nhg(bgp_vrf, &parent_pi->attr->esi, &use_l3nhg,
&is_l3nhg_active, NULL);
if (use_l3nhg)
- attr.es_flags |= ATTR_ES_L3_NHG_USE;
+ SET_FLAG(attr.es_flags, ATTR_ES_L3_NHG_USE);
if (is_l3nhg_active)
- attr.es_flags |= ATTR_ES_L3_NHG_ACTIVE;
+ SET_FLAG(attr.es_flags, ATTR_ES_L3_NHG_ACTIVE);
/* Check if route entry is already present. */
for (pi = bgp_dest_get_bgp_path_info(dest); pi; pi = pi->next)
@@ -3143,22 +3172,20 @@ static int install_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
}
/* 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,
NULL, 0, NULL))
bgp_path_info_set_flag(dest, pi, BGP_PATH_VALID);
else {
if (BGP_DEBUG(nht, NHT)) {
- inet_ntop(pp->family,
- &attr.evpn_overlay.gw_ip,
- buf1, sizeof(buf1));
+ inet_ntop(pp->family, &bre->gw_ip, buf1,
+ sizeof(buf1));
zlog_debug("%s: gateway IP NH unresolved",
buf1);
}
bgp_path_info_unset_flag(dest, pi, BGP_PATH_VALID);
}
} else {
-
/* as it is an importation, change nexthop */
bgp_path_info_set_flag(dest, pi, BGP_PATH_ANNC_NH_SELF);
}
@@ -3267,8 +3294,7 @@ static int install_evpn_route_entry_in_vni_common(
if (BGP_DEBUG(evpn_mh, EVPN_MH_RT))
zlog_debug("VNI %d path %pFX chg to %s es",
vpn->vni, &pi->net->rn->p,
- new_local_es ? "local"
- : "non-local");
+ new_local_es ? "local" : "non-local");
bgp_path_info_set_flag(dest, pi, BGP_PATH_ATTR_CHANGED);
}
@@ -3451,9 +3477,8 @@ uninstall_evpn_route_entry_in_vni_mac(struct bgp *bgp, struct bgpevpn *vpn,
* Uninstall route entry from the VRF routing table and send message
* to zebra, if appropriate.
*/
-static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf,
- const struct prefix_evpn *evp,
- struct bgp_path_info *parent_pi)
+int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, const struct prefix_evpn *evp,
+ struct bgp_path_info *parent_pi)
{
struct bgp_dest *dest;
struct bgp_path_info *pi;
@@ -3631,7 +3656,7 @@ static int is_route_matching_for_vrf(struct bgp *bgp_vrf,
assert(attr);
/* Route should have valid RT to be even considered. */
- if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
+ if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
return 0;
ecom = bgp_attr_get_ecommunity(attr);
@@ -3698,7 +3723,7 @@ static int is_route_matching_for_vni(struct bgp *bgp, struct bgpevpn *vpn,
assert(attr);
/* Route should have valid RT to be even considered. */
- if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
+ if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
return 0;
ecom = bgp_attr_get_ecommunity(attr);
@@ -3820,10 +3845,8 @@ static int bgp_evpn_route_rmac_self_check(struct bgp *bgp_vrf,
}
/* don't import hosts that are locally attached */
-static inline bool
-bgp_evpn_skip_vrf_import_of_local_es(struct bgp *bgp_vrf,
- const struct prefix_evpn *evp,
- struct bgp_path_info *pi, int install)
+bool bgp_evpn_skip_vrf_import_of_local_es(struct bgp *bgp_vrf, const struct prefix_evpn *evp,
+ struct bgp_path_info *pi, int install)
{
esi_t *esi;
@@ -4200,7 +4223,7 @@ static int bgp_evpn_install_uninstall_table(struct bgp *bgp, afi_t afi,
return 0;
/* If we don't have Route Target, nothing much to do. */
- if (!(attr->flag & ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
+ if (!CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_EXT_COMMUNITIES)))
return 0;
/* EAD prefix in the global table doesn't include the VTEP-IP so
@@ -4689,7 +4712,6 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
{
struct prefix_rd prd;
struct prefix_evpn p = {};
- struct bgp_route_evpn evpn = {};
uint8_t ipaddr_len;
uint8_t macaddr_len;
/* holds the VNI(s) as in packet */
@@ -4731,9 +4753,9 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
STREAM_GET(&attr->esi, pkt, sizeof(esi_t));
if (bgp_evpn_is_esi_local_and_non_bypass(&attr->esi))
- attr->es_flags |= ATTR_ES_IS_LOCAL;
+ SET_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
else
- attr->es_flags &= ~ATTR_ES_IS_LOCAL;
+ UNSET_FLAG(attr->es_flags, ATTR_ES_IS_LOCAL);
} else {
STREAM_FORWARD_GETP(pkt, sizeof(esi_t));
}
@@ -4791,11 +4813,11 @@ static int process_type2_route(struct peer *peer, afi_t afi, safi_t safi,
if (attr)
bgp_update(peer, (struct prefix *)&p, addpath_id, attr, afi,
safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd,
- &label[0], num_labels, 0, &evpn);
+ &label[0], num_labels, 0, NULL);
else
bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi,
ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label[0],
- num_labels, &evpn);
+ num_labels);
goto done;
fail:
@@ -4835,8 +4857,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
* Note: We just simply ignore the values as it is not clear if
* doing anything else is better.
*/
- if (attr &&
- (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) {
+ if (attr && CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_PMSI_TUNNEL))) {
enum pta_type pmsi_tnl_type = bgp_attr_get_pmsi_tnl_type(attr);
if (pmsi_tnl_type != PMSI_TNLTYPE_INGR_REPL
@@ -4885,8 +4906,7 @@ static int process_type3_route(struct peer *peer, afi_t afi, safi_t safi,
0, 0, NULL);
else
bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi,
- ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0,
- NULL);
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, NULL, 0);
return 0;
}
@@ -4899,7 +4919,8 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
{
struct prefix_rd prd;
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;
uint32_t eth_tag;
mpls_label_t label; /* holds the VNI as in the packet */
@@ -4914,6 +4935,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
flog_err(EC_BGP_EVPN_ROUTE_INVALID,
"%u:%s - Rx EVPN Type-5 NLRI with invalid length %d",
peer->bgp->vrf_id, peer->host, psize);
+ evpn_overlay_free(evpn);
return -1;
}
@@ -4929,12 +4951,9 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
p.prefixlen = EVPN_ROUTE_PREFIXLEN;
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 */
if (attr)
- memcpy(&evpn.eth_s_id, pfx, sizeof(esi_t));
+ memcpy(&evpn->eth_s_id, pfx, sizeof(esi_t));
pfx += ESI_BYTES;
/* Fetch Ethernet Tag. */
@@ -4949,6 +4968,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
EC_BGP_EVPN_ROUTE_INVALID,
"%u:%s - Rx EVPN Type-5 NLRI with invalid IP Prefix length %d",
peer->bgp->vrf_id, peer->host, ippfx_len);
+ evpn_overlay_free(evpn);
return -1;
}
p.prefix.prefix_addr.ip_prefix_length = ippfx_len;
@@ -4961,16 +4981,16 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
SET_IPADDR_V4(&p.prefix.prefix_addr.ip);
memcpy(&p.prefix.prefix_addr.ip.ipaddr_v4, pfx, 4);
pfx += 4;
- SET_IPADDR_V4(&evpn.gw_ip);
- memcpy(&evpn.gw_ip.ipaddr_v4, pfx, 4);
+ SET_IPADDR_V4(&evpn->gw_ip);
+ memcpy(&evpn->gw_ip.ipaddr_v4, pfx, 4);
pfx += 4;
} else {
SET_IPADDR_V6(&p.prefix.prefix_addr.ip);
memcpy(&p.prefix.prefix_addr.ip.ipaddr_v6, pfx,
IPV6_MAX_BYTELEN);
pfx += IPV6_MAX_BYTELEN;
- SET_IPADDR_V6(&evpn.gw_ip);
- memcpy(&evpn.gw_ip.ipaddr_v6, pfx, IPV6_MAX_BYTELEN);
+ SET_IPADDR_V6(&evpn->gw_ip);
+ memcpy(&evpn->gw_ip.ipaddr_v6, pfx, IPV6_MAX_BYTELEN);
pfx += IPV6_MAX_BYTELEN;
}
@@ -4988,20 +5008,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
* at the same time is should be treated as withdraw
*/
- if (bgp_evpn_is_esi_valid(&evpn.eth_s_id) &&
- !ipaddr_is_zero(&evpn.gw_ip)) {
+ if (bgp_evpn_is_esi_valid(&evpn->eth_s_id) &&
+ !ipaddr_is_zero(&evpn->gw_ip)) {
flog_err(EC_BGP_EVPN_ROUTE_INVALID,
"%s - Rx EVPN Type-5 ESI and gateway-IP both non-zero.",
peer->host);
is_valid_update = false;
- } else if (bgp_evpn_is_esi_valid(&evpn.eth_s_id))
- evpn.type = OVERLAY_INDEX_ESI;
- else if (!ipaddr_is_zero(&evpn.gw_ip))
- evpn.type = OVERLAY_INDEX_GATEWAY_IP;
+ } else if (bgp_evpn_is_esi_valid(&evpn->eth_s_id))
+ evpn->type = OVERLAY_INDEX_ESI;
+ else if (!ipaddr_is_zero(&evpn->gw_ip))
+ evpn->type = OVERLAY_INDEX_GATEWAY_IP;
if (attr) {
if (is_zero_mac(&attr->rmac) &&
- !bgp_evpn_is_esi_valid(&evpn.eth_s_id) &&
- ipaddr_is_zero(&evpn.gw_ip) && label == 0) {
+ !bgp_evpn_is_esi_valid(&evpn->eth_s_id) &&
+ ipaddr_is_zero(&evpn->gw_ip) && label == 0) {
flog_err(EC_BGP_EVPN_ROUTE_INVALID,
"%s - Rx EVPN Type-5 ESI, gateway-IP, RMAC and label all zero",
peer->host);
@@ -5016,7 +5036,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
if (attr && is_valid_update)
bgp_update(peer, (struct prefix *)&p, addpath_id, attr, afi,
safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd,
- &label, 1, 0, &evpn);
+ &label, 1, 0, evpn);
else {
if (!is_valid_update) {
char attr_str[BUFSIZ] = {0};
@@ -5028,8 +5048,8 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi,
attr_str);
}
bgp_withdraw(peer, (struct prefix *)&p, addpath_id, afi, safi,
- ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, 1,
- &evpn);
+ ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, 1);
+ evpn_overlay_free(evpn);
}
return 0;
@@ -5043,12 +5063,16 @@ static void evpn_mpattr_encode_type5(struct stream *s, const struct prefix *p,
int len;
char temp[16];
const struct evpn_addr *p_evpn_p;
+ struct bgp_route_evpn *bre = NULL;
memset(&temp, 0, sizeof(temp));
if (p->family != AF_EVPN)
return;
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
IP and GW-IP have to be both ipv4 or ipv6
*/
@@ -5059,7 +5083,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 */
stream_putc(s, 8 + 10 + 4 + 1 + len + 3);
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));
else
stream_put(s, 0, sizeof(esi_t));
@@ -5069,15 +5093,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);
else
stream_put(s, &p_evpn_p->prefix_addr.ip.ipaddr_v6, 16);
- if (attr && attr->evpn_overlay.type == OVERLAY_INDEX_GATEWAY_IP) {
- const struct bgp_route_evpn *evpn_overlay =
- bgp_attr_get_evpn_overlay(attr);
-
+ if (attr && bre && bre->type == OVERLAY_INDEX_GATEWAY_IP) {
if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip))
- stream_put_ipv4(s,
- evpn_overlay->gw_ip.ipaddr_v4.s_addr);
+ stream_put_ipv4(s, bre->gw_ip.ipaddr_v4.s_addr);
else
- stream_put(s, &(evpn_overlay->gw_ip.ipaddr_v6), 16);
+ stream_put(s, &(bre->gw_ip.ipaddr_v6), 16);
} else {
if (IS_IPADDR_V4(&p_evpn_p->prefix_addr.ip))
stream_put_ipv4(s, 0);
@@ -5439,7 +5459,7 @@ void evpn_rt_delete_auto(struct bgp *bgp, vni_t vni, struct list *rtl,
struct ecommunity_val eval;
if (bgp->advertise_autort_rfc8365)
- vni |= EVPN_AUTORT_VXLAN;
+ SET_FLAG(vni, EVPN_AUTORT_VXLAN);
encode_route_target_as((bgp->as & 0xFFFF), vni, &eval, true);
@@ -7717,18 +7737,18 @@ static void bgp_evpn_remote_ip_process_nexthops(struct bgpevpn *vpn,
* MAC/IP route or SVI or tenant vrf being added to EVI.
* Set nexthop as valid only if it is already L3 reachable
*/
- if (resolve && bnc->flags & BGP_NEXTHOP_EVPN_INCOMPLETE) {
- bnc->flags &= ~BGP_NEXTHOP_EVPN_INCOMPLETE;
- bnc->flags |= BGP_NEXTHOP_VALID;
- bnc->change_flags |= BGP_NEXTHOP_MACIP_CHANGED;
+ if (resolve && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE)) {
+ UNSET_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE);
+ SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
+ SET_FLAG(bnc->change_flags, BGP_NEXTHOP_MACIP_CHANGED);
evaluate_paths(bnc);
}
/* MAC/IP route or SVI or tenant vrf being deleted from EVI */
- if (!resolve && bnc->flags & BGP_NEXTHOP_VALID) {
- bnc->flags &= ~BGP_NEXTHOP_VALID;
- bnc->flags |= BGP_NEXTHOP_EVPN_INCOMPLETE;
- bnc->change_flags |= BGP_NEXTHOP_MACIP_CHANGED;
+ if (!resolve && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_VALID)) {
+ UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
+ SET_FLAG(bnc->flags, BGP_NEXTHOP_EVPN_INCOMPLETE);
+ SET_FLAG(bnc->change_flags, BGP_NEXTHOP_MACIP_CHANGED);
evaluate_paths(bnc);
}
}