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.c188
1 files changed, 123 insertions, 65 deletions
diff --git a/net/mac80211/cfg.c b/net/mac80211/cfg.c
index 44049733c4ea..be70c70d3f5b 100644
--- a/net/mac80211/cfg.c
+++ b/net/mac80211/cfg.c
@@ -136,7 +136,10 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
136 mutex_lock(&sdata->local->sta_mtx); 136 mutex_lock(&sdata->local->sta_mtx);
137 137
138 if (mac_addr) { 138 if (mac_addr) {
139 sta = sta_info_get_bss(sdata, mac_addr); 139 if (ieee80211_vif_is_mesh(&sdata->vif))
140 sta = sta_info_get(sdata, mac_addr);
141 else
142 sta = sta_info_get_bss(sdata, mac_addr);
140 if (!sta) { 143 if (!sta) {
141 ieee80211_key_free(sdata->local, key); 144 ieee80211_key_free(sdata->local, key);
142 err = -ENOENT; 145 err = -ENOENT;
@@ -157,13 +160,14 @@ static int ieee80211_add_key(struct wiphy *wiphy, struct net_device *dev,
157static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev, 160static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
158 u8 key_idx, bool pairwise, const u8 *mac_addr) 161 u8 key_idx, bool pairwise, const u8 *mac_addr)
159{ 162{
160 struct ieee80211_sub_if_data *sdata; 163 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
164 struct ieee80211_local *local = sdata->local;
161 struct sta_info *sta; 165 struct sta_info *sta;
166 struct ieee80211_key *key = NULL;
162 int ret; 167 int ret;
163 168
164 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 169 mutex_lock(&local->sta_mtx);
165 170 mutex_lock(&local->key_mtx);
166 mutex_lock(&sdata->local->sta_mtx);
167 171
168 if (mac_addr) { 172 if (mac_addr) {
169 ret = -ENOENT; 173 ret = -ENOENT;
@@ -172,33 +176,24 @@ static int ieee80211_del_key(struct wiphy *wiphy, struct net_device *dev,
172 if (!sta) 176 if (!sta)
173 goto out_unlock; 177 goto out_unlock;
174 178
175 if (pairwise) { 179 if (pairwise)
176 if (sta->ptk) { 180 key = key_mtx_dereference(local, sta->ptk);
177 ieee80211_key_free(sdata->local, sta->ptk); 181 else
178 ret = 0; 182 key = key_mtx_dereference(local, sta->gtk[key_idx]);
179 } 183 } else
180 } else { 184 key = key_mtx_dereference(local, sdata->keys[key_idx]);
181 if (sta->gtk[key_idx]) {
182 ieee80211_key_free(sdata->local,
183 sta->gtk[key_idx]);
184 ret = 0;
185 }
186 }
187
188 goto out_unlock;
189 }
190 185
191 if (!sdata->keys[key_idx]) { 186 if (!key) {
192 ret = -ENOENT; 187 ret = -ENOENT;
193 goto out_unlock; 188 goto out_unlock;
194 } 189 }
195 190
196 ieee80211_key_free(sdata->local, sdata->keys[key_idx]); 191 __ieee80211_key_free(key);
197 WARN_ON(sdata->keys[key_idx]);
198 192
199 ret = 0; 193 ret = 0;
200 out_unlock: 194 out_unlock:
201 mutex_unlock(&sdata->local->sta_mtx); 195 mutex_unlock(&local->key_mtx);
196 mutex_unlock(&local->sta_mtx);
202 197
203 return ret; 198 return ret;
204} 199}
@@ -228,11 +223,11 @@ static int ieee80211_get_key(struct wiphy *wiphy, struct net_device *dev,
228 goto out; 223 goto out;
229 224
230 if (pairwise) 225 if (pairwise)
231 key = sta->ptk; 226 key = rcu_dereference(sta->ptk);
232 else if (key_idx < NUM_DEFAULT_KEYS) 227 else if (key_idx < NUM_DEFAULT_KEYS)
233 key = sta->gtk[key_idx]; 228 key = rcu_dereference(sta->gtk[key_idx]);
234 } else 229 } else
235 key = sdata->keys[key_idx]; 230 key = rcu_dereference(sdata->keys[key_idx]);
236 231
237 if (!key) 232 if (!key)
238 goto out; 233 goto out;
@@ -330,6 +325,7 @@ static void rate_idx_to_bitrate(struct rate_info *rate, struct sta_info *sta, in
330static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo) 325static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
331{ 326{
332 struct ieee80211_sub_if_data *sdata = sta->sdata; 327 struct ieee80211_sub_if_data *sdata = sta->sdata;
328 struct timespec uptime;
333 329
334 sinfo->generation = sdata->local->sta_generation; 330 sinfo->generation = sdata->local->sta_generation;
335 331
@@ -342,7 +338,12 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
342 STATION_INFO_TX_FAILED | 338 STATION_INFO_TX_FAILED |
343 STATION_INFO_TX_BITRATE | 339 STATION_INFO_TX_BITRATE |
344 STATION_INFO_RX_BITRATE | 340 STATION_INFO_RX_BITRATE |
345 STATION_INFO_RX_DROP_MISC; 341 STATION_INFO_RX_DROP_MISC |
342 STATION_INFO_BSS_PARAM |
343 STATION_INFO_CONNECTED_TIME;
344
345 do_posix_clock_monotonic_gettime(&uptime);
346 sinfo->connected_time = uptime.tv_sec - sta->last_connected;
346 347
347 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx); 348 sinfo->inactive_time = jiffies_to_msecs(jiffies - sta->last_rx);
348 sinfo->rx_bytes = sta->rx_bytes; 349 sinfo->rx_bytes = sta->rx_bytes;
@@ -389,6 +390,16 @@ static void sta_set_sinfo(struct sta_info *sta, struct station_info *sinfo)
389 sinfo->plink_state = sta->plink_state; 390 sinfo->plink_state = sta->plink_state;
390#endif 391#endif
391 } 392 }
393
394 sinfo->bss_param.flags = 0;
395 if (sdata->vif.bss_conf.use_cts_prot)
396 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_CTS_PROT;
397 if (sdata->vif.bss_conf.use_short_preamble)
398 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_PREAMBLE;
399 if (sdata->vif.bss_conf.use_short_slot)
400 sinfo->bss_param.flags |= BSS_PARAM_FLAGS_SHORT_SLOT_TIME;
401 sinfo->bss_param.dtim_period = sdata->local->hw.conf.ps_dtim_period;
402 sinfo->bss_param.beacon_interval = sdata->vif.bss_conf.beacon_int;
392} 403}
393 404
394 405
@@ -452,7 +463,7 @@ static int ieee80211_config_beacon(struct ieee80211_sub_if_data *sdata,
452 int size; 463 int size;
453 int err = -EINVAL; 464 int err = -EINVAL;
454 465
455 old = sdata->u.ap.beacon; 466 old = rtnl_dereference(sdata->u.ap.beacon);
456 467
457 /* head must not be zero-length */ 468 /* head must not be zero-length */
458 if (params->head && !params->head_len) 469 if (params->head && !params->head_len)
@@ -547,8 +558,7 @@ static int ieee80211_add_beacon(struct wiphy *wiphy, struct net_device *dev,
547 558
548 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 559 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
549 560
550 old = sdata->u.ap.beacon; 561 old = rtnl_dereference(sdata->u.ap.beacon);
551
552 if (old) 562 if (old)
553 return -EALREADY; 563 return -EALREADY;
554 564
@@ -563,8 +573,7 @@ static int ieee80211_set_beacon(struct wiphy *wiphy, struct net_device *dev,
563 573
564 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 574 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
565 575
566 old = sdata->u.ap.beacon; 576 old = rtnl_dereference(sdata->u.ap.beacon);
567
568 if (!old) 577 if (!old)
569 return -ENOENT; 578 return -ENOENT;
570 579
@@ -578,8 +587,7 @@ static int ieee80211_del_beacon(struct wiphy *wiphy, struct net_device *dev)
578 587
579 sdata = IEEE80211_DEV_TO_SUB_IF(dev); 588 sdata = IEEE80211_DEV_TO_SUB_IF(dev);
580 589
581 old = sdata->u.ap.beacon; 590 old = rtnl_dereference(sdata->u.ap.beacon);
582
583 if (!old) 591 if (!old)
584 return -ENOENT; 592 return -ENOENT;
585 593
@@ -675,6 +683,12 @@ static void sta_apply_parameters(struct ieee80211_local *local,
675 if (set & BIT(NL80211_STA_FLAG_MFP)) 683 if (set & BIT(NL80211_STA_FLAG_MFP))
676 sta->flags |= WLAN_STA_MFP; 684 sta->flags |= WLAN_STA_MFP;
677 } 685 }
686
687 if (mask & BIT(NL80211_STA_FLAG_AUTHENTICATED)) {
688 sta->flags &= ~WLAN_STA_AUTH;
689 if (set & BIT(NL80211_STA_FLAG_AUTHENTICATED))
690 sta->flags |= WLAN_STA_AUTH;
691 }
678 spin_unlock_irqrestore(&sta->flaglock, flags); 692 spin_unlock_irqrestore(&sta->flaglock, flags);
679 693
680 /* 694 /*
@@ -712,15 +726,29 @@ static void sta_apply_parameters(struct ieee80211_local *local,
712 params->ht_capa, 726 params->ht_capa,
713 &sta->sta.ht_cap); 727 &sta->sta.ht_cap);
714 728
715 if (ieee80211_vif_is_mesh(&sdata->vif) && params->plink_action) { 729 if (ieee80211_vif_is_mesh(&sdata->vif)) {
716 switch (params->plink_action) { 730#ifdef CONFIG_MAC80211_MESH
717 case PLINK_ACTION_OPEN: 731 if (sdata->u.mesh.security & IEEE80211_MESH_SEC_SECURED)
718 mesh_plink_open(sta); 732 switch (params->plink_state) {
719 break; 733 case NL80211_PLINK_LISTEN:
720 case PLINK_ACTION_BLOCK: 734 case NL80211_PLINK_ESTAB:
721 mesh_plink_block(sta); 735 case NL80211_PLINK_BLOCKED:
722 break; 736 sta->plink_state = params->plink_state;
723 } 737 break;
738 default:
739 /* nothing */
740 break;
741 }
742 else
743 switch (params->plink_action) {
744 case PLINK_ACTION_OPEN:
745 mesh_plink_open(sta);
746 break;
747 case PLINK_ACTION_BLOCK:
748 mesh_plink_block(sta);
749 break;
750 }
751#endif
724 } 752 }
725} 753}
726 754
@@ -921,8 +949,10 @@ static int ieee80211_change_mpath(struct wiphy *wiphy,
921static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop, 949static void mpath_set_pinfo(struct mesh_path *mpath, u8 *next_hop,
922 struct mpath_info *pinfo) 950 struct mpath_info *pinfo)
923{ 951{
924 if (mpath->next_hop) 952 struct sta_info *next_hop_sta = rcu_dereference(mpath->next_hop);
925 memcpy(next_hop, mpath->next_hop->sta.addr, ETH_ALEN); 953
954 if (next_hop_sta)
955 memcpy(next_hop, next_hop_sta->sta.addr, ETH_ALEN);
926 else 956 else
927 memset(next_hop, 0, ETH_ALEN); 957 memset(next_hop, 0, ETH_ALEN);
928 958
@@ -1023,26 +1053,30 @@ static int copy_mesh_setup(struct ieee80211_if_mesh *ifmsh,
1023 u8 *new_ie; 1053 u8 *new_ie;
1024 const u8 *old_ie; 1054 const u8 *old_ie;
1025 1055
1026 /* first allocate the new vendor information element */ 1056 /* allocate information elements */
1027 new_ie = NULL; 1057 new_ie = NULL;
1028 old_ie = ifmsh->vendor_ie; 1058 old_ie = ifmsh->ie;
1029 1059
1030 ifmsh->vendor_ie_len = setup->vendor_ie_len; 1060 if (setup->ie_len) {
1031 if (setup->vendor_ie_len) { 1061 new_ie = kmemdup(setup->ie, setup->ie_len,
1032 new_ie = kmemdup(setup->vendor_ie, setup->vendor_ie_len,
1033 GFP_KERNEL); 1062 GFP_KERNEL);
1034 if (!new_ie) 1063 if (!new_ie)
1035 return -ENOMEM; 1064 return -ENOMEM;
1036 } 1065 }
1066 ifmsh->ie_len = setup->ie_len;
1067 ifmsh->ie = new_ie;
1068 kfree(old_ie);
1037 1069
1038 /* now copy the rest of the setup parameters */ 1070 /* now copy the rest of the setup parameters */
1039 ifmsh->mesh_id_len = setup->mesh_id_len; 1071 ifmsh->mesh_id_len = setup->mesh_id_len;
1040 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len); 1072 memcpy(ifmsh->mesh_id, setup->mesh_id, ifmsh->mesh_id_len);
1041 ifmsh->mesh_pp_id = setup->path_sel_proto; 1073 ifmsh->mesh_pp_id = setup->path_sel_proto;
1042 ifmsh->mesh_pm_id = setup->path_metric; 1074 ifmsh->mesh_pm_id = setup->path_metric;
1043 ifmsh->vendor_ie = new_ie; 1075 ifmsh->security = IEEE80211_MESH_SEC_NONE;
1044 1076 if (setup->is_authenticated)
1045 kfree(old_ie); 1077 ifmsh->security |= IEEE80211_MESH_SEC_AUTHED;
1078 if (setup->is_secure)
1079 ifmsh->security |= IEEE80211_MESH_SEC_SECURED;
1046 1080
1047 return 0; 1081 return 0;
1048} 1082}
@@ -1275,9 +1309,10 @@ static int ieee80211_set_channel(struct wiphy *wiphy,
1275} 1309}
1276 1310
1277#ifdef CONFIG_PM 1311#ifdef CONFIG_PM
1278static int ieee80211_suspend(struct wiphy *wiphy) 1312static int ieee80211_suspend(struct wiphy *wiphy,
1313 struct cfg80211_wowlan *wowlan)
1279{ 1314{
1280 return __ieee80211_suspend(wiphy_priv(wiphy)); 1315 return __ieee80211_suspend(wiphy_priv(wiphy), wowlan);
1281} 1316}
1282 1317
1283static int ieee80211_resume(struct wiphy *wiphy) 1318static int ieee80211_resume(struct wiphy *wiphy)
@@ -1320,6 +1355,30 @@ static int ieee80211_scan(struct wiphy *wiphy,
1320 return ieee80211_request_scan(sdata, req); 1355 return ieee80211_request_scan(sdata, req);
1321} 1356}
1322 1357
1358static int
1359ieee80211_sched_scan_start(struct wiphy *wiphy,
1360 struct net_device *dev,
1361 struct cfg80211_sched_scan_request *req)
1362{
1363 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1364
1365 if (!sdata->local->ops->sched_scan_start)
1366 return -EOPNOTSUPP;
1367
1368 return ieee80211_request_sched_scan_start(sdata, req);
1369}
1370
1371static int
1372ieee80211_sched_scan_stop(struct wiphy *wiphy, struct net_device *dev)
1373{
1374 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1375
1376 if (!sdata->local->ops->sched_scan_stop)
1377 return -EOPNOTSUPP;
1378
1379 return ieee80211_request_sched_scan_stop(sdata);
1380}
1381
1323static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev, 1382static int ieee80211_auth(struct wiphy *wiphy, struct net_device *dev,
1324 struct cfg80211_auth_request *req) 1383 struct cfg80211_auth_request *req)
1325{ 1384{
@@ -1611,16 +1670,13 @@ static int ieee80211_set_bitrate_mask(struct wiphy *wiphy,
1611{ 1670{
1612 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev); 1671 struct ieee80211_sub_if_data *sdata = IEEE80211_DEV_TO_SUB_IF(dev);
1613 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr); 1672 struct ieee80211_local *local = wdev_priv(dev->ieee80211_ptr);
1614 int i; 1673 int i, ret;
1615
1616 /*
1617 * This _could_ be supported by providing a hook for
1618 * drivers for this function, but at this point it
1619 * doesn't seem worth bothering.
1620 */
1621 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL)
1622 return -EOPNOTSUPP;
1623 1674
1675 if (local->hw.flags & IEEE80211_HW_HAS_RATE_CONTROL) {
1676 ret = drv_set_bitrate_mask(local, sdata, mask);
1677 if (ret)
1678 return ret;
1679 }
1624 1680
1625 for (i = 0; i < IEEE80211_NUM_BANDS; i++) 1681 for (i = 0; i < IEEE80211_NUM_BANDS; i++)
1626 sdata->rc_rateidx_mask[i] = mask->control[i].legacy; 1682 sdata->rc_rateidx_mask[i] = mask->control[i].legacy;
@@ -2064,6 +2120,8 @@ struct cfg80211_ops mac80211_config_ops = {
2064 .suspend = ieee80211_suspend, 2120 .suspend = ieee80211_suspend,
2065 .resume = ieee80211_resume, 2121 .resume = ieee80211_resume,
2066 .scan = ieee80211_scan, 2122 .scan = ieee80211_scan,
2123 .sched_scan_start = ieee80211_sched_scan_start,
2124 .sched_scan_stop = ieee80211_sched_scan_stop,
2067 .auth = ieee80211_auth, 2125 .auth = ieee80211_auth,
2068 .assoc = ieee80211_assoc, 2126 .assoc = ieee80211_assoc,
2069 .deauth = ieee80211_deauth, 2127 .deauth = ieee80211_deauth,