mirror of
https://github.com/torvalds/linux.git
synced 2025-04-12 06:49:52 +00:00
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 <petrm@nvidia.com> Reviewed-by: Ido Schimmel <idosch@nvidia.com> Acked-by: Nikolay Aleksandrov <razor@blackwall.org> Link: https://patch.msgid.link/90a8ca8aea4d81378b29d75d9e562433e0d5c7ff.1734540770.git.petrm@nvidia.com Signed-off-by: Jakub Kicinski <kuba@kernel.org>
This commit is contained in:
parent
f284424dc1
commit
3abd45122c
@ -51,6 +51,13 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v
|
||||
}
|
||||
}
|
||||
|
||||
if (is_vlan_dev(dev)) {
|
||||
struct net_device *real_dev = vlan_dev_real_dev(dev);
|
||||
|
||||
if (netif_is_bridge_master(real_dev))
|
||||
br_vlan_vlan_upper_event(real_dev, dev, event);
|
||||
}
|
||||
|
||||
/* not a port of a bridge */
|
||||
p = br_port_get_rtnl(dev);
|
||||
if (!p)
|
||||
|
@ -1571,6 +1571,9 @@ void br_vlan_get_stats(const struct net_bridge_vlan *v,
|
||||
void br_vlan_port_event(struct net_bridge_port *p, unsigned long event);
|
||||
int br_vlan_bridge_event(struct net_device *dev, unsigned long event,
|
||||
void *ptr);
|
||||
void br_vlan_vlan_upper_event(struct net_device *br_dev,
|
||||
struct net_device *vlan_dev,
|
||||
unsigned long event);
|
||||
int br_vlan_rtnl_init(void);
|
||||
void br_vlan_rtnl_uninit(void);
|
||||
void br_vlan_notify(const struct net_bridge *br,
|
||||
@ -1802,6 +1805,12 @@ static inline int br_vlan_bridge_event(struct net_device *dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline void br_vlan_vlan_upper_event(struct net_device *br_dev,
|
||||
struct net_device *vlan_dev,
|
||||
unsigned long event)
|
||||
{
|
||||
}
|
||||
|
||||
static inline int br_vlan_rtnl_init(void)
|
||||
{
|
||||
return 0;
|
||||
|
@ -1772,6 +1772,30 @@ int br_vlan_bridge_event(struct net_device *dev, unsigned long event, void *ptr)
|
||||
return ret;
|
||||
}
|
||||
|
||||
void br_vlan_vlan_upper_event(struct net_device *br_dev,
|
||||
struct net_device *vlan_dev,
|
||||
unsigned long event)
|
||||
{
|
||||
struct vlan_dev_priv *vlan = vlan_dev_priv(vlan_dev);
|
||||
struct net_bridge *br = netdev_priv(br_dev);
|
||||
bool bridge_binding;
|
||||
|
||||
switch (event) {
|
||||
case NETDEV_CHANGE:
|
||||
case NETDEV_UP:
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
||||
bridge_binding = vlan->flags & VLAN_FLAG_BRIDGE_BINDING;
|
||||
br_vlan_toggle_bridge_binding(br_dev, bridge_binding);
|
||||
if (bridge_binding)
|
||||
br_vlan_set_vlan_dev_state(br, vlan_dev);
|
||||
else if (!bridge_binding && netif_carrier_ok(br_dev))
|
||||
netif_carrier_on(vlan_dev);
|
||||
}
|
||||
|
||||
/* Must be protected by RTNL. */
|
||||
void br_vlan_port_event(struct net_bridge_port *p, unsigned long event)
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user