aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/driver-ops.h
diff options
context:
space:
mode:
authorJohannes Berg <johannes.berg@intel.com>2011-11-03 09:41:13 -0400
committerJohn W. Linville <linville@tuxdriver.com>2011-11-09 16:01:02 -0500
commit7b7eab6fc1bc8852d9649541b59283cd89cc526f (patch)
tree7b071ee01187bc3ee843c86b88189cc4eab73cf1 /net/mac80211/driver-ops.h
parent6e3e939f3b1bf8534b32ad09ff199d88800835a0 (diff)
mac80211: verify virtual interfaces in driver API
The driver is never informed about monitor or AP_VLAN interfaces, so whenever we pass those to it later this is a bug. Verify we don't as there are some cases where this could happen. Signed-off-by: Johannes Berg <johannes.berg@intel.com> Signed-off-by: John W. Linville <linville@tuxdriver.com>
Diffstat (limited to 'net/mac80211/driver-ops.h')
-rw-r--r--net/mac80211/driver-ops.h68
1 files changed, 62 insertions, 6 deletions
diff --git a/net/mac80211/driver-ops.h b/net/mac80211/driver-ops.h
index 5f165d7eb2db..b12ed52732c8 100644
--- a/net/mac80211/driver-ops.h
+++ b/net/mac80211/driver-ops.h
@@ -5,6 +5,11 @@
5#include "ieee80211_i.h" 5#include "ieee80211_i.h"
6#include "driver-trace.h" 6#include "driver-trace.h"
7 7
8static inline void check_sdata_in_driver(struct ieee80211_sub_if_data *sdata)
9{
10 WARN_ON(!(sdata->flags & IEEE80211_SDATA_IN_DRIVER));
11}
12
8static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb) 13static inline void drv_tx(struct ieee80211_local *local, struct sk_buff *skb)
9{ 14{
10 local->ops->tx(&local->hw, skb); 15 local->ops->tx(&local->hw, skb);
@@ -69,15 +74,23 @@ static inline int drv_resume(struct ieee80211_local *local)
69#endif 74#endif
70 75
71static inline int drv_add_interface(struct ieee80211_local *local, 76static inline int drv_add_interface(struct ieee80211_local *local,
72 struct ieee80211_vif *vif) 77 struct ieee80211_sub_if_data *sdata)
73{ 78{
74 int ret; 79 int ret;
75 80
76 might_sleep(); 81 might_sleep();
77 82
78 trace_drv_add_interface(local, vif_to_sdata(vif)); 83 if (WARN_ON(sdata->vif.type == NL80211_IFTYPE_AP_VLAN ||
79 ret = local->ops->add_interface(&local->hw, vif); 84 sdata->vif.type == NL80211_IFTYPE_MONITOR))
85 return -EINVAL;
86
87 trace_drv_add_interface(local, sdata);
88 ret = local->ops->add_interface(&local->hw, &sdata->vif);
80 trace_drv_return_int(local, ret); 89 trace_drv_return_int(local, ret);
90
91 if (ret == 0)
92 sdata->flags |= IEEE80211_SDATA_IN_DRIVER;
93
81 return ret; 94 return ret;
82} 95}
83 96
@@ -89,6 +102,8 @@ static inline int drv_change_interface(struct ieee80211_local *local,
89 102
90 might_sleep(); 103 might_sleep();
91 104
105 check_sdata_in_driver(sdata);
106
92 trace_drv_change_interface(local, sdata, type, p2p); 107 trace_drv_change_interface(local, sdata, type, p2p);
93 ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p); 108 ret = local->ops->change_interface(&local->hw, &sdata->vif, type, p2p);
94 trace_drv_return_int(local, ret); 109 trace_drv_return_int(local, ret);
@@ -96,12 +111,15 @@ static inline int drv_change_interface(struct ieee80211_local *local,
96} 111}
97 112
98static inline void drv_remove_interface(struct ieee80211_local *local, 113static inline void drv_remove_interface(struct ieee80211_local *local,
99 struct ieee80211_vif *vif) 114 struct ieee80211_sub_if_data *sdata)
100{ 115{
101 might_sleep(); 116 might_sleep();
102 117
103 trace_drv_remove_interface(local, vif_to_sdata(vif)); 118 check_sdata_in_driver(sdata);
104 local->ops->remove_interface(&local->hw, vif); 119
120 trace_drv_remove_interface(local, sdata);
121 local->ops->remove_interface(&local->hw, &sdata->vif);
122 sdata->flags &= ~IEEE80211_SDATA_IN_DRIVER;
105 trace_drv_return_void(local); 123 trace_drv_return_void(local);
106} 124}
107 125
@@ -124,6 +142,8 @@ static inline void drv_bss_info_changed(struct ieee80211_local *local,
124{ 142{
125 might_sleep(); 143 might_sleep();
126 144
145 check_sdata_in_driver(sdata);
146
127 trace_drv_bss_info_changed(local, sdata, info, changed); 147 trace_drv_bss_info_changed(local, sdata, info, changed);
128 if (local->ops->bss_info_changed) 148 if (local->ops->bss_info_changed)
129 local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed); 149 local->ops->bss_info_changed(&local->hw, &sdata->vif, info, changed);
@@ -139,6 +159,8 @@ static inline int drv_tx_sync(struct ieee80211_local *local,
139 159
140 might_sleep(); 160 might_sleep();
141 161
162 check_sdata_in_driver(sdata);
163
142 trace_drv_tx_sync(local, sdata, bssid, type); 164 trace_drv_tx_sync(local, sdata, bssid, type);
143 if (local->ops->tx_sync) 165 if (local->ops->tx_sync)
144 ret = local->ops->tx_sync(&local->hw, &sdata->vif, 166 ret = local->ops->tx_sync(&local->hw, &sdata->vif,
@@ -154,6 +176,8 @@ static inline void drv_finish_tx_sync(struct ieee80211_local *local,
154{ 176{
155 might_sleep(); 177 might_sleep();
156 178
179 check_sdata_in_driver(sdata);
180
157 trace_drv_finish_tx_sync(local, sdata, bssid, type); 181 trace_drv_finish_tx_sync(local, sdata, bssid, type);
158 if (local->ops->finish_tx_sync) 182 if (local->ops->finish_tx_sync)
159 local->ops->finish_tx_sync(&local->hw, &sdata->vif, 183 local->ops->finish_tx_sync(&local->hw, &sdata->vif,
@@ -211,6 +235,8 @@ static inline int drv_set_key(struct ieee80211_local *local,
211 235
212 might_sleep(); 236 might_sleep();
213 237
238 check_sdata_in_driver(sdata);
239
214 trace_drv_set_key(local, cmd, sdata, sta, key); 240 trace_drv_set_key(local, cmd, sdata, sta, key);
215 ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key); 241 ret = local->ops->set_key(&local->hw, cmd, &sdata->vif, sta, key);
216 trace_drv_return_int(local, ret); 242 trace_drv_return_int(local, ret);
@@ -228,6 +254,8 @@ static inline void drv_update_tkip_key(struct ieee80211_local *local,
228 if (sta) 254 if (sta)
229 ista = &sta->sta; 255 ista = &sta->sta;
230 256
257 check_sdata_in_driver(sdata);
258
231 trace_drv_update_tkip_key(local, sdata, conf, ista, iv32); 259 trace_drv_update_tkip_key(local, sdata, conf, ista, iv32);
232 if (local->ops->update_tkip_key) 260 if (local->ops->update_tkip_key)
233 local->ops->update_tkip_key(&local->hw, &sdata->vif, conf, 261 local->ops->update_tkip_key(&local->hw, &sdata->vif, conf,
@@ -243,6 +271,8 @@ static inline int drv_hw_scan(struct ieee80211_local *local,
243 271
244 might_sleep(); 272 might_sleep();
245 273
274 check_sdata_in_driver(sdata);
275
246 trace_drv_hw_scan(local, sdata); 276 trace_drv_hw_scan(local, sdata);
247 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req); 277 ret = local->ops->hw_scan(&local->hw, &sdata->vif, req);
248 trace_drv_return_int(local, ret); 278 trace_drv_return_int(local, ret);
@@ -254,6 +284,8 @@ static inline void drv_cancel_hw_scan(struct ieee80211_local *local,
254{ 284{
255 might_sleep(); 285 might_sleep();
256 286
287 check_sdata_in_driver(sdata);
288
257 trace_drv_cancel_hw_scan(local, sdata); 289 trace_drv_cancel_hw_scan(local, sdata);
258 local->ops->cancel_hw_scan(&local->hw, &sdata->vif); 290 local->ops->cancel_hw_scan(&local->hw, &sdata->vif);
259 trace_drv_return_void(local); 291 trace_drv_return_void(local);
@@ -269,6 +301,8 @@ drv_sched_scan_start(struct ieee80211_local *local,
269 301
270 might_sleep(); 302 might_sleep();
271 303
304 check_sdata_in_driver(sdata);
305
272 trace_drv_sched_scan_start(local, sdata); 306 trace_drv_sched_scan_start(local, sdata);
273 ret = local->ops->sched_scan_start(&local->hw, &sdata->vif, 307 ret = local->ops->sched_scan_start(&local->hw, &sdata->vif,
274 req, ies); 308 req, ies);
@@ -281,6 +315,8 @@ static inline void drv_sched_scan_stop(struct ieee80211_local *local,
281{ 315{
282 might_sleep(); 316 might_sleep();
283 317
318 check_sdata_in_driver(sdata);
319
284 trace_drv_sched_scan_stop(local, sdata); 320 trace_drv_sched_scan_stop(local, sdata);
285 local->ops->sched_scan_stop(&local->hw, &sdata->vif); 321 local->ops->sched_scan_stop(&local->hw, &sdata->vif);
286 trace_drv_return_void(local); 322 trace_drv_return_void(local);
@@ -377,6 +413,8 @@ static inline void drv_sta_notify(struct ieee80211_local *local,
377 enum sta_notify_cmd cmd, 413 enum sta_notify_cmd cmd,
378 struct ieee80211_sta *sta) 414 struct ieee80211_sta *sta)
379{ 415{
416 check_sdata_in_driver(sdata);
417
380 trace_drv_sta_notify(local, sdata, cmd, sta); 418 trace_drv_sta_notify(local, sdata, cmd, sta);
381 if (local->ops->sta_notify) 419 if (local->ops->sta_notify)
382 local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta); 420 local->ops->sta_notify(&local->hw, &sdata->vif, cmd, sta);
@@ -391,6 +429,8 @@ static inline int drv_sta_add(struct ieee80211_local *local,
391 429
392 might_sleep(); 430 might_sleep();
393 431
432 check_sdata_in_driver(sdata);
433
394 trace_drv_sta_add(local, sdata, sta); 434 trace_drv_sta_add(local, sdata, sta);
395 if (local->ops->sta_add) 435 if (local->ops->sta_add)
396 ret = local->ops->sta_add(&local->hw, &sdata->vif, sta); 436 ret = local->ops->sta_add(&local->hw, &sdata->vif, sta);
@@ -406,6 +446,8 @@ static inline void drv_sta_remove(struct ieee80211_local *local,
406{ 446{
407 might_sleep(); 447 might_sleep();
408 448
449 check_sdata_in_driver(sdata);
450
409 trace_drv_sta_remove(local, sdata, sta); 451 trace_drv_sta_remove(local, sdata, sta);
410 if (local->ops->sta_remove) 452 if (local->ops->sta_remove)
411 local->ops->sta_remove(&local->hw, &sdata->vif, sta); 453 local->ops->sta_remove(&local->hw, &sdata->vif, sta);
@@ -421,6 +463,8 @@ static inline int drv_conf_tx(struct ieee80211_local *local,
421 463
422 might_sleep(); 464 might_sleep();
423 465
466 check_sdata_in_driver(sdata);
467
424 trace_drv_conf_tx(local, sdata, queue, params); 468 trace_drv_conf_tx(local, sdata, queue, params);
425 if (local->ops->conf_tx) 469 if (local->ops->conf_tx)
426 ret = local->ops->conf_tx(&local->hw, &sdata->vif, 470 ret = local->ops->conf_tx(&local->hw, &sdata->vif,
@@ -436,6 +480,8 @@ static inline u64 drv_get_tsf(struct ieee80211_local *local,
436 480
437 might_sleep(); 481 might_sleep();
438 482
483 check_sdata_in_driver(sdata);
484
439 trace_drv_get_tsf(local, sdata); 485 trace_drv_get_tsf(local, sdata);
440 if (local->ops->get_tsf) 486 if (local->ops->get_tsf)
441 ret = local->ops->get_tsf(&local->hw, &sdata->vif); 487 ret = local->ops->get_tsf(&local->hw, &sdata->vif);
@@ -449,6 +495,8 @@ static inline void drv_set_tsf(struct ieee80211_local *local,
449{ 495{
450 might_sleep(); 496 might_sleep();
451 497
498 check_sdata_in_driver(sdata);
499
452 trace_drv_set_tsf(local, sdata, tsf); 500 trace_drv_set_tsf(local, sdata, tsf);
453 if (local->ops->set_tsf) 501 if (local->ops->set_tsf)
454 local->ops->set_tsf(&local->hw, &sdata->vif, tsf); 502 local->ops->set_tsf(&local->hw, &sdata->vif, tsf);
@@ -460,6 +508,8 @@ static inline void drv_reset_tsf(struct ieee80211_local *local,
460{ 508{
461 might_sleep(); 509 might_sleep();
462 510
511 check_sdata_in_driver(sdata);
512
463 trace_drv_reset_tsf(local, sdata); 513 trace_drv_reset_tsf(local, sdata);
464 if (local->ops->reset_tsf) 514 if (local->ops->reset_tsf)
465 local->ops->reset_tsf(&local->hw, &sdata->vif); 515 local->ops->reset_tsf(&local->hw, &sdata->vif);
@@ -489,6 +539,8 @@ static inline int drv_ampdu_action(struct ieee80211_local *local,
489 539
490 might_sleep(); 540 might_sleep();
491 541
542 check_sdata_in_driver(sdata);
543
492 trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size); 544 trace_drv_ampdu_action(local, sdata, action, sta, tid, ssn, buf_size);
493 545
494 if (local->ops->ampdu_action) 546 if (local->ops->ampdu_action)
@@ -644,6 +696,8 @@ static inline int drv_set_bitrate_mask(struct ieee80211_local *local,
644 696
645 might_sleep(); 697 might_sleep();
646 698
699 check_sdata_in_driver(sdata);
700
647 trace_drv_set_bitrate_mask(local, sdata, mask); 701 trace_drv_set_bitrate_mask(local, sdata, mask);
648 if (local->ops->set_bitrate_mask) 702 if (local->ops->set_bitrate_mask)
649 ret = local->ops->set_bitrate_mask(&local->hw, 703 ret = local->ops->set_bitrate_mask(&local->hw,
@@ -657,6 +711,8 @@ static inline void drv_set_rekey_data(struct ieee80211_local *local,
657 struct ieee80211_sub_if_data *sdata, 711 struct ieee80211_sub_if_data *sdata,
658 struct cfg80211_gtk_rekey_data *data) 712 struct cfg80211_gtk_rekey_data *data)
659{ 713{
714 check_sdata_in_driver(sdata);
715
660 trace_drv_set_rekey_data(local, sdata, data); 716 trace_drv_set_rekey_data(local, sdata, data);
661 if (local->ops->set_rekey_data) 717 if (local->ops->set_rekey_data)
662 local->ops->set_rekey_data(&local->hw, &sdata->vif, data); 718 local->ops->set_rekey_data(&local->hw, &sdata->vif, data);