aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/if_vlan.h1
-rw-r--r--net/8021q/vlan.c9
-rw-r--r--net/8021q/vlan_dev.c6
-rw-r--r--net/8021q/vlan_netlink.c3
4 files changed, 14 insertions, 5 deletions
diff --git a/include/linux/if_vlan.h b/include/linux/if_vlan.h
index 153f6b9e722c..3d870fda8c4f 100644
--- a/include/linux/if_vlan.h
+++ b/include/linux/if_vlan.h
@@ -339,6 +339,7 @@ enum vlan_ioctl_cmds {
339enum vlan_flags { 339enum vlan_flags {
340 VLAN_FLAG_REORDER_HDR = 0x1, 340 VLAN_FLAG_REORDER_HDR = 0x1,
341 VLAN_FLAG_GVRP = 0x2, 341 VLAN_FLAG_GVRP = 0x2,
342 VLAN_FLAG_LOOSE_BINDING = 0x4,
342}; 343};
343 344
344enum vlan_name_types { 345enum vlan_name_types {
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c
index 1483243edf14..225aa2fac0e3 100644
--- a/net/8021q/vlan.c
+++ b/net/8021q/vlan.c
@@ -431,6 +431,7 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
431 struct vlan_group *grp; 431 struct vlan_group *grp;
432 int i, flgs; 432 int i, flgs;
433 struct net_device *vlandev; 433 struct net_device *vlandev;
434 struct vlan_dev_info *vlan;
434 LIST_HEAD(list); 435 LIST_HEAD(list);
435 436
436 if (is_vlan_dev(dev)) 437 if (is_vlan_dev(dev))
@@ -507,7 +508,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
507 if (!(flgs & IFF_UP)) 508 if (!(flgs & IFF_UP))
508 continue; 509 continue;
509 510
510 dev_change_flags(vlandev, flgs & ~IFF_UP); 511 vlan = vlan_dev_info(vlandev);
512 if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
513 dev_change_flags(vlandev, flgs & ~IFF_UP);
511 vlan_transfer_operstate(dev, vlandev); 514 vlan_transfer_operstate(dev, vlandev);
512 } 515 }
513 break; 516 break;
@@ -523,7 +526,9 @@ static int vlan_device_event(struct notifier_block *unused, unsigned long event,
523 if (flgs & IFF_UP) 526 if (flgs & IFF_UP)
524 continue; 527 continue;
525 528
526 dev_change_flags(vlandev, flgs | IFF_UP); 529 vlan = vlan_dev_info(vlandev);
530 if (!(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
531 dev_change_flags(vlandev, flgs | IFF_UP);
527 vlan_transfer_operstate(dev, vlandev); 532 vlan_transfer_operstate(dev, vlandev);
528 } 533 }
529 break; 534 break;
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index de0dc6bacbe8..b7889782047e 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -431,7 +431,8 @@ int vlan_dev_change_flags(const struct net_device *dev, u32 flags, u32 mask)
431 struct vlan_dev_info *vlan = vlan_dev_info(dev); 431 struct vlan_dev_info *vlan = vlan_dev_info(dev);
432 u32 old_flags = vlan->flags; 432 u32 old_flags = vlan->flags;
433 433
434 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP)) 434 if (mask & ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |
435 VLAN_FLAG_LOOSE_BINDING))
435 return -EINVAL; 436 return -EINVAL;
436 437
437 vlan->flags = (old_flags & ~mask) | (flags & mask); 438 vlan->flags = (old_flags & ~mask) | (flags & mask);
@@ -456,7 +457,8 @@ static int vlan_dev_open(struct net_device *dev)
456 struct net_device *real_dev = vlan->real_dev; 457 struct net_device *real_dev = vlan->real_dev;
457 int err; 458 int err;
458 459
459 if (!(real_dev->flags & IFF_UP)) 460 if (!(real_dev->flags & IFF_UP) &&
461 !(vlan->flags & VLAN_FLAG_LOOSE_BINDING))
460 return -ENETDOWN; 462 return -ENETDOWN;
461 463
462 if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) { 464 if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) {
diff --git a/net/8021q/vlan_netlink.c b/net/8021q/vlan_netlink.c
index 3c9cf6a8e7fb..ddc105734af7 100644
--- a/net/8021q/vlan_netlink.c
+++ b/net/8021q/vlan_netlink.c
@@ -60,7 +60,8 @@ static int vlan_validate(struct nlattr *tb[], struct nlattr *data[])
60 if (data[IFLA_VLAN_FLAGS]) { 60 if (data[IFLA_VLAN_FLAGS]) {
61 flags = nla_data(data[IFLA_VLAN_FLAGS]); 61 flags = nla_data(data[IFLA_VLAN_FLAGS]);
62 if ((flags->flags & flags->mask) & 62 if ((flags->flags & flags->mask) &
63 ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP)) 63 ~(VLAN_FLAG_REORDER_HDR | VLAN_FLAG_GVRP |
64 VLAN_FLAG_LOOSE_BINDING))
64 return -EINVAL; 65 return -EINVAL;
65 } 66 }
66 67