#include <linux/err.h>
#include <linux/export.h>
#include <linux/if_ether.h>
#include <linux/igmp.h>
#include <linux/in.h>
#include <linux/jhash.h>
#include <linux/kernel.h>
#include <linux/log2.h>
#include <linux/netdevice.h>
#include <linux/netfilter_bridge.h>
#include <linux/random.h>
#include <linux/rculist.h>
#include <linux/skbuff.h>
#include <linux/slab.h>
#include <linux/timer.h>
#include <linux/inetdevice.h>
#include <linux/mroute.h>
#include <net/ip.h>
#include <net/switchdev.h>
#if IS_ENABLED(CONFIG_IPV6)
#include <linux/icmpv6.h>
#include <net/ipv6.h>
#include <net/mld.h>
#include <net/ip6_checksum.h>
#include <net/addrconf.h>
#endif
#include <trace/events/bridge.h>
#include "br_private.h"
#include "br_private_mcast_eht.h"
static const struct rhashtable_params br_mdb_rht_params = …;
static const struct rhashtable_params br_sg_port_rht_params = …;
static void br_multicast_start_querier(struct net_bridge_mcast *brmctx,
struct bridge_mcast_own_query *query);
static void br_ip4_multicast_add_router(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx);
static void br_ip4_multicast_leave_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
__be32 group,
__u16 vid,
const unsigned char *src);
static void br_multicast_port_group_rexmit(struct timer_list *t);
static void
br_multicast_rport_del_notify(struct net_bridge_mcast_port *pmctx, bool deleted);
static void br_ip6_multicast_add_router(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx);
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_leave_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
const struct in6_addr *group,
__u16 vid, const unsigned char *src);
#endif
static struct net_bridge_port_group *
__br_multicast_add_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct br_ip *group,
const unsigned char *src,
u8 filter_mode,
bool igmpv2_mldv1,
bool blocked);
static void br_multicast_find_del_pg(struct net_bridge *br,
struct net_bridge_port_group *pg);
static void __br_multicast_stop(struct net_bridge_mcast *brmctx);
static int br_mc_disabled_update(struct net_device *dev, bool value,
struct netlink_ext_ack *extack);
static struct net_bridge_port_group *
br_sg_port_find(struct net_bridge *br,
struct net_bridge_port_group_sg_key *sg_p)
{ … }
static struct net_bridge_mdb_entry *br_mdb_ip_get_rcu(struct net_bridge *br,
struct br_ip *dst)
{ … }
struct net_bridge_mdb_entry *br_mdb_ip_get(struct net_bridge *br,
struct br_ip *dst)
{ … }
static struct net_bridge_mdb_entry *br_mdb_ip4_get(struct net_bridge *br,
__be32 dst, __u16 vid)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static struct net_bridge_mdb_entry *br_mdb_ip6_get(struct net_bridge *br,
const struct in6_addr *dst,
__u16 vid)
{ … }
#endif
struct net_bridge_mdb_entry *
br_mdb_entry_skb_get(struct net_bridge_mcast *brmctx, struct sk_buff *skb,
u16 vid)
{ … }
static struct net_bridge_mcast_port *
br_multicast_pg_to_port_ctx(const struct net_bridge_port_group *pg)
{ … }
static struct net_bridge_mcast_port *
br_multicast_port_vid_to_port_ctx(struct net_bridge_port *port, u16 vid)
{ … }
static bool
br_multicast_ctx_should_use(const struct net_bridge_mcast *brmctx,
const struct net_bridge_mcast_port *pmctx)
{ … }
static bool br_port_group_equal(struct net_bridge_port_group *p,
struct net_bridge_port *port,
const unsigned char *src)
{ … }
static void __fwd_add_star_excl(struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg,
struct br_ip *sg_ip)
{ … }
static void __fwd_del_star_excl(struct net_bridge_port_group *pg,
struct br_ip *sg_ip)
{ … }
void br_multicast_star_g_handle_mode(struct net_bridge_port_group *pg,
u8 filter_mode)
{ … }
static void br_multicast_sg_host_state(struct net_bridge_mdb_entry *star_mp,
struct net_bridge_port_group *sg)
{ … }
static void br_multicast_star_g_host_state(struct net_bridge_mdb_entry *star_mp)
{ … }
static void br_multicast_sg_del_exclude_ports(struct net_bridge_mdb_entry *sgmp)
{ … }
void br_multicast_sg_add_exclude_ports(struct net_bridge_mdb_entry *star_mp,
struct net_bridge_port_group *sg)
{ … }
static void br_multicast_fwd_src_add(struct net_bridge_group_src *src)
{ … }
static void br_multicast_fwd_src_remove(struct net_bridge_group_src *src,
bool fastleave)
{ … }
static void br_multicast_fwd_src_handle(struct net_bridge_group_src *src)
{ … }
static void br_multicast_destroy_mdb_entry(struct net_bridge_mcast_gc *gc)
{ … }
static void br_multicast_del_mdb_entry(struct net_bridge_mdb_entry *mp)
{ … }
static void br_multicast_group_expired(struct timer_list *t)
{ … }
static void br_multicast_destroy_group_src(struct net_bridge_mcast_gc *gc)
{ … }
void __br_multicast_del_group_src(struct net_bridge_group_src *src)
{ … }
void br_multicast_del_group_src(struct net_bridge_group_src *src,
bool fastleave)
{ … }
static int
br_multicast_port_ngroups_inc_one(struct net_bridge_mcast_port *pmctx,
struct netlink_ext_ack *extack,
const char *what)
{ … }
static void br_multicast_port_ngroups_dec_one(struct net_bridge_mcast_port *pmctx)
{ … }
static int br_multicast_port_ngroups_inc(struct net_bridge_port *port,
const struct br_ip *group,
struct netlink_ext_ack *extack)
{ … }
static void br_multicast_port_ngroups_dec(struct net_bridge_port *port, u16 vid)
{ … }
u32 br_multicast_ngroups_get(const struct net_bridge_mcast_port *pmctx)
{ … }
void br_multicast_ngroups_set_max(struct net_bridge_mcast_port *pmctx, u32 max)
{ … }
u32 br_multicast_ngroups_get_max(const struct net_bridge_mcast_port *pmctx)
{ … }
static void br_multicast_destroy_port_group(struct net_bridge_mcast_gc *gc)
{ … }
void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
struct net_bridge_port_group *pg,
struct net_bridge_port_group __rcu **pp)
{ … }
static void br_multicast_find_del_pg(struct net_bridge *br,
struct net_bridge_port_group *pg)
{ … }
static void br_multicast_port_group_expired(struct timer_list *t)
{ … }
static void br_multicast_gc(struct hlist_head *head)
{ … }
static void __br_multicast_query_handle_vlan(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb)
{ … }
static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg,
__be32 ip_dst, __be32 group,
bool with_srcs, bool over_lmqt,
u8 sflag, u8 *igmp_type,
bool *need_rexmit)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg,
const struct in6_addr *ip6_dst,
const struct in6_addr *group,
bool with_srcs, bool over_llqt,
u8 sflag, u8 *igmp_type,
bool *need_rexmit)
{ … }
#endif
static struct sk_buff *br_multicast_alloc_query(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg,
struct br_ip *ip_dst,
struct br_ip *group,
bool with_srcs, bool over_lmqt,
u8 sflag, u8 *igmp_type,
bool *need_rexmit)
{ … }
struct net_bridge_mdb_entry *br_multicast_new_group(struct net_bridge *br,
struct br_ip *group)
{ … }
static void br_multicast_group_src_expired(struct timer_list *t)
{ … }
struct net_bridge_group_src *
br_multicast_find_group_src(struct net_bridge_port_group *pg, struct br_ip *ip)
{ … }
struct net_bridge_group_src *
br_multicast_new_group_src(struct net_bridge_port_group *pg, struct br_ip *src_ip)
{ … }
struct net_bridge_port_group *br_multicast_new_port_group(
struct net_bridge_port *port,
const struct br_ip *group,
struct net_bridge_port_group __rcu *next,
unsigned char flags,
const unsigned char *src,
u8 filter_mode,
u8 rt_protocol,
struct netlink_ext_ack *extack)
{ … }
void br_multicast_del_port_group(struct net_bridge_port_group *p)
{ … }
void br_multicast_host_join(const struct net_bridge_mcast *brmctx,
struct net_bridge_mdb_entry *mp, bool notify)
{ … }
void br_multicast_host_leave(struct net_bridge_mdb_entry *mp, bool notify)
{ … }
static struct net_bridge_port_group *
__br_multicast_add_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct br_ip *group,
const unsigned char *src,
u8 filter_mode,
bool igmpv2_mldv1,
bool blocked)
{ … }
static int br_multicast_add_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct br_ip *group,
const unsigned char *src,
u8 filter_mode,
bool igmpv2_mldv1)
{ … }
static int br_ip4_multicast_add_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
__be32 group,
__u16 vid,
const unsigned char *src,
bool igmpv2)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static int br_ip6_multicast_add_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
const struct in6_addr *group,
__u16 vid,
const unsigned char *src,
bool mldv1)
{ … }
#endif
static bool br_multicast_rport_del(struct hlist_node *rlist)
{ … }
static bool br_ip4_multicast_rport_del(struct net_bridge_mcast_port *pmctx)
{ … }
static bool br_ip6_multicast_rport_del(struct net_bridge_mcast_port *pmctx)
{ … }
static void br_multicast_router_expired(struct net_bridge_mcast_port *pmctx,
struct timer_list *t,
struct hlist_node *rlist)
{ … }
static void br_ip4_multicast_router_expired(struct timer_list *t)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_router_expired(struct timer_list *t)
{ … }
#endif
static void br_mc_router_state_change(struct net_bridge *p,
bool is_mc_router)
{ … }
static void br_multicast_local_router_expired(struct net_bridge_mcast *brmctx,
struct timer_list *timer)
{ … }
static void br_ip4_multicast_local_router_expired(struct timer_list *t)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_local_router_expired(struct timer_list *t)
{ … }
#endif
static void br_multicast_querier_expired(struct net_bridge_mcast *brmctx,
struct bridge_mcast_own_query *query)
{ … }
static void br_ip4_multicast_querier_expired(struct timer_list *t)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_querier_expired(struct timer_list *t)
{ … }
#endif
static void br_multicast_query_delay_expired(struct timer_list *t)
{ … }
static void br_multicast_select_own_querier(struct net_bridge_mcast *brmctx,
struct br_ip *ip,
struct sk_buff *skb)
{ … }
static void __br_multicast_send_query(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg,
struct br_ip *ip_dst,
struct br_ip *group,
bool with_srcs,
u8 sflag,
bool *need_rexmit)
{ … }
static void br_multicast_read_querier(const struct bridge_mcast_querier *querier,
struct bridge_mcast_querier *dest)
{ … }
static void br_multicast_update_querier(struct net_bridge_mcast *brmctx,
struct bridge_mcast_querier *querier,
int ifindex,
struct br_ip *saddr)
{ … }
static void br_multicast_send_query(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct bridge_mcast_own_query *own_query)
{ … }
static void
br_multicast_port_query_expired(struct net_bridge_mcast_port *pmctx,
struct bridge_mcast_own_query *query)
{ … }
static void br_ip4_multicast_port_query_expired(struct timer_list *t)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_port_query_expired(struct timer_list *t)
{ … }
#endif
static void br_multicast_port_group_rexmit(struct timer_list *t)
{ … }
static int br_mc_disabled_update(struct net_device *dev, bool value,
struct netlink_ext_ack *extack)
{ … }
void br_multicast_port_ctx_init(struct net_bridge_port *port,
struct net_bridge_vlan *vlan,
struct net_bridge_mcast_port *pmctx)
{ … }
void br_multicast_port_ctx_deinit(struct net_bridge_mcast_port *pmctx)
{ … }
int br_multicast_add_port(struct net_bridge_port *port)
{ … }
void br_multicast_del_port(struct net_bridge_port *port)
{ … }
static void br_multicast_enable(struct bridge_mcast_own_query *query)
{ … }
static void __br_multicast_enable_port_ctx(struct net_bridge_mcast_port *pmctx)
{ … }
void br_multicast_enable_port(struct net_bridge_port *port)
{ … }
static void __br_multicast_disable_port_ctx(struct net_bridge_mcast_port *pmctx)
{ … }
void br_multicast_disable_port(struct net_bridge_port *port)
{ … }
static int __grp_src_delete_marked(struct net_bridge_port_group *pg)
{ … }
static void __grp_src_mod_timer(struct net_bridge_group_src *src,
unsigned long expires)
{ … }
static void __grp_src_query_marked_and_rexmit(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg)
{ … }
static void __grp_send_query_and_rexmit(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg)
{ … }
static bool br_multicast_isinc_allow(const struct net_bridge_mcast *brmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static void __grp_src_isexc_incl(const struct net_bridge_mcast *brmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static bool __grp_src_isexc_excl(const struct net_bridge_mcast *brmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static bool br_multicast_isexc(const struct net_bridge_mcast *brmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static bool __grp_src_toin_incl(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static bool __grp_src_toin_excl(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static bool br_multicast_toin(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static void __grp_src_toex_incl(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static bool __grp_src_toex_excl(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static bool br_multicast_toex(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size,
int grec_type)
{ … }
static bool __grp_src_block_incl(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size, int grec_type)
{ … }
static bool __grp_src_block_excl(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size, int grec_type)
{ … }
static bool br_multicast_block(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct net_bridge_port_group *pg, void *h_addr,
void *srcs, u32 nsrcs, size_t addr_size, int grec_type)
{ … }
static struct net_bridge_port_group *
br_multicast_find_port(struct net_bridge_mdb_entry *mp,
struct net_bridge_port *p,
const unsigned char *src)
{ … }
static int br_ip4_multicast_igmp3_report(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb,
u16 vid)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static int br_ip6_multicast_mld2_report(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb,
u16 vid)
{ … }
#endif
static bool br_multicast_select_querier(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct br_ip *saddr)
{ … }
static struct net_bridge_port *
__br_multicast_get_querier_port(struct net_bridge *br,
const struct bridge_mcast_querier *querier)
{ … }
size_t br_multicast_querier_state_size(void)
{ … }
int br_multicast_dump_querier_state(struct sk_buff *skb,
const struct net_bridge_mcast *brmctx,
int nest_attr)
{ … }
static void
br_multicast_update_query_timer(struct net_bridge_mcast *brmctx,
struct bridge_mcast_other_query *query,
unsigned long max_delay)
{ … }
static void br_port_mc_router_state_change(struct net_bridge_port *p,
bool is_mc_router)
{ … }
static struct net_bridge_port *
br_multicast_rport_from_node(struct net_bridge_mcast *brmctx,
struct hlist_head *mc_router_list,
struct hlist_node *rlist)
{ … }
static struct hlist_node *
br_multicast_get_rport_slot(struct net_bridge_mcast *brmctx,
struct net_bridge_port *port,
struct hlist_head *mc_router_list)
{ … }
static bool br_multicast_no_router_otherpf(struct net_bridge_mcast_port *pmctx,
struct hlist_node *rnode)
{ … }
static void br_multicast_add_router(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct hlist_node *rlist,
struct hlist_head *mc_router_list)
{ … }
static void br_ip4_multicast_add_router(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx)
{ … }
static void br_ip6_multicast_add_router(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx)
{ … }
static void br_multicast_mark_router(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct timer_list *timer,
struct hlist_node *rlist,
struct hlist_head *mc_router_list)
{ … }
static void br_ip4_multicast_mark_router(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx)
{ … }
static void br_ip6_multicast_mark_router(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx)
{ … }
static void
br_ip4_multicast_query_received(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct bridge_mcast_other_query *query,
struct br_ip *saddr,
unsigned long max_delay)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void
br_ip6_multicast_query_received(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct bridge_mcast_other_query *query,
struct br_ip *saddr,
unsigned long max_delay)
{ … }
#endif
static void br_ip4_multicast_query(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb,
u16 vid)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static int br_ip6_multicast_query(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb,
u16 vid)
{ … }
#endif
static void
br_multicast_leave_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct br_ip *group,
struct bridge_mcast_other_query *other_query,
struct bridge_mcast_own_query *own_query,
const unsigned char *src)
{ … }
static void br_ip4_multicast_leave_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
__be32 group,
__u16 vid,
const unsigned char *src)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_leave_group(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
const struct in6_addr *group,
__u16 vid,
const unsigned char *src)
{ … }
#endif
static void br_multicast_err_count(const struct net_bridge *br,
const struct net_bridge_port *p,
__be16 proto)
{ … }
static void br_multicast_pim(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
const struct sk_buff *skb)
{ … }
static int br_ip4_multicast_mrd_rcv(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb)
{ … }
static int br_multicast_ipv4_rcv(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb,
u16 vid)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_mrd_rcv(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb)
{ … }
static int br_multicast_ipv6_rcv(struct net_bridge_mcast *brmctx,
struct net_bridge_mcast_port *pmctx,
struct sk_buff *skb,
u16 vid)
{ … }
#endif
int br_multicast_rcv(struct net_bridge_mcast **brmctx,
struct net_bridge_mcast_port **pmctx,
struct net_bridge_vlan *vlan,
struct sk_buff *skb, u16 vid)
{ … }
static void br_multicast_query_expired(struct net_bridge_mcast *brmctx,
struct bridge_mcast_own_query *query,
struct bridge_mcast_querier *querier)
{ … }
static void br_ip4_multicast_query_expired(struct timer_list *t)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_query_expired(struct timer_list *t)
{ … }
#endif
static void br_multicast_gc_work(struct work_struct *work)
{ … }
void br_multicast_ctx_init(struct net_bridge *br,
struct net_bridge_vlan *vlan,
struct net_bridge_mcast *brmctx)
{ … }
void br_multicast_ctx_deinit(struct net_bridge_mcast *brmctx)
{ … }
void br_multicast_init(struct net_bridge *br)
{ … }
static void br_ip4_multicast_join_snoopers(struct net_bridge *br)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_join_snoopers(struct net_bridge *br)
{ … }
#else
static inline void br_ip6_multicast_join_snoopers(struct net_bridge *br)
{
}
#endif
void br_multicast_join_snoopers(struct net_bridge *br)
{ … }
static void br_ip4_multicast_leave_snoopers(struct net_bridge *br)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
static void br_ip6_multicast_leave_snoopers(struct net_bridge *br)
{ … }
#else
static inline void br_ip6_multicast_leave_snoopers(struct net_bridge *br)
{
}
#endif
void br_multicast_leave_snoopers(struct net_bridge *br)
{ … }
static void __br_multicast_open_query(struct net_bridge *br,
struct bridge_mcast_own_query *query)
{ … }
static void __br_multicast_open(struct net_bridge_mcast *brmctx)
{ … }
void br_multicast_open(struct net_bridge *br)
{ … }
static void __br_multicast_stop(struct net_bridge_mcast *brmctx)
{ … }
void br_multicast_toggle_one_vlan(struct net_bridge_vlan *vlan, bool on)
{ … }
static void br_multicast_toggle_vlan(struct net_bridge_vlan *vlan, bool on)
{ … }
int br_multicast_toggle_vlan_snooping(struct net_bridge *br, bool on,
struct netlink_ext_ack *extack)
{ … }
bool br_multicast_toggle_global_vlan(struct net_bridge_vlan *vlan, bool on)
{ … }
void br_multicast_stop(struct net_bridge *br)
{ … }
void br_multicast_dev_del(struct net_bridge *br)
{ … }
int br_multicast_set_router(struct net_bridge_mcast *brmctx, unsigned long val)
{ … }
static void
br_multicast_rport_del_notify(struct net_bridge_mcast_port *pmctx, bool deleted)
{ … }
int br_multicast_set_port_router(struct net_bridge_mcast_port *pmctx,
unsigned long val)
{ … }
int br_multicast_set_vlan_router(struct net_bridge_vlan *v, u8 mcast_router)
{ … }
static void br_multicast_start_querier(struct net_bridge_mcast *brmctx,
struct bridge_mcast_own_query *query)
{ … }
int br_multicast_toggle(struct net_bridge *br, unsigned long val,
struct netlink_ext_ack *extack)
{ … }
bool br_multicast_enabled(const struct net_device *dev)
{ … }
EXPORT_SYMBOL_GPL(…);
bool br_multicast_router(const struct net_device *dev)
{ … }
EXPORT_SYMBOL_GPL(…);
int br_multicast_set_querier(struct net_bridge_mcast *brmctx, unsigned long val)
{ … }
int br_multicast_set_igmp_version(struct net_bridge_mcast *brmctx,
unsigned long val)
{ … }
#if IS_ENABLED(CONFIG_IPV6)
int br_multicast_set_mld_version(struct net_bridge_mcast *brmctx,
unsigned long val)
{ … }
#endif
void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx,
unsigned long val)
{ … }
void br_multicast_set_startup_query_intvl(struct net_bridge_mcast *brmctx,
unsigned long val)
{ … }
int br_multicast_list_adjacent(struct net_device *dev,
struct list_head *br_ip_list)
{ … }
EXPORT_SYMBOL_GPL(…);
bool br_multicast_has_querier_anywhere(struct net_device *dev, int proto)
{ … }
EXPORT_SYMBOL_GPL(…);
bool br_multicast_has_querier_adjacent(struct net_device *dev, int proto)
{ … }
EXPORT_SYMBOL_GPL(…);
bool br_multicast_has_router_adjacent(struct net_device *dev, int proto)
{ … }
EXPORT_SYMBOL_GPL(…);
static void br_mcast_stats_add(struct bridge_mcast_stats __percpu *stats,
const struct sk_buff *skb, u8 type, u8 dir)
{ … }
void br_multicast_count(struct net_bridge *br,
const struct net_bridge_port *p,
const struct sk_buff *skb, u8 type, u8 dir)
{ … }
int br_multicast_init_stats(struct net_bridge *br)
{ … }
void br_multicast_uninit_stats(struct net_bridge *br)
{ … }
static noinline_for_stack void mcast_stats_add_dir(u64 *dst, u64 *src)
{ … }
void br_multicast_get_stats(const struct net_bridge *br,
const struct net_bridge_port *p,
struct br_mcast_stats *dest)
{ … }
int br_mdb_hash_init(struct net_bridge *br)
{ … }
void br_mdb_hash_fini(struct net_bridge *br)
{ … }