diff options
author | Patrick McHardy <kaber@trash.net> | 2007-11-11 00:52:35 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-11-11 00:52:35 -0500 |
commit | 39aaac114e192bce500204f9c9e1fffff4c2b519 (patch) | |
tree | 621162d1a301677460c8724472ae187cfa4b2a1e | |
parent | d932e04a5e7b146c5f9bf517714b986a432a7594 (diff) |
[VLAN]: Allow setting mac address while device is up
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | net/8021q/vlan.c | 1 | ||||
-rw-r--r-- | net/8021q/vlan.h | 1 | ||||
-rw-r--r-- | net/8021q/vlan_dev.c | 26 |
3 files changed, 28 insertions, 0 deletions
diff --git a/net/8021q/vlan.c b/net/8021q/vlan.c index 0fadbc6fbc3f..6567213959cb 100644 --- a/net/8021q/vlan.c +++ b/net/8021q/vlan.c | |||
@@ -376,6 +376,7 @@ void vlan_setup(struct net_device *new_dev) | |||
376 | new_dev->init = vlan_dev_init; | 376 | new_dev->init = vlan_dev_init; |
377 | new_dev->open = vlan_dev_open; | 377 | new_dev->open = vlan_dev_open; |
378 | new_dev->stop = vlan_dev_stop; | 378 | new_dev->stop = vlan_dev_stop; |
379 | new_dev->set_mac_address = vlan_set_mac_address; | ||
379 | new_dev->set_multicast_list = vlan_dev_set_multicast_list; | 380 | new_dev->set_multicast_list = vlan_dev_set_multicast_list; |
380 | new_dev->change_rx_flags = vlan_change_rx_flags; | 381 | new_dev->change_rx_flags = vlan_change_rx_flags; |
381 | new_dev->destructor = free_netdev; | 382 | new_dev->destructor = free_netdev; |
diff --git a/net/8021q/vlan.h b/net/8021q/vlan.h index cf4a80d06b35..2cd1393073ec 100644 --- a/net/8021q/vlan.h +++ b/net/8021q/vlan.h | |||
@@ -60,6 +60,7 @@ int vlan_dev_hwaccel_hard_start_xmit(struct sk_buff *skb, struct net_device *dev | |||
60 | int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); | 60 | int vlan_dev_change_mtu(struct net_device *dev, int new_mtu); |
61 | int vlan_dev_open(struct net_device* dev); | 61 | int vlan_dev_open(struct net_device* dev); |
62 | int vlan_dev_stop(struct net_device* dev); | 62 | int vlan_dev_stop(struct net_device* dev); |
63 | int vlan_set_mac_address(struct net_device *dev, void *p); | ||
63 | int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); | 64 | int vlan_dev_ioctl(struct net_device* dev, struct ifreq *ifr, int cmd); |
64 | void vlan_dev_set_ingress_priority(const struct net_device *dev, | 65 | void vlan_dev_set_ingress_priority(const struct net_device *dev, |
65 | u32 skb_prio, short vlan_prio); | 66 | u32 skb_prio, short vlan_prio); |
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; |