br_multicast.c (8f8cb77e0b22d9044d8d57ab3bb18ea8d0474752) br_multicast.c (085b53c8beabf9b379762f73aaac562d6c428923)
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Bridge multicast support.
4 *
5 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
6 */
7
8#include <linux/err.h>

--- 27 unchanged lines hidden (view full) ---

36
37static const struct rhashtable_params br_mdb_rht_params = {
38 .head_offset = offsetof(struct net_bridge_mdb_entry, rhnode),
39 .key_offset = offsetof(struct net_bridge_mdb_entry, addr),
40 .key_len = sizeof(struct br_ip),
41 .automatic_shrinking = true,
42};
43
1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * Bridge multicast support.
4 *
5 * Copyright (c) 2010 Herbert Xu <herbert@gondor.apana.org.au>
6 */
7
8#include <linux/err.h>

--- 27 unchanged lines hidden (view full) ---

36
37static const struct rhashtable_params br_mdb_rht_params = {
38 .head_offset = offsetof(struct net_bridge_mdb_entry, rhnode),
39 .key_offset = offsetof(struct net_bridge_mdb_entry, addr),
40 .key_len = sizeof(struct br_ip),
41 .automatic_shrinking = true,
42};
43
44static const struct rhashtable_params br_sg_port_rht_params = {
45 .head_offset = offsetof(struct net_bridge_port_group, rhnode),
46 .key_offset = offsetof(struct net_bridge_port_group, key),
47 .key_len = sizeof(struct net_bridge_port_group_sg_key),
48 .automatic_shrinking = true,
49};
50
44static void br_multicast_start_querier(struct net_bridge *br,
45 struct bridge_mcast_own_query *query);
46static void br_multicast_add_router(struct net_bridge *br,
47 struct net_bridge_port *port);
48static void br_ip4_multicast_leave_group(struct net_bridge *br,
49 struct net_bridge_port *port,
50 __be32 group,
51 __u16 vid,
52 const unsigned char *src);
53static void br_multicast_port_group_rexmit(struct timer_list *t);
54
55static void __del_port_router(struct net_bridge_port *p);
56#if IS_ENABLED(CONFIG_IPV6)
57static void br_ip6_multicast_leave_group(struct net_bridge *br,
58 struct net_bridge_port *port,
59 const struct in6_addr *group,
60 __u16 vid, const unsigned char *src);
61#endif
62
51static void br_multicast_start_querier(struct net_bridge *br,
52 struct bridge_mcast_own_query *query);
53static void br_multicast_add_router(struct net_bridge *br,
54 struct net_bridge_port *port);
55static void br_ip4_multicast_leave_group(struct net_bridge *br,
56 struct net_bridge_port *port,
57 __be32 group,
58 __u16 vid,
59 const unsigned char *src);
60static void br_multicast_port_group_rexmit(struct timer_list *t);
61
62static void __del_port_router(struct net_bridge_port *p);
63#if IS_ENABLED(CONFIG_IPV6)
64static void br_ip6_multicast_leave_group(struct net_bridge *br,
65 struct net_bridge_port *port,
66 const struct in6_addr *group,
67 __u16 vid, const unsigned char *src);
68#endif
69
70static struct net_bridge_port_group *
71br_sg_port_find(struct net_bridge *br,
72 struct net_bridge_port_group_sg_key *sg_p)
73{
74 lockdep_assert_held_once(&br->multicast_lock);
75
76 return rhashtable_lookup_fast(&br->sg_port_tbl, sg_p,
77 br_sg_port_rht_params);
78}
79
63static struct net_bridge_mdb_entry *br_mdb_ip_get_rcu(struct net_bridge *br,
64 struct br_ip *dst)
65{
66 return rhashtable_lookup(&br->mdb_hash_tbl, dst, br_mdb_rht_params);
67}
68
69struct net_bridge_mdb_entry *br_mdb_ip_get(struct net_bridge *br,
70 struct br_ip *dst)

--- 136 unchanged lines hidden (view full) ---

207 WARN_ON(!hlist_unhashed(&src->node));
208
209 del_timer_sync(&src->timer);
210 kfree_rcu(src, rcu);
211}
212
213static void br_multicast_del_group_src(struct net_bridge_group_src *src)
214{
80static struct net_bridge_mdb_entry *br_mdb_ip_get_rcu(struct net_bridge *br,
81 struct br_ip *dst)
82{
83 return rhashtable_lookup(&br->mdb_hash_tbl, dst, br_mdb_rht_params);
84}
85
86struct net_bridge_mdb_entry *br_mdb_ip_get(struct net_bridge *br,
87 struct br_ip *dst)

--- 136 unchanged lines hidden (view full) ---

224 WARN_ON(!hlist_unhashed(&src->node));
225
226 del_timer_sync(&src->timer);
227 kfree_rcu(src, rcu);
228}
229
230static void br_multicast_del_group_src(struct net_bridge_group_src *src)
231{
215 struct net_bridge *br = src->pg->port->br;
232 struct net_bridge *br = src->pg->key.port->br;
216
217 hlist_del_init_rcu(&src->node);
218 src->pg->src_ents--;
219 hlist_add_head(&src->mcast_gc.gc_node, &br->mcast_gc_list);
220 queue_work(system_long_wq, &br->mcast_gc_work);
221}
222
223static void br_multicast_destroy_port_group(struct net_bridge_mcast_gc *gc)

--- 8 unchanged lines hidden (view full) ---

232 del_timer_sync(&pg->timer);
233 kfree_rcu(pg, rcu);
234}
235
236void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
237 struct net_bridge_port_group *pg,
238 struct net_bridge_port_group __rcu **pp)
239{
233
234 hlist_del_init_rcu(&src->node);
235 src->pg->src_ents--;
236 hlist_add_head(&src->mcast_gc.gc_node, &br->mcast_gc_list);
237 queue_work(system_long_wq, &br->mcast_gc_work);
238}
239
240static void br_multicast_destroy_port_group(struct net_bridge_mcast_gc *gc)

--- 8 unchanged lines hidden (view full) ---

