Skip to content

Commit cc0fdd8

Browse files
T-Xdavem330
authored andcommitted
bridge: separate querier and query timer into IGMP/IPv4 and MLD/IPv6 ones
Currently we would still potentially suffer multicast packet loss if there is just either an IGMP or an MLD querier: For the former case, we would possibly drop IPv6 multicast packets, for the latter IPv4 ones. This is because we are currently assuming that if either an IGMP or MLD querier is present that the other one is present, too. This patch makes the behaviour and fix added in "bridge: disable snooping if there is no querier" (b00589a) to also work if there is either just an IGMP or an MLD querier on the link: It refines the deactivation of the snooping to be protocol specific by using separate timers for the snooped IGMP and MLD queries as well as separate timers for our internal IGMP and MLD queriers. Signed-off-by: Linus Lüssing <linus.luessing@web.de> Signed-off-by: David S. Miller <davem@davemloft.net>
1 parent 79f9ab7 commit cc0fdd8

File tree

5 files changed

+240
-93
lines changed

5 files changed

+240
-93
lines changed

net/bridge/br_device.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ netdev_tx_t br_dev_xmit(struct sk_buff *skb, struct net_device *dev)
7171

7272
mdst = br_mdb_get(br, skb, vid);
7373
if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
74-
br_multicast_querier_exists(br))
74+
br_multicast_querier_exists(br, eth_hdr(skb)))
7575
br_multicast_deliver(mdst, skb);
7676
else
7777
br_flood_deliver(br, skb, false);

net/bridge/br_input.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ int br_handle_frame_finish(struct sk_buff *skb)
102102
} else if (is_multicast_ether_addr(dest)) {
103103
mdst = br_mdb_get(br, skb, vid);
104104
if ((mdst || BR_INPUT_SKB_CB_MROUTERS_ONLY(skb)) &&
105-
br_multicast_querier_exists(br)) {
105+
br_multicast_querier_exists(br, eth_hdr(skb))) {
106106
if ((mdst && mdst->mglist) ||
107107
br_multicast_is_router(br))
108108
skb2 = skb;

net/bridge/br_mdb.c

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -414,16 +414,20 @@ static int __br_mdb_del(struct net_bridge *br, struct br_mdb_entry *entry)
414414
if (!netif_running(br->dev) || br->multicast_disabled)
415415
return -EINVAL;
416416

417-
if (timer_pending(&br->multicast_querier_timer))
418-
return -EBUSY;
419-
420417
ip.proto = entry->addr.proto;
421-
if (ip.proto == htons(ETH_P_IP))
418+
if (ip.proto == htons(ETH_P_IP)) {
419+
if (timer_pending(&br->ip4_querier.timer))
420+
return -EBUSY;
421+
422422
ip.u.ip4 = entry->addr.u.ip4;
423423
#if IS_ENABLED(CONFIG_IPV6)
424-
else
424+
} else {
425+
if (timer_pending(&br->ip6_querier.timer))
426+
return -EBUSY;
427+
425428
ip.u.ip6 = entry->addr.u.ip6;
426429
#endif
430+
}
427431

428432
spin_lock_bh(&br->multicast_lock);
429433
mdb = mlock_dereference(br->mdb, br);

0 commit comments

Comments
 (0)