18f07b831SNikolay Aleksandrov /* SPDX-License-Identifier: GPL-2.0-or-later 28f07b831SNikolay Aleksandrov * Copyright (c) 2020, Nikolay Aleksandrov <nikolay@nvidia.com> 38f07b831SNikolay Aleksandrov */ 48f07b831SNikolay Aleksandrov #ifndef _BR_PRIVATE_MCAST_EHT_H_ 58f07b831SNikolay Aleksandrov #define _BR_PRIVATE_MCAST_EHT_H_ 68f07b831SNikolay Aleksandrov 789268b05SNikolay Aleksandrov #define BR_MCAST_DEFAULT_EHT_HOSTS_LIMIT 512 889268b05SNikolay Aleksandrov 98f07b831SNikolay Aleksandrov union net_bridge_eht_addr { 108f07b831SNikolay Aleksandrov __be32 ip4; 118f07b831SNikolay Aleksandrov #if IS_ENABLED(CONFIG_IPV6) 128f07b831SNikolay Aleksandrov struct in6_addr ip6; 138f07b831SNikolay Aleksandrov #endif 148f07b831SNikolay Aleksandrov }; 158f07b831SNikolay Aleksandrov 168f07b831SNikolay Aleksandrov /* single host's list of set entries and filter_mode */ 178f07b831SNikolay Aleksandrov struct net_bridge_group_eht_host { 188f07b831SNikolay Aleksandrov struct rb_node rb_node; 198f07b831SNikolay Aleksandrov 208f07b831SNikolay Aleksandrov union net_bridge_eht_addr h_addr; 218f07b831SNikolay Aleksandrov struct hlist_head set_entries; 228f07b831SNikolay Aleksandrov unsigned int num_entries; 238f07b831SNikolay Aleksandrov unsigned char filter_mode; 248f07b831SNikolay Aleksandrov struct net_bridge_port_group *pg; 258f07b831SNikolay Aleksandrov }; 268f07b831SNikolay Aleksandrov 278f07b831SNikolay Aleksandrov /* (host, src entry) added to a per-src set and host's list */ 288f07b831SNikolay Aleksandrov struct net_bridge_group_eht_set_entry { 298f07b831SNikolay Aleksandrov struct rb_node rb_node; 308f07b831SNikolay Aleksandrov struct hlist_node host_list; 318f07b831SNikolay Aleksandrov 328f07b831SNikolay Aleksandrov union net_bridge_eht_addr h_addr; 338f07b831SNikolay Aleksandrov struct timer_list timer; 348f07b831SNikolay Aleksandrov struct net_bridge *br; 358f07b831SNikolay Aleksandrov struct net_bridge_group_eht_set *eht_set; 368f07b831SNikolay Aleksandrov struct net_bridge_group_eht_host *h_parent; 378f07b831SNikolay Aleksandrov struct net_bridge_mcast_gc mcast_gc; 388f07b831SNikolay Aleksandrov }; 398f07b831SNikolay Aleksandrov 408f07b831SNikolay Aleksandrov /* per-src set */ 418f07b831SNikolay Aleksandrov struct net_bridge_group_eht_set { 428f07b831SNikolay Aleksandrov struct rb_node rb_node; 438f07b831SNikolay Aleksandrov 448f07b831SNikolay Aleksandrov union net_bridge_eht_addr src_addr; 458f07b831SNikolay Aleksandrov struct rb_root entry_tree; 468f07b831SNikolay Aleksandrov struct timer_list timer; 478f07b831SNikolay Aleksandrov struct net_bridge_port_group *pg; 488f07b831SNikolay Aleksandrov struct net_bridge *br; 498f07b831SNikolay Aleksandrov struct net_bridge_mcast_gc mcast_gc; 508f07b831SNikolay Aleksandrov }; 518f07b831SNikolay Aleksandrov 5289268b05SNikolay Aleksandrov #ifdef CONFIG_BRIDGE_IGMP_SNOOPING 53baa74d39SNikolay Aleksandrov void br_multicast_eht_clean_sets(struct net_bridge_port_group *pg); 54*adc47037SNikolay Aleksandrov bool br_multicast_eht_handle(const struct net_bridge_mcast *brmctx, 55*adc47037SNikolay Aleksandrov struct net_bridge_port_group *pg, 56474ddb37SNikolay Aleksandrov void *h_addr, 57474ddb37SNikolay Aleksandrov void *srcs, 58474ddb37SNikolay Aleksandrov u32 nsrcs, 59474ddb37SNikolay Aleksandrov size_t addr_size, 60474ddb37SNikolay Aleksandrov int grec_type); 612dba407fSNikolay Aleksandrov int br_multicast_eht_set_hosts_limit(struct net_bridge_port *p, 622dba407fSNikolay Aleksandrov u32 eht_hosts_limit); 63baa74d39SNikolay Aleksandrov 64ddc255d9SNikolay Aleksandrov static inline bool br_multicast_eht_should_del_pg(const struct net_bridge_port_group * pg)65ddc255d9SNikolay Aleksandrovbr_multicast_eht_should_del_pg(const struct net_bridge_port_group *pg) 66ddc255d9SNikolay Aleksandrov { 67ddc255d9SNikolay Aleksandrov return !!((pg->key.port->flags & BR_MULTICAST_FAST_LEAVE) && 68ddc255d9SNikolay Aleksandrov RB_EMPTY_ROOT(&pg->eht_host_tree)); 69ddc255d9SNikolay Aleksandrov } 70ddc255d9SNikolay Aleksandrov 7189268b05SNikolay Aleksandrov static inline bool br_multicast_eht_hosts_over_limit(const struct net_bridge_port_group * pg)7289268b05SNikolay Aleksandrovbr_multicast_eht_hosts_over_limit(const struct net_bridge_port_group *pg) 7389268b05SNikolay Aleksandrov { 7489268b05SNikolay Aleksandrov const struct net_bridge_port *p = pg->key.port; 7589268b05SNikolay Aleksandrov 7689268b05SNikolay Aleksandrov return !!(p->multicast_eht_hosts_cnt >= p->multicast_eht_hosts_limit); 7789268b05SNikolay Aleksandrov } 7889268b05SNikolay Aleksandrov br_multicast_eht_hosts_inc(struct net_bridge_port_group * pg)7989268b05SNikolay Aleksandrovstatic inline void br_multicast_eht_hosts_inc(struct net_bridge_port_group *pg) 8089268b05SNikolay Aleksandrov { 8189268b05SNikolay Aleksandrov struct net_bridge_port *p = pg->key.port; 8289268b05SNikolay Aleksandrov 8389268b05SNikolay Aleksandrov p->multicast_eht_hosts_cnt++; 8489268b05SNikolay Aleksandrov } 8589268b05SNikolay Aleksandrov br_multicast_eht_hosts_dec(struct net_bridge_port_group * pg)8689268b05SNikolay Aleksandrovstatic inline void br_multicast_eht_hosts_dec(struct net_bridge_port_group *pg) 8789268b05SNikolay Aleksandrov { 8889268b05SNikolay Aleksandrov struct net_bridge_port *p = pg->key.port; 8989268b05SNikolay Aleksandrov 9089268b05SNikolay Aleksandrov p->multicast_eht_hosts_cnt--; 9189268b05SNikolay Aleksandrov } 9289268b05SNikolay Aleksandrov #endif /* CONFIG_BRIDGE_IGMP_SNOOPING */ 9389268b05SNikolay Aleksandrov 948f07b831SNikolay Aleksandrov #endif /* _BR_PRIVATE_MCAST_EHT_H_ */ 95