mirror of
https://github.com/torvalds/linux.git
synced 2026-05-25 23:52:08 +02:00
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/20250716034504.2285203-1-dongchenchen2@huawei.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
commit
9bb8a9f6ea
|
|
@ -357,6 +357,35 @@ static int __vlan_device_event(struct net_device *dev, unsigned long event)
|
|||
return err;
|
||||
}
|
||||
|
||||
static void vlan_vid0_add(struct net_device *dev)
|
||||
{
|
||||
struct vlan_info *vlan_info;
|
||||
int err;
|
||||
|
||||
if (!(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
|
||||
return;
|
||||
|
||||
pr_info("adding VLAN 0 to HW filter on device %s\n", dev->name);
|
||||
|
||||
err = vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
|
||||
if (err)
|
||||
return;
|
||||
|
||||
vlan_info = rtnl_dereference(dev->vlan_info);
|
||||
vlan_info->auto_vid0 = true;
|
||||
}
|
||||
|
||||
static void vlan_vid0_del(struct net_device *dev)
|
||||
{
|
||||
struct vlan_info *vlan_info = rtnl_dereference(dev->vlan_info);
|
||||
|
||||
if (!vlan_info || !vlan_info->auto_vid0)
|
||||
return;
|
||||
|
||||
vlan_info->auto_vid0 = false;
|
||||
vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
|
||||
}
|
||||
|
||||
static int vlan_device_event(struct notifier_block *unused, unsigned long event,
|
||||
void *ptr)
|
||||
{
|
||||
|
|
@ -378,15 +407,10 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
|
|||
return notifier_from_errno(err);
|
||||
}
|
||||
|
||||
if ((event == NETDEV_UP) &&
|
||||
(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER)) {
|
||||
pr_info("adding VLAN 0 to HW filter on device %s\n",
|
||||
dev->name);
|
||||
vlan_vid_add(dev, htons(ETH_P_8021Q), 0);
|
||||
}
|
||||
if (event == NETDEV_DOWN &&
|
||||
(dev->features & NETIF_F_HW_VLAN_CTAG_FILTER))
|
||||
vlan_vid_del(dev, htons(ETH_P_8021Q), 0);
|
||||
if (event == NETDEV_UP)
|
||||
vlan_vid0_add(dev);
|
||||
else if (event == NETDEV_DOWN)
|
||||
vlan_vid0_del(dev);
|
||||
|
||||
vlan_info = rtnl_dereference(dev->vlan_info);
|
||||
if (!vlan_info)
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ struct vlan_info {
|
|||
struct vlan_group grp;
|
||||
struct list_head vid_list;
|
||||
unsigned int nr_vids;
|
||||
bool auto_vid0;
|
||||
struct rcu_head rcu;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -3,27 +3,101 @@
|
|||
|
||||
readonly NETNS="ns-$(mktemp -u XXXXXX)"
|
||||
|
||||
ALL_TESTS="
|
||||
test_vlan_filter_check
|
||||
test_vlan0_del_crash_01
|
||||
test_vlan0_del_crash_02
|
||||
test_vlan0_del_crash_03
|
||||
test_vid0_memleak
|
||||
"
|
||||
|
||||
ret=0
|
||||
|
||||
setup() {
|
||||
ip netns add ${NETNS}
|
||||
}
|
||||
|
||||
cleanup() {
|
||||
ip netns del $NETNS
|
||||
ip netns del $NETNS 2>/dev/null
|
||||
}
|
||||
|
||||
trap cleanup EXIT
|
||||
|
||||
fail() {
|
||||
echo "ERROR: ${1:-unexpected return code} (ret: $_)" >&2
|
||||
ret=1
|
||||
echo "ERROR: ${1:-unexpected return code} (ret: $_)" >&2
|
||||
ret=1
|
||||
}
|
||||
|
||||
ip netns add ${NETNS}
|
||||
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
|
||||
ip netns exec ${NETNS} ip link add bond_slave_1 type veth peer veth2
|
||||
ip netns exec ${NETNS} ip link set bond_slave_1 master bond0
|
||||
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
|
||||
ip netns exec ${NETNS} ip link add link bond_slave_1 name bond_slave_1.0 type vlan id 0
|
||||
ip netns exec ${NETNS} ip link add link bond0 name bond0.0 type vlan id 0
|
||||
ip netns exec ${NETNS} ip link set bond_slave_1 nomaster
|
||||
ip netns exec ${NETNS} ip link del veth2 || fail "Please check vlan HW filter function"
|
||||
tests_run()
|
||||
{
|
||||
local current_test
|
||||
for current_test in ${TESTS:-$ALL_TESTS}; do
|
||||
$current_test
|
||||
done
|
||||
}
|
||||
|
||||
test_vlan_filter_check() {
|
||||
setup
|
||||
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
|
||||
ip netns exec ${NETNS} ip link add bond_slave_1 type veth peer veth2
|
||||
ip netns exec ${NETNS} ip link set bond_slave_1 master bond0
|
||||
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
|
||||
ip netns exec ${NETNS} ip link add link bond_slave_1 name bond_slave_1.0 type vlan id 0
|
||||
ip netns exec ${NETNS} ip link add link bond0 name bond0.0 type vlan id 0
|
||||
ip netns exec ${NETNS} ip link set bond_slave_1 nomaster
|
||||
ip netns exec ${NETNS} ip link del veth2 || fail "Please check vlan HW filter function"
|
||||
cleanup
|
||||
}
|
||||
|
||||
#enable vlan_filter feature of real_dev with vlan0 during running time
|
||||
test_vlan0_del_crash_01() {
|
||||
setup
|
||||
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
|
||||
ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q
|
||||
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
|
||||
ip netns exec ${NETNS} ifconfig bond0 up
|
||||
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on
|
||||
ip netns exec ${NETNS} ifconfig bond0 down
|
||||
ip netns exec ${NETNS} ifconfig bond0 up
|
||||
ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function"
|
||||
cleanup
|
||||
}
|
||||
|
||||
#enable vlan_filter feature and add vlan0 for real_dev during running time
|
||||
test_vlan0_del_crash_02() {
|
||||
setup
|
||||
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
|
||||
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
|
||||
ip netns exec ${NETNS} ifconfig bond0 up
|
||||
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on
|
||||
ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q
|
||||
ip netns exec ${NETNS} ifconfig bond0 down
|
||||
ip netns exec ${NETNS} ifconfig bond0 up
|
||||
ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function"
|
||||
cleanup
|
||||
}
|
||||
|
||||
#enable vlan_filter feature of real_dev during running time
|
||||
#test kernel_bug of vlan unregister
|
||||
test_vlan0_del_crash_03() {
|
||||
setup
|
||||
ip netns exec ${NETNS} ip link add bond0 type bond mode 0
|
||||
ip netns exec ${NETNS} ip link add link bond0 name vlan0 type vlan id 0 protocol 802.1q
|
||||
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
|
||||
ip netns exec ${NETNS} ifconfig bond0 up
|
||||
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter on
|
||||
ip netns exec ${NETNS} ifconfig bond0 down
|
||||
ip netns exec ${NETNS} ip link del vlan0 || fail "Please check vlan HW filter function"
|
||||
cleanup
|
||||
}
|
||||
|
||||
test_vid0_memleak() {
|
||||
setup
|
||||
ip netns exec ${NETNS} ip link add bond0 up type bond mode 0
|
||||
ip netns exec ${NETNS} ethtool -K bond0 rx-vlan-filter off
|
||||
ip netns exec ${NETNS} ip link del dev bond0 || fail "Please check vlan HW filter function"
|
||||
cleanup
|
||||
}
|
||||
|
||||
tests_run
|
||||
exit $ret
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user