--- /dev/null
+From 308453aa9156a3b8ee382c0949befb507a32b0c1 Mon Sep 17 00:00:00 2001
+From: Mike Manning <mmanning@brocade.com>
+Date: Fri, 27 May 2016 17:45:07 +0100
+Subject: vlan: Propagate MAC address to VLANs
+
+From: Mike Manning <mmanning@brocade.com>
+
+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 <mmanning@brocade.com>
+Signed-off-by: David S. Miller <davem@davemloft.net>
+Signed-off-by: Sumit Semwal <sumit.semwal@linaro.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);
+