Staging: batman-adv: Allow the MAC address to be set
authorAndrew Lunn <andrew@lunn.ch>
Sat, 2 Jan 2010 10:30:49 +0000 (11:30 +0100)
committerGreg Kroah-Hartman <gregkh@suse.de>
Thu, 4 Mar 2010 00:42:36 +0000 (16:42 -0800)
Some embedded devices have very limited sources of entropy for the
random number generator. It has been observed that the random MAC
address on the interface bat0 is not always random. When testing with
a collection of identical hardware, sometimes the bat0 device the same
MAC address on multiple devices, causing mayhem. This patch allows the
MAC address to be set by the user.

Signed-off-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Simon Wunderlich <siwu@hrz.tu-chemnitz.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
drivers/staging/batman-adv/soft-interface.c
drivers/staging/batman-adv/translation-table.c
drivers/staging/batman-adv/translation-table.h

index 8ae3483a625906c95f4c9b00702c6c1f299f83ae..bc0217b1aeb1b7c6c63da96792e034debb4aa2e9 100644 (file)
@@ -145,9 +145,18 @@ struct net_device_stats *interface_stats(struct net_device *dev)
        return &priv->stats;
 }
 
-int interface_set_mac_addr(struct net_device *dev, void *addr)
+int interface_set_mac_addr(struct net_device *dev, void *p)
 {
-       return -EBUSY;
+       struct sockaddr *addr = p;
+
+       if (!is_valid_ether_addr(addr->sa_data))
+               return -EADDRNOTAVAIL;
+
+       hna_local_remove(dev->dev_addr, "mac address changed");
+       memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
+       hna_local_add(dev->dev_addr);
+
+       return 0;
 }
 
 int interface_change_mtu(struct net_device *dev, int new_mtu)
index 8c8136b7162829be4152c53078a8080b2f57c2a1..53a054e413d758bb998c57a0078013fb62c927d5 100644 (file)
@@ -211,6 +211,21 @@ static void hna_local_del(struct hna_local_entry *hna_local_entry,
        _hna_local_del(hna_local_entry);
 }
 
+void hna_local_remove(uint8_t *addr, char *message)
+{
+       struct hna_local_entry *hna_local_entry;
+       unsigned long flags;
+
+       spin_lock_irqsave(&hna_local_hash_lock, flags);
+
+       hna_local_entry = (struct hna_local_entry *)
+               hash_find(hna_local_hash, addr);
+       if (hna_local_entry)
+               hna_local_del(hna_local_entry, message);
+
+       spin_unlock_irqrestore(&hna_local_hash_lock, flags);
+}
+
 void hna_local_purge(struct work_struct *work)
 {
        struct hna_local_entry *hna_local_entry;
index f7da81129318d10c60b384ab3a54d0dc70c1fa6f..281125b729fbd1bf34b194b37a37f70c2f57e612 100644 (file)
@@ -23,6 +23,7 @@
 
 int hna_local_init(void);
 void hna_local_add(uint8_t *addr);
+void hna_local_remove(uint8_t *addr, char *message);
 int hna_local_fill_buffer(unsigned char *buff, int buff_len);
 int hna_local_fill_buffer_text(unsigned char *buff, int buff_len);
 void hna_local_purge(struct work_struct *work);