aboutsummaryrefslogtreecommitdiffstats
path: root/net/mac80211/cfg.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/mac80211/cfg.c')
-rw-r--r--net/mac80211/cfg.c110
1 files changed, 56 insertions, 54 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 6ac49231efa9..e9ba6fcc0e45 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -136,7 +136,6 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
136 struct ieee80211_sub_if_data *sdata; 136 struct ieee80211_sub_if_data *sdata;
137 struct sta_info *sta = NULL; 137 struct sta_info *sta = NULL;
138 enum ieee80211_key_alg alg; 138 enum ieee80211_key_alg alg;
139 int ret;
140 struct ieee80211_key *key; 139 struct ieee80211_key *key;
141 140
142 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 141 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
@@ -170,12 +169,7 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
170 169
171 ieee80211_key_link(key, sdata, sta); 170 ieee80211_key_link(key, sdata, sta);
172 171
173 ret = 0; 172 return 0;
174
175 if (sta)
176 sta_info_put(sta);
177
178 return ret;
179} 173}
180 174
181static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 175static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
@@ -184,7 +178,6 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
184 struct ieee80211_sub_if_data *sdata; 178 struct ieee80211_sub_if_data *sdata;
185 struct sta_info *sta; 179 struct sta_info *sta;
186 int ret; 180 int ret;
187 struct ieee80211_key *key;
188 181
189 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 182 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
190 183
@@ -195,21 +188,18 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
195 188
196 ret = 0; 189 ret = 0;
197 if (sta->key) { 190 if (sta->key) {
198 key = sta->key; 191 ieee80211_key_free(sta->key);
199 ieee80211_key_free(key);
200 WARN_ON(sta->key); 192 WARN_ON(sta->key);
201 } else 193 } else
202 ret = -ENOENT; 194 ret = -ENOENT;
203 195
204 sta_info_put(sta);
205 return ret; 196 return ret;
206 } 197 }
207 198
208 if (!sdata->keys[key_idx]) 199 if (!sdata->keys[key_idx])
209 return -ENOENT; 200 return -ENOENT;
210 201
211 key = sdata->keys[key_idx]; 202 ieee80211_key_free(sdata->keys[key_idx]);
212 ieee80211_key_free(key);
213 WARN_ON(sdata->keys[key_idx]); 203 WARN_ON(sdata->keys[key_idx]);
214 204
215 return 0; 205 return 0;
@@ -292,8 +282,6 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
292 err = 0; 282 err = 0;
293 283
294 out: 284 out:
295 if (sta)
296 sta_info_put(sta);
297 return err; 285 return err;
298} 286}
299 287
@@ -311,7 +299,7 @@ static int ieee80211_config_default_key(struct wiphy *wiphy,
311 299
312static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 300static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
313{ 301{
314 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); 302 struct ieee80211_sub_if_data *sdata = sta->sdata;
315 303
316 sinfo->filled = STATION_INFO_INACTIVE_TIME | 304 sinfo->filled = STATION_INFO_INACTIVE_TIME |
317 STATION_INFO_RX_BYTES | 305 STATION_INFO_RX_BYTES |
@@ -340,16 +328,20 @@ static int ieee80211_dump_station(struct wiphy *wiphy, struct net_device *dev,
340{ 328{
341 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 329 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
342 struct sta_info *sta; 330 struct sta_info *sta;
331 int ret = -ENOENT;
332
333 rcu_read_lock();
343 334
344 sta = sta_info_get_by_idx(local, idx, dev); 335 sta = sta_info_get_by_idx(local, idx, dev);
345 if (!sta) 336 if (sta) {
346 return -ENOENT; 337 ret = 0;
338 memcpy(mac, sta->addr, ETH_ALEN);
339 sta_set_sinfo(sta, sinfo);
340 }
347 341
348 memcpy(mac, sta->addr, ETH_ALEN); 342 rcu_read_unlock();
349 sta_set_sinfo(sta, sinfo);
350 sta_info_put(sta);
351 343
352 return 0; 344 return ret;
353} 345}
354 346
355static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev, 347static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
@@ -357,16 +349,21 @@ static int ieee80211_get_station(struct wiphy *wiphy, struct net_device *dev,
357{ 349{
358 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 350 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
359 struct sta_info *sta; 351 struct sta_info *sta;
352 int ret = -ENOENT;
360 353
361 sta = sta_info_get(local, mac); 354 rcu_read_lock();
362 if (!sta)
363 return -ENOENT;
364 355
365 /* XXX: verify sta->dev == dev */ 356 /* XXX: verify sta->dev == dev */
366 sta_set_sinfo(sta, sinfo);
367 sta_info_put(sta);
368 357
369 return 0; 358 sta = sta_info_get(local, mac);
359 if (sta) {
360 ret = 0;
361 sta_set_sinfo(sta, sinfo);
362 }
363
364 rcu_read_unlock();
365
366 return ret;
370} 367}
371 368
372/* 369/*
@@ -559,8 +556,8 @@ static void ieee80211_send_layer2_update(struct sta_info *sta)
559 msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */ 556 msg->xid_info[1] = 1; /* LLC types/classes: Type 1 LLC */
560 msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */ 557 msg->xid_info[2] = 0; /* XID sender's receive window size (RW) */
561 558
562 skb->dev = sta->dev; 559 skb->dev = sta->sdata->dev;
563 skb->protocol = eth_type_trans(skb, sta->dev); 560 skb->protocol = eth_type_trans(skb, sta->sdata->dev);
564 memset(skb->cb, 0, sizeof(skb->cb)); 561 memset(skb->cb, 0, sizeof(skb->cb));
565 netif_rx(skb); 562 netif_rx(skb);
566} 563}
@@ -572,7 +569,7 @@ static void sta_apply_parameters(struct ieee80211_local *local,
572 u32 rates; 569 u32 rates;
573 int i, j; 570 int i, j;
574 struct ieee80211_supported_band *sband; 571 struct ieee80211_supported_band *sband;
575 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(sta->dev); 572 struct ieee80211_sub_if_data *sdata = sta->sdata;
576 573
577 if (params->station_flags & STATION_FLAG_CHANGED) { 574 if (params->station_flags & STATION_FLAG_CHANGED) {
578 sta->flags &= ~WLAN_STA_AUTHORIZED; 575 sta->flags &= ~WLAN_STA_AUTHORIZED;
@@ -644,14 +641,13 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
644 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 641 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
645 642
646 if (ieee80211_vif_is_mesh(&sdata->vif)) 643 if (ieee80211_vif_is_mesh(&sdata->vif))
647 sta = mesh_plink_add(mac, DEFAULT_RATES, dev); 644 sta = mesh_plink_add(mac, DEFAULT_RATES, sdata);
648 else 645 else
649 sta = sta_info_add(local, dev, mac, GFP_KERNEL); 646 sta = sta_info_add(sdata, mac);
650 647
651 if (IS_ERR(sta)) 648 if (IS_ERR(sta))
652 return PTR_ERR(sta); 649 return PTR_ERR(sta);
653 650
654 sta->dev = sdata->dev;
655 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN || 651 if (sdata->vif.type == IEEE80211_IF_TYPE_VLAN ||
656 sdata->vif.type == IEEE80211_IF_TYPE_AP) 652 sdata->vif.type == IEEE80211_IF_TYPE_AP)
657 ieee80211_send_layer2_update(sta); 653 ieee80211_send_layer2_update(sta);
@@ -662,15 +658,14 @@ static int ieee80211_add_station(struct wiphy *wiphy, struct net_device *dev,
662 658
663 rate_control_rate_init(sta, local); 659 rate_control_rate_init(sta, local);
664 660
665 sta_info_put(sta);
666
667 return 0; 661 return 0;
668} 662}
669 663
670static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev, 664static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
671 u8 *mac) 665 u8 *mac)
672{ 666{
673 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 667 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
668 struct ieee80211_local *local = sdata->local;
674 struct sta_info *sta; 669 struct sta_info *sta;
675 670
676 if (mac) { 671 if (mac) {
@@ -679,10 +674,14 @@ static int ieee80211_del_station(struct wiphy *wiphy, struct net_device *dev,
679 if (!sta) 674 if (!sta)
680 return -ENOENT; 675 return -ENOENT;
681 676
682 sta_info_free(sta); 677 sta_info_unlink(&sta);
683 sta_info_put(sta); 678
679 if (sta) {
680 synchronize_rcu();
681 sta_info_destroy(sta);
682 }
684 } else 683 } else
685 sta_info_flush(local, dev); 684 sta_info_flush(local, sdata);
686 685
687 return 0; 686 return 0;
688} 687}
@@ -701,21 +700,19 @@ static int ieee80211_change_station(struct wiphy *wiphy,
701 if (!sta) 700 if (!sta)
702 return -ENOENT; 701 return -ENOENT;
703 702
704 if (params->vlan && params->vlan != sta->dev) { 703 if (params->vlan && params->vlan != sta->sdata->dev) {
705 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan); 704 vlansdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
706 705
707 if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN || 706 if (vlansdata->vif.type != IEEE80211_IF_TYPE_VLAN ||
708 vlansdata->vif.type != IEEE80211_IF_TYPE_AP) 707 vlansdata->vif.type != IEEE80211_IF_TYPE_AP)
709 return -EINVAL; 708 return -EINVAL;
710 709
711 sta->dev = params->vlan; 710 sta->sdata = IEEE80211_DEV_TO_SUB_IF(params->vlan);
712 ieee80211_send_layer2_update(sta); 711 ieee80211_send_layer2_update(sta);
713 } 712 }
714 713
715 sta_apply_parameters(local, sta, params); 714 sta_apply_parameters(local, sta, params);
716 715
717 sta_info_put(sta);
718
719 return 0; 716 return 0;
720} 717}
721 718
@@ -735,23 +732,26 @@ static int ieee80211_add_mpath(struct wiphy *wiphy, struct net_device *dev,
735 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 732 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
736 return -ENOTSUPP; 733 return -ENOTSUPP;
737 734
735 rcu_read_lock();
738 sta = sta_info_get(local, next_hop); 736 sta = sta_info_get(local, next_hop);
739 if (!sta) 737 if (!sta) {
738 rcu_read_unlock();
740 return -ENOENT; 739 return -ENOENT;
740 }
741 741
742 err = mesh_path_add(dst, dev); 742 err = mesh_path_add(dst, dev);
743 if (err) 743 if (err) {
744 rcu_read_unlock();
744 return err; 745 return err;
746 }
745 747
746 rcu_read_lock();
747 mpath = mesh_path_lookup(dst, dev); 748 mpath = mesh_path_lookup(dst, dev);
748 if (!mpath) { 749 if (!mpath) {
749 rcu_read_unlock(); 750 rcu_read_unlock();
750 sta_info_put(sta);
751 return -ENXIO; 751 return -ENXIO;
752 } 752 }
753 mesh_path_fix_nexthop(mpath, sta); 753 mesh_path_fix_nexthop(mpath, sta);
754 sta_info_put(sta); 754
755 rcu_read_unlock(); 755 rcu_read_unlock();
756 return 0; 756 return 0;
757} 757}
@@ -760,7 +760,7 @@ static int ieee80211_del_mpath(struct wiphy *wiphy, struct net_device *dev,
760 u8 *dst) 760 u8 *dst)
761{ 761{
762 if (dst) 762 if (dst)
763 return mesh_path_del(dst, dev); 763 return mesh_path_del(dst, dev, false);
764 764
765 mesh_path_flush(dev); 765 mesh_path_flush(dev);
766 return 0; 766 return 0;
@@ -781,20 +781,22 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
781 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT) 781 if (sdata->vif.type != IEEE80211_IF_TYPE_MESH_POINT)
782 return -ENOTSUPP; 782 return -ENOTSUPP;
783 783
784 rcu_read_lock();
785
784 sta = sta_info_get(local, next_hop); 786 sta = sta_info_get(local, next_hop);
785 if (!sta) 787 if (!sta) {
788 rcu_read_unlock();
786 return -ENOENT; 789 return -ENOENT;
790 }
787 791
788 rcu_read_lock();
789 mpath = mesh_path_lookup(dst, dev); 792 mpath = mesh_path_lookup(dst, dev);
790 if (!mpath) { 793 if (!mpath) {
791 rcu_read_unlock(); 794 rcu_read_unlock();
792 sta_info_put(sta);
793 return -ENOENT; 795 return -ENOENT;
794 } 796 }
795 797
796 mesh_path_fix_nexthop(mpath, sta); 798 mesh_path_fix_nexthop(mpath, sta);
797 sta_info_put(sta); 799
798 rcu_read_unlock(); 800 rcu_read_unlock();
799 return 0; 801 return 0;
800} 802}