1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright (c) 2020, Nikolay Aleksandrov <nikolay@nvidia.com>
3  */
4 #ifndef _BR_PRIVATE_MCAST_EHT_H_
5 #define _BR_PRIVATE_MCAST_EHT_H_
6 
7 #define BR_MCAST_DEFAULT_EHT_HOSTS_LIMIT 512
8 
9 union net_bridge_eht_addr {
10 	__be32				ip4;
11 #if IS_ENABLED(CONFIG_IPV6)
12 	struct in6_addr			ip6;
13 #endif
14 };
15 
16 /* single host's list of set entries and filter_mode */
17 struct net_bridge_group_eht_host {
18 	struct rb_node			rb_node;
19 
20 	union net_bridge_eht_addr	h_addr;
21 	struct hlist_head		set_entries;
22 	unsigned int			num_entries;
23 	unsigned char			filter_mode;
24 	struct net_bridge_port_group	*pg;
25 };
26 
27 /* (host, src entry) added to a per-src set and host's list */
28 struct net_bridge_group_eht_set_entry {
29 	struct rb_node			rb_node;
30 	struct hlist_node		host_list;
31 
32 	union net_bridge_eht_addr	h_addr;
33 	struct timer_list		timer;
34 	struct net_bridge		*br;
35 	struct net_bridge_group_eht_set	*eht_set;
36 	struct net_bridge_group_eht_host *h_parent;
37 	struct net_bridge_mcast_gc	mcast_gc;
38 };
39 
40 /* per-src set */
41 struct net_bridge_group_eht_set {
42 	struct rb_node			rb_node;
43 
44 	union net_bridge_eht_addr	src_addr;
45 	struct rb_root			entry_tree;
46 	struct timer_list		timer;
47 	struct net_bridge_port_group	*pg;
48 	struct net_bridge		*br;
49 	struct net_bridge_mcast_gc	mcast_gc;
50 };
51 
52 #ifdef CONFIG_BRIDGE_IGMP_SNOOPING
53 void br_multicast_eht_clean_sets(struct net_bridge_port_group *pg);
54 bool br_multicast_eht_handle(const struct net_bridge_mcast *brmctx,
55 			     struct net_bridge_port_group *pg,
56 			     void *h_addr,
57 			     void *srcs,
58 			     u32 nsrcs,
59 			     size_t addr_size,
60 			     int grec_type);
61 int br_multicast_eht_set_hosts_limit(struct net_bridge_port *p,
62 				     u32 eht_hosts_limit);
63 
64 static inline bool
br_multicast_eht_should_del_pg(const struct net_bridge_port_group * pg)65 br_multicast_eht_should_del_pg(const struct net_bridge_port_group *pg)
66 {
67 	return !!((pg->key.port->flags & BR_MULTICAST_FAST_LEAVE) &&
68 		  RB_EMPTY_ROOT(&pg->eht_host_tree));
69 }
70 
71 static inline bool
br_multicast_eht_hosts_over_limit(const struct net_bridge_port_group * pg)72 br_multicast_eht_hosts_over_limit(const struct net_bridge_port_group *pg)
73 {
74 	const struct net_bridge_port *p = pg->key.port;
75 
76 	return !!(p->multicast_eht_hosts_cnt >= p->multicast_eht_hosts_limit);
77 }
78 
br_multicast_eht_hosts_inc(struct net_bridge_port_group * pg)79 static inline void br_multicast_eht_hosts_inc(struct net_bridge_port_group *pg)
80 {
81 	struct net_bridge_port *p = pg->key.port;
82 
83 	p->multicast_eht_hosts_cnt++;
84 }
85 
br_multicast_eht_hosts_dec(struct net_bridge_port_group * pg)86 static inline void br_multicast_eht_hosts_dec(struct net_bridge_port_group *pg)
87 {
88 	struct net_bridge_port *p = pg->key.port;
89 
90 	p->multicast_eht_hosts_cnt--;
91 }
92 #endif /* CONFIG_BRIDGE_IGMP_SNOOPING */
93 
94 #endif /* _BR_PRIVATE_MCAST_EHT_H_ */
95