From 4865a82e2baf712cdfe2364129acd5f63073b37a Mon Sep 17 00:00:00 2001 From: Dawid Kopec Date: Wed, 12 Mar 2025 15:22:57 +0100 Subject: [PATCH] bgpd: check rmac and nh of evpn imported routes Check rmac and nh of new bestpath for evpn imported prefix before withdrawal. Currently when new bestpath is designated, evpn imported routes are being withdrawn from kernel causing downtime which length depends on amount of routes to process. Basically in a setup where multiple peers advertise identical evpn type-5 routes, if we clear session with any of them (and at least one is still up), we observe route withdrawals from kernel (even though we receive those routes from remaining peers). If the amount of routes is significant it causes a noticeable downtime before routes are readded to kernel. Also menitoned behavior (where routes are being withdrawn immediately even if other peers advertise them) has started to occur after backpressure bgp zebra client https://github.com/FRRouting/frr/pull/15524 Let's check rmac entry and nh of new selected bestpath and do not actually withdraw them from kernel if those two are the same. This fixes and issue where the same routes are being advertised by multiple peers and we clear session with one of them https://github.com/FRRouting/frr/issues/18240 Signed-off-by: Dawid Kopec --- bgpd/bgp_route.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_route.c b/bgpd/bgp_route.c index a7825165e7e8..334b02448875 100644 --- a/bgpd/bgp_route.c +++ b/bgpd/bgp_route.c @@ -3947,8 +3947,10 @@ static void bgp_process_main_one(struct bgp *bgp, struct bgp_dest *dest, * we need to withdraw the route first to clear * the nh neigh and the RMAC entry. */ - if (old_select && - is_route_parent_evpn(old_select)) + if (old_select && is_route_parent_evpn(old_select) && + old_select->attr->nexthop.s_addr != new_select->attr->nexthop.s_addr && + !memcmp(&old_select->attr->rmac, &new_select->attr->rmac, + sizeof(struct ethaddr))) bgp_zebra_withdraw_actual(dest, old_select, bgp); bgp_zebra_route_install(dest, new_select, bgp, true,