From 56fe240061ea63dfab41b3544248f51099323f91 Mon Sep 17 00:00:00 2001 From: Trey Aspelund Date: Tue, 31 Jan 2023 14:36:45 -0500 Subject: bgpd: only rescan EVPN tables if self-mac changes When processing an interface up/create event from zebra, we insert that interface's MAC address into the self_mac_hash used for dropping EVPN routes carrying a 'self mac' (RMAC ext-comm or MAC in Type-2 NLRI). However, we were unconditionally triggering a "rescan" of the EVPN RIB to ensure we handle routes that match the MAC - even if the MAC already existed in self_mac_hash (i.e. the change wasn't actionable). This adds logic to only kick off a "rescan" if the MAC learned from zebra is not already in the self_mac_hash. Signed-off-by: Trey Aspelund --- bgpd/bgp_mac.c | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_mac.c b/bgpd/bgp_mac.c index 6272bdb88..0398e4e8c 100644 --- a/bgpd/bgp_mac.c +++ b/bgpd/bgp_mac.c @@ -279,15 +279,29 @@ static void bgp_mac_remove_ifp_internal(struct bgp_self_mac *bsm, char *ifname, } } +/* Add/Update entry of the 'bgp mac hash' table. + * A rescan of the EVPN tables is only needed if + * a new hash bucket is allocated. + * Learning an existing mac on a new interface (or + * having an existing mac move from one interface to + * another) does not result in changes to self mac + * state, so we shouldn't trigger a rescan. + */ void bgp_mac_add_mac_entry(struct interface *ifp) { struct bgp_self_mac lookup; struct bgp_self_mac *bsm; struct bgp_self_mac *old_bsm; char *ifname; + bool mac_added = false; memcpy(&lookup.macaddr, &ifp->hw_addr, ETH_ALEN); - bsm = hash_get(bm->self_mac_hash, &lookup, bgp_mac_hash_alloc); + bsm = hash_lookup(bm->self_mac_hash, &lookup); + if (!bsm) { + bsm = hash_get(bm->self_mac_hash, &lookup, bgp_mac_hash_alloc); + /* mac is new, rescan needs to be triggered */ + mac_added = true; + } /* * Does this happen to be a move @@ -318,7 +332,8 @@ void bgp_mac_add_mac_entry(struct interface *ifp) listnode_add(bsm->ifp_list, ifname); } - bgp_mac_rescan_all_evpn_tables(&bsm->macaddr); + if (mac_added) + bgp_mac_rescan_all_evpn_tables(&bsm->macaddr); } void bgp_mac_del_mac_entry(struct interface *ifp) -- cgit v1.2.3