aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-07-15 00:13:44 -0700
committerDavid S. Miller <davem@davemloft.net>2008-07-15 00:13:44 -0700
commite308a5d806c852f56590ffdd3834d0df0cbed8d7 (patch)
tree294ff654e90950f5162737c26f4799b0b710b748 /net
parentf1f28aa3510ddb84c966bac65611bb866c77a092 (diff)
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')
-rw-r--r--net/core/dev.c14
-rw-r--r--net/core/dev_mcast.c12
-rw-r--r--net/mac80211/main.c4
-rw-r--r--net/mac80211/mlme.c4
4 files changed, 34 insertions, 0 deletions
diff --git a/net/core/dev.c b/net/core/dev.c
index d933d1bfa6f..ef1502d71f2 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 f8a3455f449..b6b2a129971 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;
}
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 36859e79492..095b7d928d6 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -292,7 +292,9 @@ static int ieee80211_open(struct net_device *dev)
local->fif_other_bss++;
netif_tx_lock_bh(local->mdev);
+ netif_addr_lock(local->mdev);
ieee80211_configure_filter(local);
+ netif_addr_unlock(local->mdev);
netif_tx_unlock_bh(local->mdev);
break;
case IEEE80211_IF_TYPE_STA:
@@ -491,7 +493,9 @@ static int ieee80211_stop(struct net_device *dev)
local->fif_other_bss--;
netif_tx_lock_bh(local->mdev);
+ netif_addr_lock(local->mdev);
ieee80211_configure_filter(local);
+ netif_addr_unlock(local->mdev);
netif_tx_unlock_bh(local->mdev);
break;
case IEEE80211_IF_TYPE_MESH_POINT:
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8f51375317d..1232ba25e1e 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3869,6 +3869,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
netif_tx_lock_bh(local->mdev);
+ netif_addr_lock(local->mdev);
local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
local->ops->configure_filter(local_to_hw(local),
FIF_BCN_PRBRESP_PROMISC,
@@ -3876,6 +3877,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
local->mdev->mc_count,
local->mdev->mc_list);
+ netif_addr_unlock(local->mdev);
netif_tx_unlock_bh(local->mdev);
rcu_read_lock();
@@ -4063,12 +4065,14 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
local->scan_dev = dev;
netif_tx_lock_bh(local->mdev);
+ netif_addr_lock(local->mdev);
local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
local->ops->configure_filter(local_to_hw(local),
FIF_BCN_PRBRESP_PROMISC,
&local->filter_flags,
local->mdev->mc_count,
local->mdev->mc_list);
+ netif_addr_unlock(local->mdev);
netif_tx_unlock_bh(local->mdev);
/* TODO: start scan as soon as all nullfunc frames are ACKed */