diff options
author | Nikolay Aleksandrov <nikolay@cumulusnetworks.com> | 2020-09-07 12:56:07 +0300 |
---|---|---|
committer | Jakub Kicinski <kuba@kernel.org> | 2020-09-07 13:16:34 -0700 |
commit | 8b671779b7e2db78664cf05a03ced49bcaa37874 (patch) | |
tree | 8ebb059cb1d490b9c7c792b6d53992e5c0aa92ba /net/bridge/br_private.h | |
parent | 681590bd4cdc74f17dfbdfa792f027772e149e1d (diff) | |
download | linux-8b671779b7e2db78664cf05a03ced49bcaa37874.tar.gz |
net: bridge: mcast: add support for group source list
Initial functions for group source lists which are needed for IGMPv3
and MLDv2 include/exclude lists. Both IPv4 and IPv6 sources are supported.
User-added mdb entries are created with exclude filter mode, we can
extend that later to allow user-supplied mode. When group src entries
are deleted, they're freed from a workqueue to make sure their timers
are not still running. Source entries are protected by the multicast_lock
and rcu. The number of src groups per port group is limited to 32.
v4: use the new port group del function directly
add igmpv2/mldv1 bool to denote if the entry was added in those
modes, it will later replace the old update_timer bool
v3: add IPv6 support
v2: allow src groups to be traversed under rcu
Signed-off-by: Nikolay Aleksandrov <nikolay@cumulusnetworks.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Diffstat (limited to 'net/bridge/br_private.h')
-rw-r--r-- | net/bridge/br_private.h | 26 |
1 files changed, 25 insertions, 1 deletions
diff --git a/net/bridge/br_private.h b/net/bridge/br_private.h index 800e9b91483c..eab8952a332a 100644 --- a/net/bridge/br_private.h +++ b/net/bridge/br_private.h @@ -214,13 +214,34 @@ struct net_bridge_fdb_entry { #define MDB_PG_FLAGS_OFFLOAD BIT(1) #define MDB_PG_FLAGS_FAST_LEAVE BIT(2) +#define PG_SRC_ENT_LIMIT 32 + +#define BR_SGRP_F_DELETE BIT(0) +#define BR_SGRP_F_SEND BIT(1) + +struct net_bridge_group_src { + struct hlist_node node; + + struct br_ip addr; + struct net_bridge_port_group *pg; + u8 flags; + struct timer_list timer; + + struct net_bridge *br; + struct hlist_node del_node; + struct rcu_head rcu; +}; + struct net_bridge_port_group { struct net_bridge_port *port; struct net_bridge_port_group __rcu *next; struct br_ip addr; unsigned char eth_addr[ETH_ALEN] __aligned(2); unsigned char flags; + unsigned char filter_mode; + struct hlist_head src_list; + unsigned int src_ents; struct timer_list timer; struct hlist_node mglist; @@ -410,6 +431,7 @@ struct net_bridge { struct rhashtable mdb_hash_tbl; + struct hlist_head src_gc_list; struct hlist_head mdb_list; struct hlist_head router_list; @@ -423,6 +445,7 @@ struct net_bridge { struct bridge_mcast_own_query ip6_own_query; struct bridge_mcast_querier ip6_querier; #endif /* IS_ENABLED(CONFIG_IPV6) */ + struct work_struct src_gc_work; #endif struct timer_list hello_timer; @@ -770,7 +793,8 @@ br_multicast_new_group(struct net_bridge *br, struct br_ip *group); struct net_bridge_port_group * br_multicast_new_port_group(struct net_bridge_port *port, struct br_ip *group, struct net_bridge_port_group __rcu *next, - unsigned char flags, const unsigned char *src); + unsigned char flags, const unsigned char *src, + u8 filter_mode); int br_mdb_hash_init(struct net_bridge *br); void br_mdb_hash_fini(struct net_bridge *br); void br_mdb_notify(struct net_device *dev, struct net_bridge_port *port, |