net: check vlan filter feature in vlan_vids_add_by_dev() and vlan_vids_del_by_dev()
[ Upstream commit 01a564bab4876007ce35f312e16797dfe40e4823 ] I got the below warning trace: WARNING: CPU: 4 PID: 4056 at net/core/dev.c:11066 unregister_netdevice_many_notify CPU: 4 PID: 4056 Comm: ip Not tainted 6.7.0-rc4+ #15 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.15.0-1 04/01/2014 RIP: 0010:unregister_netdevice_many_notify+0x9a4/0x9b0 Call Trace: rtnl_dellink rtnetlink_rcv_msg netlink_rcv_skb netlink_unicast netlink_sendmsg __sock_sendmsg ____sys_sendmsg ___sys_sendmsg __sys_sendmsg do_syscall_64 entry_SYSCALL_64_after_hwframe It can be repoduced via: ip netns add ns1 ip netns exec ns1 ip link add bond0 type bond mode 0 ip netns exec ns1 ip link add bond_slave_1 type veth peer veth2 ip netns exec ns1 ip link set bond_slave_1 master bond0 [1] ip netns exec ns1 ethtool -K bond0 rx-vlan-filter off [2] ip netns exec ns1 ip link add link bond_slave_1 name bond_slave_1.0 type vlan id 0 [3] ip netns exec ns1 ip link add link bond0 name bond0.0 type vlan id 0 [4] ip netns exec ns1 ip link set bond_slave_1 nomaster [5] ip netns exec ns1 ip link del veth2 ip netns del ns1 This is all caused by command [1] turning off the rx-vlan-filter function of bond0. The reason is the same as commit01f4fd2708
("bonding: Fix incorrect deletion of ETH_P_8021AD protocol vid from slaves"). Commands [2] [3] add the same vid to slave and master respectively, causing command [4] to empty slave->vlan_info. The following command [5] triggers this problem. To fix this problem, we should add VLAN_FILTER feature checks in vlan_vids_add_by_dev() and vlan_vids_del_by_dev() to prevent incorrect addition or deletion of vlan_vid information. Fixes:348a1443cc
("vlan: introduce functions to do mass addition/deletion of vids by another device") Signed-off-by: Liu Jian <liujian56@huawei.com> Signed-off-by: Paolo Abeni <pabeni@redhat.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
This commit is contained in:
parent
ea03196ebc
commit
a70c2dd741
|
@ -407,6 +407,8 @@ int vlan_vids_add_by_dev(struct net_device *dev,
|
|||
return 0;
|
||||
|
||||
list_for_each_entry(vid_info, &vlan_info->vid_list, list) {
|
||||
if (!vlan_hw_filter_capable(by_dev, vid_info->proto))
|
||||
continue;
|
||||
err = vlan_vid_add(dev, vid_info->proto, vid_info->vid);
|
||||
if (err)
|
||||
goto unwind;
|
||||
|
@ -417,6 +419,8 @@ int vlan_vids_add_by_dev(struct net_device *dev,
|
|||
list_for_each_entry_continue_reverse(vid_info,
|
||||
&vlan_info->vid_list,
|
||||
list) {
|
||||
if (!vlan_hw_filter_capable(by_dev, vid_info->proto))
|
||||
continue;
|
||||
vlan_vid_del(dev, vid_info->proto, vid_info->vid);
|
||||
}
|
||||
|
||||
|
@ -436,8 +440,11 @@ void vlan_vids_del_by_dev(struct net_device *dev,
|
|||
if (!vlan_info)
|
||||
return;
|
||||
|
||||
list_for_each_entry(vid_info, &vlan_info->vid_list, list)
|
||||
list_for_each_entry(vid_info, &vlan_info->vid_list, list) {
|
||||
if (!vlan_hw_filter_capable(by_dev, vid_info->proto))
|
||||
continue;
|
||||
vlan_vid_del(dev, vid_info->proto, vid_info->vid);
|
||||
}
|
||||
}
|
||||
EXPORT_SYMBOL(vlan_vids_del_by_dev);
|
||||
|
||||
|
|
Loading…
Reference in New Issue