Skip to content

Conversation

@KanjiMonster
Copy link
Contributor

Properly handle L2 neighbors moving between ports without corrupting the cache.

Description

Due to bad assumptions, the code handling L2 neighbors moving between ports corrupts the local neighbor cache, poentially breaking additional moves or maybe even timouts.

  1. When updating the port, updating the cache fails as the new entry is considered identical.
  2. subsequently when moving to the original port back we think we already have a flow, and don't update it again.
  3. nl_bridge::fdb_timeout() does not check the port of the returned entry from the cache, potentially deleting the wrong neighbor.

Fix both issues to allow proper updating of flows when L2 neighbors move between ports.

How Has This Been Tested?

Extending the neighbor moving test to move twice, which then fails.

nl_cache_search() uses nl_object_identical()[1] to lookup the target
object. This limits the check to unique attributes, which does not
include the ifindex [2].

Therefore nl_cache_search() may return an object for a different port,
in case it moved, which we then may wrongly remove from the cache.

So add a check for the ifindex of the hit before attempting to delete
any neighbors or cache entries.

We could have also alternatively used nl_cache_find() which uses all
attributes, but this function iterates over the whole cache intead of
using the hashtable if possible, so would be much less performant.

[1] https://github.com/thom311/libnl/blob/libnl3_7_0/lib/cache.c#L1113-L1114
[2] https://github.com/thom311/libnl/blob/libnl3_7_0/lib/route/neigh.c#L323

Fixes: 291591d ("l2 aging added")
Signed-off-by: Jonas Gorski <jonas.gorski@bisdn.de>
Calling nl_cache_add() for an object cache that supports hashing will
refuse to add an object if it already contains an "identical" object,
where identical is considered having the same master, vid and mac for
AF_BRIDGE neighbors.

Therefore we need to remove the old entry first before we can add an
updated one when we handle neighbors moving between ports.

Without it, we may fail to update the flow if the port moves back again
to its original port, as the outdated entry makes us think we already
have a flow for it.

Fixes: de9b16e ("nl_bridge: take over fdb entries instead of creating them")
Signed-off-by: Jonas Gorski <jonas.gorski@bisdn.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants