summaryrefslogtreecommitdiff
path: root/net/core
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-07-15 07:13:44 (GMT)
committerDavid S. Miller <davem@davemloft.net>2008-07-15 07:13:44 (GMT)
commite308a5d806c852f56590ffdd3834d0df0cbed8d7 (patch)
tree294ff654e90950f5162737c26f4799b0b710b748 /net/core
parentf1f28aa3510ddb84c966bac65611bb866c77a092 (diff)
downloadlinux-e308a5d806c852f56590ffdd3834d0df0cbed8d7.tar.xz
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>
Diffstat (limited to 'net/core')
-rw-r--r--net/core/dev.c14
-rw-r--r--net/core/dev_mcast.c12
2 files changed, 26 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index d933d1b..ef1502d 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2982,7 +2982,9 @@ void __dev_set_rx_mode(struct net_device *dev)
void dev_set_rx_mode(struct net_device *dev)
{
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
__dev_set_rx_mode(dev);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
}
@@ -3062,9 +3064,11 @@ int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
ASSERT_RTNL();
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
if (!err)
__dev_set_rx_mode(dev);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
return err;
}
@@ -3088,9 +3092,11 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen)
ASSERT_RTNL();
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
if (!err)
__dev_set_rx_mode(dev);
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
return err;
}
@@ -3159,10 +3165,12 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from)
int err = 0;
netif_tx_lock_bh(to);
+ netif_addr_lock(to);
err = __dev_addr_sync(&to->uc_list, &to->uc_count,
&from->uc_list, &from->uc_count);
if (!err)
__dev_set_rx_mode(to);
+ netif_addr_unlock(to);
netif_tx_unlock_bh(to);
return err;
}
@@ -3180,13 +3188,17 @@ EXPORT_SYMBOL(dev_unicast_sync);
void dev_unicast_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->uc_list, &to->uc_count,
&from->uc_list, &from->uc_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_unicast_unsync);
@@ -3208,6 +3220,7 @@ static void __dev_addr_discard(struct dev_addr_list **list)
static void dev_addr_discard(struct net_device *dev)
{
netif_tx_lock_bh(dev);
+ netif_addr_lock(dev);
__dev_addr_discard(&dev->uc_list);
dev->uc_count = 0;
@@ -3215,6 +3228,7 @@ static void dev_addr_discard(struct net_device *dev)
__dev_addr_discard(&dev->mc_list);
dev->mc_count = 0;
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
}
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 dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
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 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
__dev_set_rx_mode(dev);
}
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
return err;
}
@@ -96,9 +98,11 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
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 dev_mc_sync(struct net_device *to, struct net_device *from)
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 @@ EXPORT_SYMBOL(dev_mc_sync);
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 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
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 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
seq_putc(seq, '\n');
}
+ netif_addr_unlock(dev);
netif_tx_unlock_bh(dev);
return 0;
}