netdev: Add netdev->addr_list_lock protection.

Add netif_addr_{lock,unlock}{,_bh}() helpers.

Use them to protect operations that operate on or read
the network device unicast and multicast address lists.

Also use them in cases where the code simply wants to
block calls into the driver's ->set_rx_mode() and
->set_multicast_list() methods.

Signed-off-by: David S. Miller <davem@davemloft.net>
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index f8a3455..b6b2a12 100644
--- a/net/core/dev_mcast.c
+++ b/net/core/dev_mcast.c
@@ -73,6 +73,7 @@
 	int err;
 
 	netif_tx_lock_bh(dev);
+	netif_addr_lock(dev);
 	err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
 				addr, alen, glbl);
 	if (!err) {
@@ -83,6 +84,7 @@
 
 		__dev_set_rx_mode(dev);
 	}
+	netif_addr_unlock(dev);
 	netif_tx_unlock_bh(dev);
 	return err;
 }
@@ -96,9 +98,11 @@
 	int err;
 
 	netif_tx_lock_bh(dev);
+	netif_addr_lock(dev);
 	err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
 	if (!err)
 		__dev_set_rx_mode(dev);
+	netif_addr_unlock(dev);
 	netif_tx_unlock_bh(dev);
 	return err;
 }
@@ -120,10 +124,12 @@
 	int err = 0;
 
 	netif_tx_lock_bh(to);
+	netif_addr_lock(to);
 	err = __dev_addr_sync(&to->mc_list, &to->mc_count,
 			      &from->mc_list, &from->mc_count);
 	if (!err)
 		__dev_set_rx_mode(to);
+	netif_addr_unlock(to);
 	netif_tx_unlock_bh(to);
 
 	return err;
@@ -144,13 +150,17 @@
 void dev_mc_unsync(struct net_device *to, struct net_device *from)
 {
 	netif_tx_lock_bh(from);
+	netif_addr_lock(from);
 	netif_tx_lock_bh(to);
+	netif_addr_lock(to);
 
 	__dev_addr_unsync(&to->mc_list, &to->mc_count,
 			  &from->mc_list, &from->mc_count);
 	__dev_set_rx_mode(to);
 
+	netif_addr_unlock(to);
 	netif_tx_unlock_bh(to);
+	netif_addr_unlock(from);
 	netif_tx_unlock_bh(from);
 }
 EXPORT_SYMBOL(dev_mc_unsync);
@@ -165,6 +175,7 @@
 		return 0;
 
 	netif_tx_lock_bh(dev);
+	netif_addr_lock(dev);
 	for (m = dev->mc_list; m; m = m->next) {
 		int i;
 
@@ -176,6 +187,7 @@
 
 		seq_putc(seq, '\n');
 	}
+	netif_addr_unlock(dev);
 	netif_tx_unlock_bh(dev);
 	return 0;
 }