Skip to content

Commit d5a1022

Browse files
Nikolay Aleksandrovkuba-moo
authored andcommitted
net: bridge: multicast: mark IGMPv3/MLDv2 fast-leave deletes
Mark groups which were deleted due to fast leave/EHT. Signed-off-by: Nikolay Aleksandrov <[email protected]> Signed-off-by: Jakub Kicinski <[email protected]>
1 parent e87e4b5 commit d5a1022

File tree

3 files changed

+20
-12
lines changed

3 files changed

+20
-12
lines changed

net/bridge/br_multicast.c

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,8 @@ static void br_multicast_fwd_src_add(struct net_bridge_group_src *src)
442442
br_multicast_sg_add_exclude_ports(star_mp, sg);
443443
}
444444

445-
static void br_multicast_fwd_src_remove(struct net_bridge_group_src *src)
445+
static void br_multicast_fwd_src_remove(struct net_bridge_group_src *src,
446+
bool fastleave)
446447
{
447448
struct net_bridge_port_group *p, *pg = src->pg;
448449
struct net_bridge_port_group __rcu **pp;
@@ -467,6 +468,8 @@ static void br_multicast_fwd_src_remove(struct net_bridge_group_src *src)
467468
(p->flags & MDB_PG_FLAGS_PERMANENT))
468469
break;
469470

471+
if (fastleave)
472+
p->flags |= MDB_PG_FLAGS_FAST_LEAVE;
470473
br_multicast_del_pg(mp, p, pp);
471474
break;
472475
}
@@ -560,11 +563,12 @@ static void br_multicast_destroy_group_src(struct net_bridge_mcast_gc *gc)
560563
kfree_rcu(src, rcu);
561564
}
562565

