diff --git a/bgpd/bgp_attr_evpn.c b/bgpd/bgp_attr_evpn.c index 1df646c346..0e341a8c6b 100644 --- a/bgpd/bgp_attr_evpn.c +++ b/bgpd/bgp_attr_evpn.c @@ -315,3 +315,4 @@ extern bool is_zero_gw_ip(const union gw_addr *gw_ip, const afi_t afi) return false; } + diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index b29825afc5..ae365fa13e 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3972,7 +3972,7 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, mpls_label_t label; /* holds the VNI as in the packet */ int ret; afi_t gw_afi; - bool is_valid_update = false; + bool is_valid_update = true; /* Type-5 route should be 34 or 58 bytes: * RD (8), ESI (10), Eth Tag (4), IP len (1), IP (4 or 16), @@ -4001,9 +4001,9 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, /* Additional information outside of prefix - ESI and GW IP */ memset(&evpn, 0, sizeof(evpn)); - /* Fetch ESI */ + /* Fetch ESI overlay index */ if (attr) - memcpy(&attr->esi, pfx, sizeof(esi_t)); + memcpy(&evpn.eth_s_id, pfx, sizeof(esi_t)); pfx += ESI_BYTES; /* Fetch Ethernet Tag. */ @@ -4052,25 +4052,53 @@ static int process_type5_route(struct peer *peer, afi_t afi, safi_t safi, * field */ + /* + * 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) + && !is_zero_gw_ip(&evpn.gw_ip, gw_afi)) { + 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 (!is_zero_gw_ip(&evpn.gw_ip, gw_afi)) + evpn.type = OVERLAY_INDEX_GATEWAY_IP; if (attr) { - is_valid_update = true; - if (is_zero_mac(&attr->rmac) && - is_zero_gw_ip(&evpn.gw_ip, gw_afi)) + if (is_zero_mac(&attr->rmac) + && !bgp_evpn_is_esi_valid(&evpn.eth_s_id) + && is_zero_gw_ip(&evpn.gw_ip, gw_afi) && label == 0) { + flog_err(EC_BGP_EVPN_ROUTE_INVALID, + "%s - Rx EVPN Type-5 ESI, gateway-IP, RMAC and label all zero", + peer->host); is_valid_update = false; + } if (is_mcast_mac(&attr->rmac) || is_bcast_mac(&attr->rmac)) is_valid_update = false; } /* Process the route. */ - if (is_valid_update) + if (attr && is_valid_update) ret = bgp_update(peer, (struct prefix *)&p, addpath_id, attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, 1, 0, &evpn); - else + else { + if (!is_valid_update) { + char attr_str[BUFSIZ] = {0}; + + bgp_dump_attr(attr, attr_str, BUFSIZ); + zlog_warn( + "Invalid update from peer %s vrf %u prefix %pFX attr %s - treat as withdraw", + peer->hostname, peer->bgp->vrf_id, &p, + attr_str); + } ret = bgp_withdraw(peer, (struct prefix *)&p, addpath_id, attr, afi, safi, ZEBRA_ROUTE_BGP, BGP_ROUTE_NORMAL, &prd, &label, 1, &evpn); + } return ret; } diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 4ec8ac305a..794da3b9c1 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3442,23 +3442,6 @@ struct bgp_path_info *info_make(int type, int sub_type, unsigned short instance, return new; } -static void overlay_index_update(struct attr *attr, - union gw_addr *gw_ip) -{ - if (!attr) - return; - if (gw_ip == NULL) { - struct bgp_route_evpn eo; - - memset(&eo, 0, sizeof(eo)); - bgp_attr_set_evpn_overlay(attr, &eo); - } else { - struct bgp_route_evpn eo = {.gw_ip = *gw_ip}; - - bgp_attr_set_evpn_overlay(attr, &eo); - } -} - static bool overlay_index_equal(afi_t afi, struct bgp_path_info *path, union gw_addr *gw_ip) { @@ -3641,6 +3624,11 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (has_valid_label) assert(label != NULL); + /* Update overlay index of the attribute */ + if (afi == AFI_L2VPN && evpn) + memcpy(&attr->evpn_overlay, evpn, + sizeof(struct bgp_route_evpn)); + /* When peer's soft reconfiguration enabled. Record input packet in Adj-RIBs-In. */ if (!soft_reconfig @@ -3816,12 +3804,6 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, goto filtered; } - /* Update Overlay Index */ - if (afi == AFI_L2VPN) { - overlay_index_update(&new_attr, - evpn == NULL ? NULL : &evpn->gw_ip); - } - /* The flag BGP_NODE_FIB_INSTALL_PENDING is for the following * condition : * Suppress fib is enabled @@ -3856,10 +3838,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, && (!has_valid_label || memcmp(&(bgp_path_info_extra_get(pi))->label, label, num_labels * sizeof(mpls_label_t)) - == 0) - && (overlay_index_equal( - afi, pi, - evpn == NULL ? NULL : &evpn->gw_ip))) { + == 0)) { if (get_active_bdc_from_pi(pi, afi, safi) && peer->sort == BGP_PEER_EBGP && CHECK_FLAG(pi->flags, BGP_PATH_HISTORY)) { @@ -3867,7 +3846,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, - addpath_id, NULL, pfx_buf, + addpath_id, evpn, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); @@ -3893,7 +3872,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, - addpath_id, NULL, pfx_buf, + addpath_id, evpn, pfx_buf, sizeof(pfx_buf)); zlog_debug( "%s rcvd %s...duplicate ignored", @@ -3920,7 +3899,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str( afi, safi, prd, p, label, num_labels, - addpath_id ? 1 : 0, addpath_id, NULL, + addpath_id ? 1 : 0, addpath_id, evpn, pfx_buf, sizeof(pfx_buf)); zlog_debug( "%s rcvd %s, flapped quicker than processing", @@ -3934,7 +3913,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, if (bgp_debug_update(peer, p, NULL, 1)) { bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, addpath_id ? 1 : 0, - addpath_id, NULL, pfx_buf, + addpath_id, evpn, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); } @@ -4207,7 +4186,7 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, - addpath_id ? 1 : 0, addpath_id, NULL, + addpath_id ? 1 : 0, addpath_id, evpn, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd %s", peer->host, pfx_buf); } @@ -4239,11 +4218,6 @@ int bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id, } } - /* Update Overlay Index */ - if (afi == AFI_L2VPN) { - overlay_index_update(new->attr, - evpn == NULL ? NULL : &evpn->gw_ip); - } /* Nexthop reachability check. */ if (((afi == AFI_IP || afi == AFI_IP6) && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) @@ -4353,7 +4327,7 @@ filtered: } bgp_debug_rdpfxpath2str(afi, safi, prd, p, label, num_labels, - addpath_id ? 1 : 0, addpath_id, NULL, + addpath_id ? 1 : 0, addpath_id, evpn, pfx_buf, sizeof(pfx_buf)); zlog_debug("%s rcvd UPDATE about %s -- DENIED due to: %s", peer->host, pfx_buf, reason);