diff options
| author | Jakub Kicinski <kuba@kernel.org> | 2025-07-17 07:44:30 -0700 |
|---|---|---|
| committer | Jakub Kicinski <kuba@kernel.org> | 2025-07-17 07:44:31 -0700 |
| commit | 9bb8a9f6ea964e25b2a2a6e464bad85ea591b230 (patch) | |
| tree | fba7eae0038048b197d8b4d65baf8293fa53019a /net | |
| parent | Merge tag 'ovpn-net-20250716' of https://github.com/OpenVPN/ovpn-net-next (diff) | |
| parent | selftests: Add test cases for vlan_filter modification during runtime (diff) | |
| download | linux-9bb8a9f6ea964e25b2a2a6e464bad85ea591b230.tar.gz linux-9bb8a9f6ea964e25b2a2a6e464bad85ea591b230.zip | |
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>
Diffstat (limited to 'net')
| -rw-r--r-- | net/8021q/vlan.c | 42 | ||||
| -rw-r--r-- | net/8021q/vlan.h | 1 |
2 files changed, 34 insertions, 9 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 06908e37c3d9..9a6df8c1daf9 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c @@ -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) diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index 5eaf38875554..c7ffe591d593 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h @@ -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; }; |
