diff options
Diffstat (limited to 'net/bridge/br_multicast.c')
-rw-r--r-- | net/bridge/br_multicast.c | 43 |
1 files changed, 29 insertions, 14 deletions
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c index ac363b104239..3b8c5d1d0c55 100644 --- a/net/bridge/br_multicast.c +++ b/net/bridge/br_multicast.c @@ -560,7 +560,7 @@ static void br_multicast_destroy_group_src(struct net_bridge_mcast_gc *gc) kfree_rcu(src, rcu); } -static void br_multicast_del_group_src(struct net_bridge_group_src *src) +void br_multicast_del_group_src(struct net_bridge_group_src *src) { struct net_bridge *br = src->pg->key.port->br; @@ -1092,7 +1092,7 @@ out: spin_unlock(&br->multicast_lock); } -static struct net_bridge_group_src * +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 *ent; @@ -1804,7 +1804,8 @@ static void __grp_send_query_and_rexmit(struct net_bridge_port_group *pg) * EXCLUDE (X,Y) ALLOW (A) EXCLUDE (X+A,Y-A) (A)=GMI */ static bool br_multicast_isinc_allow(struct net_bridge_port_group *pg, void *h_addr, - void *srcs, u32 nsrcs, size_t addr_size) + void *srcs, u32 nsrcs, size_t addr_size, + int grec_type) { struct net_bridge *br = pg->key.port->br; struct net_bridge_group_src *ent; @@ -1828,6 +1829,9 @@ static bool br_multicast_isinc_allow(struct net_bridge_port_group *pg, void *h_a __grp_src_mod_timer(ent, now + br_multicast_gmi(br)); } + if (br_multicast_eht_handle(pg, h_addr, srcs, nsrcs, addr_size, grec_type)) + changed = true; + return changed; } @@ -2140,7 +2144,7 @@ static bool br_multicast_toex(struct net_bridge_port_group *pg, void *h_addr, * INCLUDE (A) BLOCK (B) INCLUDE (A) Send Q(G,A*B) */ static bool __grp_src_block_incl(struct net_bridge_port_group *pg, void *h_addr, - void *srcs, u32 nsrcs, size_t addr_size) + void *srcs, u32 nsrcs, size_t addr_size, int grec_type) { struct net_bridge_group_src *ent; u32 src_idx, to_send = 0; @@ -2161,6 +2165,9 @@ static bool __grp_src_block_incl(struct net_bridge_port_group *pg, void *h_addr, } } + if (br_multicast_eht_handle(pg, h_addr, srcs, nsrcs, addr_size, grec_type)) + changed = true; + if (to_send) __grp_src_query_marked_and_rexmit(pg); @@ -2180,7 +2187,7 @@ static bool __grp_src_block_incl(struct net_bridge_port_group *pg, void *h_addr, * Send Q(G,A-Y) */ static bool __grp_src_block_excl(struct net_bridge_port_group *pg, void *h_addr, - void *srcs, u32 nsrcs, size_t addr_size) + void *srcs, u32 nsrcs, size_t addr_size, int grec_type) { struct net_bridge_group_src *ent; u32 src_idx, to_send = 0; @@ -2208,6 +2215,9 @@ static bool __grp_src_block_excl(struct net_bridge_port_group *pg, void *h_addr, } } + if (br_multicast_eht_handle(pg, h_addr, srcs, nsrcs, addr_size, grec_type)) + changed = true; + if (to_send) __grp_src_query_marked_and_rexmit(pg); @@ -2215,16 +2225,18 @@ static bool __grp_src_block_excl(struct net_bridge_port_group *pg, void *h_addr, } static bool br_multicast_block(struct net_bridge_port_group *pg, void *h_addr, - void *srcs, u32 nsrcs, size_t addr_size) + void *srcs, u32 nsrcs, size_t addr_size, int grec_type) { bool changed = false; switch (pg->filter_mode) { case MCAST_INCLUDE: - changed = __grp_src_block_incl(pg, h_addr, srcs, nsrcs, addr_size); + changed = __grp_src_block_incl(pg, h_addr, srcs, nsrcs, addr_size, + grec_type); break; case MCAST_EXCLUDE: - changed = __grp_src_block_excl(pg, h_addr, srcs, nsrcs, addr_size); + changed = __grp_src_block_excl(pg, h_addr, srcs, nsrcs, addr_size, + grec_type); break; } @@ -2327,11 +2339,11 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br, switch (type) { case IGMPV3_ALLOW_NEW_SOURCES: changed = br_multicast_isinc_allow(pg, h_addr, grec->grec_src, - nsrcs, sizeof(__be32)); + nsrcs, sizeof(__be32), type); break; case IGMPV3_MODE_IS_INCLUDE: changed = br_multicast_isinc_allow(pg, h_addr, grec->grec_src, - nsrcs, sizeof(__be32)); + nsrcs, sizeof(__be32), type); break; case IGMPV3_MODE_IS_EXCLUDE: changed = br_multicast_isexc(pg, h_addr, grec->grec_src, @@ -2347,7 +2359,7 @@ static int br_ip4_multicast_igmp3_report(struct net_bridge *br, break; case IGMPV3_BLOCK_OLD_SOURCES: changed = br_multicast_block(pg, h_addr, grec->grec_src, - nsrcs, sizeof(__be32)); + nsrcs, sizeof(__be32), type); break; } if (changed) @@ -2455,12 +2467,14 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, case MLD2_ALLOW_NEW_SOURCES: changed = br_multicast_isinc_allow(pg, h_addr, grec->grec_src, nsrcs, - sizeof(struct in6_addr)); + sizeof(struct in6_addr), + grec->grec_type); break; case MLD2_MODE_IS_INCLUDE: changed = br_multicast_isinc_allow(pg, h_addr, grec->grec_src, nsrcs, - sizeof(struct in6_addr)); + sizeof(struct in6_addr), + grec->grec_type); break; case MLD2_MODE_IS_EXCLUDE: changed = br_multicast_isexc(pg, h_addr, @@ -2480,7 +2494,8 @@ static int br_ip6_multicast_mld2_report(struct net_bridge *br, case MLD2_BLOCK_OLD_SOURCES: changed = br_multicast_block(pg, h_addr, grec->grec_src, nsrcs, - sizeof(struct in6_addr)); + sizeof(struct in6_addr), + grec->grec_type); break; } if (changed) |