aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2008-07-15 03:13:44 -0400
committerDavid S. Miller <davem@davemloft.net>2008-07-15 03:13:44 -0400
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 d933d1bfa6fa..ef1502d71f25 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -2982,7 +2982,9 @@ void __dev_set_rx_mode(struct net_device *dev)
2982void dev_set_rx_mode(struct net_device *dev) 2982void dev_set_rx_mode(struct net_device *dev)
2983{ 2983{
2984 netif_tx_lock_bh(dev); 2984 netif_tx_lock_bh(dev);
2985 netif_addr_lock(dev);
2985 __dev_set_rx_mode(dev); 2986 __dev_set_rx_mode(dev);
2987 netif_addr_unlock(dev);
2986 netif_tx_unlock_bh(dev); 2988 netif_tx_unlock_bh(dev);
2987} 2989}
2988 2990
@@ -3062,9 +3064,11 @@ int dev_unicast_delete(struct net_device *dev, void *addr, int alen)
3062 ASSERT_RTNL(); 3064 ASSERT_RTNL();
3063 3065
3064 netif_tx_lock_bh(dev); 3066 netif_tx_lock_bh(dev);
3067 netif_addr_lock(dev);
3065 err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0); 3068 err = __dev_addr_delete(&dev->uc_list, &dev->uc_count, addr, alen, 0);
3066 if (!err) 3069 if (!err)
3067 __dev_set_rx_mode(dev); 3070 __dev_set_rx_mode(dev);
3071 netif_addr_unlock(dev);
3068 netif_tx_unlock_bh(dev); 3072 netif_tx_unlock_bh(dev);
3069 return err; 3073 return err;
3070} 3074}
@@ -3088,9 +3092,11 @@ int dev_unicast_add(struct net_device *dev, void *addr, int alen)
3088 ASSERT_RTNL(); 3092 ASSERT_RTNL();
3089 3093
3090 netif_tx_lock_bh(dev); 3094 netif_tx_lock_bh(dev);
3095 netif_addr_lock(dev);
3091 err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0); 3096 err = __dev_addr_add(&dev->uc_list, &dev->uc_count, addr, alen, 0);
3092 if (!err) 3097 if (!err)
3093 __dev_set_rx_mode(dev); 3098 __dev_set_rx_mode(dev);
3099 netif_addr_unlock(dev);
3094 netif_tx_unlock_bh(dev); 3100 netif_tx_unlock_bh(dev);
3095 return err; 3101 return err;
3096} 3102}
@@ -3159,10 +3165,12 @@ int dev_unicast_sync(struct net_device *to, struct net_device *from)
3159 int err = 0; 3165 int err = 0;
3160 3166
3161 netif_tx_lock_bh(to); 3167 netif_tx_lock_bh(to);
3168 netif_addr_lock(to);
3162 err = __dev_addr_sync(&to->uc_list, &to->uc_count, 3169 err = __dev_addr_sync(&to->uc_list, &to->uc_count,
3163 &from->uc_list, &from->uc_count); 3170 &from->uc_list, &from->uc_count);
3164 if (!err) 3171 if (!err)
3165 __dev_set_rx_mode(to); 3172 __dev_set_rx_mode(to);
3173 netif_addr_unlock(to);
3166 netif_tx_unlock_bh(to); 3174 netif_tx_unlock_bh(to);
3167 return err; 3175 return err;
3168} 3176}
@@ -3180,13 +3188,17 @@ EXPORT_SYMBOL(dev_unicast_sync);
3180void dev_unicast_unsync(struct net_device *to, struct net_device *from) 3188void dev_unicast_unsync(struct net_device *to, struct net_device *from)
3181{ 3189{
3182 netif_tx_lock_bh(from); 3190 netif_tx_lock_bh(from);
3191 netif_addr_lock(from);
3183 netif_tx_lock_bh(to); 3192 netif_tx_lock_bh(to);
3193 netif_addr_lock(to);
3184 3194
3185 __dev_addr_unsync(&to->uc_list, &to->uc_count, 3195 __dev_addr_unsync(&to->uc_list, &to->uc_count,
3186 &from->uc_list, &from->uc_count); 3196 &from->uc_list, &from->uc_count);
3187 __dev_set_rx_mode(to); 3197 __dev_set_rx_mode(to);
3188 3198
3199 netif_addr_unlock(to);
3189 netif_tx_unlock_bh(to); 3200 netif_tx_unlock_bh(to);
3201 netif_addr_unlock(from);
3190 netif_tx_unlock_bh(from); 3202 netif_tx_unlock_bh(from);
3191} 3203}
3192EXPORT_SYMBOL(dev_unicast_unsync); 3204EXPORT_SYMBOL(dev_unicast_unsync);
@@ -3208,6 +3220,7 @@ static void __dev_addr_discard(struct dev_addr_list **list)
3208static void dev_addr_discard(struct net_device *dev) 3220static void dev_addr_discard(struct net_device *dev)
3209{ 3221{
3210 netif_tx_lock_bh(dev); 3222 netif_tx_lock_bh(dev);
3223 netif_addr_lock(dev);
3211 3224
3212 __dev_addr_discard(&dev->uc_list); 3225 __dev_addr_discard(&dev->uc_list);
3213 dev->uc_count = 0; 3226 dev->uc_count = 0;
@@ -3215,6 +3228,7 @@ static void dev_addr_discard(struct net_device *dev)
3215 __dev_addr_discard(&dev->mc_list); 3228 __dev_addr_discard(&dev->mc_list);
3216 dev->mc_count = 0; 3229 dev->mc_count = 0;
3217 3230
3231 netif_addr_unlock(dev);
3218 netif_tx_unlock_bh(dev); 3232 netif_tx_unlock_bh(dev);
3219} 3233}
3220 3234
diff --git a/net/core/dev_mcast.c b/net/core/dev_mcast.c
index f8a3455f4493..b6b2a129971a 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)
73 int err; 73 int err;
74 74
75 netif_tx_lock_bh(dev); 75 netif_tx_lock_bh(dev);
76 netif_addr_lock(dev);
76 err = __dev_addr_delete(&dev->mc_list, &dev->mc_count, 77 err = __dev_addr_delete(&dev->mc_list, &dev->mc_count,
77 addr, alen, glbl); 78 addr, alen, glbl);
78 if (!err) { 79 if (!err) {
@@ -83,6 +84,7 @@ int dev_mc_delete(struct net_device *dev, void *addr, int alen, int glbl)
83 84
84 __dev_set_rx_mode(dev); 85 __dev_set_rx_mode(dev);
85 } 86 }
87 netif_addr_unlock(dev);
86 netif_tx_unlock_bh(dev); 88 netif_tx_unlock_bh(dev);
87 return err; 89 return err;
88} 90}
@@ -96,9 +98,11 @@ int dev_mc_add(struct net_device *dev, void *addr, int alen, int glbl)
96 int err; 98 int err;
97 99
98 netif_tx_lock_bh(dev); 100 netif_tx_lock_bh(dev);
101 netif_addr_lock(dev);
99 err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl); 102 err = __dev_addr_add(&dev->mc_list, &dev->mc_count, addr, alen, glbl);
100 if (!err) 103 if (!err)
101 __dev_set_rx_mode(dev); 104 __dev_set_rx_mode(dev);
105 netif_addr_unlock(dev);
102 netif_tx_unlock_bh(dev); 106 netif_tx_unlock_bh(dev);
103 return err; 107 return err;
104} 108}
@@ -120,10 +124,12 @@ int dev_mc_sync(struct net_device *to, struct net_device *from)
120 int err = 0; 124 int err = 0;
121 125
122 netif_tx_lock_bh(to); 126 netif_tx_lock_bh(to);
127 netif_addr_lock(to);
123 err = __dev_addr_sync(&to->mc_list, &to->mc_count, 128 err = __dev_addr_sync(&to->mc_list, &to->mc_count,
124 &from->mc_list, &from->mc_count); 129 &from->mc_list, &from->mc_count);
125 if (!err) 130 if (!err)
126 __dev_set_rx_mode(to); 131 __dev_set_rx_mode(to);
132 netif_addr_unlock(to);
127 netif_tx_unlock_bh(to); 133 netif_tx_unlock_bh(to);
128 134
129 return err; 135 return err;
@@ -144,13 +150,17 @@ EXPORT_SYMBOL(dev_mc_sync);
144void dev_mc_unsync(struct net_device *to, struct net_device *from) 150void dev_mc_unsync(struct net_device *to, struct net_device *from)
145{ 151{
146 netif_tx_lock_bh(from); 152 netif_tx_lock_bh(from);
153 netif_addr_lock(from);
147 netif_tx_lock_bh(to); 154 netif_tx_lock_bh(to);
155 netif_addr_lock(to);
148 156
149 __dev_addr_unsync(&to->mc_list, &to->mc_count, 157 __dev_addr_unsync(&to->mc_list, &to->mc_count,
150 &from->mc_list, &from->mc_count); 158 &from->mc_list, &from->mc_count);
151 __dev_set_rx_mode(to); 159 __dev_set_rx_mode(to);
152 160
161 netif_addr_unlock(to);
153 netif_tx_unlock_bh(to); 162 netif_tx_unlock_bh(to);
163 netif_addr_unlock(from);
154 netif_tx_unlock_bh(from); 164 netif_tx_unlock_bh(from);
155} 165}
156EXPORT_SYMBOL(dev_mc_unsync); 166EXPORT_SYMBOL(dev_mc_unsync);
@@ -165,6 +175,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
165 return 0; 175 return 0;
166 176
167 netif_tx_lock_bh(dev); 177 netif_tx_lock_bh(dev);
178 netif_addr_lock(dev);
168 for (m = dev->mc_list; m; m = m->next) { 179 for (m = dev->mc_list; m; m = m->next) {
169 int i; 180 int i;
170 181
@@ -176,6 +187,7 @@ static int dev_mc_seq_show(struct seq_file *seq, void *v)
176 187
177 seq_putc(seq, '\n'); 188 seq_putc(seq, '\n');
178 } 189 }
190 netif_addr_unlock(dev);
179 netif_tx_unlock_bh(dev); 191 netif_tx_unlock_bh(dev);
180 return 0; 192 return 0;
181} 193}
diff --git a/net/mac80211/main.c b/net/mac80211/main.c
index 36859e794928..095b7d928d64 100644
--- a/net/mac80211/main.c
+++ b/net/mac80211/main.c
@@ -292,7 +292,9 @@ static int ieee80211_open(struct net_device *dev)
292 local->fif_other_bss++; 292 local->fif_other_bss++;
293 293
294 netif_tx_lock_bh(local->mdev); 294 netif_tx_lock_bh(local->mdev);
295 netif_addr_lock(local->mdev);
295 ieee80211_configure_filter(local); 296 ieee80211_configure_filter(local);
297 netif_addr_unlock(local->mdev);
296 netif_tx_unlock_bh(local->mdev); 298 netif_tx_unlock_bh(local->mdev);
297 break; 299 break;
298 case IEEE80211_IF_TYPE_STA: 300 case IEEE80211_IF_TYPE_STA:
@@ -491,7 +493,9 @@ static int ieee80211_stop(struct net_device *dev)
491 local->fif_other_bss--; 493 local->fif_other_bss--;
492 494
493 netif_tx_lock_bh(local->mdev); 495 netif_tx_lock_bh(local->mdev);
496 netif_addr_lock(local->mdev);
494 ieee80211_configure_filter(local); 497 ieee80211_configure_filter(local);
498 netif_addr_unlock(local->mdev);
495 netif_tx_unlock_bh(local->mdev); 499 netif_tx_unlock_bh(local->mdev);
496 break; 500 break;
497 case IEEE80211_IF_TYPE_MESH_POINT: 501 case IEEE80211_IF_TYPE_MESH_POINT:
diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c
index 8f51375317dd..1232ba25e1e9 100644
--- a/net/mac80211/mlme.c
+++ b/net/mac80211/mlme.c
@@ -3869,6 +3869,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
3869 3869
3870 3870
3871 netif_tx_lock_bh(local->mdev); 3871 netif_tx_lock_bh(local->mdev);
3872 netif_addr_lock(local->mdev);
3872 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC; 3873 local->filter_flags &= ~FIF_BCN_PRBRESP_PROMISC;
3873 local->ops->configure_filter(local_to_hw(local), 3874 local->ops->configure_filter(local_to_hw(local),
3874 FIF_BCN_PRBRESP_PROMISC, 3875 FIF_BCN_PRBRESP_PROMISC,
@@ -3876,6 +3877,7 @@ void ieee80211_scan_completed(struct ieee80211_hw *hw)
3876 local->mdev->mc_count, 3877 local->mdev->mc_count,
3877 local->mdev->mc_list); 3878 local->mdev->mc_list);
3878 3879
3880 netif_addr_unlock(local->mdev);
3879 netif_tx_unlock_bh(local->mdev); 3881 netif_tx_unlock_bh(local->mdev);
3880 3882
3881 rcu_read_lock(); 3883 rcu_read_lock();
@@ -4063,12 +4065,14 @@ static int ieee80211_sta_start_scan(struct net_device *dev,
4063 local->scan_dev = dev; 4065 local->scan_dev = dev;
4064 4066
4065 netif_tx_lock_bh(local->mdev); 4067 netif_tx_lock_bh(local->mdev);
4068 netif_addr_lock(local->mdev);
4066 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC; 4069 local->filter_flags |= FIF_BCN_PRBRESP_PROMISC;
4067 local->ops->configure_filter(local_to_hw(local), 4070 local->ops->configure_filter(local_to_hw(local),
4068 FIF_BCN_PRBRESP_PROMISC, 4071 FIF_BCN_PRBRESP_PROMISC,
4069 &local->filter_flags, 4072 &local->filter_flags,
4070 local->mdev->mc_count, 4073 local->mdev->mc_count,
4071 local->mdev->mc_list); 4074 local->mdev->mc_list);
4075 netif_addr_unlock(local->mdev);
4072 netif_tx_unlock_bh(local->mdev); 4076 netif_tx_unlock_bh(local->mdev);
4073 4077
4074 /* TODO: start scan as soon as all nullfunc frames are ACKed */ 4078 /* TODO: start scan as soon as all nullfunc frames are ACKed */