From bea96b9f07200f55bff014f0162044748fa79574 Mon Sep 17 00:00:00 2001 From: Jonas Gorski Date: Thu, 19 Dec 2024 09:49:59 +0100 Subject: [PATCH] cnetlink: ignore locked fdb entries Treat locked fdb entries like they don't exist. This means that we need to treat locked entries that loose their locked flag as if they were new fdb entries. Signed-off-by: Jonas Gorski --- src/netlink/cnetlink.cc | 36 +++++++++++++++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/src/netlink/cnetlink.cc b/src/netlink/cnetlink.cc index 6d421910..94540a29 100644 --- a/src/netlink/cnetlink.cc +++ b/src/netlink/cnetlink.cc @@ -1718,9 +1718,16 @@ bool cnetlink::check_ll_neigh(rtnl_neigh *neigh) noexcept { // TODO this function could already be moved to nl_bridge void cnetlink::neigh_ll_created(rtnl_neigh *neigh) noexcept { + uint32_t ext_flags; + if (!check_ll_neigh(neigh)) return; + /* ignore locked fdb entries */ + if (!rtnl_neigh_get_ext_flags(neigh, &ext_flags) && + ext_flags & NTF_EXT_LOCKED) + return; + int ifindex = rtnl_neigh_get_ifindex(neigh); rtnl_link *base_link = get_link(ifindex, AF_UNSPEC); // either tap, vxlan, ... rtnl_link *br_link = get_link(ifindex, AF_BRIDGE); @@ -1750,9 +1757,26 @@ void cnetlink::neigh_ll_created(rtnl_neigh *neigh) noexcept { void cnetlink::neigh_ll_updated(rtnl_neigh *old_neigh, rtnl_neigh *new_neigh) noexcept { + bool old_locked, new_locked, update = true; + uint32_t ext_flags; + if (!check_ll_neigh(old_neigh) || !check_ll_neigh(new_neigh)) return; + old_locked = !rtnl_neigh_get_ext_flags(old_neigh, &ext_flags) && + ext_flags & NTF_EXT_LOCKED; + new_locked = !rtnl_neigh_get_ext_flags(old_neigh, &ext_flags) && + ext_flags & NTF_EXT_LOCKED; + + if (old_locked) { + /* ignore still locked entry */ + if (new_locked) + return; + + /* we ignored the locked entry creation */ + update = false; + } + int old_ifindex = rtnl_neigh_get_ifindex(old_neigh); rtnl_link *old_base_link = get_link(old_ifindex, AF_UNSPEC); // either tap, vxlan, ... @@ -1765,14 +1789,24 @@ void cnetlink::neigh_ll_updated(rtnl_neigh *old_neigh, LOG(WARNING) << __FUNCTION__ << ": neighbor update for VXLAN neighbors not supported"; } else { - bridge->add_neigh_to_fdb(new_neigh, true); + if (new_locked) + bridge->remove_neigh_from_fdb(new_neigh); + else + bridge->add_neigh_to_fdb(new_neigh, update); } } void cnetlink::neigh_ll_deleted(rtnl_neigh *neigh) noexcept { + uint32_t ext_flags; + if (!check_ll_neigh(neigh)) return; + /* ignore locked fdb entries */ + if (!rtnl_neigh_get_ext_flags(neigh, &ext_flags) && + ext_flags & NTF_EXT_LOCKED) + return; + int ifindex = rtnl_neigh_get_ifindex(neigh); rtnl_link *l = get_link(ifindex, AF_UNSPEC);