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) &&
            !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);
 }
 
 
 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)
 
        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);
            !(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;
        /* 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);