summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/net/macvlan.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 9f4d65c3095f..b7c9791009d0 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -213,6 +213,29 @@ static int macvlan_stop(struct net_device *dev)
return 0;
}
+static int macvlan_set_mac_address(struct net_device *dev, void *p)
+{
+ struct macvlan_dev *vlan = netdev_priv(dev);
+ struct net_device *lowerdev = vlan->lowerdev;
+ struct sockaddr *addr = p;
+ int err;
+
+ if (!is_valid_ether_addr(addr->sa_data))
+ return -EADDRNOTAVAIL;
+
+ if (!(dev->flags & IFF_UP))
+ goto out;
+
+ err = dev_unicast_add(lowerdev, addr->sa_data, ETH_ALEN);
+ if (err < 0)
+ return err;
+ dev_unicast_delete(lowerdev, dev->dev_addr, ETH_ALEN);
+
+out:
+ memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+ return 0;
+}
+
static void macvlan_change_rx_flags(struct net_device *dev, int change)
{
struct macvlan_dev *vlan = netdev_priv(dev);
@@ -300,6 +323,7 @@ static void macvlan_setup(struct net_device *dev)
dev->stop = macvlan_stop;
dev->change_mtu = macvlan_change_mtu;
dev->change_rx_flags = macvlan_change_rx_flags;
+ dev->set_mac_address = macvlan_set_mac_address;
dev->set_multicast_list = macvlan_set_multicast_list;
dev->hard_start_xmit = macvlan_hard_start_xmit;
dev->destructor = free_netdev;