diff options
Diffstat (limited to 'net/8021q/vlan_dev.c')
-rw-r--r-- | net/8021q/vlan_dev.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c index 1a1740aa9a8b..7a36878241da 100644 --- a/net/8021q/vlan_dev.c +++ b/net/8021q/vlan_dev.c | |||
@@ -665,6 +665,32 @@ int vlan_dev_stop(struct net_device *dev) | |||
665 | return 0; | 665 | return 0; |
666 | } | 666 | } |
667 | 667 | ||
668 | int vlan_set_mac_address(struct net_device *dev, void *p) | ||
669 | { | ||
670 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | ||
671 | struct sockaddr *addr = p; | ||
672 | int err; | ||
673 | |||
674 | if (!is_valid_ether_addr(addr->sa_data)) | ||
675 | return -EADDRNOTAVAIL; | ||
676 | |||
677 | if (!(dev->flags & IFF_UP)) | ||
678 | goto out; | ||
679 | |||
680 | if (compare_ether_addr(addr->sa_data, real_dev->dev_addr)) { | ||
681 | err = dev_unicast_add(real_dev, addr->sa_data, ETH_ALEN); | ||
682 | if (err < 0) | ||
683 | return err; | ||
684 | } | ||
685 | |||
686 | if (compare_ether_addr(dev->dev_addr, real_dev->dev_addr)) | ||
687 | dev_unicast_delete(real_dev, dev->dev_addr, ETH_ALEN); | ||
688 | |||
689 | out: | ||
690 | memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); | ||
691 | return 0; | ||
692 | } | ||
693 | |||
668 | int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) | 694 | int vlan_dev_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) |
669 | { | 695 | { |
670 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; | 696 | struct net_device *real_dev = VLAN_DEV_INFO(dev)->real_dev; |