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