diff options
| author | Philippe Guibert <philippe.guibert@6wind.com> | 2023-05-11 17:11:14 +0200 | 
|---|---|---|
| committer | Philippe Guibert <philippe.guibert@6wind.com> | 2023-07-13 12:05:15 +0200 | 
| commit | 58592be57783a3b24e7351af2a5afc61299768df (patch) | |
| tree | 9d2e62cd4365eb05d4719941171a523e39c6a27f /bgpd/bgp_nht.c | |
| parent | 1b34877af6f1f0b2f922a62ad60c933e7a1683c3 (diff) | |
bgpd: upon if event, evaluate bnc with matching nexthop
In BGP, when an interface event is detected or triggered,
the BNC that have a next-hop that matches the interface
are not evaluated.
The paths attached to the bnc context are evaluated in the
following situation:
- In the up event case, if at least one next-hop interface
matched the event interface.
- In the down event case, if there is no alternate next-hop
that does not use the event interface.
Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
Diffstat (limited to 'bgpd/bgp_nht.c')
| -rw-r--r-- | bgpd/bgp_nht.c | 40 | 
1 files changed, 39 insertions, 1 deletions
diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index fbb8831acd..992a7c1cda 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -717,11 +717,48 @@ static void bgp_nht_ifp_table_handle(struct bgp *bgp,  				     struct interface *ifp, bool up)  {  	struct bgp_nexthop_cache *bnc; +	struct nexthop *nhop; +	uint8_t other_nh_count; +	bool nhop_ll_found; +	bool nhop_found;  	frr_each (bgp_nexthop_cache, table, bnc) { -		if (bnc->ifindex_ipv6_ll != ifp->ifindex) +		other_nh_count = 0; +		nhop_ll_found = bnc->ifindex_ipv6_ll == ifp->ifindex; +		for (nhop = bnc->nexthop; nhop; nhop = nhop->next) { +			if (nhop->ifindex == bnc->ifindex_ipv6_ll) +				continue; + +			if (nhop->ifindex != ifp->ifindex) { +				other_nh_count++; +				continue; +			} +			if (nhop->vrf_id != ifp->vrf->vrf_id) { +				other_nh_count++; +				continue; +			} +			nhop_found = true; +		} + +		if (!nhop_found && !nhop_ll_found) +			/* The event interface does not match the nexthop cache +			 * entry */ +			continue; + +		if (!up && other_nh_count > 0) +			/* Down event ignored in case of multiple next-hop +			 * interfaces. The other might interfaces might be still +			 * up. The cases where all interfaces are down or a bnc +			 * is invalid are processed by a separate zebra rnh +			 * messages. +			 */  			continue; +		if (!nhop_ll_found) { +			evaluate_paths(bnc); +			continue; +		} +  		bnc->last_update = monotime(NULL);  		bnc->change_flags = 0; @@ -734,6 +771,7 @@ static void bgp_nht_ifp_table_handle(struct bgp *bgp,  		if (up) {  			SET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);  			SET_FLAG(bnc->change_flags, BGP_NEXTHOP_CHANGED); +			/* change nexthop number only for ll */  			bnc->nexthop_num = 1;  		} else {  			UNSET_FLAG(bnc->flags, BGP_NEXTHOP_PEER_NOTIFIED);  | 
