mirror of
				https://git.proxmox.com/git/mirror_frr
				synced 2025-11-04 01:27:09 +00:00 
			
		
		
		
	Merge pull request #13509 from pguibert6WIND/bgp_nht_other_if_cases
bgpd: upon if up event, evaluate bnc with matching nexthop
This commit is contained in:
		
						commit
						d6878aacef
					
				@ -43,9 +43,9 @@ int bgp_nexthop_cache_compare(const struct bgp_nexthop_cache *a,
 | 
			
		||||
	if (a->srte_color > b->srte_color)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	if (a->ifindex < b->ifindex)
 | 
			
		||||
	if (a->ifindex_ipv6_ll < b->ifindex_ipv6_ll)
 | 
			
		||||
		return -1;
 | 
			
		||||
	if (a->ifindex > b->ifindex)
 | 
			
		||||
	if (a->ifindex_ipv6_ll > b->ifindex_ipv6_ll)
 | 
			
		||||
		return 1;
 | 
			
		||||
 | 
			
		||||
	return prefix_cmp(&a->prefix, &b->prefix);
 | 
			
		||||
@ -65,7 +65,7 @@ struct bgp_nexthop_cache *bnc_new(struct bgp_nexthop_cache_head *tree,
 | 
			
		||||
	bnc = XCALLOC(MTYPE_BGP_NEXTHOP_CACHE,
 | 
			
		||||
		      sizeof(struct bgp_nexthop_cache));
 | 
			
		||||
	bnc->prefix = *prefix;
 | 
			
		||||
	bnc->ifindex = ifindex;
 | 
			
		||||
	bnc->ifindex_ipv6_ll = ifindex;
 | 
			
		||||
	bnc->srte_color = srte_color;
 | 
			
		||||
	bnc->tree = tree;
 | 
			
		||||
	LIST_INIT(&(bnc->paths));
 | 
			
		||||
@ -105,7 +105,7 @@ struct bgp_nexthop_cache *bnc_find(struct bgp_nexthop_cache_head *tree,
 | 
			
		||||
 | 
			
		||||
	bnc.prefix = *prefix;
 | 
			
		||||
	bnc.srte_color = srte_color;
 | 
			
		||||
	bnc.ifindex = ifindex;
 | 
			
		||||
	bnc.ifindex_ipv6_ll = ifindex;
 | 
			
		||||
	return bgp_nexthop_cache_find(tree, &bnc);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -857,8 +857,9 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
 | 
			
		||||
				json_object_string_add(
 | 
			
		||||
					json_gate, "interfaceName",
 | 
			
		||||
					ifindex2ifname(
 | 
			
		||||
						bnc->ifindex ? bnc->ifindex
 | 
			
		||||
							     : nexthop->ifindex,
 | 
			
		||||
						bnc->ifindex_ipv6_ll
 | 
			
		||||
							? bnc->ifindex_ipv6_ll
 | 
			
		||||
							: nexthop->ifindex,
 | 
			
		||||
						bgp->vrf_id));
 | 
			
		||||
				break;
 | 
			
		||||
			case NEXTHOP_TYPE_IPV4:
 | 
			
		||||
@ -869,8 +870,9 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
 | 
			
		||||
				json_object_string_add(
 | 
			
		||||
					json_gate, "interfaceName",
 | 
			
		||||
					ifindex2ifname(
 | 
			
		||||
						bnc->ifindex ? bnc->ifindex
 | 
			
		||||
							     : nexthop->ifindex,
 | 
			
		||||
						bnc->ifindex_ipv6_ll
 | 
			
		||||
							? bnc->ifindex_ipv6_ll
 | 
			
		||||
							: nexthop->ifindex,
 | 
			
		||||
						bgp->vrf_id));
 | 
			
		||||
				break;
 | 
			
		||||
			case NEXTHOP_TYPE_IPV4_IFINDEX:
 | 
			
		||||
@ -879,8 +881,9 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
 | 
			
		||||
				json_object_string_add(
 | 
			
		||||
					json_gate, "interfaceName",
 | 
			
		||||
					ifindex2ifname(
 | 
			
		||||
						bnc->ifindex ? bnc->ifindex
 | 
			
		||||
							     : nexthop->ifindex,
 | 
			
		||||
						bnc->ifindex_ipv6_ll
 | 
			
		||||
							? bnc->ifindex_ipv6_ll
 | 
			
		||||
							: nexthop->ifindex,
 | 
			
		||||
						bgp->vrf_id));
 | 
			
		||||
				break;
 | 
			
		||||
			case NEXTHOP_TYPE_BLACKHOLE:
 | 
			
		||||
@ -914,9 +917,9 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
 | 
			
		||||
		case NEXTHOP_TYPE_IPV6_IFINDEX:
 | 
			
		||||
			vty_out(vty, "  gate %pI6", &nexthop->gate.ipv6);
 | 
			
		||||
			if (nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX &&
 | 
			
		||||
			    bnc->ifindex)
 | 
			
		||||
			    bnc->ifindex_ipv6_ll)
 | 
			
		||||
				vty_out(vty, ", if %s\n",
 | 
			
		||||
					ifindex2ifname(bnc->ifindex,
 | 
			
		||||
					ifindex2ifname(bnc->ifindex_ipv6_ll,
 | 
			
		||||
						       bgp->vrf_id));
 | 
			
		||||
			else if (nexthop->ifindex)
 | 
			
		||||
				vty_out(vty, ", if %s\n",
 | 
			
		||||
@ -929,9 +932,9 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
 | 
			
		||||
		case NEXTHOP_TYPE_IPV4_IFINDEX:
 | 
			
		||||
			vty_out(vty, "  gate %pI4", &nexthop->gate.ipv4);
 | 
			
		||||
			if (nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX &&
 | 
			
		||||
			    bnc->ifindex)
 | 
			
		||||
			    bnc->ifindex_ipv6_ll)
 | 
			
		||||
				vty_out(vty, ", if %s\n",
 | 
			
		||||
					ifindex2ifname(bnc->ifindex,
 | 
			
		||||
					ifindex2ifname(bnc->ifindex_ipv6_ll,
 | 
			
		||||
						       bgp->vrf_id));
 | 
			
		||||
			else if (nexthop->ifindex)
 | 
			
		||||
				vty_out(vty, ", if %s\n",
 | 
			
		||||
@ -942,8 +945,9 @@ static void bgp_show_nexthops_detail(struct vty *vty, struct bgp *bgp,
 | 
			
		||||
			break;
 | 
			
		||||
		case NEXTHOP_TYPE_IFINDEX:
 | 
			
		||||
			vty_out(vty, "  if %s\n",
 | 
			
		||||
				ifindex2ifname(bnc->ifindex ? bnc->ifindex
 | 
			
		||||
							    : nexthop->ifindex,
 | 
			
		||||
				ifindex2ifname(bnc->ifindex_ipv6_ll
 | 
			
		||||
						       ? bnc->ifindex_ipv6_ll
 | 
			
		||||
						       : nexthop->ifindex,
 | 
			
		||||
					       bgp->vrf_id));
 | 
			
		||||
			break;
 | 
			
		||||
		case NEXTHOP_TYPE_BLACKHOLE:
 | 
			
		||||
 | 
			
		||||
@ -27,7 +27,7 @@ PREDECL_RBTREE_UNIQ(bgp_nexthop_cache);
 | 
			
		||||
/* BGP nexthop cache value structure. */
 | 
			
		||||
struct bgp_nexthop_cache {
 | 
			
		||||
	/* The ifindex of the outgoing interface *if* it's a v6 LL */
 | 
			
		||||
	ifindex_t ifindex;
 | 
			
		||||
	ifindex_t ifindex_ipv6_ll;
 | 
			
		||||
 | 
			
		||||
	/* RB-tree entry. */
 | 
			
		||||
	struct bgp_nexthop_cache_item entry;
 | 
			
		||||
 | 
			
		||||
@ -70,9 +70,10 @@ static int bgp_isvalid_nexthop_for_ebgp(struct bgp_nexthop_cache *bnc,
 | 
			
		||||
		if (nexthop->type == NEXTHOP_TYPE_IFINDEX ||
 | 
			
		||||
		    nexthop->type == NEXTHOP_TYPE_IPV4_IFINDEX ||
 | 
			
		||||
		    nexthop->type == NEXTHOP_TYPE_IPV6_IFINDEX) {
 | 
			
		||||
			ifp = if_lookup_by_index(
 | 
			
		||||
				bnc->ifindex ? bnc->ifindex : nexthop->ifindex,
 | 
			
		||||
				bnc->bgp->vrf_id);
 | 
			
		||||
			ifp = if_lookup_by_index(bnc->ifindex_ipv6_ll
 | 
			
		||||
							 ? bnc->ifindex_ipv6_ll
 | 
			
		||||
							 : nexthop->ifindex,
 | 
			
		||||
						 bnc->bgp->vrf_id);
 | 
			
		||||
		}
 | 
			
		||||
		if (!ifp)
 | 
			
		||||
			continue;
 | 
			
		||||
@ -91,9 +92,10 @@ static int bgp_isvalid_nexthop_for_mplsovergre(struct bgp_nexthop_cache *bnc,
 | 
			
		||||
 | 
			
		||||
	for (nexthop = bnc->nexthop; nexthop; nexthop = nexthop->next) {
 | 
			
		||||
		if (nexthop->type != NEXTHOP_TYPE_BLACKHOLE) {
 | 
			
		||||
			ifp = if_lookup_by_index(
 | 
			
		||||
				bnc->ifindex ? bnc->ifindex : nexthop->ifindex,
 | 
			
		||||
				bnc->bgp->vrf_id);
 | 
			
		||||
			ifp = if_lookup_by_index(bnc->ifindex_ipv6_ll
 | 
			
		||||
							 ? bnc->ifindex_ipv6_ll
 | 
			
		||||
							 : nexthop->ifindex,
 | 
			
		||||
						 bnc->bgp->vrf_id);
 | 
			
		||||
			if (ifp && (ifp->ll_type == ZEBRA_LLT_IPGRE ||
 | 
			
		||||
				    ifp->ll_type == ZEBRA_LLT_IP6GRE))
 | 
			
		||||
				break;
 | 
			
		||||
@ -137,8 +139,8 @@ static void bgp_unlink_nexthop_check(struct bgp_nexthop_cache *bnc)
 | 
			
		||||
	if (LIST_EMPTY(&(bnc->paths)) && !bnc->nht_info) {
 | 
			
		||||
		if (BGP_DEBUG(nht, NHT))
 | 
			
		||||
			zlog_debug("%s: freeing bnc %pFX(%d)(%u)(%s)", __func__,
 | 
			
		||||
				   &bnc->prefix, bnc->ifindex, bnc->srte_color,
 | 
			
		||||
				   bnc->bgp->name_pretty);
 | 
			
		||||
				   &bnc->prefix, bnc->ifindex_ipv6_ll,
 | 
			
		||||
				   bnc->srte_color, bnc->bgp->name_pretty);
 | 
			
		||||
		/* only unregister if this is the last nh for this prefix*/
 | 
			
		||||
		if (!bnc_existing_for_prefix(bnc))
 | 
			
		||||
			unregister_zebra_rnh(bnc);
 | 
			
		||||
@ -215,7 +217,7 @@ bgp_find_ipv6_nexthop_matching_peer(struct peer *peer)
 | 
			
		||||
			if (BGP_DEBUG(nht, NHT)) {
 | 
			
		||||
				zlog_debug(
 | 
			
		||||
					"Found bnc: %pFX(%u)(%u)(%p) for peer: %s(%s) %p",
 | 
			
		||||
					&bnc->prefix, bnc->ifindex,
 | 
			
		||||
					&bnc->prefix, bnc->ifindex_ipv6_ll,
 | 
			
		||||
					bnc->srte_color, bnc, peer->host,
 | 
			
		||||
					peer->bgp->name_pretty, peer);
 | 
			
		||||
			}
 | 
			
		||||
@ -362,15 +364,17 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
 | 
			
		||||
		bnc->bgp = bgp_nexthop;
 | 
			
		||||
		if (BGP_DEBUG(nht, NHT))
 | 
			
		||||
			zlog_debug("Allocated bnc %pFX(%d)(%u)(%s) peer %p",
 | 
			
		||||
				   &bnc->prefix, bnc->ifindex, bnc->srte_color,
 | 
			
		||||
				   bnc->bgp->name_pretty, peer);
 | 
			
		||||
				   &bnc->prefix, bnc->ifindex_ipv6_ll,
 | 
			
		||||
				   bnc->srte_color, bnc->bgp->name_pretty,
 | 
			
		||||
				   peer);
 | 
			
		||||
	} else {
 | 
			
		||||
		if (BGP_DEBUG(nht, NHT))
 | 
			
		||||
			zlog_debug(
 | 
			
		||||
				"Found existing bnc %pFX(%d)(%s) flags 0x%x ifindex %d #paths %d peer %p",
 | 
			
		||||
				&bnc->prefix, bnc->ifindex,
 | 
			
		||||
				bnc->bgp->name_pretty, bnc->flags, bnc->ifindex,
 | 
			
		||||
				bnc->path_count, bnc->nht_info);
 | 
			
		||||
				&bnc->prefix, bnc->ifindex_ipv6_ll,
 | 
			
		||||
				bnc->bgp->name_pretty, bnc->flags,
 | 
			
		||||
				bnc->ifindex_ipv6_ll, bnc->path_count,
 | 
			
		||||
				bnc->nht_info);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pi && is_route_parent_evpn(pi))
 | 
			
		||||
@ -417,10 +421,10 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
 | 
			
		||||
		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
 | 
			
		||||
		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
 | 
			
		||||
	}
 | 
			
		||||
	if (peer && (bnc->ifindex != ifindex)) {
 | 
			
		||||
	if (peer && (bnc->ifindex_ipv6_ll != ifindex)) {
 | 
			
		||||
		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
 | 
			
		||||
		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_VALID);
 | 
			
		||||
		bnc->ifindex = ifindex;
 | 
			
		||||
		bnc->ifindex_ipv6_ll = ifindex;
 | 
			
		||||
	}
 | 
			
		||||
	if (bgp_route->inst_type == BGP_INSTANCE_TYPE_VIEW) {
 | 
			
		||||
		SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
 | 
			
		||||
@ -549,8 +553,8 @@ static void bgp_process_nexthop_update(struct bgp_nexthop_cache *bnc,
 | 
			
		||||
		zlog_debug(
 | 
			
		||||
			"%s(%u): Rcvd NH update %pFX(%u)(%u) - metric %d/%d #nhops %d/%d flags %s",
 | 
			
		||||
			bnc->bgp->name_pretty, bnc->bgp->vrf_id, &nhr->prefix,
 | 
			
		||||
			bnc->ifindex, bnc->srte_color, nhr->metric, bnc->metric,
 | 
			
		||||
			nhr->nexthop_num, bnc->nexthop_num,
 | 
			
		||||
			bnc->ifindex_ipv6_ll, bnc->srte_color, nhr->metric,
 | 
			
		||||
			bnc->metric, nhr->nexthop_num, bnc->nexthop_num,
 | 
			
		||||
			bgp_nexthop_dump_bnc_flags(bnc, bnc_buf,
 | 
			
		||||
						   sizeof(bnc_buf)));
 | 
			
		||||
	}
 | 
			
		||||
@ -703,9 +707,40 @@ 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_found;
 | 
			
		||||
 | 
			
		||||
	frr_each (bgp_nexthop_cache, table, bnc) {
 | 
			
		||||
		if (bnc->ifindex != ifp->ifindex)
 | 
			
		||||
		other_nh_count = 0;
 | 
			
		||||
		nhop_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)
 | 
			
		||||
			/* 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;
 | 
			
		||||
 | 
			
		||||
		bnc->last_update = monotime(NULL);
 | 
			
		||||
@ -813,9 +848,9 @@ void bgp_nht_interface_events(struct peer *peer)
 | 
			
		||||
	if (!bnc)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (bnc->ifindex)
 | 
			
		||||
	if (bnc->ifindex_ipv6_ll)
 | 
			
		||||
		event_add_event(bm->master, bgp_nht_ifp_initial, bnc->bgp,
 | 
			
		||||
				bnc->ifindex, NULL);
 | 
			
		||||
				bnc->ifindex_ipv6_ll, NULL);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void bgp_parse_nexthop_update(int command, vrf_id_t vrf_id)
 | 
			
		||||
@ -1074,7 +1109,7 @@ static void register_zebra_rnh(struct bgp_nexthop_cache *bnc)
 | 
			
		||||
	if (bnc->flags & BGP_NEXTHOP_REGISTERED)
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (bnc->ifindex) {
 | 
			
		||||
	if (bnc->ifindex_ipv6_ll) {
 | 
			
		||||
		SET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@ -1095,7 +1130,7 @@ static void unregister_zebra_rnh(struct bgp_nexthop_cache *bnc)
 | 
			
		||||
	if (!CHECK_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED))
 | 
			
		||||
		return;
 | 
			
		||||
 | 
			
		||||
	if (bnc->ifindex) {
 | 
			
		||||
	if (bnc->ifindex_ipv6_ll) {
 | 
			
		||||
		UNSET_FLAG(bnc->flags, BGP_NEXTHOP_REGISTERED);
 | 
			
		||||
		return;
 | 
			
		||||
	}
 | 
			
		||||
@ -1128,7 +1163,7 @@ void evaluate_paths(struct bgp_nexthop_cache *bnc)
 | 
			
		||||
 | 
			
		||||
		zlog_debug(
 | 
			
		||||
			"NH update for %pFX(%d)(%u)(%s) - flags %s chgflags %s- evaluate paths",
 | 
			
		||||
			&bnc->prefix, bnc->ifindex, bnc->srte_color,
 | 
			
		||||
			&bnc->prefix, bnc->ifindex_ipv6_ll, bnc->srte_color,
 | 
			
		||||
			bnc->bgp->name_pretty,
 | 
			
		||||
			bgp_nexthop_dump_bnc_flags(bnc, bnc_buf,
 | 
			
		||||
						   sizeof(bnc_buf)),
 | 
			
		||||
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user