bgpd: fix flushing ipv6 flowspec entries when peering stops

When a BGP flowspec peering stops, the BGP RIB entries for IPv6
flowspec entries are removed, but not the ZEBRA RIB IPv6 entries.

Actually, when calling bgp_zebra_withdraw() function call, only
the AFI_IP parameter is passed to the bgp_pbr_update_entry() function
in charge of the Flowspec add/delete in zebra. Fix this by passing
the AFI parameter to the bgp_zebra_withdraw() function.

Note that using topotest does not show up the problem as the
flowspec driver code is not present and was refused. Without that,
routes are not installed, and can not be uninstalled.

Fixes: 529efa2346 ("bgpd: allow flowspec entries to be announced to zebra")
Link: https://github.com/FRRouting/frr/pull/2025

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2024-02-07 22:34:34 +01:00
parent ab3d0846bd
commit ec6e09c271
3 changed files with 16 additions and 13 deletions

View file

@ -3520,7 +3520,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
*/
if (old_select &&
is_route_parent_evpn(old_select))
bgp_zebra_withdraw(p, old_select, bgp, safi);
bgp_zebra_withdraw(p, old_select, bgp, afi,
safi);
bgp_zebra_announce(dest, p, new_select, bgp, afi, safi);
} else {
@ -3530,7 +3531,8 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest,
|| old_select->sub_type == BGP_ROUTE_AGGREGATE
|| old_select->sub_type == BGP_ROUTE_IMPORTED))
bgp_zebra_withdraw(p, old_select, bgp, safi);
bgp_zebra_withdraw(p, old_select, bgp, afi,
safi);
}
}
@ -4427,7 +4429,7 @@ void bgp_update(struct peer *peer, const struct prefix *p, uint32_t addpath_id,
if (pi && pi->attr->rmap_table_id != new_attr.rmap_table_id) {
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED))
/* remove from RIB previous entry */
bgp_zebra_withdraw(p, pi, bgp, safi);
bgp_zebra_withdraw(p, pi, bgp, afi, safi);
}
if (peer->sort == BGP_PEER_EBGP) {
@ -6029,7 +6031,7 @@ bool bgp_inbound_policy_exists(struct peer *peer, struct bgp_filter *filter)
}
static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
safi_t safi)
afi_t afi, safi_t safi)
{
struct bgp_dest *dest;
struct bgp_path_info *pi;
@ -6053,7 +6055,8 @@ static void bgp_cleanup_table(struct bgp *bgp, struct bgp_table *table,
|| pi->sub_type == BGP_ROUTE_IMPORTED)) {
if (bgp_fibupd_safi(safi))
bgp_zebra_withdraw(p, pi, bgp, safi);
bgp_zebra_withdraw(p, pi, bgp, afi,
safi);
}
dest = bgp_path_info_reap(dest, pi);
@ -6071,7 +6074,7 @@ void bgp_cleanup_routes(struct bgp *bgp)
for (afi = AFI_IP; afi < AFI_MAX; ++afi) {
if (afi == AFI_L2VPN)
continue;
bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST],
bgp_cleanup_table(bgp, bgp->rib[afi][SAFI_UNICAST], afi,
SAFI_UNICAST);
/*
* VPN and ENCAP and EVPN tables are two-level (RD is top level)
@ -6083,7 +6086,7 @@ void bgp_cleanup_routes(struct bgp *bgp)
dest = bgp_route_next(dest)) {
table = bgp_dest_get_bgp_table_info(dest);
if (table != NULL) {
bgp_cleanup_table(bgp, table, safi);
bgp_cleanup_table(bgp, table, afi, safi);
bgp_table_finish(&table);
bgp_dest_set_bgp_table_info(dest, NULL);
dest = bgp_dest_unlock_node(dest);
@ -6096,7 +6099,7 @@ void bgp_cleanup_routes(struct bgp *bgp)
dest = bgp_route_next(dest)) {
table = bgp_dest_get_bgp_table_info(dest);
if (table != NULL) {
bgp_cleanup_table(bgp, table, safi);
bgp_cleanup_table(bgp, table, afi, safi);
bgp_table_finish(&table);
bgp_dest_set_bgp_table_info(dest, NULL);
dest = bgp_dest_unlock_node(dest);
@ -6110,7 +6113,7 @@ void bgp_cleanup_routes(struct bgp *bgp)
dest = bgp_route_next(dest)) {
table = bgp_dest_get_bgp_table_info(dest);
if (table != NULL) {
bgp_cleanup_table(bgp, table, SAFI_EVPN);
bgp_cleanup_table(bgp, table, afi, SAFI_EVPN);
bgp_table_finish(&table);
bgp_dest_set_bgp_table_info(dest, NULL);
dest = bgp_dest_unlock_node(dest);

View file

@ -1724,7 +1724,7 @@ void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi,
}
void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info,
struct bgp *bgp, safi_t safi)
struct bgp *bgp, afi_t afi, safi_t safi)
{
struct zapi_route api;
struct peer *peer;
@ -1743,7 +1743,7 @@ void bgp_zebra_withdraw(const struct prefix *p, struct bgp_path_info *info,
if (safi == SAFI_FLOWSPEC) {
peer = info->peer;
bgp_pbr_update_entry(peer->bgp, p, info, AFI_IP, safi, false);
bgp_pbr_update_entry(peer->bgp, p, info, afi, safi, false);
return;
}
@ -1784,7 +1784,7 @@ void bgp_zebra_withdraw_table_all_subtypes(struct bgp *bgp, afi_t afi, safi_t sa
if (CHECK_FLAG(pi->flags, BGP_PATH_SELECTED)
&& (pi->type == ZEBRA_ROUTE_BGP))
bgp_zebra_withdraw(bgp_dest_get_prefix(dest),
pi, bgp, safi);
pi, bgp, afi, safi);
}
}
}

View file

@ -34,7 +34,7 @@ extern void bgp_zebra_announce(struct bgp_dest *dest, const struct prefix *p,
extern void bgp_zebra_announce_table(struct bgp *bgp, afi_t afi, safi_t safi);
extern void bgp_zebra_withdraw(const struct prefix *p,
struct bgp_path_info *path, struct bgp *bgp,
safi_t safi);
afi_t afi, safi_t safi);
/* Announce routes of any bgp subtype of a table to zebra */
extern void bgp_zebra_announce_table_all_subtypes(struct bgp *bgp, afi_t afi,