Commit 851d0a7
bridge: Fix a deadlock when enabling multicast snooping
When enabling multicast snooping, bridge module deadlocks on multicast_lock
if 1) IPv6 is enabled, and 2) there is an existing querier on the same L2
network.
The deadlock was caused by the following sequence: While holding the lock,
br_multicast_open calls br_multicast_join_snoopers, which eventually causes
IP stack to (attempt to) send out a Listener Report (in igmp6_join_group).
Since the destination Ethernet address is a multicast address, br_dev_xmit
feeds the packet back to the bridge via br_multicast_rcv, which in turn
calls br_multicast_add_group, which then deadlocks on multicast_lock.
The fix is to move the call br_multicast_join_snoopers outside of the
critical section. This works since br_multicast_join_snoopers only deals
with IP and does not modify any multicast data structures of the bridge,
so there's no need to hold the lock.
Steps to reproduce:
1. sysctl net.ipv6.conf.all.force_mld_version=1
2. have another querier
3. ip link set dev bridge type bridge mcast_snooping 0 && \
ip link set dev bridge type bridge mcast_snooping 1 < deadlock >
A typical call trace looks like the following:
[ 936.251495] _raw_spin_lock+0x5c/0x68
[ 936.255221] br_multicast_add_group+0x40/0x170 [bridge]
[ 936.260491] br_multicast_rcv+0x7ac/0xe30 [bridge]
[ 936.265322] br_dev_xmit+0x140/0x368 [bridge]
[ 936.269689] dev_hard_start_xmit+0x94/0x158
[ 936.273876] __dev_queue_xmit+0x5ac/0x7f8
[ 936.277890] dev_queue_xmit+0x10/0x18
[ 936.281563] neigh_resolve_output+0xec/0x198
[ 936.285845] ip6_finish_output2+0x240/0x710
[ 936.290039] __ip6_finish_output+0x130/0x170
[ 936.294318] ip6_output+0x6c/0x1c8
[ 936.297731] NF_HOOK.constprop.0+0xd8/0xe8
[ 936.301834] igmp6_send+0x358/0x558
[ 936.305326] igmp6_join_group.part.0+0x30/0xf0
[ 936.309774] igmp6_group_added+0xfc/0x110
[ 936.313787] __ipv6_dev_mc_inc+0x1a4/0x290
[ 936.317885] ipv6_dev_mc_inc+0x10/0x18
[ 936.321677] br_multicast_open+0xbc/0x110 [bridge]
[ 936.326506] br_multicast_toggle+0xec/0x140 [bridge]
Fixes: 4effd28 ("bridge: join all-snoopers multicast address")
Signed-off-by: Joseph Huang <[email protected]>
Acked-by: Nikolay Aleksandrov <[email protected]>
Link: https://lore.kernel.org/r/[email protected]
Signed-off-by: Jakub Kicinski <[email protected]>1 parent eb96b68 commit 851d0a7
3 files changed
+41
-9
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
177 | 177 | | |
178 | 178 | | |
179 | 179 | | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
180 | 183 | | |
181 | 184 | | |
182 | 185 | | |
| |||
197 | 200 | | |
198 | 201 | | |
199 | 202 | | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
200 | 206 | | |
201 | 207 | | |
202 | 208 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3286 | 3286 | | |
3287 | 3287 | | |
3288 | 3288 | | |
3289 | | - | |
| 3289 | + | |
3290 | 3290 | | |
3291 | 3291 | | |
3292 | 3292 | | |
| |||
3317 | 3317 | | |
3318 | 3318 | | |
3319 | 3319 | | |
3320 | | - | |
| 3320 | + | |
3321 | 3321 | | |
3322 | 3322 | | |
3323 | 3323 | | |
| |||
3336 | 3336 | | |
3337 | 3337 | | |
3338 | 3338 | | |
3339 | | - | |
3340 | | - | |
3341 | | - | |
3342 | 3339 | | |
3343 | 3340 | | |
3344 | 3341 | | |
| |||
3354 | 3351 | | |
3355 | 3352 | | |
3356 | 3353 | | |
3357 | | - | |
3358 | | - | |
3359 | | - | |
3360 | 3354 | | |
3361 | 3355 | | |
3362 | 3356 | | |
| |||
3487 | 3481 | | |
3488 | 3482 | | |
3489 | 3483 | | |
| 3484 | + | |
3490 | 3485 | | |
3491 | 3486 | | |
3492 | 3487 | | |
| |||
3495 | 3490 | | |
3496 | 3491 | | |
3497 | 3492 | | |
3498 | | - | |
| 3493 | + | |
3499 | 3494 | | |
3500 | 3495 | | |
3501 | 3496 | | |
| |||
3506 | 3501 | | |
3507 | 3502 | | |
3508 | 3503 | | |
| 3504 | + | |
| 3505 | + | |
3509 | 3506 | | |
3510 | 3507 | | |
3511 | 3508 | | |
| 3509 | + | |
| 3510 | + | |
| 3511 | + | |
| 3512 | + | |
| 3513 | + | |
| 3514 | + | |
| 3515 | + | |
| 3516 | + | |
| 3517 | + | |
| 3518 | + | |
| 3519 | + | |
| 3520 | + | |
| 3521 | + | |
| 3522 | + | |
| 3523 | + | |
| 3524 | + | |
| 3525 | + | |
| 3526 | + | |
| 3527 | + | |
3512 | 3528 | | |
3513 | 3529 | | |
3514 | 3530 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
792 | 792 | | |
793 | 793 | | |
794 | 794 | | |
| 795 | + | |
| 796 | + | |
795 | 797 | | |
796 | 798 | | |
797 | 799 | | |
| |||
969 | 971 | | |
970 | 972 | | |
971 | 973 | | |
| 974 | + | |
| 975 | + | |
| 976 | + | |
| 977 | + | |
| 978 | + | |
| 979 | + | |
| 980 | + | |
| 981 | + | |
972 | 982 | | |
973 | 983 | | |
974 | 984 | | |
| |||
0 commit comments