diff options
author | Johannes Nixdorf <jnixdorf-oss@avm.de> | 2023-10-16 15:27:21 +0200 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2023-10-17 17:39:01 -0700 |
commit | bdb4dfda3b41649c41cc2222857c9207fc47a950 (patch) | |
tree | 417f72c395f9743c1c0226a4d51097dc5344a9a8 /net/bridge/br_private.h | |
parent | cbf51acbc5d50341290c79c97bda8cf46f5c4f22 (diff) | |
download | linux-bdb4dfda3b41649c41cc2222857c9207fc47a950.tar.gz linux-bdb4dfda3b41649c41cc2222857c9207fc47a950.tar.bz2 linux-bdb4dfda3b41649c41cc2222857c9207fc47a950.zip |
net: bridge: Track and limit dynamically learned FDB entries
A malicious actor behind one bridge port may spam the kernel with packets
with a random source MAC address, each of which will create an FDB entry,
each of which is a dynamic allocation in the kernel.
There are roughly 2^48 different MAC addresses, further limited by the
rhashtable they are stored in to 2^31. Each entry is of the type struct
net_bridge_fdb_entry, which is currently 128 bytes big. This means the
maximum amount of memory allocated for FDB entries is 2^31 * 128B =
256GiB, which is too much for most computers.
Mitigate this by maintaining a per bridge count of those automatically
generated entries in fdb_n_learned, and a limit in fdb_max_learned. If
the limit is hit new entries are not learned anymore.
For backwards compatibility the default setting of 0 disables the limit.
User-added entries by netlink or from bridge or bridge port addresses
are never blocked and do not count towards that limit.
Introduce a new fdb entry flag BR_FDB_DYNAMIC_LEARNED to keep track of
whether an FDB entry is included in the count. The flag is enabled for
dynamically learned entries, and disabled for all other entries. This
should be equivalent to BR_FDB_ADDED_BY_USER and BR_FDB_LOCAL being unset,
but contrary to the two flags it can be toggled atomically.
Atomicity is required here, as there are multiple callers that modify the
flags, but are not under a common lock (br_fdb_update is the exception
for br->hash_lock, br_fdb_external_learn_add for RTNL).
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Signed-off-by: Johannes Nixdorf <jnixdorf-oss@avm.de>
Link: https://lore.kernel.org/r/20231016-fdb_limit-v5-2-32cddff87758@avm.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/bridge/br_private.h')
-rw-r--r-- | net/bridge/br_private.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index cbbe35278459..27a7a06660f3 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -274,6 +274,7 @@ enum { BR_FDB_NOTIFY, BR_FDB_NOTIFY_INACTIVE, BR_FDB_LOCKED, + BR_FDB_DYNAMIC_LEARNED, }; struct net_bridge_fdb_key { @@ -555,6 +556,9 @@ struct net_bridge { struct kobject *ifobj; u32 auto_cnt; + atomic_t fdb_n_learned; + u32 fdb_max_learned; + #ifdef CONFIG_NET_SWITCHDEV /* Counter used to make sure that hardware domains get unique * identifiers in case a bridge spans multiple switchdev instances. |