249 del_timer_sync(&pg->timer);
250 kfree_rcu(pg, rcu);
251}
252
253void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
254 struct net_bridge_port_group *pg,
255 struct net_bridge_port_group __rcu **pp)
256{
240 struct net_bridge *br = pg->port->br;
257 struct net_bridge *br = pg->key.port->br;
241 struct net_bridge_group_src *ent;
242 struct hlist_node *tmp;
243
258 struct net_bridge_group_src *ent;
259 struct hlist_node *tmp;
260
261 rhashtable_remove_fast(&br->sg_port_tbl, &pg->rhnode,
262 br_sg_port_rht_params);
244 rcu_assign_pointer(*pp, pg->next);
245 hlist_del_init(&pg->mglist);
246 hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node)
247 br_multicast_del_group_src(ent);
248 br_mdb_notify(br->dev, mp, pg, RTM_DELMDB);
249 hlist_add_head(&pg->mcast_gc.gc_node, &br->mcast_gc_list);
250 queue_work(system_long_wq, &br->mcast_gc_work);
251
252 if (!mp->ports && !mp->host_joined && netif_running(br->dev))
253 mod_timer(&mp->timer, jiffies);
254}
255
256static void br_multicast_find_del_pg(struct net_bridge *br,
257 struct net_bridge_port_group *pg)
258{
259 struct net_bridge_port_group __rcu **pp;
260 struct net_bridge_mdb_entry *mp;
261 struct net_bridge_port_group *p;
262
263 rcu_assign_pointer(*pp, pg->next);
264 hlist_del_init(&pg->mglist);
265 hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node)
266 br_multicast_del_group_src(ent);
267 br_mdb_notify(br->dev, mp, pg, RTM_DELMDB);
268 hlist_add_head(&pg->mcast_gc.gc_node, &br->mcast_gc_list);
269 queue_work(system_long_wq, &br->mcast_gc_work);
270
271 if (!mp->ports && !mp->host_joined && netif_running(br->dev))
272 mod_timer(&mp->timer, jiffies);
273}
274
275static void br_multicast_find_del_pg(struct net_bridge *br,
276 struct net_bridge_port_group *pg)
277{
278 struct net_bridge_port_group __rcu **pp;
279 struct net_bridge_mdb_entry *mp;
280 struct net_bridge_port_group *p;
281
263 mp = br_mdb_ip_get(br, &pg->addr);
282 mp = br_mdb_ip_get(br, &pg->key.addr);
264 if (WARN_ON(!mp))
265 return;
266
267 for (pp = &mp->ports;
268 (p = mlock_dereference(*pp, br)) != NULL;
269 pp = &p->next) {
270 if (p != pg)
271 continue;

--- 4 unchanged lines hidden (view full) ---

276
277 WARN_ON(1);
278}
279
280static void br_multicast_port_group_expired(struct timer_list *t)
281{
282 struct net_bridge_port_group *pg = from_timer(pg, t, timer);
283 struct net_bridge_group_src *src_ent;
283 if (WARN_ON(!mp))
284 return;
285
286 for (pp = &mp->ports;
287 (p = mlock_dereference(*pp, br)) != NULL;
288 pp = &p->next) {
289 if (p != pg)
290 continue;

--- 4 unchanged lines hidden (view full) ---

295
296 WARN_ON(1);
297}
298
299static void br_multicast_port_group_expired(struct timer_list *t)
300{
301 struct net_bridge_port_group *pg = from_timer(pg, t, timer);
302 struct net_bridge_group_src *src_ent;
284 struct net_bridge *br = pg->port->br;
303 struct net_bridge *br = pg->key.port->br;
285 struct hlist_node *tmp;
286 bool changed;
287
288 spin_lock(&br->multicast_lock);
289 if (!netif_running(br->dev) || timer_pending(&pg->timer) ||
290 hlist_unhashed(&pg->mglist) || pg->flags & MDB_PG_FLAGS_PERMANENT)
291 goto out;
292

--- 4 unchanged lines hidden (view full) ---

297 br_multicast_del_group_src(src_ent);
298 changed = true;
299 }
300 }
301
302 if (hlist_empty(&pg->src_list)) {
303 br_multicast_find_del_pg(br, pg);
304 } else if (changed) {
304 struct hlist_node *tmp;
305 bool changed;
306
307 spin_lock(&br->multicast_lock);
308 if (!netif_running(br->dev) || timer_pending(&pg->timer) ||
309 hlist_unhashed(&pg->mglist) || pg->flags & MDB_PG_FLAGS_PERMANENT)
310 goto out;
311

--- 4 unchanged lines hidden (view full) ---

316 br_multicast_del_group_src(src_ent);
317 changed = true;
318 }
319 }
320
321 if (hlist_empty(&pg->src_list)) {
322 br_multicast_find_del_pg(br, pg);
323 } else if (changed) {
305 struct net_bridge_mdb_entry *mp = br_mdb_ip_get(br, &pg->addr);
324 struct net_bridge_mdb_entry *mp = br_mdb_ip_get(br, &pg->key.addr);
306
307 if (WARN_ON(!mp))
308 goto out;
309 br_mdb_notify(br->dev, mp, pg, RTM_NEWMDB);
310 }
311out:
312 spin_unlock(&br->multicast_lock);
313}

--- 11 unchanged lines hidden (view full) ---

325
326static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br,
327 struct net_bridge_port_group *pg,
328 __be32 ip_dst, __be32 group,
329 bool with_srcs, bool over_lmqt,
330 u8 sflag, u8 *igmp_type,
331 bool *need_rexmit)
332{
325
326 if (WARN_ON(!mp))
327 goto out;
328 br_mdb_notify(br->dev, mp, pg, RTM_NEWMDB);
329 }
330out:
331 spin_unlock(&br->multicast_lock);
332}

--- 11 unchanged lines hidden (view full) ---

344
345static struct sk_buff *br_ip4_multicast_alloc_query(struct net_bridge *br,
346 struct net_bridge_port_group *pg,
347 __be32 ip_dst, __be32 group,
348 bool with_srcs, bool over_lmqt,
349 u8 sflag, u8 *igmp_type,
350 bool *need_rexmit)
351{
333 struct net_bridge_port *p = pg ? pg->port : NULL;
352 struct net_bridge_port *p = pg ? pg->key.port : NULL;
334 struct net_bridge_group_src *ent;
335 size_t pkt_size, igmp_hdr_size;
336 unsigned long now = jiffies;
337 struct igmpv3_query *ihv3;
338 void *csum_start = NULL;
339 __sum16 *csum = NULL;
340 struct sk_buff *skb;
341 struct igmphdr *ih;

--- 129 unchanged lines hidden (view full) ---

471static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
472 struct net_bridge_port_group *pg,
473 const struct in6_addr *ip6_dst,
474 const struct in6_addr *group,
475 bool with_srcs, bool over_llqt,
476 u8 sflag, u8 *igmp_type,
477 bool *need_rexmit)
478{
353 struct net_bridge_group_src *ent;
354 size_t pkt_size, igmp_hdr_size;
355 unsigned long now = jiffies;
356 struct igmpv3_query *ihv3;
357 void *csum_start = NULL;
358 __sum16 *csum = NULL;
359 struct sk_buff *skb;
360 struct igmphdr *ih;

--- 129 unchanged lines hidden (view full) ---

490static struct sk_buff *br_ip6_multicast_alloc_query(struct net_bridge *br,
491 struct net_bridge_port_group *pg,
492 const struct in6_addr *ip6_dst,
493 const struct in6_addr *group,
494 bool with_srcs, bool over_llqt,
495 u8 sflag, u8 *igmp_type,
496 bool *need_rexmit)
497{
479 struct net_bridge_port *p = pg ? pg->port : NULL;
498 struct net_bridge_port *p = pg ? pg->key.port : NULL;
480 struct net_bridge_group_src *ent;
481 size_t pkt_size, mld_hdr_size;
482 unsigned long now = jiffies;
483 struct mld2_query *mld2q;
484 void *csum_start = NULL;
485 unsigned long interval;
486 __sum16 *csum = NULL;
487 struct ipv6hdr *ip6h;

--- 285 unchanged lines hidden (view full) ---

773#endif
774 }
775
776 grp_src = kzalloc(sizeof(*grp_src), GFP_ATOMIC);
777 if (unlikely(!grp_src))
778 return NULL;
779
780 grp_src->pg = pg;
499 struct net_bridge_group_src *ent;
500 size_t pkt_size, mld_hdr_size;
501 unsigned long now = jiffies;
502 struct mld2_query *mld2q;
503 void *csum_start = NULL;
504 unsigned long interval;
505 __sum16 *csum = NULL;
506 struct ipv6hdr *ip6h;

--- 285 unchanged lines hidden (view full) ---

792#endif
793 }
794
795 grp_src = kzalloc(sizeof(*grp_src), GFP_ATOMIC);
796 if (unlikely(!grp_src))
797 return NULL;
798
799 grp_src->pg = pg;
781 grp_src->br = pg->port->br;
800 grp_src->br = pg->key.port->br;
782 grp_src->addr = *src_ip;
783 grp_src->mcast_gc.destroy = br_multicast_destroy_group_src;
784 timer_setup(&grp_src->timer, br_multicast_group_src_expired, 0);
785
786 hlist_add_head_rcu(&grp_src->node, &pg->src_list);
787 pg->src_ents++;
788
789 return grp_src;

