From c37f785edd55b70e0bdf08f7ec125291760e0b5f Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Fri, 4 Aug 2017 12:45:42 -0700 Subject: [PATCH] 3.18-stable patches added patches: vlan-propagate-mac-address-to-vlans.patch --- queue-3.18/series | 1 + .../vlan-propagate-mac-address-to-vlans.patch | 105 ++++++++++++++++++ 2 files changed, 106 insertions(+) create mode 100644 queue-3.18/vlan-propagate-mac-address-to-vlans.patch diff --git a/queue-3.18/series b/queue-3.18/series index c1ebb5e9a2f..c5d6a24f84d 100644 --- a/queue-3.18/series +++ b/queue-3.18/series @@ -31,3 +31,4 @@ net-sched-fix-soft-lockup-in-tc_classify.patch ipmi-watchdog-fix-watchdog-timeout-set-on-reboot.patch dentry-name-snapshots.patch v4l-s5c73m3-fix-negation-operator.patch +vlan-propagate-mac-address-to-vlans.patch diff --git a/queue-3.18/vlan-propagate-mac-address-to-vlans.patch b/queue-3.18/vlan-propagate-mac-address-to-vlans.patch new file mode 100644 index 00000000000..5bc86286020 --- /dev/null +++ b/queue-3.18/vlan-propagate-mac-address-to-vlans.patch @@ -0,0 +1,105 @@ +From 308453aa9156a3b8ee382c0949befb507a32b0c1 Mon Sep 17 00:00:00 2001 +From: Mike Manning +Date: Fri, 27 May 2016 17:45:07 +0100 +Subject: vlan: Propagate MAC address to VLANs + +From: Mike Manning + +commit 308453aa9156a3b8ee382c0949befb507a32b0c1 upstream. + +The MAC address of the physical interface is only copied to the VLAN +when it is first created, resulting in an inconsistency after MAC +address changes of only newly created VLANs having an up-to-date MAC. + +The VLANs should continue inheriting the MAC address of the physical +interface until the VLAN MAC address is explicitly set to any value. +This allows IPv6 EUI64 addresses for the VLAN to reflect any changes +to the MAC of the physical interface and thus for DAD to behave as +expected. + +Signed-off-by: Mike Manning +Signed-off-by: David S. Miller +Signed-off-by: Sumit Semwal +Signed-off-by: Greg Kroah-Hartman + +--- + net/8021q/vlan.c | 5 +++++ + net/8021q/vlan.h | 2 ++ + net/8021q/vlan_dev.c | 20 +++++++++++++++++--- + 3 files changed, 24 insertions(+), 3 deletions(-) + +--- a/net/8021q/vlan.c ++++ b/net/8021q/vlan.c +@@ -292,6 +292,10 @@ static void vlan_sync_address(struct net + if (ether_addr_equal(vlan->real_dev_addr, dev->dev_addr)) + return; + ++ /* vlan continues to inherit address of lower device */ ++ if (vlan_dev_inherit_address(vlandev, dev)) ++ goto out; ++ + /* vlan address was different from the old address and is equal to + * the new address */ + if (!ether_addr_equal(vlandev->dev_addr, vlan->real_dev_addr) && +@@ -304,6 +308,7 @@ static void vlan_sync_address(struct net + !ether_addr_equal(vlandev->dev_addr, dev->dev_addr)) + dev_uc_add(dev, vlandev->dev_addr); + ++out: + ether_addr_copy(vlan->real_dev_addr, dev->dev_addr); + } + +--- a/net/8021q/vlan.h ++++ b/net/8021q/vlan.h +@@ -109,6 +109,8 @@ int vlan_check_real_dev(struct net_devic + void vlan_setup(struct net_device *dev); + int register_vlan_dev(struct net_device *dev); + void unregister_vlan_dev(struct net_device *dev, struct list_head *head); ++bool vlan_dev_inherit_address(struct net_device *dev, ++ struct net_device *real_dev); + + static inline u32 vlan_get_ingress_priority(struct net_device *dev, + u16 vlan_tci) +--- a/net/8021q/vlan_dev.c ++++ b/net/8021q/vlan_dev.c +@@ -276,6 +276,17 @@ void vlan_dev_get_realdev_name(const str + strncpy(result, vlan_dev_priv(dev)->real_dev->name, 23); + } + ++bool vlan_dev_inherit_address(struct net_device *dev, ++ struct net_device *real_dev) ++{ ++ if (dev->addr_assign_type != NET_ADDR_STOLEN) ++ return false; ++ ++ ether_addr_copy(dev->dev_addr, real_dev->dev_addr); ++ call_netdevice_notifiers(NETDEV_CHANGEADDR, dev); ++ return true; ++} ++ + static int vlan_dev_open(struct net_device *dev) + { + struct vlan_dev_priv *vlan = vlan_dev_priv(dev); +@@ -286,7 +297,8 @@ static int vlan_dev_open(struct net_devi + !(vlan->flags & VLAN_FLAG_LOOSE_BINDING)) + return -ENETDOWN; + +- if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr)) { ++ if (!ether_addr_equal(dev->dev_addr, real_dev->dev_addr) && ++ !vlan_dev_inherit_address(dev, real_dev)) { + err = dev_uc_add(real_dev, dev->dev_addr); + if (err < 0) + goto out; +@@ -591,8 +603,10 @@ static int vlan_dev_init(struct net_devi + /* ipv6 shared card related stuff */ + dev->dev_id = real_dev->dev_id; + +- if (is_zero_ether_addr(dev->dev_addr)) +- eth_hw_addr_inherit(dev, real_dev); ++ if (is_zero_ether_addr(dev->dev_addr)) { ++ ether_addr_copy(dev->dev_addr, real_dev->dev_addr); ++ dev->addr_assign_type = NET_ADDR_STOLEN; ++ } + if (is_zero_ether_addr(dev->broadcast)) + memcpy(dev->broadcast, real_dev->broadcast, dev->addr_len); + -- 2.47.3