Commit c7f3489b authored by Jakub Kicinski's avatar Jakub Kicinski
Browse files

Merge branch 'net-bridge-multicast-per-port-eht-hosts-limit'

Nikolay Aleksandrov says:

====================
net: bridge: multicast: per-port EHT hosts limit

This set adds a simple configurable per-port EHT tracked hosts limit.
Patch 01 adds a default limit of 512 tracked hosts per-port, since the EHT
changes are still only in net-next that shouldn't be a problem. Then
patch 02 adds the ability to configure and retrieve the hosts limit
and to retrieve the current number of tracked hosts per port.
Let's be on the safe side and limit the number of tracked hosts by
default while allowing the user to increase that limit if needed.
====================

Link: https://lore.kernel.org/r/20210126093533.441338-1-razor@blackwall.org


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parents 1d96006d 2dba407f
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -525,6 +525,8 @@ enum {
	IFLA_BRPORT_BACKUP_PORT,
	IFLA_BRPORT_MRP_RING_OPEN,
	IFLA_BRPORT_MRP_IN_OPEN,
	IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
	IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
	__IFLA_BRPORT_MAX
};
#define IFLA_BRPORT_MAX (__IFLA_BRPORT_MAX - 1)
+1 −0
Original line number Diff line number Diff line
@@ -1608,6 +1608,7 @@ static void br_mc_disabled_update(struct net_device *dev, bool value)
int br_multicast_add_port(struct net_bridge_port *port)
{
	port->multicast_router = MDB_RTR_TYPE_TEMP_QUERY;
	port->multicast_eht_hosts_limit = BR_MCAST_DEFAULT_EHT_HOSTS_LIMIT;

	timer_setup(&port->multicast_router_timer,
		    br_multicast_router_expired, 0);
+22 −0
Original line number Diff line number Diff line
@@ -127,6 +127,8 @@ static void __eht_destroy_host(struct net_bridge_group_eht_host *eht_host)
{
	WARN_ON(!hlist_empty(&eht_host->set_entries));

	br_multicast_eht_hosts_dec(eht_host->pg);

	rb_erase(&eht_host->rb_node, &eht_host->pg->eht_host_tree);
	RB_CLEAR_NODE(&eht_host->rb_node);
	kfree(eht_host);
@@ -257,6 +259,9 @@ __eht_lookup_create_host(struct net_bridge_port_group *pg,
			return this;
	}

	if (br_multicast_eht_hosts_over_limit(pg))
		return NULL;

	eht_host = kzalloc(sizeof(*eht_host), GFP_ATOMIC);
	if (!eht_host)
		return NULL;
@@ -269,6 +274,8 @@ __eht_lookup_create_host(struct net_bridge_port_group *pg,
	rb_link_node(&eht_host->rb_node, parent, link);
	rb_insert_color(&eht_host->rb_node, &pg->eht_host_tree);

	br_multicast_eht_hosts_inc(pg);

	return eht_host;
}

@@ -854,3 +861,18 @@ bool br_multicast_eht_handle(struct net_bridge_port_group *pg,
out:
	return changed;
}

int br_multicast_eht_set_hosts_limit(struct net_bridge_port *p,
				     u32 eht_hosts_limit)
{
	struct net_bridge *br = p->br;

	if (!eht_hosts_limit)
		return -EINVAL;

	spin_lock_bh(&br->multicast_lock);
	p->multicast_eht_hosts_limit = eht_hosts_limit;
	spin_unlock_bh(&br->multicast_lock);

	return 0;
}
+18 −1
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@
#include "br_private_stp.h"
#include "br_private_cfm.h"
#include "br_private_tunnel.h"
#include "br_private_mcast_eht.h"

static int __get_num_vlan_infos(struct net_bridge_vlan_group *vg,
				u32 filter_mask)
@@ -199,6 +200,8 @@ static inline size_t br_port_info_size(void)
		+ nla_total_size(sizeof(u16))	/* IFLA_BRPORT_GROUP_FWD_MASK */
		+ nla_total_size(sizeof(u8))	/* IFLA_BRPORT_MRP_RING_OPEN */
		+ nla_total_size(sizeof(u8))	/* IFLA_BRPORT_MRP_IN_OPEN */
		+ nla_total_size(sizeof(u32))	/* IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT */
		+ nla_total_size(sizeof(u32))	/* IFLA_BRPORT_MCAST_EHT_HOSTS_CNT */
		+ 0;
}

@@ -283,7 +286,11 @@ static int br_port_fill_attrs(struct sk_buff *skb,

#ifdef CONFIG_BRIDGE_IGMP_SNOOPING
	if (nla_put_u8(skb, IFLA_BRPORT_MULTICAST_ROUTER,
		       p->multicast_router))
		       p->multicast_router) ||
	    nla_put_u32(skb, IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT,
			p->multicast_eht_hosts_limit) ||
	    nla_put_u32(skb, IFLA_BRPORT_MCAST_EHT_HOSTS_CNT,
			p->multicast_eht_hosts_cnt))
		return -EMSGSIZE;
#endif

@@ -820,6 +827,7 @@ static const struct nla_policy br_port_policy[IFLA_BRPORT_MAX + 1] = {
	[IFLA_BRPORT_NEIGH_SUPPRESS] = { .type = NLA_U8 },
	[IFLA_BRPORT_ISOLATED]	= { .type = NLA_U8 },
	[IFLA_BRPORT_BACKUP_PORT] = { .type = NLA_U32 },
	[IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT] = { .type = NLA_U32 },
};

/* Change the state of the port and notify spanning tree */
@@ -955,6 +963,15 @@ static int br_setport(struct net_bridge_port *p, struct nlattr *tb[])
		if (err)
			return err;
	}

	if (tb[IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT]) {
		u32 hlimit;

		hlimit = nla_get_u32(tb[IFLA_BRPORT_MCAST_EHT_HOSTS_LIMIT]);
		err = br_multicast_eht_set_hosts_limit(p, hlimit);
		if (err)
			return err;
	}
#endif

	if (tb[IFLA_BRPORT_GROUP_FWD_MASK]) {
+2 −0
Original line number Diff line number Diff line
@@ -310,6 +310,8 @@ struct net_bridge_port {
#if IS_ENABLED(CONFIG_IPV6)
	struct bridge_mcast_own_query	ip6_own_query;
#endif /* IS_ENABLED(CONFIG_IPV6) */
	u32				multicast_eht_hosts_limit;
	u32				multicast_eht_hosts_cnt;
	unsigned char			multicast_router;
	struct bridge_mcast_stats	__percpu *mcast_stats;
	struct timer_list		multicast_router_timer;
Loading