--- 9 unchanged lines hidden (view full) ---

799 u8 rt_protocol)
800{
801 struct net_bridge_port_group *p;
802
803 p = kzalloc(sizeof(*p), GFP_ATOMIC);
804 if (unlikely(!p))
805 return NULL;
806
801 grp_src->addr = *src_ip;
802 grp_src->mcast_gc.destroy = br_multicast_destroy_group_src;
803 timer_setup(&grp_src->timer, br_multicast_group_src_expired, 0);
804
805 hlist_add_head_rcu(&grp_src->node, &pg->src_list);
806 pg->src_ents++;
807
808 return grp_src;

--- 9 unchanged lines hidden (view full) ---

818 u8 rt_protocol)
819{
820 struct net_bridge_port_group *p;
821
822 p = kzalloc(sizeof(*p), GFP_ATOMIC);
823 if (unlikely(!p))
824 return NULL;
825
807 p->addr = *group;
808 p->port = port;
826 p->key.addr = *group;
827 p->key.port = port;
809 p->flags = flags;
810 p->filter_mode = filter_mode;
811 p->rt_protocol = rt_protocol;
812 p->mcast_gc.destroy = br_multicast_destroy_port_group;
813 INIT_HLIST_HEAD(&p->src_list);
828 p->flags = flags;
829 p->filter_mode = filter_mode;
830 p->rt_protocol = rt_protocol;
831 p->mcast_gc.destroy = br_multicast_destroy_port_group;
832 INIT_HLIST_HEAD(&p->src_list);
833
834 if (!br_multicast_is_star_g(group) &&
835 rhashtable_lookup_insert_fast(&port->br->sg_port_tbl, &p->rhnode,
836 br_sg_port_rht_params)) {
837 kfree(p);
838 return NULL;
839 }
840
814 rcu_assign_pointer(p->next, next);
815 timer_setup(&p->timer, br_multicast_port_group_expired, 0);
816 timer_setup(&p->rexmit_timer, br_multicast_port_group_rexmit, 0);
817 hlist_add_head(&p->mglist, &port->mglist);
818
819 if (src)
820 memcpy(p->eth_addr, src, ETH_ALEN);
821 else
822 eth_broadcast_addr(p->eth_addr);
823
824 return p;
825}
826
827static bool br_port_group_equal(struct net_bridge_port_group *p,
828 struct net_bridge_port *port,
829 const unsigned char *src)
830{
841 rcu_assign_pointer(p->next, next);
842 timer_setup(&p->timer, br_multicast_port_group_expired, 0);
843 timer_setup(&p->rexmit_timer, br_multicast_port_group_rexmit, 0);
844 hlist_add_head(&p->mglist, &port->mglist);
845
846 if (src)
847 memcpy(p->eth_addr, src, ETH_ALEN);
848 else
849 eth_broadcast_addr(p->eth_addr);
850
851 return p;
852}
853
854static bool br_port_group_equal(struct net_bridge_port_group *p,
855 struct net_bridge_port *port,
856 const unsigned char *src)
857{
831 if (p->port != port)
858 if (p->key.port != port)
832 return false;
833
834 if (!(port->flags & BR_MULTICAST_TO_UNICAST))
835 return true;
836
837 return ether_addr_equal(src, p->eth_addr);
838}
839

--- 45 unchanged lines hidden (view full) ---

885 goto out;
886 }
887
888 for (pp = &mp->ports;
889 (p = mlock_dereference(*pp, br)) != NULL;
890 pp = &p->next) {
891 if (br_port_group_equal(p, port, src))
892 goto found;
859 return false;
860
861 if (!(port->flags & BR_MULTICAST_TO_UNICAST))
862 return true;
863
864 return ether_addr_equal(src, p->eth_addr);
865}
866

--- 45 unchanged lines hidden (view full) ---

912 goto out;
913 }
914
915 for (pp = &mp->ports;
916 (p = mlock_dereference(*pp, br)) != NULL;
917 pp = &p->next) {
918 if (br_port_group_equal(p, port, src))
919 goto found;
893 if ((unsigned long)p->port < (unsigned long)port)
920 if ((unsigned long)p->key.port < (unsigned long)port)
894 break;
895 }
896
897 p = br_multicast_new_port_group(port, group, *pp, 0, src, filter_mode,
898 RTPROT_KERNEL);
899 if (unlikely(!p))
900 goto err;
901 rcu_assign_pointer(*pp, p);

--- 259 unchanged lines hidden (view full) ---

1161 br_multicast_port_query_expired(port, &port->ip6_own_query);
1162}
1163#endif
1164
1165static void br_multicast_port_group_rexmit(struct timer_list *t)
1166{
1167 struct net_bridge_port_group *pg = from_timer(pg, t, rexmit_timer);
1168 struct bridge_mcast_other_query *other_query = NULL;
921 break;
922 }
923
924 p = br_multicast_new_port_group(port, group, *pp, 0, src, filter_mode,
925 RTPROT_KERNEL);
926 if (unlikely(!p))
927 goto err;
928 rcu_assign_pointer(*pp, p);

--- 259 unchanged lines hidden (view full) ---

1188 br_multicast_port_query_expired(port, &port->ip6_own_query);
1189}
1190#endif
1191
1192static void br_multicast_port_group_rexmit(struct timer_list *t)
1193{
1194 struct net_bridge_port_group *pg = from_timer(pg, t, rexmit_timer);
1195 struct bridge_mcast_other_query *other_query = NULL;
1169 struct net_bridge *br = pg->port->br;
1196 struct net_bridge *br = pg->key.port->br;
1170 bool need_rexmit = false;
1171
1172 spin_lock(&br->multicast_lock);
1173 if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) ||
1174 !br_opt_get(br, BROPT_MULTICAST_ENABLED) ||
1175 !br_opt_get(br, BROPT_MULTICAST_QUERIER))
1176 goto out;
1177
1197 bool need_rexmit = false;
1198
1199 spin_lock(&br->multicast_lock);
1200 if (!netif_running(br->dev) || hlist_unhashed(&pg->mglist) ||
1201 !br_opt_get(br, BROPT_MULTICAST_ENABLED) ||
1202 !br_opt_get(br, BROPT_MULTICAST_QUERIER))
1203 goto out;
1204
1178 if (pg->addr.proto == htons(ETH_P_IP))
1205 if (pg->key.addr.proto == htons(ETH_P_IP))
1179 other_query = &br->ip4_other_query;
1180#if IS_ENABLED(CONFIG_IPV6)
1181 else
1182 other_query = &br->ip6_other_query;
1183#endif
1184
1185 if (!other_query || timer_pending(&other_query->timer))
1186 goto out;
1187
1188 if (pg->grp_query_rexmit_cnt) {
1189 pg->grp_query_rexmit_cnt--;
1206 other_query = &br->ip4_other_query;
1207#if IS_ENABLED(CONFIG_IPV6)
1208 else
1209 other_query = &br->ip6_other_query;
1210#endif
1211
1212 if (!other_query || timer_pending(&other_query->timer))
1213 goto out;
1214
1215 if (pg->grp_query_rexmit_cnt) {
1216 pg->grp_query_rexmit_cnt--;
1190 __br_multicast_send_query(br, pg->port, pg, &pg->addr,
1191 &pg->addr, false, 1, NULL);
1217 __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr,
1218 &pg->key.addr, false, 1, NULL);
1192 }
1219 }
1193 __br_multicast_send_query(br, pg->port, pg, &pg->addr,
1194 &pg->addr, true, 0, &need_rexmit);
1220 __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr,
1221 &pg->key.addr, true, 0, &need_rexmit);
1195
1196 if (pg->grp_query_rexmit_cnt || need_rexmit)
1197 mod_timer(&pg->rexmit_timer, jiffies +
1198 br->multicast_last_member_interval);
1199out:
1200 spin_unlock(&br->multicast_lock);
1201}
1202

--- 117 unchanged lines hidden (view full) ---

1320 }
1321
1322 return deleted;
1323}
1324
1325static void __grp_src_query_marked_and_rexmit(struct net_bridge_port_group *pg)
1326{
1327 struct bridge_mcast_other_query *other_query = NULL;
1222
1223 if (pg->grp_query_rexmit_cnt || need_rexmit)
1224 mod_timer(&pg->rexmit_timer, jiffies +
1225 br->multicast_last_member_interval);
1226out:
1227 spin_unlock(&br->multicast_lock);
1228}
1229

--- 117 unchanged lines hidden (view full) ---