563-
void br_multicast_del_group_src(struct net_bridge_group_src *src)
566+
void br_multicast_del_group_src(struct net_bridge_group_src *src,
567+
bool fastleave)
564568
{
565569
struct net_bridge *br = src->pg->key.port->br;
566570

567-
br_multicast_fwd_src_remove(src);
571+
br_multicast_fwd_src_remove(src, fastleave);
568572
hlist_del_init_rcu(&src->node);
569573
src->pg->src_ents--;
570574
hlist_add_head(&src->mcast_gc.gc_node, &br->mcast_gc_list);
@@ -596,7 +600,7 @@ void br_multicast_del_pg(struct net_bridge_mdb_entry *mp,
596600
hlist_del_init(&pg->mglist);
597601
br_multicast_eht_clean_sets(pg);
598602
hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node)
599-
br_multicast_del_group_src(ent);
603+
br_multicast_del_group_src(ent, false);
600604
br_mdb_notify(br->dev, mp, pg, RTM_DELMDB);
601605
if (!br_multicast_is_star_g(&mp->addr)) {
602606
rhashtable_remove_fast(&br->sg_port_tbl, &pg->rhnode,
@@ -653,7 +657,7 @@ static void br_multicast_port_group_expired(struct timer_list *t)
653657
pg->filter_mode = MCAST_INCLUDE;
654658
hlist_for_each_entry_safe(src_ent, tmp, &pg->src_list, node) {
655659
if (!timer_pending(&src_ent->timer)) {
656-
br_multicast_del_group_src(src_ent);
660+
br_multicast_del_group_src(src_ent, false);
657661
changed = true;
658662
}
659663
}
@@ -1080,7 +1084,7 @@ static void br_multicast_group_src_expired(struct timer_list *t)
10801084

10811085
pg = src->pg;
10821086
if (pg->filter_mode == MCAST_INCLUDE) {
1083-
br_multicast_del_group_src(src);
1087+
br_multicast_del_group_src(src, false);
10841088
if (!hlist_empty(&pg->src_list))
10851089
goto out;
10861090
br_multicast_find_del_pg(br, pg);
@@ -1704,7 +1708,7 @@ static int __grp_src_delete_marked(struct net_bridge_port_group *pg)
17041708

17051709
hlist_for_each_entry_safe(ent, tmp, &pg->src_list, node)
17061710
if (ent->flags & BR_SGRP_F_DELETE) {
1707-
br_multicast_del_group_src(ent);
1711+
br_multicast_del_group_src(ent, false);
17081712
deleted++;
17091713
}
17101714

@@ -2053,6 +2057,7 @@ static bool br_multicast_toin(struct net_bridge_port_group *pg, void *h_addr,
20532057
}
20542058

20552059
if (br_multicast_eht_should_del_pg(pg)) {
2060+
pg->flags |= MDB_PG_FLAGS_FAST_LEAVE;
20562061
br_multicast_find_del_pg(pg->key.port->br, pg);
20572062
/* a notification has already been sent and we shouldn't
20582063
* access pg after the delete so we have to return false
@@ -2273,6 +2278,8 @@ static bool br_multicast_block(struct net_bridge_port_group *pg, void *h_addr,
22732278

22742279
if ((pg->filter_mode == MCAST_INCLUDE && hlist_empty(&pg->src_list)) ||
22752280
br_multicast_eht_should_del_pg(pg)) {
2281+
if (br_multicast_eht_should_del_pg(pg))
2282+
pg->flags |= MDB_PG_FLAGS_FAST_LEAVE;
22762283
br_multicast_find_del_pg(pg->key.port->br, pg);
22772284
/* a notification has already been sent and we shouldn't
22782285
* access pg after the delete so we have to return false

net/bridge/br_multicast_eht.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -537,7 +537,7 @@ static bool __eht_allow_excl(struct net_bridge_port_group *pg,
537537
src_ent = br_multicast_find_group_src(pg, &src_ip);
538538
if (!src_ent)
539539
continue;
540-
br_multicast_del_group_src(src_ent);
540+
br_multicast_del_group_src(src_ent, true);
541541
changed = true;
542542
}
543543
}
@@ -588,7 +588,7 @@ static bool __eht_block_incl(struct net_bridge_port_group *pg,
588588
src_ent = br_multicast_find_group_src(pg, &src_ip);
589589
if (!src_ent)
590590
continue;
591-
br_multicast_del_group_src(src_ent);
591+
br_multicast_del_group_src(src_ent, true);
592592
changed = true;
593593
}
594594

@@ -625,7 +625,7 @@ static bool __eht_block_excl(struct net_bridge_port_group *pg,
625625
src_ent = br_multicast_find_group_src(pg, &src_ip);
626626
if (!src_ent)
627627
continue;
628-
br_multicast_del_group_src(src_ent);
628+
br_multicast_del_group_src(src_ent, true);
629629
changed = true;
630630
}
631631
}
@@ -689,7 +689,7 @@ static bool __eht_inc_exc(struct net_bridge_port_group *pg,
689689
br_multicast_ip_src_to_eht_addr(&src_ent->addr,
690690
&eht_src_addr);
691691
if (!br_multicast_eht_set_lookup(pg, &eht_src_addr)) {
692-
br_multicast_del_group_src(src_ent);
692+
br_multicast_del_group_src(src_ent, true);
693693
changed = true;
694694
continue;
695695
}

net/bridge/br_private.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -850,7 +850,8 @@ void br_multicast_sg_add_exclude_ports(struct net_bridge_mdb_entry *star_mp,
850850
struct net_bridge_port_group *sg);
851851
struct net_bridge_group_src *
852852
br_multicast_find_group_src(struct net_bridge_port_group *pg, struct br_ip *ip);
853-
void br_multicast_del_group_src(struct net_bridge_group_src *src);
853+
void br_multicast_del_group_src(struct net_bridge_group_src *src,
854+
bool fastleave);
854855

855856
static inline bool br_group_is_l2(const struct br_ip *group)
856857
{

0 commit comments

Comments
 (0)