Skip to content

Commit 9bb8a9f

Browse files
committed
Merge branch 'net-vlan-fix-vlan-0-refcount-imbalance-of-toggling-filtering-during-runtime'
Dong Chenchen says: ==================== net: vlan: fix VLAN 0 refcount imbalance of toggling filtering during runtime Fix VLAN 0 refcount imbalance of toggling filtering during runtime. ==================== Link: https://patch.msgid.link/[email protected] Signed-off-by: Jakub Kicinski <[email protected]>
2 parents afb5bef + e0f3b3e commit 9bb8a9f

File tree

3 files changed

+120
-21
lines changed

3 files changed

+120
-21
lines changed

net/8021q/vlan.c

Lines changed: 33 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,35 @@ static int __vlan_device_event(struct net_device *dev, unsigned long event)
357357
return err;
358358
}
359359

360+
static void vlan_vid0_add(struct net_device *dev)
361+
{
362+
struct vlan_info *vlan_info;
363+
int err;
364+
365+
if (!(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
366+
return;
367+
368+
pr_info("adding VLAN 0 to HW filter on device %s\n", dev->name);
369+
370+
err = vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
371+
if (err)
372+
return;
373+
374+
vlan_info = rtnl_dereference(dev->vlan_info);
375+
vlan_info->auto_vid0 = true;
376+
}
377+
378+
static void vlan_vid0_del(struct net_device *dev)
379+
{
380+
struct vlan_info *vlan_info = rtnl_dereference(dev->vlan_info);
381+
382+
if (!vlan_info || !vlan_info->auto_vid0)
383+
return;
384+
385+
vlan_info->auto_vid0 = false;
386+
vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
387+
}
388+
360389
static int vlan_device_event(struct notifier_block *unused, unsigned long event,
361390
void *ptr)
362391
{
@@ -378,15 +407,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
378407
return notifier_from_errno(err);
379408
}
380409

381-
if ((event == NETDEV_UP) &&
382-
(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
383-
pr_info("adding VLAN 0 to HW filter on device %s\n",
384-
dev->name);
385-
vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
386-
}
387-
if (event == NETDEV_DOWN &&
388-
(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
389-
vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
410+
if (event == NETDEV_UP)
411+
vlan_vid0_add(dev);
412+
else if (event == NETDEV_DOWN)
413+
vlan_vid0_del(dev);
390414

391415
vlan_info = rtnl_dereference(dev->vlan_info);
392416
if (!vlan_info)

net/8021q/vlan.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ struct vlan_info {
3333
struct vlan_group grp;
3434
struct list_head vid_list;
3535
unsigned int nr_vids;
36+
bool auto_vid0;
3637
struct rcu_head rcu;
3738
};
3839

tools/testing/selftests/net/vlan_hw_filter.sh

Lines changed: 86 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,101 @@
33

44
readonly NETNS="ns-$(mktemp -u XXXXXX)"
55

6+
ALL_TESTS="
7+
test_vlan_filter_check
8+
test_vlan0_del_crash_01
9+
test_vlan0_del_crash_02
10+
test_vlan0_del_crash_03
11+
test_vid0_memleak
12+
"
13+
614
ret=0
715

16+
setup() {
17+
ip netns add ${NETNS}
18+
}
19+
820
cleanup() {
9-
ip netns del $NETNS
21+
ip netns del $NETNS 2>/dev/null
1022
}
1123

1224
trap cleanup EXIT
1325

1426
fail() {
15-
echo "ERROR: ${1:-unexpected return code} (ret: $_)" >&2
16-
ret=1
27+
echo "ERROR: ${1:-unexpected return code} (ret: $_)" >&2
28+
ret=1
29+
}
30+
31+
tests_run()
32+
{
33+
local current_test
34+
for current_test in ${TESTS:-$ALL_TESTS}; do
35+
$current_test
36+
done
37+
}
38+
39+
test_vlan_filter_check() {
40+
setup
41+
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
42+
ip netns exec ${NETNS} ip link add bond_slave_1 type veth peer veth2
43+
ip netns exec ${NETNS} ip link set bond_slave_1 master bond0
44+
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
45+
ip netns exec ${NETNS} ip link add link bond_slave_1 name bond_slave_1.0 type vlan id 0
46+
ip netns exec ${NETNS} ip link add link bond0 name bond0.0 type vlan id 0
47+
ip netns exec ${NETNS} ip link set bond_slave_1 nomaster
48+
ip netns exec ${NETNS} ip link del veth2 || fail "Please check vlan HW filter function"
49+
cleanup
1750
}
1851

19-
ip netns add ${NETNS}
20-
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
21-
ip netns exec ${NETNS} ip link add bond_slave_1 type veth peer veth2
22-
ip netns exec ${NETNS} ip link set bond_slave_1 master bond0
23-
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
24-
ip netns exec ${NETNS} ip link add link bond_slave_1 name bond_slave_1.0 type vlan id 0
25-
ip netns exec ${NETNS} ip link add link bond0 name bond0.0 type vlan id 0
26-
ip netns exec ${NETNS} ip link set bond_slave_1 nomaster
27-
ip netns exec ${NETNS} ip link del veth2 || fail "Please check vlan HW filter function"
52+
#enable vlan_filter feature of real_dev with vlan0 during running time
53+
test_vlan0_del_crash_01() {
54+
setup
55+
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
56+
ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q
57+
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
58+
ip netns exec ${NETNS} ifconfig bond0 up
59+
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on
60+
ip netns exec ${NETNS} ifconfig bond0 down
61+
ip netns exec ${NETNS} ifconfig bond0 up
62+
ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function"
63+
cleanup
64+
}
65+
66+
#enable vlan_filter feature and add vlan0 for real_dev during running time
67+
test_vlan0_del_crash_02() {
68+
setup
69+
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
70+
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
71+
ip netns exec ${NETNS} ifconfig bond0 up
72+
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on
73+
ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q
74+
ip netns exec ${NETNS} ifconfig bond0 down
75+
ip netns exec ${NETNS} ifconfig bond0 up
76+
ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function"
77+
cleanup
78+
}
79+
80+
#enable vlan_filter feature of real_dev during running time
81+
#test kernel_bug of vlan unregister
82+
test_vlan0_del_crash_03() {
83+
setup
84+
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
85+
ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q
86+
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
87+
ip netns exec ${NETNS} ifconfig bond0 up
88+
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on
89+
ip netns exec ${NETNS} ifconfig bond0 down
90+
ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function"
91+
cleanup
92+
}
93+
94+
test_vid0_memleak() {
95+
setup
96+
ip netns exec ${NETNS} ip link add bond0 up type bond mode 0
97+
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
98+
ip netns exec ${NETNS} ip link del dev bond0 || fail "Please check vlan HW filter function"
99+
cleanup
100+
}
28101

102+
tests_run
29103
exit $ret

0 commit comments

Comments
 (0)