Commit ddd1ad68 authored by Johannes Nixdorf's avatar Johannes Nixdorf Committed by Jakub Kicinski

net: bridge: Add netlink knobs for number / max learned FDB entries

The previous patch added accounting and a limit for the number of
dynamically learned FDB entries per bridge. However it did not provide
means to actually configure those bounds or read back the count. This
patch does that.

Two new netlink attributes are added for the accounting and limit of
dynamically learned FDB entries:
 - IFLA_BR_FDB_N_LEARNED (RO) for the number of entries accounted for
   a single bridge.
 - IFLA_BR_FDB_MAX_LEARNED (RW) for the configured limit of entries for
   the bridge.

The new attributes are used like this:

 # ip link add name br up type bridge fdb_max_learned 256
 # ip link add name v1 up master br type veth peer v2
 # ip link set up dev v2
 # mausezahn -a rand -c 1024 v2
 0.01 seconds (90877 packets per second
 # bridge fdb | grep -v permanent | wc -l
 256
 # ip -d link show dev br
 13: br: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 [...]
     [...] fdb_n_learned 256 fdb_max_learned 256
Signed-off-by: default avatarJohannes Nixdorf <jnixdorf-oss@avm.de>
Acked-by: default avatarNikolay Aleksandrov <razor@blackwall.org>
Reviewed-by: default avatarIdo Schimmel <idosch@nvidia.com>
Link: https://lore.kernel.org/r/20231016-fdb_limit-v5-3-32cddff87758@avm.deSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent bdb4dfda
...@@ -510,6 +510,8 @@ enum { ...@@ -510,6 +510,8 @@ enum {
IFLA_BR_VLAN_STATS_PER_PORT, IFLA_BR_VLAN_STATS_PER_PORT,
IFLA_BR_MULTI_BOOLOPT, IFLA_BR_MULTI_BOOLOPT,
IFLA_BR_MCAST_QUERIER_STATE, IFLA_BR_MCAST_QUERIER_STATE,
IFLA_BR_FDB_N_LEARNED,
IFLA_BR_FDB_MAX_LEARNED,
__IFLA_BR_MAX, __IFLA_BR_MAX,
}; };
......
...@@ -1265,6 +1265,8 @@ static const struct nla_policy br_policy[IFLA_BR_MAX + 1] = { ...@@ -1265,6 +1265,8 @@ static const struct nla_policy br_policy[IFLA_BR_MAX + 1] = {
[IFLA_BR_VLAN_STATS_PER_PORT] = { .type = NLA_U8 }, [IFLA_BR_VLAN_STATS_PER_PORT] = { .type = NLA_U8 },
[IFLA_BR_MULTI_BOOLOPT] = [IFLA_BR_MULTI_BOOLOPT] =
NLA_POLICY_EXACT_LEN(sizeof(struct br_boolopt_multi)), NLA_POLICY_EXACT_LEN(sizeof(struct br_boolopt_multi)),
[IFLA_BR_FDB_N_LEARNED] = { .type = NLA_REJECT },
[IFLA_BR_FDB_MAX_LEARNED] = { .type = NLA_U32 },
}; };
static int br_changelink(struct net_device *brdev, struct nlattr *tb[], static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
...@@ -1539,6 +1541,12 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[], ...@@ -1539,6 +1541,12 @@ static int br_changelink(struct net_device *brdev, struct nlattr *tb[],
return err; return err;
} }
if (data[IFLA_BR_FDB_MAX_LEARNED]) {
u32 val = nla_get_u32(data[IFLA_BR_FDB_MAX_LEARNED]);
WRITE_ONCE(br->fdb_max_learned, val);
}
return 0; return 0;
} }
...@@ -1593,6 +1601,8 @@ static size_t br_get_size(const struct net_device *brdev) ...@@ -1593,6 +1601,8 @@ static size_t br_get_size(const struct net_device *brdev)
nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_TOPOLOGY_CHANGE_TIMER */ nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_TOPOLOGY_CHANGE_TIMER */
nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_GC_TIMER */ nla_total_size_64bit(sizeof(u64)) + /* IFLA_BR_GC_TIMER */
nla_total_size(ETH_ALEN) + /* IFLA_BR_GROUP_ADDR */ nla_total_size(ETH_ALEN) + /* IFLA_BR_GROUP_ADDR */
nla_total_size(sizeof(u32)) + /* IFLA_BR_FDB_N_LEARNED */
nla_total_size(sizeof(u32)) + /* IFLA_BR_FDB_MAX_LEARNED */
#ifdef CONFIG_BRIDGE_IGMP_SNOOPING #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_ROUTER */ nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_ROUTER */
nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_SNOOPING */ nla_total_size(sizeof(u8)) + /* IFLA_BR_MCAST_SNOOPING */
...@@ -1668,7 +1678,10 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev) ...@@ -1668,7 +1678,10 @@ static int br_fill_info(struct sk_buff *skb, const struct net_device *brdev)
nla_put_u8(skb, IFLA_BR_TOPOLOGY_CHANGE_DETECTED, nla_put_u8(skb, IFLA_BR_TOPOLOGY_CHANGE_DETECTED,
br->topology_change_detected) || br->topology_change_detected) ||
nla_put(skb, IFLA_BR_GROUP_ADDR, ETH_ALEN, br->group_addr) || nla_put(skb, IFLA_BR_GROUP_ADDR, ETH_ALEN, br->group_addr) ||
nla_put(skb, IFLA_BR_MULTI_BOOLOPT, sizeof(bm), &bm)) nla_put(skb, IFLA_BR_MULTI_BOOLOPT, sizeof(bm), &bm) ||
nla_put_u32(skb, IFLA_BR_FDB_N_LEARNED,
atomic_read(&br->fdb_n_learned)) ||
nla_put_u32(skb, IFLA_BR_FDB_MAX_LEARNED, br->fdb_max_learned))
return -EMSGSIZE; return -EMSGSIZE;
#ifdef CONFIG_BRIDGE_VLAN_FILTERING #ifdef CONFIG_BRIDGE_VLAN_FILTERING
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment