diff options
| author | anlan_cs <vic.lan@pica8.com> | 2023-05-18 20:49:16 +0800 |
|---|---|---|
| committer | anlan_cs <vic.lan@pica8.com> | 2023-06-03 09:27:53 +0800 |
| commit | 0c061db4d0827fb3162c33b0799e664576ee718e (patch) | |
| tree | d3ec3404aebd20e98e2e8006b47d6b36d0f02363 | |
| parent | ff82184faebac4f7de68018c54f0f55da2ebcf37 (diff) | |
bgpd: Fix missing deletion of evpn routes
Consider the scenario of evpn, the box has some type-5 ECMP routes.
After one of its remote peers is removed ( or down ), `show evpn rmac vni all`
kept no change **sometimes**, it means the rmac of the removed peer maybe is
still in this box, and the traffic will be wrongly forwarded to the removed
peer.
The root cause is that the best path selection for type-5 routes maybe
keep no change and the best path is not routed to the removed peer, so `bgpd`
wrongly doesn't tell `zebra` to remove ( withdraw ) the type-5 routes owned
by the removed peer.
So, add a new flag to force the deletion.
Signed-off-by: anlan_cs <vic.lan@pica8.com>
| -rw-r--r-- | bgpd/bgp_evpn.c | 3 | ||||
| -rw-r--r-- | bgpd/bgp_route.c | 13 | ||||
| -rw-r--r-- | bgpd/bgp_table.h | 1 |
3 files changed, 13 insertions, 4 deletions
diff --git a/bgpd/bgp_evpn.c b/bgpd/bgp_evpn.c index fc8889c175..66157eb8e2 100644 --- a/bgpd/bgp_evpn.c +++ b/bgpd/bgp_evpn.c @@ -3271,6 +3271,9 @@ static int uninstall_evpn_route_entry_in_vrf(struct bgp *bgp_vrf, bgp_aggregate_decrement(bgp_vrf, bgp_dest_get_prefix(dest), pi, afi, safi); + /* Force deletion */ + SET_FLAG(dest->flags, BGP_NODE_PROCESS_CLEAR); + /* Mark entry for deletion */ bgp_path_info_delete(dest, pi); diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index 7b7a7ad207..a2bd6131bd 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3227,10 +3227,11 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, /* If best route remains the same and this is not due to user-initiated * clear, see exactly what needs to be done. */ - if (old_select && old_select == new_select - && !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR) - && !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED) - && !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) { + if (old_select && old_select == new_select && + !CHECK_FLAG(dest->flags, BGP_NODE_USER_CLEAR) && + !CHECK_FLAG(dest->flags, BGP_NODE_PROCESS_CLEAR) && + !CHECK_FLAG(old_select->flags, BGP_PATH_ATTR_CHANGED) && + !bgp_addpath_is_addpath_used(&bgp->tx_addpath, afi, safi)) { if (bgp_zebra_has_route_changed(old_select)) { #ifdef ENABLE_BGP_VNC vnc_import_bgp_add_route(bgp, p, old_select); @@ -3284,6 +3285,10 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, */ UNSET_FLAG(dest->flags, BGP_NODE_USER_CLEAR); + /* If the process wants to force deletion this flag will be set + */ + UNSET_FLAG(dest->flags, BGP_NODE_PROCESS_CLEAR); + /* bestpath has changed; bump version */ if (old_select || new_select) { bgp_bump_version(dest); diff --git a/bgpd/bgp_table.h b/bgpd/bgp_table.h index 9027af5ba3..91941315f7 100644 --- a/bgpd/bgp_table.h +++ b/bgpd/bgp_table.h @@ -100,6 +100,7 @@ struct bgp_node { #define BGP_NODE_FIB_INSTALLED (1 << 6) #define BGP_NODE_LABEL_REQUESTED (1 << 7) #define BGP_NODE_SOFT_RECONFIG (1 << 8) +#define BGP_NODE_PROCESS_CLEAR (1 << 9) struct bgp_addpath_node_data tx_addpath; |
