Skip to content

Commit e5baec5

Browse files
committed
net: bridge: Handle changes in VLAN_FLAG_BRIDGE_BINDING
JIRA: https://issues.redhat.com/browse/RHEL-75595 commit 3abd451 Author: Petr Machata <[email protected]> Date: Wed Dec 18 18:15:57 2024 +0100 net: bridge: Handle changes in VLAN_FLAG_BRIDGE_BINDING When bridge binding is enabled on a VLAN netdevice, its link state should track bridge ports that are members of the corresponding VLAN. This works for newly-added netdevices. However toggling the option does not have the effect of enabling or disabling the behavior as appropriate. In this patch, react to bridge_binding toggles on VLAN uppers. Signed-off-by: Petr Machata <[email protected]> Reviewed-by: Ido Schimmel <[email protected]> Acked-by: Nikolay Aleksandrov <[email protected]> Link: https://patch.msgid.link/90a8ca8aea4d81378b29d75d9e562433e0d5c7ff.1734540770.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <[email protected]> Signed-off-by: Mohammad Heib <[email protected]>
1 parent a5e342c commit e5baec5

File tree

3 files changed

+40
-0
lines changed

3 files changed

+40
-0
lines changed

net/bridge/br.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,13 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
5151
}
5252
}
5353

54+
if (is_vlan_dev(dev)) {
55+
struct net_device *real_dev = vlan_dev_real_dev(dev);
56+
57+
if (netif_is_bridge_master(real_dev))
58+
br_vlan_vlan_upper_event(real_dev, dev, event);
59+
}
60+
5461
/* not a port of a bridge */
5562
p = br_port_get_rtnl(dev);
5663
if (!p)

net/bridge/br_private.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1571,6 +1571,9 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
15711571
void br_vlan_port_event(struct net_bridge_port *p, unsigned long event);
15721572
int br_vlan_bridge_event(struct net_device *dev, unsigned long event,
15731573
void *ptr);
1574+
void br_vlan_vlan_upper_event(struct net_device *br_dev,
1575+
struct net_device *vlan_dev,
1576+
unsigned long event);
15741577
int br_vlan_rtnl_init(void);
15751578
void br_vlan_rtnl_uninit(void);
15761579
void br_vlan_notify(const struct net_bridge *br,
@@ -1802,6 +1805,12 @@ static inline int br_vlan_bridge_event(struct net_device *dev,
18021805
return 0;
18031806
}
18041807

1808+
static inline void br_vlan_vlan_upper_event(struct net_device *br_dev,
1809+
struct net_device *vlan_dev,
1810+
unsigned long event)
1811+
{
1812+
}
1813+
18051814
static inline int br_vlan_rtnl_init(void)
18061815
{
18071816
return 0;

net/bridge/br_vlan.c

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1772,6 +1772,30 @@ int br_vlan_bridge_event(struct net_device *dev, unsigned long event, void *ptr)
17721772
return ret;
17731773
}
17741774

1775+
void br_vlan_vlan_upper_event(struct net_device *br_dev,
1776+
struct net_device *vlan_dev,
1777+
unsigned long event)
1778+
{
1779+
struct vlan_dev_priv *vlan = vlan_dev_priv(vlan_dev);
1780+
struct net_bridge *br = netdev_priv(br_dev);
1781+
bool bridge_binding;
1782+
1783+
switch (event) {
1784+
case NETDEV_CHANGE:
1785+
case NETDEV_UP:
1786+
break;
1787+
default:
1788+
return;
1789+
}
1790+
1791+
bridge_binding = vlan->flags & VLAN_FLAG_BRIDGE_BINDING;
1792+
br_vlan_toggle_bridge_binding(br_dev, bridge_binding);
1793+
if (bridge_binding)
1794+
br_vlan_set_vlan_dev_state(br, vlan_dev);
1795+
else if (!bridge_binding && netif_carrier_ok(br_dev))
1796+
netif_carrier_on(vlan_dev);
1797+
}
1798+
17751799
/* Must be protected by RTNL. */
17761800
void br_vlan_port_event(struct net_bridge_port *p, unsigned long event)
17771801
{

0 commit comments

Comments
 (0)