diff options
Diffstat (limited to 'bgpd')
| -rw-r--r-- | bgpd/bgp_attr.h | 4 | ||||
| -rw-r--r-- | bgpd/bgp_evpn.c | 23 | ||||
| -rw-r--r-- | bgpd/bgp_evpn.h | 1 | ||||
| -rw-r--r-- | bgpd/bgp_nht.c | 11 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 28 | 
5 files changed, 58 insertions, 9 deletions
diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index 42002bd378..375a2272e1 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -69,6 +69,10 @@  #define BGP_PREFIX_SID_IPV6_LENGTH            19  #define BGP_PREFIX_SID_ORIGINATOR_SRGB_LENGTH  6 +#define BGP_ATTR_NH_AFI(afi, attr) \ +	((afi != AFI_L2VPN) ? afi : \ +	((attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV4) ? AFI_IP : AFI_IP6)) +  /* PMSI tunnel types (RFC 6514) */  struct bgp_attr_encap_subtlv { diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index 07d3f7b31e..36ea9a991a 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -6026,3 +6026,26 @@ int bgp_evpn_get_type5_prefixlen(struct prefix *pfx)  	return evp->prefix.prefix_addr.ip_prefix_length;  } + +/* + * Should we register nexthop for this EVPN prefix for nexthop tracking? + */ +bool bgp_evpn_is_prefix_nht_supported(struct prefix *pfx) +{ +	struct prefix_evpn *evp = (struct prefix_evpn *)pfx; + +	/* +	 * EVPN RT-5 should not be marked as valid and imported to vrfs if the +	 * BGP nexthop is not reachable. To check for the nexthop reachability, +	 * Add nexthop for EVPN RT-5 for nexthop tracking. +	 * +	 * Ideally, a BGP route should be marked as valid only if the +	 * nexthop is reachable. Thus, other EVPN route types also should be +	 * added here after testing is performed for them. +	 */ +	if (pfx && pfx->family == AF_EVPN && +	    evp->prefix.route_type == BGP_EVPN_IP_PREFIX_ROUTE) +		return true; + +	return false; +} diff --git a/bgpd/bgp_evpn.h b/bgpd/bgp_evpn.h index 6d1e8cd31b..798c3e59bc 100644 --- a/bgpd/bgp_evpn.h +++ b/bgpd/bgp_evpn.h @@ -191,5 +191,6 @@ extern void bgp_evpn_cleanup_on_disable(struct bgp *bgp);  extern void bgp_evpn_cleanup(struct bgp *bgp);  extern void bgp_evpn_init(struct bgp *bgp);  extern int bgp_evpn_get_type5_prefixlen(struct prefix *pfx); +extern bool bgp_evpn_is_prefix_nht_supported(struct prefix *pfx);  #endif /* _QUAGGA_BGP_EVPN_H */ diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 6be08efb21..0969c8e77e 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -43,6 +43,7 @@  #include "bgpd/bgp_fsm.h"  #include "bgpd/bgp_zebra.h"  #include "bgpd/bgp_flowspec_util.h" +#include "bgpd/bgp_evpn.h"  extern struct zclient *zclient; @@ -773,6 +774,16 @@ static void evaluate_paths(struct bgp_nexthop_cache *bnc)  		    || CHECK_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED))  			SET_FLAG(path->flags, BGP_PATH_IGP_CHANGED); +		if (safi == SAFI_EVPN && +		    bgp_evpn_is_prefix_nht_supported(&rn->p)) { +			if (CHECK_FLAG(path->flags, BGP_PATH_VALID)) +				bgp_evpn_import_route(bgp_path, afi, safi, +						      &rn->p, path); +			else +				bgp_evpn_unimport_route(bgp_path, afi, safi, +							&rn->p, path); +		} +  		bgp_process(bgp_path, rn, afi, safi);  	} diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 261fe77800..a40cd737a8 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3038,6 +3038,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,  	int connected = 0;  	int do_loop_check = 1;  	int has_valid_label = 0; +	afi_t nh_afi;  #if ENABLE_BGP_VNC  	int vnc_implicit_withdraw = 0;  #endif @@ -3433,8 +3434,10 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,  		/* Nexthop reachability check - for unicast and  		 * labeled-unicast.. */ -		if ((afi == AFI_IP || afi == AFI_IP6) -		    && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) { +		if (((afi == AFI_IP || afi == AFI_IP6) +		    && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) +		    || (safi == SAFI_EVPN && +			bgp_evpn_is_prefix_nht_supported(p))) {  			if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1  			    && !CHECK_FLAG(peer->flags,  					   PEER_FLAG_DISABLE_CONNECTED_CHECK) @@ -3449,8 +3452,10 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,  			if (pi->extra && pi->extra->bgp_orig)  				bgp_nexthop = pi->extra->bgp_orig; -			if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, afi, pi, -						    NULL, connected) +			nh_afi = BGP_ATTR_NH_AFI(afi, pi->attr); + +			if (bgp_find_or_add_nexthop(bgp, bgp_nexthop, nh_afi, +						    pi, NULL, connected)  			    || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))  				bgp_path_info_set_flag(rn, pi, BGP_PATH_VALID);  			else { @@ -3498,7 +3503,8 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,  		 * updating  		 * the attributes for the route in the VNI(s).  		 */ -		if (safi == SAFI_EVPN && !same_attr) +		if (safi == SAFI_EVPN && !same_attr && +		    CHECK_FLAG(pi->flags, BGP_PATH_VALID))  			bgp_evpn_import_route(bgp, afi, safi, p, pi);  		/* Process change. */ @@ -3571,8 +3577,9 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,  				     evpn == NULL ? NULL : &evpn->gw_ip);  	}  	/* Nexthop reachability check. */ -	if ((afi == AFI_IP || afi == AFI_IP6) -	    && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) { +	if (((afi == AFI_IP || afi == AFI_IP6) +	    && (safi == SAFI_UNICAST || safi == SAFI_LABELED_UNICAST)) +	    || (safi == SAFI_EVPN && bgp_evpn_is_prefix_nht_supported(p))) {  		if (peer->sort == BGP_PEER_EBGP && peer->ttl == 1  		    && !CHECK_FLAG(peer->flags,  				   PEER_FLAG_DISABLE_CONNECTED_CHECK) @@ -3581,7 +3588,10 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,  		else  			connected = 0; -		if (bgp_find_or_add_nexthop(bgp, bgp, afi, new, NULL, connected) +		nh_afi = BGP_ATTR_NH_AFI(afi, new->attr); + +		if (bgp_find_or_add_nexthop(bgp, bgp, nh_afi, new, NULL, +					    connected)  		    || CHECK_FLAG(peer->flags, PEER_FLAG_IS_RFAPI_HD))  			bgp_path_info_set_flag(rn, new, BGP_PATH_VALID);  		else { @@ -3632,7 +3642,7 @@ int bgp_update(struct peer *peer, struct prefix *p, uint32_t addpath_id,  		return -1;  	/* If this is an EVPN route, process for import. */ -	if (safi == SAFI_EVPN) +	if (safi == SAFI_EVPN && CHECK_FLAG(new->flags, BGP_PATH_VALID))  		bgp_evpn_import_route(bgp, afi, safi, p, new);  	hook_call(bgp_process, bgp, afi, safi, rn, peer, false);  | 
