From 75223bcc52f96aae58863ddad1a88b745c906db0 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 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);