aboutsummaryrefslogtreecommitdiffstats
path: root/net/8021q/vlan_dev.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2019-04-19 16:58:17 -0400
committerDavid S. Miller <davem@davemloft.net>2019-04-19 16:58:17 -0400
commit1ab839281cf72476988901a2606378d76530f99c (patch)
treeba9d30159bb848eb705fa8d3c88e31b819e3921f /net/8021q/vlan_dev.c
parent7d26c96052cd42439180edfeee48cc784075b78a (diff)
parent8e1acd4fc552f5590e9d5ff6e5cb5eeafd638d30 (diff)
Merge branch 'net-support-binding-vlan-dev-link-state-to-vlan-member-bridge-ports'
Mike Manning says: ==================== net: support binding vlan dev link state to vlan member bridge ports For vlan filtering on bridges, the bridge may also have vlan devices as upper devices. For switches, these are used to provide L3 packet processing for ports that are members of a given vlan. While it is correct that the admin state for these vlan devices is either set directly for the device or inherited from the lower device, the link state is also transferred from the lower device. So this is always up if the bridge is in admin up state and there is at least one bridge port that is up, regardless of the vlan that the port is in. The link state of the vlan device may need to track only the state of the subset of ports that are also members of the corresponding vlan, rather than that of all ports. This series provides an optional vlan flag so that the link state of the vlan device is only up if there is at least one bridge port that is up AND is a member of the corresponding vlan. v2: - Address review comments from Nikolay Aleksandrov in patches 3 & 4 and add patch 5 to address bridge link down due to STP v3: - Address review comment from Nikolay Aleksandrov in patch 4 so as to remove unnecessary inline #ifdef ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r--net/8021q/vlan_dev.c22
1 files changed, 14 insertions, 8 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 8d77b6ee4477..f044ae56a313 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -223,7 +223,8 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask)
223 u32 old_flags = vlan->flags; 223 u32 old_flags = vlan->flags;
224 224
225 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP | 225 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |
226 VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP)) 226 VLAN_FLAG_LOOSE_BINDING | VLAN_FLAG_MVRP |
227 VLAN_FLAG_BRIDGE_BINDING))
227 return -EINVAL; 228 return -EINVAL;
228 229
229 vlan->flags = (old_flags & ~mask) | (flags & mask); 230 vlan->flags = (old_flags & ~mask) | (flags & mask);
@@ -296,7 +297,8 @@ static int vlan_dev_open(struct net_device *dev)
296 if (vlan->flags & VLAN_FLAG_MVRP) 297 if (vlan->flags & VLAN_FLAG_MVRP)
297 vlan_mvrp_request_join(dev); 298 vlan_mvrp_request_join(dev);
298 299
299 if (netif_carrier_ok(real_dev)) 300 if (netif_carrier_ok(real_dev) &&
301 !(vlan->flags & VLAN_FLAG_BRIDGE_BINDING))
300 netif_carrier_on(dev); 302 netif_carrier_on(dev);
301 return 0; 303 return 0;
302 304
@@ -326,7 +328,8 @@ static int vlan_dev_stop(struct net_device *dev)
326 if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) 328 if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr))
327 dev_uc_del(real_dev, dev->dev_addr); 329 dev_uc_del(real_dev, dev->dev_addr);
328 330
329 netif_carrier_off(dev); 331 if (!(vlan->flags & VLAN_FLAG_BRIDGE_BINDING))
332 netif_carrier_off(dev);
330 return 0; 333 return 0;
331} 334}
332 335
@@ -550,7 +553,8 @@ static const struct net_device_ops vlan_netdev_ops;
550 553
551static int vlan_dev_init(struct net_device *dev) 554static int vlan_dev_init(struct net_device *dev)
552{ 555{
553 struct net_device *real_dev = vlan_dev_priv(dev)->real_dev; 556 struct vlan_dev_priv *vlan = vlan_dev_priv(dev);
557 struct net_device *real_dev = vlan->real_dev;
554 558
555 netif_carrier_off(dev); 559 netif_carrier_off(dev);
556 560
@@ -561,6 +565,9 @@ static int vlan_dev_init(struct net_device *dev)
561 (1<<__LINK_STATE_DORMANT))) | 565 (1<<__LINK_STATE_DORMANT))) |
562 (1<<__LINK_STATE_PRESENT); 566 (1<<__LINK_STATE_PRESENT);
563 567
568 if (vlan->flags & VLAN_FLAG_BRIDGE_BINDING)
569 dev->state |= (1 << __LINK_STATE_NOCARRIER);
570
564 dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG | 571 dev->hw_features = NETIF_F_HW_CSUM | NETIF_F_SG |
565 NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE | 572 NETIF_F_FRAGLIST | NETIF_F_GSO_SOFTWARE |
566 NETIF_F_GSO_ENCAP_ALL | 573 NETIF_F_GSO_ENCAP_ALL |
@@ -591,8 +598,7 @@ static int vlan_dev_init(struct net_device *dev)
591#endif 598#endif
592 599
593 dev->needed_headroom = real_dev->needed_headroom; 600 dev->needed_headroom = real_dev->needed_headroom;
594 if (vlan_hw_offload_capable(real_dev->features, 601 if (vlan_hw_offload_capable(real_dev->features, vlan->vlan_proto)) {
595 vlan_dev_priv(dev)->vlan_proto)) {
596 dev->header_ops = &vlan_passthru_header_ops; 602 dev->header_ops = &vlan_passthru_header_ops;
597 dev->hard_header_len = real_dev->hard_header_len; 603 dev->hard_header_len = real_dev->hard_header_len;
598 } else { 604 } else {
@@ -606,8 +612,8 @@ static int vlan_dev_init(struct net_device *dev)
606 612
607 vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev)); 613 vlan_dev_set_lockdep_class(dev, vlan_dev_get_lock_subclass(dev));
608 614
609 vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats); 615 vlan->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
610 if (!vlan_dev_priv(dev)->vlan_pcpu_stats) 616 if (!vlan->vlan_pcpu_stats)
611 return -ENOMEM; 617 return -ENOMEM;
612 618
613 return 0; 619 return 0;