diff options
32 files changed, 253 insertions, 906 deletions
diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index f5780eca4d..908c024e9d 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -824,56 +824,55 @@ bool attrhash_cmp(const void *p1, const void *p2)  		&& attr1->med == attr2->med  	    && attr1->local_pref == attr2->local_pref  	    && attr1->rmap_change_flags == attr2->rmap_change_flags) { -		if (attr1->aggregator_as == attr2->aggregator_as && -		    attr1->aggregator_addr.s_addr == -			    attr2->aggregator_addr.s_addr && -		    attr1->weight == attr2->weight && -		    attr1->tag == attr2->tag && -		    attr1->label_index == attr2->label_index && -		    attr1->mp_nexthop_len == attr2->mp_nexthop_len && -		    bgp_attr_get_ecommunity(attr1) == -			    bgp_attr_get_ecommunity(attr2) && -		    bgp_attr_get_ipv6_ecommunity(attr1) == -			    bgp_attr_get_ipv6_ecommunity(attr2) && -		    bgp_attr_get_lcommunity(attr1) == -			    bgp_attr_get_lcommunity(attr2) && -		    bgp_attr_get_cluster(attr1) == -			    bgp_attr_get_cluster(attr2) && -		    bgp_attr_get_transit(attr1) == -			    bgp_attr_get_transit(attr2) && -		    bgp_attr_get_aigp_metric(attr1) == -			    bgp_attr_get_aigp_metric(attr2) && -		    attr1->rmap_table_id == attr2->rmap_table_id && -		    (attr1->encap_tunneltype == attr2->encap_tunneltype) && -		    encap_same(attr1->encap_subtlvs, attr2->encap_subtlvs) +		if (attr1->aggregator_as == attr2->aggregator_as +		    && attr1->aggregator_addr.s_addr +			       == attr2->aggregator_addr.s_addr +		    && attr1->weight == attr2->weight +		    && attr1->tag == attr2->tag +		    && attr1->label_index == attr2->label_index +		    && attr1->mp_nexthop_len == attr2->mp_nexthop_len +		    && bgp_attr_get_ecommunity(attr1) +			       == bgp_attr_get_ecommunity(attr2) +		    && bgp_attr_get_ipv6_ecommunity(attr1) +			       == bgp_attr_get_ipv6_ecommunity(attr2) +		    && bgp_attr_get_lcommunity(attr1) +				   == bgp_attr_get_lcommunity(attr2) +		    && bgp_attr_get_cluster(attr1) +			       == bgp_attr_get_cluster(attr2) +		    && bgp_attr_get_transit(attr1) +			       == bgp_attr_get_transit(attr2) +		    && bgp_attr_get_aigp_metric(attr1) +			       == bgp_attr_get_aigp_metric(attr2) +		    && attr1->rmap_table_id == attr2->rmap_table_id +		    && (attr1->encap_tunneltype == attr2->encap_tunneltype) +		    && encap_same(attr1->encap_subtlvs, attr2->encap_subtlvs)  #ifdef ENABLE_BGP_VNC  		    && encap_same(bgp_attr_get_vnc_subtlvs(attr1),  				  bgp_attr_get_vnc_subtlvs(attr2))  #endif  		    && IPV6_ADDR_SAME(&attr1->mp_nexthop_global, -				      &attr2->mp_nexthop_global) && -		    IPV6_ADDR_SAME(&attr1->mp_nexthop_local, -				   &attr2->mp_nexthop_local) && -		    IPV4_ADDR_SAME(&attr1->mp_nexthop_global_in, -				   &attr2->mp_nexthop_global_in) && -		    IPV4_ADDR_SAME(&attr1->originator_id, -				   &attr2->originator_id) && -		    overlay_index_same(attr1, attr2) && -		    !memcmp(&attr1->esi, &attr2->esi, sizeof(esi_t)) && -		    attr1->es_flags == attr2->es_flags && -		    attr1->mm_sync_seqnum == attr2->mm_sync_seqnum && -		    attr1->df_pref == attr2->df_pref && -		    attr1->df_alg == attr2->df_alg && -		    attr1->nh_ifindex == attr2->nh_ifindex && -		    attr1->nh_flag == attr2->nh_flag && -		    attr1->nh_lla_ifindex == attr2->nh_lla_ifindex && -		    attr1->distance == attr2->distance && -		    srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn) && -		    srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn) && -		    attr1->srte_color == attr2->srte_color && -		    attr1->nh_type == attr2->nh_type && -		    attr1->bh_type == attr2->bh_type && -		    attr1->otc == attr2->otc) +				      &attr2->mp_nexthop_global) +		    && IPV6_ADDR_SAME(&attr1->mp_nexthop_local, +				      &attr2->mp_nexthop_local) +		    && IPV4_ADDR_SAME(&attr1->mp_nexthop_global_in, +				      &attr2->mp_nexthop_global_in) +		    && IPV4_ADDR_SAME(&attr1->originator_id, +				      &attr2->originator_id) +		    && overlay_index_same(attr1, attr2) +		    && !memcmp(&attr1->esi, &attr2->esi, sizeof(esi_t)) +		    && attr1->es_flags == attr2->es_flags +		    && attr1->mm_sync_seqnum == attr2->mm_sync_seqnum +		    && attr1->df_pref == attr2->df_pref +		    && attr1->df_alg == attr2->df_alg +		    && attr1->nh_ifindex == attr2->nh_ifindex +		    && attr1->nh_lla_ifindex == attr2->nh_lla_ifindex +		    && attr1->distance == attr2->distance +		    && srv6_l3vpn_same(attr1->srv6_l3vpn, attr2->srv6_l3vpn) +		    && srv6_vpn_same(attr1->srv6_vpn, attr2->srv6_vpn) +		    && attr1->srte_color == attr2->srte_color +		    && attr1->nh_type == attr2->nh_type +		    && attr1->bh_type == attr2->bh_type +		    && attr1->otc == attr2->otc)  			return true;  	} @@ -2254,12 +2253,6 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,  				return BGP_ATTR_PARSE_WITHDRAW;  			}  			attr->nh_ifindex = peer->nexthop.ifp->ifindex; -			if (if_is_operative(peer->nexthop.ifp)) -				SET_FLAG(attr->nh_flag, -					 BGP_ATTR_NH_IF_OPERSTATE); -			else -				UNSET_FLAG(attr->nh_flag, -					   BGP_ATTR_NH_IF_OPERSTATE);  		}  		break;  	case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL: @@ -2277,12 +2270,6 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,  				return BGP_ATTR_PARSE_WITHDRAW;  			}  			attr->nh_ifindex = peer->nexthop.ifp->ifindex; -			if (if_is_operative(peer->nexthop.ifp)) -				SET_FLAG(attr->nh_flag, -					 BGP_ATTR_NH_IF_OPERSTATE); -			else -				UNSET_FLAG(attr->nh_flag, -					   BGP_ATTR_NH_IF_OPERSTATE);  		}  		if (attr->mp_nexthop_len  		    == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) { diff --git a/bgpd/bgp_attr.h b/bgpd/bgp_attr.h index f8beb5fba9..a34da1a6de 100644 --- a/bgpd/bgp_attr.h +++ b/bgpd/bgp_attr.h @@ -170,12 +170,6 @@ struct attr {  	uint32_t med;  	uint32_t local_pref;  	ifindex_t nh_ifindex; -	uint8_t nh_flag; - -#define BGP_ATTR_NH_VALID 0x01 -#define BGP_ATTR_NH_IF_OPERSTATE 0x02 -#define BGP_ATTR_NH_MP_PREFER_GLOBAL 0x04 /* MP Nexthop preference */ -#define BGP_ATTR_NH_REFRESH 0x08  	/* Path origin attribute */  	uint8_t origin; @@ -226,6 +220,9 @@ struct attr {  	/* MP Nexthop length */  	uint8_t mp_nexthop_len; +	/* MP Nexthop preference */ +	uint8_t mp_nexthop_prefer_global; +  	/* Static MAC for EVPN */  	uint8_t sticky; diff --git a/bgpd/bgp_mpath.c b/bgpd/bgp_mpath.c index 84c847d796..32a5e14b11 100644 --- a/bgpd/bgp_mpath.c +++ b/bgpd/bgp_mpath.c @@ -142,21 +142,15 @@ int bgp_path_info_nexthop_cmp(struct bgp_path_info *bpi1,  					&bpi2->attr->mp_nexthop_global);  				break;  			case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL: -				addr1 = (CHECK_FLAG( -						bpi1->attr->nh_flag, -						BGP_ATTR_NH_MP_PREFER_GLOBAL)) +				addr1 = (bpi1->attr->mp_nexthop_prefer_global)  						? bpi1->attr->mp_nexthop_global  						: bpi1->attr->mp_nexthop_local; -				addr2 = (CHECK_FLAG( -						bpi2->attr->nh_flag, -						BGP_ATTR_NH_MP_PREFER_GLOBAL)) +				addr2 = (bpi2->attr->mp_nexthop_prefer_global)  						? bpi2->attr->mp_nexthop_global  						: bpi2->attr->mp_nexthop_local; -				if (!CHECK_FLAG(bpi1->attr->nh_flag, -						BGP_ATTR_NH_MP_PREFER_GLOBAL) && -				    !CHECK_FLAG(bpi2->attr->nh_flag, -						BGP_ATTR_NH_MP_PREFER_GLOBAL)) +				if (!bpi1->attr->mp_nexthop_prefer_global +				    && !bpi2->attr->mp_nexthop_prefer_global)  					compare = !bgp_interface_same(  						bpi1->peer->ifp,  						bpi2->peer->ifp); diff --git a/bgpd/bgp_mplsvpn.c b/bgpd/bgp_mplsvpn.c index 9b86c9b4b1..c92d678eff 100644 --- a/bgpd/bgp_mplsvpn.c +++ b/bgpd/bgp_mplsvpn.c @@ -1060,11 +1060,9 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,  {  	struct bgp_path_info *bpi_ultimate;  	struct bgp *bgp_nexthop; -	struct bgp_table *table;  	bool nh_valid;  	bpi_ultimate = bgp_get_imported_bpi_ultimate(source_bpi); -	table = bgp_dest_table(bpi_ultimate->net);  	if (bpi->extra && bpi->extra->bgp_orig)  		bgp_nexthop = bpi->extra->bgp_orig; @@ -1072,25 +1070,13 @@ static bool leak_update_nexthop_valid(struct bgp *to_bgp, struct bgp_dest *bn,  		bgp_nexthop = bgp_orig;  	/* -	 * No nexthop tracking for redistributed routes, -	 * for static (i.e. coming from the bgp network statement or for +	 * No nexthop tracking for redistributed routes or for  	 * EVPN-imported routes that get leaked.  	 */  	if (bpi_ultimate->sub_type == BGP_ROUTE_REDISTRIBUTE ||  	    is_pi_family_evpn(bpi_ultimate))  		nh_valid = 1; -	else if (bpi_ultimate->type == ZEBRA_ROUTE_BGP && -		 bpi_ultimate->sub_type == BGP_ROUTE_STATIC && table && -		 (table->safi == SAFI_UNICAST || -		  table->safi == SAFI_LABELED_UNICAST)) { -		/* Routes from network statement */ -		if (CHECK_FLAG(bgp_nexthop->flags, BGP_FLAG_IMPORT_CHECK)) -			nh_valid = bgp_find_or_add_nexthop( -				to_bgp, bgp_nexthop, afi, safi, bpi_ultimate, -				NULL, 0, p); -		else -			nh_valid = 1; -	} else +	else  		/*  		 * TBD do we need to do anything about the  		 * 'connected' parameter? @@ -1280,7 +1266,6 @@ leak_update(struct bgp *to_bgp, struct bgp_dest *bn,  		if (debug)  			zlog_debug("%s: ->%s: %pBD Found route, changed attr",  				   __func__, to_bgp->name_pretty, bn); -		UNSET_FLAG(bpi->attr->nh_flag, BGP_ATTR_NH_REFRESH);  		return bpi;  	} @@ -1879,31 +1864,11 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */  	uint32_t num_labels = 0;  	int nexthop_self_flag = 1;  	struct bgp_path_info *bpi_ultimate = NULL; -	struct bgp_path_info *bpi;  	int origin_local = 0;  	struct bgp *src_vrf; -	struct interface *ifp;  	int debug = BGP_DEBUG(vpn, VPN_LEAK_TO_VRF); -	/* -	 * For VRF-2-VRF route-leaking, -	 * the source will be the originating VRF. -	 * -	 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?) -	 * get the source VRF (BGP) by looking at the RD. -	 */ -	struct bgp *src_bgp = bgp_lookup_by_rd(path_vpn, prd, afi); - -	if (path_vpn->extra && path_vpn->extra->bgp_orig) -		src_vrf = path_vpn->extra->bgp_orig; -	else if (src_bgp) -		src_vrf = src_bgp; -	else -		src_vrf = from_bgp; - -	bn = bgp_afi_node_get(to_bgp->rib[afi][safi], afi, safi, p, NULL); -  	if (!vpn_leak_from_vpn_active(to_bgp, afi, &debugmsg)) {  		if (debug)  			zlog_debug("%s: skipping: %s", __func__, debugmsg); @@ -1963,18 +1928,6 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */  	community_strip_accept_own(&static_attr); -	for (bpi = bgp_dest_get_bgp_path_info(bn); bpi; bpi = bpi->next) { -		if (bpi->extra && bpi->extra->parent == path_vpn) -			break; -	} - -	if (bpi && -	    leak_update_nexthop_valid(to_bgp, bn, &static_attr, afi, safi, -				      path_vpn, bpi, src_vrf, p, debug)) -		SET_FLAG(static_attr.nh_flag, BGP_ATTR_NH_VALID); -	else -		UNSET_FLAG(static_attr.nh_flag, BGP_ATTR_NH_VALID); -  	/*  	 * Nexthop: stash and clear  	 * @@ -2017,22 +1970,6 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */  		break;  	} -	if (static_attr.nexthop.s_addr == INADDR_ANY && -	    IN6_IS_ADDR_UNSPECIFIED(&static_attr.mp_nexthop_global)) { -		ifp = if_get_vrf_loopback(src_vrf->vrf_id); -		if (ifp) -			static_attr.nh_ifindex = ifp->ifindex; -	} else if (static_attr.nh_ifindex) -		ifp = if_lookup_by_index(static_attr.nh_ifindex, -					 src_vrf->vrf_id); -	else -		ifp = NULL; - -	if (ifp && if_is_operative(ifp)) -		SET_FLAG(static_attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE); -	else -		UNSET_FLAG(static_attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE); -  	/*  	 * route map handling  	 */ @@ -2114,6 +2051,22 @@ static bool vpn_leak_to_vrf_update_onevrf(struct bgp *to_bgp,   /* to */  		zlog_debug("%s: pfx %pBD: num_labels %d", __func__,  			   path_vpn->net, num_labels); +	/* +	 * For VRF-2-VRF route-leaking, +	 * the source will be the originating VRF. +	 * +	 * If ACCEPT_OWN mechanism is enabled, then we SHOULD(?) +	 * get the source VRF (BGP) by looking at the RD. +	 */ +	struct bgp *src_bgp = bgp_lookup_by_rd(path_vpn, prd, afi); + +	if (path_vpn->extra && path_vpn->extra->bgp_orig) +		src_vrf = path_vpn->extra->bgp_orig; +	else if (src_bgp) +		src_vrf = src_bgp; +	else +		src_vrf = from_bgp; +  	leak_update(to_bgp, bn, new_attr, afi, safi, path_vpn, pLabels,  		    num_labels, src_vrf, &nexthop_orig, nexthop_self_flag,  		    debug); diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index b6b0c584d7..cf8ff524e9 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -46,7 +46,6 @@  #include "bgpd/bgp_flowspec_util.h"  #include "bgpd/bgp_evpn.h"  #include "bgpd/bgp_rd.h" -#include "bgpd/bgp_mplsvpn.h"  extern struct zclient *zclient; @@ -389,7 +388,7 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,  	if (pi && is_route_parent_evpn(pi))  		bnc->is_evpn_gwip_nexthop = true; -	if (is_bgp_static_route && !CHECK_FLAG(bnc->flags, BGP_STATIC_ROUTE)) { +	if (is_bgp_static_route) {  		SET_FLAG(bnc->flags, BGP_STATIC_ROUTE);  		/* If we're toggling the type, re-register */ @@ -424,8 +423,8 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,  		SET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);  		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);  		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); -	} else if (peer && !connected && -		   CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) { +	} else if (peer && !connected +		   && CHECK_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED)) {  		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_CONNECTED);  		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);  		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID); @@ -835,13 +834,10 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)  {  	struct bgp_nexthop_cache_head *tree = NULL;  	struct bgp_nexthop_cache *bnc_nhc, *bnc_import; -	struct bgp_path_info *pi; -	struct bgp_dest *dest;  	struct bgp *bgp;  	struct prefix match;  	struct zapi_route nhr;  	afi_t afi; -	safi_t safi;  	bgp = bgp_lookup_by_vrf_id(vrf_id);  	if (!bgp) { @@ -862,37 +858,25 @@ void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)  	tree = &bgp->nexthop_cache_table[afi];  	bnc_nhc = bnc_find(tree, &match, nhr.srte_color, 0); -	if (bnc_nhc) +	if (!bnc_nhc) { +		if (BGP_DEBUG(nht, NHT)) +			zlog_debug( +				"parse nexthop update(%pFX(%u)(%s)): bnc info not found for nexthop cache", +				&nhr.prefix, nhr.srte_color, bgp->name_pretty); +	} else  		bgp_process_nexthop_update(bnc_nhc, &nhr, false); -	else if (BGP_DEBUG(nht, NHT)) -		zlog_debug( -			"parse nexthop update(%pFX(%u)(%s)): bnc info not found for nexthop cache", -			&nhr.prefix, nhr.srte_color, bgp->name_pretty);  	tree = &bgp->import_check_table[afi];  	bnc_import = bnc_find(tree, &match, nhr.srte_color, 0); -	if (bnc_import) { +	if (!bnc_import) { +		if (BGP_DEBUG(nht, NHT)) +			zlog_debug( +				"parse nexthop update(%pFX(%u)(%s)): bnc info not found for import check", +				&nhr.prefix, nhr.srte_color, bgp->name_pretty); +	} else  		bgp_process_nexthop_update(bnc_import, &nhr, true); -		safi = nhr.safi; -		if (bgp->rib[afi][safi]) { -			dest = bgp_afi_node_get(bgp->rib[afi][safi], afi, safi, -						&match, NULL); - -			for (pi = bgp_dest_get_bgp_path_info(dest); pi; -			     pi = pi->next) -				if (pi->peer == bgp->peer_self && -				    pi->type == ZEBRA_ROUTE_BGP && -				    pi->sub_type == BGP_ROUTE_STATIC) -					vpn_leak_from_vrf_update( -						bgp_get_default(), bgp, pi); -		} -	} else if (BGP_DEBUG(nht, NHT)) -		zlog_debug( -			"parse nexthop update(%pFX(%u)(%s)): bnc info not found for import check", -			&nhr.prefix, nhr.srte_color, bgp->name_pretty); -  	/*  	 * HACK: if any BGP route is dependant on an SR-policy that doesn't  	 * exist, zebra will never send NH updates relative to that policy. In @@ -1005,8 +989,7 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)  			 */  			else if (pi->attr->mp_nexthop_len  				 == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { -				if (CHECK_FLAG(pi->attr->nh_flag, -					       BGP_ATTR_NH_MP_PREFER_GLOBAL)) +				if (pi->attr->mp_nexthop_prefer_global)  					p->u.prefix6 =  						pi->attr->mp_nexthop_global;  				else diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index a2792b9b79..87871573f0 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -8684,7 +8684,6 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,  	afi_t afi;  	route_map_result_t ret;  	struct bgp_redist *red; -	struct interface *ifp;  	/* Make default attribute. */  	bgp_attr_default_set(&attr, bgp, BGP_ORIGIN_INCOMPLETE); @@ -8734,11 +8733,6 @@ void bgp_redistribute_add(struct bgp *bgp, struct prefix *p,  	}  	attr.nh_type = nhtype;  	attr.nh_ifindex = ifindex; -	ifp = if_lookup_by_index(ifindex, bgp->vrf_id); -	if (ifp && if_is_operative(ifp)) -		SET_FLAG(attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE); -	else -		UNSET_FLAG(attr.nh_flag, BGP_ATTR_NH_IF_OPERSTATE);  	attr.med = metric;  	attr.distance = distance; @@ -9425,10 +9419,9 @@ void route_vty_out(struct vty *vty, const struct prefix *p,  						       "link-local");  				if ((IPV6_ADDR_CMP(&attr->mp_nexthop_global, -						   &attr->mp_nexthop_local) != -				     0) && -				    !CHECK_FLAG(attr->nh_flag, -						BGP_ATTR_NH_MP_PREFER_GLOBAL)) +						   &attr->mp_nexthop_local) +				     != 0) +				    && !attr->mp_nexthop_prefer_global)  					json_object_boolean_true_add(  						json_nexthop_ll, "used");  				else @@ -9440,11 +9433,10 @@ void route_vty_out(struct vty *vty, const struct prefix *p,  		} else {  			/* Display LL if LL/Global both in table unless  			 * prefer-global is set */ -			if (((attr->mp_nexthop_len == -			      BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) && -			     !CHECK_FLAG(attr->nh_flag, -					 BGP_ATTR_NH_MP_PREFER_GLOBAL)) || -			    (path->peer->conf_if)) { +			if (((attr->mp_nexthop_len +			      == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) +			     && !attr->mp_nexthop_prefer_global) +			    || (path->peer->conf_if)) {  				if (path->peer->conf_if) {  					len = vty_out(vty, "%s",  						      path->peer->conf_if); @@ -10706,8 +10698,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,  			json_object_boolean_true_add(json_nexthop_ll,  						     "accessible"); -			if (!CHECK_FLAG(attr->nh_flag, -					BGP_ATTR_NH_MP_PREFER_GLOBAL)) +			if (!attr->mp_nexthop_prefer_global)  				json_object_boolean_true_add(json_nexthop_ll,  							     "used");  			else @@ -10717,8 +10708,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,  			vty_out(vty, "    (%s) %s\n",  				inet_ntop(AF_INET6, &attr->mp_nexthop_local,  					  buf, INET6_ADDRSTRLEN), -				CHECK_FLAG(attr->nh_flag, -					   BGP_ATTR_NH_MP_PREFER_GLOBAL) +				attr->mp_nexthop_prefer_global  					? "(prefer-global)"  					: "(used)");  		} diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index f779b34371..1ce2eb4352 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -3531,11 +3531,11 @@ route_set_ipv6_nexthop_prefer_global(void *rule, const struct prefix *prefix,  	if (CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IN)  	    || CHECK_FLAG(peer->rmap_type, PEER_RMAP_TYPE_IMPORT)) {  		/* Set next hop preference to global */ -		SET_FLAG(path->attr->nh_flag, BGP_ATTR_NH_MP_PREFER_GLOBAL); +		path->attr->mp_nexthop_prefer_global = true;  		SET_FLAG(path->attr->rmap_change_flags,  			 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);  	} else { -		UNSET_FLAG(path->attr->nh_flag, BGP_ATTR_NH_MP_PREFER_GLOBAL); +		path->attr->mp_nexthop_prefer_global = false;  		SET_FLAG(path->attr->rmap_change_flags,  			 BATTR_RMAP_IPV6_PREFER_GLOBAL_CHANGED);  	} diff --git a/bgpd/bgp_snmp_bgp4v2.c b/bgpd/bgp_snmp_bgp4v2.c index fe0c33251e..d8d8549960 100644 --- a/bgpd/bgp_snmp_bgp4v2.c +++ b/bgpd/bgp_snmp_bgp4v2.c @@ -704,8 +704,7 @@ static uint8_t *bgp4v2PathAttrTable(struct variable *v, oid name[],  		case BGP_ATTR_NHLEN_IPV6_GLOBAL:  			return SNMP_INTEGER(2);  		case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL: -			if (CHECK_FLAG(path->attr->nh_flag, -				       BGP_ATTR_NH_MP_PREFER_GLOBAL)) +			if (path->attr->mp_nexthop_prefer_global)  				return SNMP_INTEGER(2);  			else  				return SNMP_INTEGER(4); @@ -719,8 +718,7 @@ static uint8_t *bgp4v2PathAttrTable(struct variable *v, oid name[],  		case BGP_ATTR_NHLEN_IPV6_GLOBAL:  			return SNMP_IP6ADDRESS(path->attr->mp_nexthop_global);  		case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL: -			if (CHECK_FLAG(path->attr->nh_flag, -				       BGP_ATTR_NH_MP_PREFER_GLOBAL)) +			if (path->attr->mp_nexthop_prefer_global)  				return SNMP_IP6ADDRESS(  					path->attr->mp_nexthop_global);  			else diff --git a/bgpd/bgp_zebra.c b/bgpd/bgp_zebra.c index f6e7b444c6..8ce17ab49e 100644 --- a/bgpd/bgp_zebra.c +++ b/bgpd/bgp_zebra.c @@ -234,7 +234,6 @@ static int bgp_ifp_up(struct interface *ifp)  	struct connected *c;  	struct nbr_connected *nc;  	struct listnode *node, *nnode; -	struct bgp *bgp_default = bgp_get_default();  	struct bgp *bgp;  	bgp = ifp->vrf->info; @@ -257,14 +256,6 @@ static int bgp_ifp_up(struct interface *ifp)  	hook_call(bgp_vrf_status_changed, bgp, ifp);  	bgp_nht_ifp_up(ifp); -	if (bgp_default && if_is_loopback(ifp)) { -		vpn_leak_zebra_vrf_label_update(bgp, AFI_IP); -		vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6); -		vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP); -		vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP6); -		vpn_leak_postchange_all(); -	} -  	return 0;  } @@ -273,7 +264,6 @@ static int bgp_ifp_down(struct interface *ifp)  	struct connected *c;  	struct nbr_connected *nc;  	struct listnode *node, *nnode; -	struct bgp *bgp_default = bgp_get_default();  	struct bgp *bgp;  	struct peer *peer; @@ -313,14 +303,6 @@ static int bgp_ifp_down(struct interface *ifp)  	hook_call(bgp_vrf_status_changed, bgp, ifp);  	bgp_nht_ifp_down(ifp); -	if (bgp_default && if_is_loopback(ifp)) { -		vpn_leak_zebra_vrf_label_update(bgp, AFI_IP); -		vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6); -		vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP); -		vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP6); -		vpn_leak_postchange_all(); -	} -  	return 0;  } @@ -408,16 +390,10 @@ static int bgp_interface_address_add(ZAPI_CALLBACK_ARGS)  static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS)  {  	struct listnode *node, *nnode; -	struct bgp_path_info *pi; -	struct bgp_table *table; -	struct bgp_dest *dest;  	struct connected *ifc;  	struct peer *peer; -	struct bgp *bgp, *from_bgp, *bgp_default; -	struct listnode *next; +	struct bgp *bgp;  	struct prefix *addr; -	afi_t afi; -	safi_t safi;  	bgp = bgp_lookup_by_vrf_id(vrf_id); @@ -445,6 +421,9 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS)  		 * we do not want the peering to bounce.  		 */  		for (ALL_LIST_ELEMENTS(bgp->peer, node, nnode, peer)) { +			afi_t afi; +			safi_t safi; +  			if (addr->family == AF_INET)  				continue; @@ -460,44 +439,6 @@ static int bgp_interface_address_delete(ZAPI_CALLBACK_ARGS)  		}  	} -	bgp_default = bgp_get_default(); -	afi = family2afi(addr->family); -	safi = SAFI_UNICAST; - -	/* When the last IPv4 address was deleted, Linux removes all routes -	 * using the interface so that bgpd needs to re-send them. -	 */ -	if (bgp_default && afi == AFI_IP) { -		for (ALL_LIST_ELEMENTS_RO(bm->bgp, next, from_bgp)) { -			table = from_bgp->rib[afi][safi]; -			if (!table) -				continue; - -			for (dest = bgp_table_top(table); dest; -			     dest = bgp_route_next(dest)) { -				for (pi = bgp_dest_get_bgp_path_info(dest); pi; -				     pi = pi->next) { -					if (pi->type == ZEBRA_ROUTE_BGP && -					    pi->attr && -					    pi->attr->nh_ifindex == -						    ifc->ifp->ifindex) { -						SET_FLAG(pi->attr->nh_flag, -							 BGP_ATTR_NH_REFRESH); -					} -				} -			} - -			if (from_bgp->inst_type != BGP_INSTANCE_TYPE_VRF) -				continue; - -			vpn_leak_postchange(BGP_VPN_POLICY_DIR_TOVPN, afi, -					    bgp_default, from_bgp); - -			vpn_leak_postchange(BGP_VPN_POLICY_DIR_FROMVPN, afi, -					    bgp_default, from_bgp); -		} -	} -  	connected_free(&ifc);  	return 0; @@ -1066,8 +1007,7 @@ bgp_path_info_to_ipv6_nexthop(struct bgp_path_info *path, ifindex_t *ifindex)  	    || path->attr->mp_nexthop_len  		       == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) {  		/* Check if route-map is set to prefer global over link-local */ -		if (CHECK_FLAG(path->attr->nh_flag, -			       BGP_ATTR_NH_MP_PREFER_GLOBAL)) { +		if (path->attr->mp_nexthop_prefer_global) {  			nexthop = &path->attr->mp_nexthop_global;  			if (IN6_IS_ADDR_LINKLOCAL(nexthop))  				*ifindex = path->attr->nh_ifindex; @@ -1367,7 +1307,6 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,  	uint8_t distance;  	struct peer *peer;  	struct bgp_path_info *mpinfo; -	struct bgp_path_info *bpi_ultimate;  	struct bgp *bgp_orig;  	uint32_t metric;  	struct attr local_attr; @@ -1416,9 +1355,13 @@ void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,  	peer = info->peer; -	if (info->type == ZEBRA_ROUTE_BGP) { -		bpi_ultimate = bgp_get_imported_bpi_ultimate(info); -		peer = bpi_ultimate->peer; +	if (info->type == ZEBRA_ROUTE_BGP +	    && info->sub_type == BGP_ROUTE_IMPORTED) { + +		/* Obtain peer from parent */ +		if (info->extra && info->extra->parent) +			peer = ((struct bgp_path_info *)(info->extra->parent)) +				       ->peer;  	}  	tag = info->attr->tag; @@ -3250,7 +3193,6 @@ extern struct zebra_privs_t bgpd_privs;  static int bgp_ifp_create(struct interface *ifp)  { -	struct bgp *bgp_default = bgp_get_default();  	struct bgp *bgp;  	if (BGP_DEBUG(zebra, ZEBRA)) @@ -3265,17 +3207,6 @@ static int bgp_ifp_create(struct interface *ifp)  	bgp_update_interface_nbrs(bgp, ifp, ifp);  	hook_call(bgp_vrf_status_changed, bgp, ifp); - -	if (bgp_default && -	    (if_is_loopback_exact(ifp) || -	     (if_is_vrf(ifp) && ifp->vrf->vrf_id != VRF_DEFAULT))) { -		vpn_leak_zebra_vrf_label_update(bgp, AFI_IP); -		vpn_leak_zebra_vrf_label_update(bgp, AFI_IP6); -		vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP); -		vpn_leak_zebra_vrf_sid_update(bgp, AFI_IP6); -		vpn_leak_postchange_all(); -	} -  	return 0;  } @@ -564,24 +564,9 @@ size_t if_lookup_by_hwaddr(const uint8_t *hw_addr, size_t addrsz,  	return count;  } -/* Get the VRF loopback interface, i.e. the loopback on the default VRF - * or the VRF interface. - */ -struct interface *if_get_vrf_loopback(vrf_id_t vrf_id) -{ -	struct interface *ifp = NULL; -	struct vrf *vrf = vrf_lookup_by_id(vrf_id); - -	FOR_ALL_INTERFACES (vrf, ifp) -		if (if_is_loopback(ifp)) -			return ifp; - -	return NULL; -}  /* Get interface by name if given name interface doesn't exist create - * one. - */ +   one. */  struct interface *if_get_by_name(const char *name, vrf_id_t vrf_id,  				 const char *vrf_name)  { @@ -532,7 +532,6 @@ static inline bool if_address_is_local(const void *matchaddr, int family,  struct vrf;  extern struct interface *if_lookup_by_name_vrf(const char *name, struct vrf *vrf);  extern struct interface *if_lookup_by_name(const char *ifname, vrf_id_t vrf_id); -extern struct interface *if_get_vrf_loopback(vrf_id_t vrf_id);  extern struct interface *if_get_by_name(const char *ifname, vrf_id_t vrf_id,  					const char *vrf_name); diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/zebra.conf index 375bbea9ff..46831bb711 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce1/zebra.conf @@ -4,8 +4,6 @@ hostname ce1  !  interface lo   ip address 99.0.0.1/32 - ip address 5.1.0.1/24 - ip address 6.0.2.1/24  !  interface ce1-eth0   description to r1 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/zebra.conf index 90dd3c55b4..fb4d8cc9c4 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce2/zebra.conf @@ -4,8 +4,6 @@ hostname ce2  !  interface lo   ip address 99.0.0.2/32 - ip address 5.1.0.1/24 - ip address 6.0.2.1/24  !  interface ce2-eth0   description to r3 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf index cf7396eb12..e316de5690 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/bgpd.conf @@ -19,7 +19,6 @@ router bgp 5227       network 5.1.3.0/24 route-map rm-nh       network 6.0.1.0/24 route-map rm-nh       network 6.0.2.0/24 route-map rm-nh-same -     network 6.0.3.0/24 route-map rm-nh-same       neighbor 192.168.1.1 activate   exit-address-family  ! diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/zebra.conf index df6ac47b08..77a1163a4b 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce3/zebra.conf @@ -4,7 +4,6 @@ hostname ce3  !  interface lo   ip address 99.0.0.3/32 - ip address 6.0.3.1/24  !  interface ce3-eth0   description to r4 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf index 9a6ca08a0b..60d9e93108 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/bgpd.conf @@ -19,7 +19,6 @@ router bgp 5228 vrf ce4-cust2       network 5.4.3.0/24 route-map rm-nh       network 6.0.1.0/24 route-map rm-nh       network 6.0.2.0/24 route-map rm-nh-same -     network 6.0.3.0/24 route-map rm-nh-same       neighbor 192.168.2.1 activate   exit-address-family  ! diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf index 0e3a736292..e55c9e779a 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/ce4/zebra.conf @@ -4,7 +4,6 @@ hostname ce4  !  interface ce4-cust2   ip address 99.0.0.4/32 - ip address 6.0.3.1/24  !  interface ce4-eth0   description to r4 diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py index b2bf5f5f63..5161d8471f 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/customize.py @@ -175,20 +175,6 @@ def ltemplatePreRouterStartHook():              "setup {0} vrf {0}-cust1, {0}-eth4. enabled mpls input.".format(rtr)          )      # configure cust2 VRFs & MPLS -    rtrs = ["r1"] -    cmds = [ -        "ip link add {0}-cust3 type vrf table 20", -        "ip link set dev {0}-cust3 up", -        "ip link add {0}-cust4 type vrf table 30", -        "ip link set dev {0}-cust4 up", -        "ip link add {0}-cust5 type vrf table 40", -        "ip link set dev {0}-cust5 up", -    ] -    for rtr in rtrs: -        for cmd in cmds: -            cc.doCmd(tgen, rtr, cmd.format(rtr)) -        logger.info("setup {0} vrf {0}-cust3 and{0}-cust4.".format(rtr)) -    # configure cust2 VRFs & MPLS      rtrs = ["r4"]      cmds = [          "ip link add {0}-cust2 type vrf table 20", diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf index 24e9f95372..8d42cfc0d8 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/bgpd.conf @@ -11,7 +11,6 @@ log file bgpd.log debugging  #debug bgp vpn leak-from-vrf  #debug bgp vpn label  #debug bgp updates out -#debug bgp nht  router bgp 5226     bgp router-id 1.1.1.1 @@ -40,11 +39,6 @@ router bgp 5227 vrf r1-cust1     neighbor 192.168.1.2 timers 3 10     address-family ipv4 unicast -     network 10.2.3.4/32 -     network 192.0.0.0/24 - -     redistribute connected -       neighbor 192.168.1.2 activate       neighbor 192.168.1.2 next-hop-self @@ -57,47 +51,5 @@ router bgp 5227 vrf r1-cust1     exit-address-family -router bgp 5228 vrf r1-cust3 -   bgp router-id 192.168.1.1 - -   address-family ipv4 unicast -     rd vpn export 10:13 -     rt vpn import 52:100 - -     import vpn -     export vpn -   exit-address-family - - -router bgp 5227 vrf r1-cust4 -   no bgp network import-check - -   bgp router-id 192.168.1.1 - -   address-family ipv4 unicast -     network 28.0.0.0/24 - -     rd vpn export 10:14 -     rt vpn export 52:100 - -     import vpn -     export vpn -   exit-address-family - - -router bgp 5227 vrf r1-cust5 -   bgp router-id 192.168.1.1 - -   address-family ipv4 unicast -     redistribute connected - -     label vpn export 105 -     rd vpn export 10:15 -     rt vpn both 52:100 - -     import vpn -     export vpn -   exit-address-family -  !  end diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/staticd.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/staticd.conf deleted file mode 100644 index 59430fdf99..0000000000 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/staticd.conf +++ /dev/null @@ -1,6 +0,0 @@ -hostname r1 -log file staticd.log -! -vrf r1-cust1 - ip route 192.0.0.0/24 192.168.1.2 -exit-vrf diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/zebra.conf b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/zebra.conf index e81bc6b2ab..221bc7a839 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/zebra.conf +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/r1/zebra.conf @@ -4,9 +4,6 @@ hostname r1  password zebra  #debug zebra packet -#debug zebra rib detailed -#debug zebra dplane detailed -#debug zebra nexthop detail  interface lo   ip address 1.1.1.1/32 @@ -21,14 +18,6 @@ interface r1-eth4   ip address 192.168.1.1/24   no link-detect -interface r1-cust1 - ip address 10.4.5.6/24 - no link-detect - -interface r1-cust5 - ip address 29.0.0.1/32 - no link-detect -  ip forwarding diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py index 89369241a8..91a7adf997 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_mpls.py @@ -81,24 +81,3 @@ if ret != False and found != None:          "wait",          "CE3->CE4 (loopback) ping",      ) -    luCommand( -        "r1", -        "ip vrf exec r1-cust1 ping 6.0.3.1 -I 10.4.5.6 -c 1", -        " 0. packet loss", -        "wait", -        "R1(r1-cust1)->CE3/4 (loopback) ping", -    ) -    luCommand( -        "r1", -        "ip vrf exec r1-cust1 ping 6.0.3.1 -I 10.4.5.6 -c 1", -        " 0. packet loss", -        "pass", -        "R1(r1-cust1)->CE3/4 (loopback) ping", -    ) -    luCommand( -        "r1", -        "ip vrf exec r1-cust5 ping 6.0.3.1 -I 29.0.0.1 -c 1", -        " 0. packet loss", -        "pass", -        "R1(r1-cust5)->CE3/4 ( (loopback) ping", -    ) diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py index e9647898ab..75158b127e 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_linux_vrf.py @@ -72,53 +72,3 @@ luCommand(      "wait",      "CE4->PE4 ping",  ) -ret = luCommand( -    "r1", -    "ip vrf exec r1-cust5 ping 29.0.0.1 -I 29.0.0.1 -c 1", -    " 0. packet loss", -    "pass", -    "Ping its own IP. Check https://bugzilla.kernel.org/show_bug.cgi?id=203483 if it fails", -) -luCommand( -    "r1", -    "ip vrf exec r1-cust5 ping 192.168.1.1 -I 29.0.0.1 -c 1", -    " 0. packet loss", -    "pass", -    "R1(r1-cust5)->R1(r1-cust1 - r1-eth4) ping", -) -luCommand( -    "r1", -    "ip vrf exec r1-cust5 ping 192.168.1.2 -I 29.0.0.1 -c 1", -    " 0. packet loss", -    "wait", -    "R1(r1-cust5)->CE1 ping", -) -luCommand( -    "r1", -    "ip vrf exec r1-cust5 ping 192.168.1.2 -I 29.0.0.1 -c 1", -    " 0. packet loss", -    "pass", -    "R1(r1-cust5)->CE1 ping", -) -luCommand( -    "r1", -    "ip vrf exec r1-cust5 ping 99.0.0.1 -I 29.0.0.1 -c 1", -    " 0. packet loss", -    "pass", -    "R1(r1-cust5)->CE1 (loopback) ping", -) -luCommand( -    "r1", -    "ip vrf exec r1-cust5 ping 5.1.0.1 -I 29.0.0.1 -c 1", -    " 0. packet loss", -    "wait", -    "R1(r1-cust5)->CE1 (loopback) ping", -    time=30, -) -luCommand( -    "r1", -    "ip vrf exec r1-cust5 ping 5.1.0.1 -I 29.0.0.1 -c 1", -    " 0. packet loss", -    "pass", -    "R1(r1-cust5)->CE1 (loopback) ping", -) diff --git a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py index 3242e3bd3a..1e2758c1c9 100644 --- a/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py +++ b/tests/topotests/bgp_l3vpn_to_bgp_vrf/scripts/check_routes.py @@ -54,44 +54,15 @@ bgpribRequireUnicastRoutes("ce4", "ipv4", "ce4-cust2", "Cust 4 routes in ce1", w  #  # r1 vtysh -c "show bgp vrf r1-cust1 ipv4"  # -want_r1_cust1_3_5_routes = [ +want_r1_cust1_routes = [      {"p": "5.1.0.0/24", "n": "99.0.0.1"},      {"p": "5.1.1.0/24", "n": "99.0.0.1"},      {"p": "6.0.1.0/24", "n": "99.0.0.1"},      {"p": "6.0.2.0/24", "n": "99.0.0.1"}, -    {"p": "10.2.3.4/32", "n": "0.0.0.0", "bp": False}, -    {"p": "10.4.5.0/24", "n": "0.0.0.0", "bp": True}, -    {"p": "28.0.0.0/24", "n": "0.0.0.0", "bp": True}, -    {"p": "29.0.0.1/32", "n": "0.0.0.0", "bp": True},      {"p": "99.0.0.1/32", "n": "192.168.1.2"}, -    {"p": "192.0.0.0/24", "n": "0.0.0.0", "bp": True}, -    {"p": "192.168.1.0/24", "n": "0.0.0.0", "bp": True},  ]  bgpribRequireUnicastRoutes( -    "r1", "ipv4", "r1-cust1", "Customer 1 routes in r1 vrf", want_r1_cust1_3_5_routes -) -bgpribRequireUnicastRoutes( -    "r1", "ipv4", "r1-cust3", "Customer 3 routes in r1 vrf", want_r1_cust1_3_5_routes -) -bgpribRequireUnicastRoutes( -    "r1", "ipv4", "r1-cust5", "Customer 5 routes in r1 vrf", want_r1_cust1_3_5_routes -) - -want_r1_cust4_routes = [ -    {"p": "5.1.0.0/24", "n": "99.0.0.1", "exist": False}, -    {"p": "5.1.1.0/24", "n": "99.0.0.1", "exist": False}, -    {"p": "6.0.1.0/24", "n": "99.0.0.1", "exist": False}, -    {"p": "6.0.2.0/24", "n": "99.0.0.1", "exist": False}, -    {"p": "10.2.3.4/32", "n": "0.0.0.0", "exist": False}, -    {"p": "10.4.5.0/24", "n": "0.0.0.0", "exist": False}, -    {"p": "28.0.0.0/24", "n": "0.0.0.0", "bp": True}, -    {"p": "29.0.0.1/32", "n": "0.0.0.0", "exist": False}, -    {"p": "99.0.0.1/32", "n": "192.168.1.2", "exist": False}, -    {"p": "192.0.0.0/24", "n": "0.0.0.0", "exist": False}, -    {"p": "192.168.1.0/24", "n": "0.0.0.0", "exist": False}, -] -bgpribRequireUnicastRoutes( -    "r1", "ipv4", "r1-cust4", "Customer 4 routes in r1 vrf", want_r1_cust4_routes +    "r1", "ipv4", "r1-cust1", "Customer 1 routes in r1 vrf", want_r1_cust1_routes  )  want_r3_cust1_routes = [ @@ -99,20 +70,10 @@ want_r3_cust1_routes = [      {"p": "5.1.1.0/24", "n": "99.0.0.2"},      {"p": "6.0.1.0/24", "n": "99.0.0.2"},      {"p": "6.0.2.0/24", "n": "99.0.0.2"}, -    {"p": "10.2.3.4/32", "n": "0.0.0.0", "exist": False}, -    {"p": "28.0.0.0/24", "n": "1.1.1.1", "bp": True}, -    {"p": "29.0.0.1/32", "n": "1.1.1.1", "bp": True},      {"p": "99.0.0.2/32", "n": "192.168.1.2"}, -    {"p": "192.0.0.0/24", "n": "1.1.1.1", "bp": True}, -    {"p": "192.168.1.0/24", "n": "1.1.1.1", "bp": True},  ]  bgpribRequireUnicastRoutes( -    "r3", -    "ipv4", -    "r3-cust1", -    "Customer 1 routes in r3 vrf", -    want_r3_cust1_routes, -    retry=30, +    "r3", "ipv4", "r3-cust1", "Customer 1 routes in r3 vrf", want_r3_cust1_routes  )  want_r4_cust1_routes = [ @@ -120,20 +81,10 @@ want_r4_cust1_routes = [      {"p": "5.1.3.0/24", "n": "99.0.0.3"},      {"p": "6.0.1.0/24", "n": "99.0.0.3"},      {"p": "6.0.2.0/24", "n": "99.0.0.3"}, -    {"p": "10.2.3.4/32", "n": "0.0.0.0", "exist": False}, -    {"p": "28.0.0.0/24", "n": "1.1.1.1", "bp": True}, -    {"p": "29.0.0.1/32", "n": "1.1.1.1", "bp": True},      {"p": "99.0.0.3/32", "n": "192.168.1.2"}, -    {"p": "192.0.0.0/24", "n": "1.1.1.1", "bp": True}, -    {"p": "192.168.1.0/24", "n": "1.1.1.1", "bp": True},  ]  bgpribRequireUnicastRoutes( -    "r4", -    "ipv4", -    "r4-cust1", -    "Customer 1 routes in r4 vrf", -    want_r4_cust1_routes, -    retry=30, +    "r4", "ipv4", "r4-cust1", "Customer 1 routes in r4 vrf", want_r4_cust1_routes  )  want_r4_cust2_routes = [ @@ -141,20 +92,10 @@ want_r4_cust2_routes = [      {"p": "5.4.3.0/24", "n": "99.0.0.4"},      {"p": "6.0.1.0/24", "n": "99.0.0.4"},      {"p": "6.0.2.0/24", "n": "99.0.0.4"}, -    {"p": "10.2.3.4/32", "n": "0.0.0.0", "exist": False}, -    {"p": "28.0.0.0/24", "n": "1.1.1.1", "bp": True}, -    {"p": "29.0.0.1/32", "n": "1.1.1.1", "bp": True},      {"p": "99.0.0.4/32", "n": "192.168.2.2"}, -    {"p": "192.0.0.0/24", "n": "1.1.1.1", "bp": True}, -    {"p": "192.168.1.0/24", "n": "1.1.1.1", "bp": True},  ]  bgpribRequireUnicastRoutes( -    "r4", -    "ipv4", -    "r4-cust2", -    "Customer 2 routes in r4 vrf", -    want_r4_cust2_routes, -    retry=30, +    "r4", "ipv4", "r4-cust2", "Customer 2 routes in r4 vrf", want_r4_cust2_routes  )  ######################################################################## @@ -726,7 +667,7 @@ bgpribRequireUnicastRoutes(  luCommand(      "ce1",      'vtysh -c "show bgp ipv4 uni"', -    "18 routes and 19", +    "12 routes and 12",      "wait",      "Local and remote routes",      10, @@ -748,7 +689,7 @@ bgpribRequireUnicastRoutes(  luCommand(      "ce2",      'vtysh -c "show bgp ipv4 uni"', -    "18 routes and 22", +    "12 routes and 15",      "wait",      "Local and remote routes",      10, @@ -780,7 +721,7 @@ luCommand("r4", 'vtysh -c "show ip route vrf r4-cust2"')  luCommand(      "ce3",      'vtysh -c "show bgp ipv4 uni"', -    "18 routes and 19", +    "12 routes and 13",      "wait",      "Local and remote routes",      10, @@ -802,7 +743,7 @@ bgpribRequireUnicastRoutes(  luCommand(      "ce4",      'vtysh -c "show bgp vrf ce4-cust2 ipv4 uni"', -    "18 routes and 21", +    "12 routes and 14",      "wait",      "Local and remote routes",      10, diff --git a/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf b/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf index 0540a62096..03dfbf9322 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf +++ b/tests/topotests/bgp_vrf_route_leak_basic/r1/bgpd.conf @@ -1,11 +1,5 @@  hostname r1 - -#debug bgp vpn leak-to-vrf -#debug bgp vpn leak-from-vrf -#debug bgp nht - -  router bgp 99 vrf DONNA    no bgp ebgp-requires-policy    address-family ipv4 unicast diff --git a/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf b/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf index 731a00829d..35038557df 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf +++ b/tests/topotests/bgp_vrf_route_leak_basic/r1/zebra.conf @@ -16,9 +16,3 @@ int dummy4    ip address 10.0.3.1/24    no shut  ! -int EVA -  no shut -! -int DONNA -  no shut -! diff --git a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py index be07c85997..191a0b53ec 100644 --- a/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py +++ b/tests/topotests/bgp_vrf_route_leak_basic/test_bgp-vrf-route-leak-basic.py @@ -29,7 +29,6 @@ import os  import sys  from functools import partial  import pytest -import time  CWD = os.path.dirname(os.path.realpath(__file__))  sys.path.append(os.path.join(CWD, "../")) @@ -78,117 +77,7 @@ def teardown_module(mod):      tgen.stop_topology() -def check_bgp_rib(router, vrf, in_fib): -    if in_fib: -        attr = [{"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]}] -    else: -        attr = [{"protocol": "bgp", "nexthops": []}] - -    if vrf == "DONNA": -        expect = { -            "10.0.0.0/24": [ -                { -                    "protocol": "connected", -                } -            ], -            "10.0.1.0/24": attr, -            "10.0.2.0/24": [{"protocol": "connected"}], -            "10.0.3.0/24": attr, -        } -    else: -        expect = { -            "10.0.0.0/24": attr, -            "10.0.1.0/24": [ -                { -                    "protocol": "connected", -                } -            ], -            "10.0.2.0/24": attr, -            "10.0.3.0/24": [ -                { -                    "protocol": "connected", -                } -            ], -        } - -    test_func = partial( -        topotest.router_json_cmp, router, "show ip route vrf %s json" % vrf, expect -    ) -    return topotest.run_and_expect(test_func, None, count=10, wait=0.5) - - -def check_bgp_fib(router, vrf, in_rib): -    # Check FIB -    # DONNA -    # 10.0.1.0/24 dev EVA proto bgp metric 20 -    # 10.0.3.0/24 dev EVA proto bgp metric 20 -    # EVA -    # 10.0.0.0/24 dev DONNA proto bgp metric 20 -    # 10.0.2.0/24 dev DONNA proto bgp metric 20 - -    if vrf == "DONNA": -        table = 1001 -        nh_vrf = "EVA" -    else: -        table = 1002 -        nh_vrf = "DONNA" - -    negate = "" if in_rib else "! " - -    cmd = "%sip route show table %s | grep %s" % (negate, table, nh_vrf) -    result = False -    retry = 5 -    output = "" -    while retry: -        retry -= 1 -        try: -            output = router.cmd_raises(cmd) -            result = True -            break -        except: -            time.sleep(0.1) - -    logger.info("VRF %s leaked FIB content %s: %s", vrf, cmd, output) - -    return result, output - - -def check_bgp_ping(router, vrf): -    if vrf == "DONNA": -        cmd = "ip vrf exec DONNA ping -c1 10.0.1.1 -I 10.0.0.1" -    else: -        cmd = "ip vrf exec EVA ping -c1 10.0.0.1 -I 10.0.1.1" - -    result = False -    retry = 5 -    output = "" -    while retry: -        retry -= 1 -        try: -            output = router.cmd_raises(cmd) -            result = True -            break -        except: -            time.sleep(0.1) - -    return result, output - - -def check_bgp_ping_own_ip(router): -    cmd = "ip vrf exec DONNA ping -c1 10.0.0.1 -I 10.0.0.1" - -    output = "" -    try: -        output = router.cmd_raises(cmd) -        result = True -    except: -        result = False -        pass - -    return result, output - - -def test_vrf_route_leak_test1(): +def test_vrf_route_leak():      logger.info("Ensure that routes are leaked back and forth")      tgen = get_topogen()      # Don't run this test if we have any failure. @@ -197,86 +86,53 @@ def test_vrf_route_leak_test1():      r1 = tgen.gears["r1"] -    result, output = check_bgp_ping_own_ip(r1) -    assert ( -        result -    ), "Ping from VRF fails - check https://bugzilla.kernel.org/show_bug.cgi?id=203483\n:{}".format( -        output -    ) - -    for vrf in ["EVA", "DONNA"]: -        result, diff = check_bgp_rib(r1, vrf, True) -        assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff) -        result, output = check_bgp_fib(r1, vrf, True) -        assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output) -        result, output = check_bgp_ping(r1, vrf) -        assert result, "Ping from VRF {} failed:\n{}".format(vrf, output) - +    # Test DONNA VRF. +    expect = { +        "10.0.0.0/24": [ +            { +                "protocol": "connected", +            } +        ], +        "10.0.1.0/24": [ +            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} +        ], +        "10.0.2.0/24": [{"protocol": "connected"}], +        "10.0.3.0/24": [ +            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} +        ], +    } -def test_vrf_route_leak_test2(): -    logger.info( -        "Ensure that leaked are still present after VRF iface IP address deletion" +    test_func = partial( +        topotest.router_json_cmp, r1, "show ip route vrf DONNA json", expect      ) -    tgen = get_topogen() -    # Don't run this test if we have any failure. -    if tgen.routers_have_failure(): -        pytest.skip(tgen.errors) - -    r1 = tgen.gears["r1"] - -    logger.info("Adding and removing an IPv4 address to EVA and DONNA VRF ifaces") -    r1.cmd("ip address add 1.1.1.1/32 dev EVA && ip address del 1.1.1.1/32 dev EVA") -    r1.cmd("ip address add 2.2.2.2/32 dev DONNA && ip address del 2.2.2.2/32 dev DONNA") - -    for vrf in ["EVA", "DONNA"]: -        result, diff = check_bgp_rib(r1, vrf, True) -        assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff) -        result, output = check_bgp_fib(r1, vrf, True) -        assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output) -        result, output = check_bgp_ping(r1, vrf) -        assert result, "Ping from VRF {} failed:\n{}".format(vrf, output) - - -def test_vrf_route_leak_test3(): -    logger.info("Ensure that setting down the VRF ifaces invalidates leaked routes") -    tgen = get_topogen() -    # Don't run this test if we have any failure. -    if tgen.routers_have_failure(): -        pytest.skip(tgen.errors) - -    r1 = tgen.gears["r1"] +    result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +    assert result, "BGP VRF DONNA check failed:\n{}".format(diff) + +    # Test EVA VRF. +    expect = { +        "10.0.0.0/24": [ +            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} +        ], +        "10.0.1.0/24": [ +            { +                "protocol": "connected", +            } +        ], +        "10.0.2.0/24": [ +            {"protocol": "bgp", "selected": True, "nexthops": [{"fib": True}]} +        ], +        "10.0.3.0/24": [ +            { +                "protocol": "connected", +            } +        ], +    } -    logger.info("Setting down EVA and DONNA VRF ifaces") -    r1.cmd("ip link set EVA down") -    r1.cmd("ip link set DONNA down") - -    for vrf in ["EVA", "DONNA"]: -        result, diff = check_bgp_rib(r1, vrf, False) -        assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff) -        result, output = check_bgp_fib(r1, vrf, False) -        assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output) - - -def test_vrf_route_leak_test4(): -    logger.info("Ensure that setting up the VRF ifaces validates leaked routes") -    tgen = get_topogen() -    # Don't run this test if we have any failure. -    if tgen.routers_have_failure(): -        pytest.skip(tgen.errors) - -    r1 = tgen.gears["r1"] - -    logger.info("Setting up EVA and DONNA VRF ifaces") -    r1.cmd("ip link set EVA up") -    r1.cmd("ip link set DONNA up") - -    for vrf in ["EVA", "DONNA"]: -        result, diff = check_bgp_rib(r1, vrf, True) -        assert result, "BGP RIB VRF {} check failed:\n{}".format(vrf, diff) -        result, output = check_bgp_fib(r1, vrf, True) -        assert result, "BGP FIB VRF {} check failed:\n{}".format(vrf, output) -        result, output = check_bgp_ping(r1, vrf) -        assert result, "Ping from VRF {} failed:\n{}".format(vrf, output) +    test_func = partial( +        topotest.router_json_cmp, r1, "show ip route vrf EVA json", expect +    ) +    result, diff = topotest.run_and_expect(test_func, None, count=10, wait=0.5) +    assert result, "BGP VRF EVA check failed:\n{}".format(diff)  def test_memory_leak(): diff --git a/tests/topotests/lib/bgprib.py b/tests/topotests/lib/bgprib.py index 01439373c5..35a57d0a99 100644 --- a/tests/topotests/lib/bgprib.py +++ b/tests/topotests/lib/bgprib.py @@ -37,7 +37,6 @@  from lib.lutil import luCommand, luResult, LUtil  import json  import re -import time  # gpz: get rib in json form and compare against desired routes  class BgpRib: @@ -49,15 +48,7 @@ class BgpRib:          for pfx in pfxtbl.keys():              if debug:                  self.log("trying pfx %s" % pfx) -            if "exist" in want and want["exist"] == False: -                if pfx == want["p"]: -                    if debug: -                        self.log("unexpected route: pfx=" + want["p"]) -                    return 0 -                if debug: -                    self.log("unwant pfx=" + want["p"] + ", not " + pfx) -                continue -            elif pfx != want["p"]: +            if pfx != want["p"]:                  if debug:                      self.log("want pfx=" + want["p"] + ", not " + pfx)                  continue @@ -84,67 +75,53 @@ class BgpRib:              if debug:                  self.log("missing route: pfx=" + want["p"] + ", nh=" + want["n"])              return 0 -        if "exist" in want and want["exist"] == False: -            return 1 -        return 0 -    def RequireVpnRoutes(self, target, title, wantroutes, retry=0, wait=1, debug=0): +    def RequireVpnRoutes(self, target, title, wantroutes, debug=0):          import json          logstr = "RequireVpnRoutes " + str(wantroutes) -        retry += 1 -        while retry: -            retry -= 1 -            # non json form for humans -            luCommand( -                target, -                'vtysh -c "show bgp ipv4 vpn"', -                ".", -                "None", -                "Get VPN RIB (non-json)", -            ) -            ret = luCommand( -                target, -                'vtysh -c "show bgp ipv4 vpn json"', -                ".*", -                "None", -                "Get VPN RIB (json)", -            ) -            if re.search(r"^\s*$", ret): -                # degenerate case: empty json means no routes -                if len(wantroutes) > 0: -                    luResult(target, False, title, logstr) -                    return -                luResult(target, True, title, logstr) -            rib = json.loads(ret) -            rds = rib["routes"]["routeDistinguishers"] -            for want in wantroutes: -                found = 0 -                if debug: -                    self.log("want rd %s" % want["rd"]) -                for rd in rds.keys(): -                    if rd != want["rd"]: -                        continue -                    if debug: -                        self.log("found rd %s" % rd) -                    table = rds[rd] -                    if self.routes_include_wanted(table, want, debug): -                        found = 1 -                        break -                if not found: -                    if retry: -                        break -                    luResult(target, False, title, logstr) -                    return -            if not found and retry: -                time.sleep(wait) -                continue +        # non json form for humans +        luCommand( +            target, +            'vtysh -c "show bgp ipv4 vpn"', +            ".", +            "None", +            "Get VPN RIB (non-json)", +        ) +        ret = luCommand( +            target, +            'vtysh -c "show bgp ipv4 vpn json"', +            ".*", +            "None", +            "Get VPN RIB (json)", +        ) +        if re.search(r"^\s*$", ret): +            # degenerate case: empty json means no routes +            if len(wantroutes) > 0: +                luResult(target, False, title, logstr) +                return              luResult(target, True, title, logstr) -            break +        rib = json.loads(ret) +        rds = rib["routes"]["routeDistinguishers"] +        for want in wantroutes: +            found = 0 +            if debug: +                self.log("want rd %s" % want["rd"]) +            for rd in rds.keys(): +                if rd != want["rd"]: +                    continue +                if debug: +                    self.log("found rd %s" % rd) +                table = rds[rd] +                if self.routes_include_wanted(table, want, debug): +                    found = 1 +                    break +            if not found: +                luResult(target, False, title, logstr) +                return +        luResult(target, True, title, logstr) -    def RequireUnicastRoutes( -        self, target, afi, vrf, title, wantroutes, retry=0, wait=1, debug=0 -    ): +    def RequireUnicastRoutes(self, target, afi, vrf, title, wantroutes, debug=0):          logstr = "RequireUnicastRoutes %s" % str(wantroutes)          vrfstr = ""          if vrf != "": @@ -153,62 +130,48 @@ class BgpRib:          if (afi != "ipv4") and (afi != "ipv6"):              self.log("ERROR invalid afi") -        retry += 1 -        while retry: -            retry -= 1 -            cmdstr = "show bgp %s %s unicast" % (vrfstr, afi) -            # non json form for humans -            cmd = 'vtysh -c "%s"' % cmdstr -            luCommand( -                target, cmd, ".", "None", "Get %s %s RIB (non-json)" % (vrfstr, afi) -            ) -            cmd = 'vtysh -c "%s json"' % cmdstr -            ret = luCommand( -                target, cmd, ".*", "None", "Get %s %s RIB (json)" % (vrfstr, afi) -            ) -            if re.search(r"^\s*$", ret): -                # degenerate case: empty json means no routes -                if len(wantroutes) > 0: -                    luResult(target, False, title, logstr) -                    return -                luResult(target, True, title, logstr) -            rib = json.loads(ret) -            try: -                table = rib["routes"] -                # KeyError: 'routes' probably means missing/bad VRF -            except KeyError as err: -                if vrf != "": -                    errstr = "-script ERROR: check if wrong vrf (%s)" % (vrf) -                else: -                    errstr = "-script ERROR: check if vrf missing" -                if retry: -                    time.sleep(wait) -                    continue -                luResult(target, False, title + errstr, logstr) +        cmdstr = "show bgp %s %s unicast" % (vrfstr, afi) +        # non json form for humans +        cmd = 'vtysh -c "%s"' % cmdstr +        luCommand(target, cmd, ".", "None", "Get %s %s RIB (non-json)" % (vrfstr, afi)) +        cmd = 'vtysh -c "%s json"' % cmdstr +        ret = luCommand( +            target, cmd, ".*", "None", "Get %s %s RIB (json)" % (vrfstr, afi) +        ) +        if re.search(r"^\s*$", ret): +            # degenerate case: empty json means no routes +            if len(wantroutes) > 0: +                luResult(target, False, title, logstr)                  return -            # if debug: -            #    self.log("table=%s" % table) -            for want in wantroutes: -                if debug: -                    self.log("want=%s" % want) -                if not self.routes_include_wanted(table, want, debug): -                    if retry: -                        time.sleep(wait) -                        continue -                    luResult(target, False, title, logstr) -                    return              luResult(target, True, title, logstr) -            break +        rib = json.loads(ret) +        try: +            table = rib["routes"] +            # KeyError: 'routes' probably means missing/bad VRF +        except KeyError as err: +            if vrf != "": +                errstr = "-script ERROR: check if wrong vrf (%s)" % (vrf) +            else: +                errstr = "-script ERROR: check if vrf missing" +            luResult(target, False, title + errstr, logstr) +            return +        # if debug: +        #    self.log("table=%s" % table) +        for want in wantroutes: +            if debug: +                self.log("want=%s" % want) +            if not self.routes_include_wanted(table, want, debug): +                luResult(target, False, title, logstr) +                return +        luResult(target, True, title, logstr)  BgpRib = BgpRib() -def bgpribRequireVpnRoutes(target, title, wantroutes, retry=0, wait=1, debug=0): -    BgpRib.RequireVpnRoutes(target, title, wantroutes, retry, wait, debug) +def bgpribRequireVpnRoutes(target, title, wantroutes, debug=0): +    BgpRib.RequireVpnRoutes(target, title, wantroutes, debug) -def bgpribRequireUnicastRoutes( -    target, afi, vrf, title, wantroutes, retry=0, wait=1, debug=0 -): -    BgpRib.RequireUnicastRoutes(target, afi, vrf, title, wantroutes, retry, wait, debug) +def bgpribRequireUnicastRoutes(target, afi, vrf, title, wantroutes, debug=0): +    BgpRib.RequireUnicastRoutes(target, afi, vrf, title, wantroutes, debug) diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt index 6bafbbb556..86c089ab3b 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r1/zebra-vrf-default.txt @@ -5,5 +5,5 @@ B>* 10.0.3.0/24 [20/20] via 10.0.30.3, r1-eth2 (vrf neno), weight 1, XX:XX:XX  O>* 10.0.4.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX  O   10.0.20.0/24 [110/10] is directly connected, r1-eth1, weight 1, XX:XX:XX  C>* 10.0.20.0/24 is directly connected, r1-eth1, XX:XX:XX -B>* 10.0.30.0/24 [20/0] is directly connected, neno (vrf neno), weight 1, XX:XX:XX +B>* 10.0.30.0/24 [20/0] is directly connected, r1-eth2 (vrf neno), weight 1, XX:XX:XX  O>* 10.0.40.0/24 [110/20] via 10.0.20.2, r1-eth1, weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt index 3ed6b1b3a1..9681d8a04e 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-default.txt @@ -7,4 +7,4 @@ B>* 10.0.4.0/24 [20/20] via 10.0.40.4, r2-eth2 (vrf ray), weight 1, XX:XX:XX  O   10.0.20.0/24 [110/10] is directly connected, r2-eth1, weight 1, XX:XX:XX  C>* 10.0.20.0/24 is directly connected, r2-eth1, XX:XX:XX  O>* 10.0.30.0/24 [110/20] via 10.0.20.1, r2-eth1, weight 1, XX:XX:XX -B>* 10.0.40.0/24 [20/0] is directly connected, ray (vrf ray), weight 1, XX:XX:XX +B>* 10.0.40.0/24 [20/0] is directly connected, r2-eth2 (vrf ray), weight 1, XX:XX:XX diff --git a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt index 4ad8441d85..ce9903ae71 100644 --- a/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt +++ b/tests/topotests/ospf_multi_vrf_bgp_route_leak/r2/zebra-vrf-ray.txt @@ -1,9 +1,9 @@  VRF ray:  B   10.0.1.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX -B   10.0.2.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX +B   10.0.2.0/24 [20/0] is directly connected, r2-eth0 (vrf default) inactive, weight 1, XX:XX:XX  B>* 10.0.3.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX  O>* 10.0.4.0/24 [110/20] via 10.0.40.4, r2-eth2, weight 1, XX:XX:XX -B   10.0.20.0/24 [20/0] is directly connected, lo (vrf default) inactive, weight 1, XX:XX:XX +B   10.0.20.0/24 [20/0] is directly connected, r2-eth1 (vrf default) inactive, weight 1, XX:XX:XX  B>* 10.0.30.0/24 [20/20] via 10.0.20.1, r2-eth1 (vrf default), weight 1, XX:XX:XX  O   10.0.40.0/24 [110/10] is directly connected, r2-eth2, weight 1, XX:XX:XX  C>* 10.0.40.0/24 is directly connected, r2-eth2, XX:XX:XX diff --git a/zebra/connected.c b/zebra/connected.c index 57c7f1925b..c01be58e82 100644 --- a/zebra/connected.c +++ b/zebra/connected.c @@ -387,14 +387,10 @@ void connected_down(struct interface *ifp, struct connected *ifc)  		.ifindex = ifp->ifindex,  		.vrf_id = ifp->vrf->vrf_id,  	}; -	struct zebra_vrf *zvrf, *zvrf_iter; -	uint32_t count_ipv4 = 0; +	struct zebra_vrf *zvrf; +	uint32_t count = 0;  	struct listnode *cnode;  	struct connected *c; -	struct route_table *table; -	struct route_node *rn; -	struct route_entry *re, *next; -	struct vrf *vrf;  	zvrf = ifp->vrf->info;  	if (!zvrf) { @@ -460,14 +456,12 @@ void connected_down(struct interface *ifp, struct connected *ifc)  		prefix_copy(&cp, CONNECTED_PREFIX(c));  		apply_mask(&cp); -		if (CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN)) -			continue; +		if (prefix_same(&p, &cp) && +		    !CHECK_FLAG(c->conf, ZEBRA_IFC_DOWN)) +			count++; -		if (prefix_same(&p, &cp)) +		if (count >= 1)  			return; - -		if (cp.family == AF_INET) -			count_ipv4++;  	}  	/* @@ -480,60 +474,6 @@ void connected_down(struct interface *ifp, struct connected *ifc)  	rib_delete(afi, SAFI_MULTICAST, zvrf->vrf->vrf_id, ZEBRA_ROUTE_CONNECT,  		   0, 0, &p, NULL, &nh, 0, zvrf->table_id, 0, 0, false); -	/* When the last IPv4 address of an interface is deleted, Linux removes -	 * all routes using this interface without any Netlink advertisement. -	 * The removed routes include those that only have this particular -	 * interface as a nexthop. Among those, remove the kernel one from the -	 * FRR RIB and reinstall the other that have been added from FRR. -	 */ -	if (afi == AFI_IP && count_ipv4 == 0 && if_is_operative(ifp)) { -		RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id) { -			zvrf_iter = vrf->info; - -			if (!zvrf_iter) -				continue; - -			table = zvrf_iter->table[AFI_IP][SAFI_UNICAST]; -			if (!table) -				continue; - -			for (rn = route_top(table); rn; -			     rn = srcdest_route_next(rn)) { -				RNODE_FOREACH_RE_SAFE (rn, re, next) { -					if (CHECK_FLAG(re->status, -						       ROUTE_ENTRY_REMOVED)) -						continue; -					if (re->nhe->ifp != ifp) -						continue; -					if (re->type == ZEBRA_ROUTE_KERNEL) -						rib_delete( -							afi, SAFI_UNICAST, -							zvrf_iter->vrf->vrf_id, -							re->type, 0, re->flags, -							&rn->p, NULL, &nh, 0, -							zvrf_iter->table_id, -							re->metric, -							re->distance, false); -					else if (re->type != -						 ZEBRA_ROUTE_CONNECT) { -						SET_FLAG(re->status, -							 ROUTE_ENTRY_CHANGED); -						UNSET_FLAG( -							re->status, -							ROUTE_ENTRY_INSTALLED); -						rib_add(afi, SAFI_UNICAST, -							zvrf_iter->vrf->vrf_id, -							re->type, 0, 0, &rn->p, -							NULL, &nh, re->nhe_id, -							zvrf_iter->table_id, -							re->metric, 0, -							re->distance, 0, false); -					} -				} -			} -		} -	} -  	/* Schedule LSP forwarding entries for processing, if appropriate. */  	if (zvrf->vrf->vrf_id == VRF_DEFAULT) {  		if (IS_ZEBRA_DEBUG_MPLS)  | 