1347 }
1348
1349 return deleted;
1350}
1351
1352static void __grp_src_query_marked_and_rexmit(struct net_bridge_port_group *pg)
1353{
1354 struct bridge_mcast_other_query *other_query = NULL;
1328 struct net_bridge *br = pg->port->br;
1355 struct net_bridge *br = pg->key.port->br;
1329 u32 lmqc = br->multicast_last_member_count;
1330 unsigned long lmqt, lmi, now = jiffies;
1331 struct net_bridge_group_src *ent;
1332
1333 if (!netif_running(br->dev) ||
1334 !br_opt_get(br, BROPT_MULTICAST_ENABLED))
1335 return;
1336
1356 u32 lmqc = br->multicast_last_member_count;
1357 unsigned long lmqt, lmi, now = jiffies;
1358 struct net_bridge_group_src *ent;
1359
1360 if (!netif_running(br->dev) ||
1361 !br_opt_get(br, BROPT_MULTICAST_ENABLED))
1362 return;
1363
1337 if (pg->addr.proto == htons(ETH_P_IP))
1364 if (pg->key.addr.proto == htons(ETH_P_IP))
1338 other_query = &br->ip4_other_query;
1339#if IS_ENABLED(CONFIG_IPV6)
1340 else
1341 other_query = &br->ip6_other_query;
1342#endif
1343
1344 lmqt = now + br_multicast_lmqt(br);
1345 hlist_for_each_entry(ent, &pg->src_list, node) {

--- 8 unchanged lines hidden (view full) ---

1354 }
1355 }
1356 }
1357
1358 if (!br_opt_get(br, BROPT_MULTICAST_QUERIER) ||
1359 !other_query || timer_pending(&other_query->timer))
1360 return;
1361
1365 other_query = &br->ip4_other_query;
1366#if IS_ENABLED(CONFIG_IPV6)
1367 else
1368 other_query = &br->ip6_other_query;
1369#endif
1370
1371 lmqt = now + br_multicast_lmqt(br);
1372 hlist_for_each_entry(ent, &pg->src_list, node) {

--- 8 unchanged lines hidden (view full) ---

1381 }
1382 }
1383 }
1384
1385 if (!br_opt_get(br, BROPT_MULTICAST_QUERIER) ||
1386 !other_query || timer_pending(&other_query->timer))
1387 return;
1388
1362 __br_multicast_send_query(br, pg->port, pg, &pg->addr,
1363 &pg->addr, true, 1, NULL);
1389 __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr,
1390 &pg->key.addr, true, 1, NULL);
1364
1365 lmi = now + br->multicast_last_member_interval;
1366 if (!timer_pending(&pg->rexmit_timer) ||
1367 time_after(pg->rexmit_timer.expires, lmi))
1368 mod_timer(&pg->rexmit_timer, lmi);
1369}
1370
1371static void __grp_send_query_and_rexmit(struct net_bridge_port_group *pg)
1372{
1373 struct bridge_mcast_other_query *other_query = NULL;
1391
1392 lmi = now + br->multicast_last_member_interval;
1393 if (!timer_pending(&pg->rexmit_timer) ||
1394 time_after(pg->rexmit_timer.expires, lmi))
1395 mod_timer(&pg->rexmit_timer, lmi);
1396}
1397
1398static void __grp_send_query_and_rexmit(struct net_bridge_port_group *pg)
1399{
1400 struct bridge_mcast_other_query *other_query = NULL;
1374 struct net_bridge *br = pg->port->br;
1401 struct net_bridge *br = pg->key.port->br;
1375 unsigned long now = jiffies, lmi;
1376
1377 if (!netif_running(br->dev) ||
1378 !br_opt_get(br, BROPT_MULTICAST_ENABLED))
1379 return;
1380
1402 unsigned long now = jiffies, lmi;
1403
1404 if (!netif_running(br->dev) ||
1405 !br_opt_get(br, BROPT_MULTICAST_ENABLED))
1406 return;
1407
1381 if (pg->addr.proto == htons(ETH_P_IP))
1408 if (pg->key.addr.proto == htons(ETH_P_IP))
1382 other_query = &br->ip4_other_query;
1383#if IS_ENABLED(CONFIG_IPV6)
1384 else
1385 other_query = &br->ip6_other_query;
1386#endif
1387
1388 if (br_opt_get(br, BROPT_MULTICAST_QUERIER) &&
1389 other_query && !timer_pending(&other_query->timer)) {
1390 lmi = now + br->multicast_last_member_interval;
1391 pg->grp_query_rexmit_cnt = br->multicast_last_member_count - 1;
1409 other_query = &br->ip4_other_query;
1410#if IS_ENABLED(CONFIG_IPV6)
1411 else
1412 other_query = &br->ip6_other_query;
1413#endif
1414
1415 if (br_opt_get(br, BROPT_MULTICAST_QUERIER) &&
1416 other_query && !timer_pending(&other_query->timer)) {
1417 lmi = now + br->multicast_last_member_interval;
1418 pg->grp_query_rexmit_cnt = br->multicast_last_member_count - 1;
1392 __br_multicast_send_query(br, pg->port, pg, &pg->addr,
1393 &pg->addr, false, 0, NULL);
1419 __br_multicast_send_query(br, pg->key.port, pg, &pg->key.addr,
1420 &pg->key.addr, false, 0, NULL);
1394 if (!timer_pending(&pg->rexmit_timer) ||
1395 time_after(pg->rexmit_timer.expires, lmi))
1396 mod_timer(&pg->rexmit_timer, lmi);
1397 }
1398
1399 if (pg->filter_mode == MCAST_EXCLUDE &&
1400 (!timer_pending(&pg->timer) ||
1401 time_after(pg->timer.expires, now + br_multicast_lmqt(br))))
1402 mod_timer(&pg->timer, now + br_multicast_lmqt(br));
1403}
1404
1405/* State Msg type New state Actions
1406 * INCLUDE (A) IS_IN (B) INCLUDE (A+B) (B)=GMI
1407 * INCLUDE (A) ALLOW (B) INCLUDE (A+B) (B)=GMI
1408 * EXCLUDE (X,Y) ALLOW (A) EXCLUDE (X+A,Y-A) (A)=GMI
1409 */
1410static bool br_multicast_isinc_allow(struct net_bridge_port_group *pg,
1411 void *srcs, u32 nsrcs, size_t src_size)
1412{
1421 if (!timer_pending(&pg->rexmit_timer) ||
1422 time_after(pg->rexmit_timer.expires, lmi))
1423 mod_timer(&pg->rexmit_timer, lmi);
1424 }
1425
1426 if (pg->filter_mode == MCAST_EXCLUDE &&
1427 (!timer_pending(&pg->timer) ||
1428 time_after(pg->timer.expires, now + br_multicast_lmqt(br))))
1429 mod_timer(&pg->timer, now + br_multicast_lmqt(br));
1430}
1431
1432/* State Msg type New state Actions
1433 * INCLUDE (A) IS_IN (B) INCLUDE (A+B) (B)=GMI
1434 * INCLUDE (A) ALLOW (B) INCLUDE (A+B) (B)=GMI
1435 * EXCLUDE (X,Y) ALLOW (A) EXCLUDE (X+A,Y-A) (A)=GMI
1436 */
1437static bool br_multicast_isinc_allow(struct net_bridge_port_group *pg,
1438 void *srcs, u32 nsrcs, size_t src_size)
1439{
1413 struct net_bridge *br = pg->port->br;
1440 struct net_bridge *br = pg->key.port->br;
1414 struct net_bridge_group_src *ent;
1415 unsigned long now = jiffies;
1416 bool changed = false;
1417 struct br_ip src_ip;
1418 u32 src_idx;
1419
1420 memset(&src_ip, 0, sizeof(src_ip));
1441 struct net_bridge_group_src *ent;
1442 unsigned long now = jiffies;
1443 bool changed = false;
1444 struct br_ip src_ip;
1445 u32 src_idx;
1446
1447 memset(&src_ip, 0, sizeof(src_ip));
1421 src_ip.proto = pg->addr.proto;
1448 src_ip.proto = pg->key.addr.proto;
1422 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1423 memcpy(&src_ip.src, srcs, src_size);
1424 ent = br_multicast_find_group_src(pg, &src_ip);
1425 if (!ent) {
1426 ent = br_multicast_new_group_src(pg, &src_ip);
1427 if (ent)
1428 changed = true;
1429 }

--- 17 unchanged lines hidden (view full) ---

1447 struct net_bridge_group_src *ent;
1448 struct br_ip src_ip;
1449 u32 src_idx;
1450
1451 hlist_for_each_entry(ent, &pg->src_list, node)
1452 ent->flags |= BR_SGRP_F_DELETE;
1453
1454 memset(&src_ip, 0, sizeof(src_ip));
1449 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1450 memcpy(&src_ip.src, srcs, src_size);
1451 ent = br_multicast_find_group_src(pg, &src_ip);
1452 if (!ent) {
1453 ent = br_multicast_new_group_src(pg, &src_ip);
1454 if (ent)
1455 changed = true;
1456 }

--- 17 unchanged lines hidden (view full) ---

1474 struct net_bridge_group_src *ent;
1475 struct br_ip src_ip;
1476 u32 src_idx;
1477
1478 hlist_for_each_entry(ent, &pg->src_list, node)
1479 ent->flags |= BR_SGRP_F_DELETE;
1480
1481 memset(&src_ip, 0, sizeof(src_ip));
1455 src_ip.proto = pg->addr.proto;
1482 src_ip.proto = pg->key.addr.proto;
1456 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1457 memcpy(&src_ip.src, srcs, src_size);
1458 ent = br_multicast_find_group_src(pg, &src_ip);
1459 if (ent)
1460 ent->flags &= ~BR_SGRP_F_DELETE;
1461 else
1462 br_multicast_new_group_src(pg, &src_ip);
1463 srcs += src_size;

--- 6 unchanged lines hidden (view full) ---

1470 * EXCLUDE (X,Y) IS_EX (A) EXCLUDE (A-Y,Y*A) (A-X-Y)=GMI
1471 * Delete (X-A)
1472 * Delete (Y-A)
1473 * Group Timer=GMI
1474 */
1475static bool __grp_src_isexc_excl(struct net_bridge_port_group *pg,
1476 void *srcs, u32 nsrcs, size_t src_size)
1477{
1483 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1484 memcpy(&src_ip.src, srcs, src_size);
1485 ent = br_multicast_find_group_src(pg, &src_ip);
1486 if (ent)
1487 ent->flags &= ~BR_SGRP_F_DELETE;
1488 else
1489 br_multicast_new_group_src(pg, &src_ip);
1490 srcs += src_size;

--- 6 unchanged lines hidden (view full) ---

1497 * EXCLUDE (X,Y) IS_EX (A) EXCLUDE (A-Y,Y*A) (A-X-Y)=GMI
1498 * Delete (X-A)
1499 * Delete (Y-A)
1500 * Group Timer=GMI
1501 */
1502static bool __grp_src_isexc_excl(struct net_bridge_port_group *pg,
1503 void *srcs, u32 nsrcs, size_t src_size)
1504{
1478 struct net_bridge *br = pg->port->br;
1505 struct net_bridge *br = pg->key.port->br;
1479 struct net_bridge_group_src *ent;
1480 unsigned long now = jiffies;
1481 bool changed = false;
1482 struct br_ip src_ip;
1483 u32 src_idx;
1484
1485 hlist_for_each_entry(ent, &pg->src_list, node)
1486 ent->flags |= BR_SGRP_F_DELETE;
1487
1488 memset(&src_ip, 0, sizeof(src_ip));
1506 struct net_bridge_group_src *ent;
1507 unsigned long now = jiffies;
1508 bool changed = false;
1509 struct br_ip src_ip;
1510 u32 src_idx;
1511
1512 hlist_for_each_entry(ent, &pg->src_list, node)
1513 ent->flags |= BR_SGRP_F_DELETE;
1514
1515 memset(&src_ip, 0, sizeof(src_ip));
1489 src_ip.proto = pg->addr.proto;
1516 src_ip.proto = pg->key.addr.proto;
1490 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1491 memcpy(&src_ip.src, srcs, src_size);
1492 ent = br_multicast_find_group_src(pg, &src_ip);
1493 if (ent) {
1494 ent->flags &= ~BR_SGRP_F_DELETE;
1495 } else {
1496 ent = br_multicast_new_group_src(pg, &src_ip);
1497 if (ent) {

--- 9 unchanged lines hidden (view full) ---

1507 changed = true;
1508
1509 return changed;
1510}
1511
1512static bool br_multicast_isexc(struct net_bridge_port_group *pg,
1513 void *srcs, u32 nsrcs, size_t src_size)
1514{
1517 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1518 memcpy(&src_ip.src, srcs, src_size);
1519 ent = br_multicast_find_group_src(pg, &src_ip);
1520 if (ent) {
1521 ent->flags &= ~BR_SGRP_F_DELETE;
1522 } else {
1523 ent = br_multicast_new_group_src(pg, &src_ip);
1524 if (ent) {

--- 9 unchanged lines hidden (view full) ---

1534 changed = true;
1535
1536 return changed;
1537}
1538
1539static bool br_multicast_isexc(struct net_bridge_port_group *pg,
1540 void *srcs, u32 nsrcs, size_t src_size)
1541{
1515 struct net_bridge *br = pg->port->br;
1542 struct net_bridge *br = pg->key.port->br;
1516 bool changed = false;
1517
1518 switch (pg->filter_mode) {
1519 case MCAST_INCLUDE:
1520 __grp_src_isexc_incl(pg, srcs, nsrcs, src_size);
1521 changed = true;
1522 break;
1523 case MCAST_EXCLUDE:

--- 9 unchanged lines hidden (view full) ---

1533
1534/* State Msg type New state Actions
1535 * INCLUDE (A) TO_IN (B) INCLUDE (A+B) (B)=GMI
1536 * Send Q(G,A-B)
1537 */
1538static bool __grp_src_toin_incl(struct net_bridge_port_group *pg,
1539 void *srcs, u32 nsrcs, size_t src_size)
1540{
1543 bool changed = false;
1544
1545 switch (pg->filter_mode) {
1546 case MCAST_INCLUDE:
1547 __grp_src_isexc_incl(pg, srcs, nsrcs, src_size);
1548 changed = true;
1549 break;
1550 case MCAST_EXCLUDE:

--- 9 unchanged lines hidden (view full) ---

1560
1561/* State Msg type New state Actions
1562 * INCLUDE (A) TO_IN (B) INCLUDE (A+B) (B)=GMI
1563 * Send Q(G,A-B)
1564 */
1565static bool __grp_src_toin_incl(struct net_bridge_port_group *pg,
1566 void *srcs, u32 nsrcs, size_t src_size)
1567{
1541 struct net_bridge *br = pg->port->br;
1568 struct net_bridge *br = pg->key.port->br;
1542 u32 src_idx, to_send = pg->src_ents;
1543 struct net_bridge_group_src *ent;
1544 unsigned long now = jiffies;
1545 bool changed = false;
1546 struct br_ip src_ip;
1547
1548 hlist_for_each_entry(ent, &pg->src_list, node)
1549 ent->flags |= BR_SGRP_F_SEND;
1550
1551 memset(&src_ip, 0, sizeof(src_ip));
1569 u32 src_idx, to_send = pg->src_ents;
1570 struct net_bridge_group_src *ent;
1571 unsigned long now = jiffies;
1572 bool changed = false;
1573 struct br_ip src_ip;
1574
1575 hlist_for_each_entry(ent, &pg->src_list, node)
1576 ent->flags |= BR_SGRP_F_SEND;
1577
1578 memset(&src_ip, 0, sizeof(src_ip));
1552 src_ip.proto = pg->addr.proto;
1579 src_ip.proto = pg->key.addr.proto;
1553 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1554 memcpy(&src_ip.src, srcs, src_size);
1555 ent = br_multicast_find_group_src(pg, &src_ip);
1556 if (ent) {
1557 ent->flags &= ~BR_SGRP_F_SEND;
1558 to_send--;
1559 } else {
1560 ent = br_multicast_new_group_src(pg, &src_ip);

--- 14 unchanged lines hidden (view full) ---

1575/* State Msg type New state Actions
1576 * EXCLUDE (X,Y) TO_IN (A) EXCLUDE (X+A,Y-A) (A)=GMI
1577 * Send Q(G,X-A)
1578 * Send Q(G)
1579 */
1580static bool __grp_src_toin_excl(struct net_bridge_port_group *pg,
1581 void *srcs, u32 nsrcs, size_t src_size)
1582{
1580 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1581 memcpy(&src_ip.src, srcs, src_size);
1582 ent = br_multicast_find_group_src(pg, &src_ip);
1583 if (ent) {
1584 ent->flags &= ~BR_SGRP_F_SEND;
1585 to_send--;
1586 } else {
1587 ent = br_multicast_new_group_src(pg, &src_ip);

--- 14 unchanged lines hidden (view full) ---

1602/* State Msg type New state Actions
1603 * EXCLUDE (X,Y) TO_IN (A) EXCLUDE (X+A,Y-A) (A)=GMI
1604 * Send Q(G,X-A)
1605 * Send Q(G)
1606 */
1607static bool __grp_src_toin_excl(struct net_bridge_port_group *pg,
1608 void *srcs, u32 nsrcs, size_t src_size)
1609{
1583 struct net_bridge *br = pg->port->br;
1610 struct net_bridge *br = pg->key.port->br;
1584 u32 src_idx, to_send = pg->src_ents;
1585 struct net_bridge_group_src *ent;
1586 unsigned long now = jiffies;
1587 bool changed = false;
1588 struct br_ip src_ip;
1589
1590 hlist_for_each_entry(ent, &pg->src_list, node)
1591 if (timer_pending(&ent->timer))
1592 ent->flags |= BR_SGRP_F_SEND;
1593
1594 memset(&src_ip, 0, sizeof(src_ip));
1611 u32 src_idx, to_send = pg->src_ents;
1612 struct net_bridge_group_src *ent;
1613 unsigned long now = jiffies;
1614 bool changed = false;
1615 struct br_ip src_ip;
1616
1617 hlist_for_each_entry(ent, &pg->src_list, node)
1618 if (timer_pending(&ent->timer))
1619 ent->flags |= BR_SGRP_F_SEND;
1620
1621 memset(&src_ip, 0, sizeof(src_ip));
1595 src_ip.proto = pg->addr.proto;
1622 src_ip.proto = pg->key.addr.proto;
1596 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1597 memcpy(&src_ip.src, srcs, src_size);
1598 ent = br_multicast_find_group_src(pg, &src_ip);
1599 if (ent) {
1600 if (timer_pending(&ent->timer)) {
1601 ent->flags &= ~BR_SGRP_F_SEND;
1602 to_send--;
1603 }

--- 44 unchanged lines hidden (view full) ---

1648 struct net_bridge_group_src *ent;
1649 u32 src_idx, to_send = 0;
1650 struct br_ip src_ip;
1651
1652 hlist_for_each_entry(ent, &pg->src_list, node)
1653 ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE;
1654
1655 memset(&src_ip, 0, sizeof(src_ip));
1623 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1624 memcpy(&src_ip.src, srcs, src_size);
1625 ent = br_multicast_find_group_src(pg, &src_ip);
1626 if (ent) {
1627 if (timer_pending(&ent->timer)) {
1628 ent->flags &= ~BR_SGRP_F_SEND;
1629 to_send--;
1630 }

--- 44 unchanged lines hidden (view full) ---

1675 struct net_bridge_group_src *ent;
1676 u32 src_idx, to_send = 0;
1677 struct br_ip src_ip;
1678
1679 hlist_for_each_entry(ent, &pg->src_list, node)
1680 ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE;
1681
1682 memset(&src_ip, 0, sizeof(src_ip));
1656 src_ip.proto = pg->addr.proto;
1683 src_ip.proto = pg->key.addr.proto;
1657 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1658 memcpy(&src_ip.src, srcs, src_size);
1659 ent = br_multicast_find_group_src(pg, &src_ip);
1660 if (ent) {
1661 ent->flags = (ent->flags & ~BR_SGRP_F_DELETE) |
1662 BR_SGRP_F_SEND;
1663 to_send++;
1664 } else {

--- 21 unchanged lines hidden (view full) ---

1686 u32 src_idx, to_send = 0;
1687 bool changed = false;
1688 struct br_ip src_ip;
1689
1690 hlist_for_each_entry(ent, &pg->src_list, node)
1691 ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE;
1692
1693 memset(&src_ip, 0, sizeof(src_ip));
1684 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1685 memcpy(&src_ip.src, srcs, src_size);
1686 ent = br_multicast_find_group_src(pg, &src_ip);
1687 if (ent) {
1688 ent->flags = (ent->flags & ~BR_SGRP_F_DELETE) |
1689 BR_SGRP_F_SEND;
1690 to_send++;
1691 } else {

--- 21 unchanged lines hidden (view full) ---

1713 u32 src_idx, to_send = 0;
1714 bool changed = false;
1715 struct br_ip src_ip;
1716
1717 hlist_for_each_entry(ent, &pg->src_list, node)
1718 ent->flags = (ent->flags & ~BR_SGRP_F_SEND) | BR_SGRP_F_DELETE;
1719
1720 memset(&src_ip, 0, sizeof(src_ip));
1694 src_ip.proto = pg->addr.proto;
1721 src_ip.proto = pg->key.addr.proto;
1695 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1696 memcpy(&src_ip.src, srcs, src_size);
1697 ent = br_multicast_find_group_src(pg, &src_ip);
1698 if (ent) {
1699 ent->flags &= ~BR_SGRP_F_DELETE;
1700 } else {
1701 ent = br_multicast_new_group_src(pg, &src_ip);
1702 if (ent) {

--- 14 unchanged lines hidden (view full) ---

1717 __grp_src_query_marked_and_rexmit(pg);
1718
1719 return changed;
1720}
1721
1722static bool br_multicast_toex(struct net_bridge_port_group *pg,
1723 void *srcs, u32 nsrcs, size_t src_size)
1724{
1722 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1723 memcpy(&src_ip.src, srcs, src_size);
1724 ent = br_multicast_find_group_src(pg, &src_ip);
1725 if (ent) {
1726 ent->flags &= ~BR_SGRP_F_DELETE;
1727 } else {
1728 ent = br_multicast_new_group_src(pg, &src_ip);
1729 if (ent) {

--- 14 unchanged lines hidden (view full) ---

1744 __grp_src_query_marked_and_rexmit(pg);
1745
1746 return changed;
1747}
1748
1749static bool br_multicast_toex(struct net_bridge_port_group *pg,
1750 void *srcs, u32 nsrcs, size_t src_size)
1751{
1725 struct net_bridge *br = pg->port->br;
1752 struct net_bridge *br = pg->key.port->br;
1726 bool changed = false;
1727
1728 switch (pg->filter_mode) {
1729 case MCAST_INCLUDE:
1730 __grp_src_toex_incl(pg, srcs, nsrcs, src_size);
1731 changed = true;
1732 break;
1733 case MCAST_EXCLUDE:

--- 16 unchanged lines hidden (view full) ---

1750 struct net_bridge_group_src *ent;
1751 u32 src_idx, to_send = 0;
1752 struct br_ip src_ip;
1753
1754 hlist_for_each_entry(ent, &pg->src_list, node)
1755 ent->flags &= ~BR_SGRP_F_SEND;
1756
1757 memset(&src_ip, 0, sizeof(src_ip));
1753 bool changed = false;
1754
1755 switch (pg->filter_mode) {
1756 case MCAST_INCLUDE:
1757 __grp_src_toex_incl(pg, srcs, nsrcs, src_size);
1758 changed = true;
1759 break;
1760 case MCAST_EXCLUDE:

--- 16 unchanged lines hidden (view full) ---

1777 struct net_bridge_group_src *ent;
1778 u32 src_idx, to_send = 0;
1779 struct br_ip src_ip;
1780
1781 hlist_for_each_entry(ent, &pg->src_list, node)
1782 ent->flags &= ~BR_SGRP_F_SEND;
1783
1784 memset(&src_ip, 0, sizeof(src_ip));
1758 src_ip.proto = pg->addr.proto;
1785 src_ip.proto = pg->key.addr.proto;
1759 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1760 memcpy(&src_ip.src, srcs, src_size);
1761 ent = br_multicast_find_group_src(pg, &src_ip);
1762 if (ent) {
1763 ent->flags |= BR_SGRP_F_SEND;
1764 to_send++;
1765 }
1766 srcs += src_size;
1767 }
1768
1769 if (to_send)
1770 __grp_src_query_marked_and_rexmit(pg);
1771
1772 if (pg->filter_mode == MCAST_INCLUDE && hlist_empty(&pg->src_list))
1786 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1787 memcpy(&src_ip.src, srcs, src_size);
1788 ent = br_multicast_find_group_src(pg, &src_ip);
1789 if (ent) {
1790 ent->flags |= BR_SGRP_F_SEND;
1791 to_send++;
1792 }
1793 srcs += src_size;
1794 }
1795
1796 if (to_send)
1797 __grp_src_query_marked_and_rexmit(pg);
1798
1799 if (pg->filter_mode == MCAST_INCLUDE && hlist_empty(&pg->src_list))
1773 br_multicast_find_del_pg(pg->port->br, pg);
1800 br_multicast_find_del_pg(pg->key.port->br, pg);
1774}
1775
1776/* State Msg type New state Actions
1777 * EXCLUDE (X,Y) BLOCK (A) EXCLUDE (X+(A-Y),Y) (A-X-Y)=Group Timer
1778 * Send Q(G,A-Y)
1779 */
1780static bool __grp_src_block_excl(struct net_bridge_port_group *pg,
1781 void *srcs, u32 nsrcs, size_t src_size)
1782{
1783 struct net_bridge_group_src *ent;
1784 u32 src_idx, to_send = 0;
1785 bool changed = false;
1786 struct br_ip src_ip;
1787
1788 hlist_for_each_entry(ent, &pg->src_list, node)
1789 ent->flags &= ~BR_SGRP_F_SEND;
1790
1791 memset(&src_ip, 0, sizeof(src_ip));
1801}
1802
1803/* State Msg type New state Actions
1804 * EXCLUDE (X,Y) BLOCK (A) EXCLUDE (X+(A-Y),Y) (A-X-Y)=Group Timer
1805 * Send Q(G,A-Y)
1806 */
1807static bool __grp_src_block_excl(struct net_bridge_port_group *pg,
1808 void *srcs, u32 nsrcs, size_t src_size)
1809{
1810 struct net_bridge_group_src *ent;
1811 u32 src_idx, to_send = 0;
1812 bool changed = false;
1813 struct br_ip src_ip;
1814
1815 hlist_for_each_entry(ent, &pg->src_list, node)
1816 ent->flags &= ~BR_SGRP_F_SEND;
1817
1818 memset(&src_ip, 0, sizeof(src_ip));
1792 src_ip.proto = pg->addr.proto;
1819 src_ip.proto = pg->key.addr.proto;
1793 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1794 memcpy(&src_ip.src, srcs, src_size);
1795 ent = br_multicast_find_group_src(pg, &src_ip);
1796 if (!ent) {
1797 ent = br_multicast_new_group_src(pg, &src_ip);
1798 if (ent) {
1799 mod_timer(&ent->timer, pg->timer.expires);
1800 changed = true;

--- 690 unchanged lines hidden (view full) ---

2491 }
2492
2493 goto out;
2494 }
2495
2496 for (p = mlock_dereference(mp->ports, br);
2497 p != NULL;
2498 p = mlock_dereference(p->next, br)) {
1820 for (src_idx = 0; src_idx < nsrcs; src_idx++) {
1821 memcpy(&src_ip.src, srcs, src_size);
1822 ent = br_multicast_find_group_src(pg, &src_ip);
1823 if (!ent) {
1824 ent = br_multicast_new_group_src(pg, &src_ip);
1825 if (ent) {
1826 mod_timer(&ent->timer, pg->timer.expires);
1827 changed = true;

--- 690 unchanged lines hidden (view full) ---

2518 }
2519
2520 goto out;
2521 }
2522
2523 for (p = mlock_dereference(mp->ports, br);
2524 p != NULL;
2525 p = mlock_dereference(p->next, br)) {
2499 if (p->port != port)
2526 if (p->key.port != port)
2500 continue;
2501
2502 if (!hlist_unhashed(&p->mglist) &&
2503 (timer_pending(&p->timer) ?
2504 time_after(p->timer.expires, time) :
2505 try_to_del_timer_sync(&p->timer) >= 0)) {
2506 mod_timer(&p->timer, time);
2507 }

--- 743 unchanged lines hidden (view full) ---

3251 if (!port->dev || port->dev == dev)
3252 continue;
3253
3254 hlist_for_each_entry_rcu(group, &port->mglist, mglist) {
3255 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
3256 if (!entry)
3257 goto unlock;
3258
2527 continue;
2528
2529 if (!hlist_unhashed(&p->mglist) &&
2530 (timer_pending(&p->timer) ?
2531 time_after(p->timer.expires, time) :
2532 try_to_del_timer_sync(&p->timer) >= 0)) {
2533 mod_timer(&p->timer, time);
2534 }

--- 743 unchanged lines hidden (view full) ---

3278 if (!port->dev || port->dev == dev)
3279 continue;
3280
3281 hlist_for_each_entry_rcu(group, &port->mglist, mglist) {
3282 entry = kmalloc(sizeof(*entry), GFP_ATOMIC);
3283 if (!entry)
3284 goto unlock;
3285
3259 entry->addr = group->addr;
3286 entry->addr = group->key.addr;
3260 list_add(&entry->list, br_ip_list);
3261 count++;
3262 }
3263 }
3264
3265unlock:
3266 rcu_read_unlock();
3267 return count;

--- 240 unchanged lines hidden (view full) ---

3508 mcast_stats_add_dir(tdst.mld_v2reports, temp.mld_v2reports);
3509 tdst.mld_parse_errors += temp.mld_parse_errors;
3510 }
3511 memcpy(dest, &tdst, sizeof(*dest));
3512}
3513
3514int br_mdb_hash_init(struct net_bridge *br)
3515{
3287 list_add(&entry->list, br_ip_list);
3288 count++;
3289 }
3290 }
3291
3292unlock:
3293 rcu_read_unlock();
3294 return count;

--- 240 unchanged lines hidden (view full) ---

3535 mcast_stats_add_dir(tdst.mld_v2reports, temp.mld_v2reports);
3536 tdst.mld_parse_errors += temp.mld_parse_errors;
3537 }
3538 memcpy(dest, &tdst, sizeof(*dest));
3539}
3540
3541int br_mdb_hash_init(struct net_bridge *br)
3542{
3516 return rhashtable_init(&br->mdb_hash_tbl, &br_mdb_rht_params);
3543 int err;
3544
3545 err = rhashtable_init(&br->sg_port_tbl, &br_sg_port_rht_params);
3546 if (err)
3547 return err;
3548
3549 err = rhashtable_init(&br->mdb_hash_tbl, &br_mdb_rht_params);
3550 if (err) {
3551 rhashtable_destroy(&br->sg_port_tbl);
3552 return err;
3553 }
3554
3555 return 0;
3517}
3518
3519void br_mdb_hash_fini(struct net_bridge *br)
3520{
3556}
3557
3558void br_mdb_hash_fini(struct net_bridge *br)
3559{
3560 rhashtable_destroy(&br->sg_port_tbl);
3521 rhashtable_destroy(&br->mdb_hash_tbl);
3522}
3561 rhashtable_destroy(&br->mdb_hash_tbl);
3562}