0001
0002
0003
0004
0005
0006
0007 #include <linux/gfp.h>
0008 #include <linux/kernel.h>
0009 #include <linux/random.h>
0010 #include <linux/rculist.h>
0011
0012 #include "ieee80211_i.h"
0013 #include "rate.h"
0014 #include "mesh.h"
0015
0016 #define PLINK_CNF_AID(mgmt) ((mgmt)->u.action.u.self_prot.variable + 2)
0017 #define PLINK_GET_LLID(p) (p + 2)
0018 #define PLINK_GET_PLID(p) (p + 4)
0019
0020 #define mod_plink_timer(s, t) (mod_timer(&s->mesh->plink_timer, \
0021 jiffies + msecs_to_jiffies(t)))
0022
0023 enum plink_event {
0024 PLINK_UNDEFINED,
0025 OPN_ACPT,
0026 OPN_RJCT,
0027 OPN_IGNR,
0028 CNF_ACPT,
0029 CNF_RJCT,
0030 CNF_IGNR,
0031 CLS_ACPT,
0032 CLS_IGNR
0033 };
0034
0035 static const char * const mplstates[] = {
0036 [NL80211_PLINK_LISTEN] = "LISTEN",
0037 [NL80211_PLINK_OPN_SNT] = "OPN-SNT",
0038 [NL80211_PLINK_OPN_RCVD] = "OPN-RCVD",
0039 [NL80211_PLINK_CNF_RCVD] = "CNF_RCVD",
0040 [NL80211_PLINK_ESTAB] = "ESTAB",
0041 [NL80211_PLINK_HOLDING] = "HOLDING",
0042 [NL80211_PLINK_BLOCKED] = "BLOCKED"
0043 };
0044
0045 static const char * const mplevents[] = {
0046 [PLINK_UNDEFINED] = "NONE",
0047 [OPN_ACPT] = "OPN_ACPT",
0048 [OPN_RJCT] = "OPN_RJCT",
0049 [OPN_IGNR] = "OPN_IGNR",
0050 [CNF_ACPT] = "CNF_ACPT",
0051 [CNF_RJCT] = "CNF_RJCT",
0052 [CNF_IGNR] = "CNF_IGNR",
0053 [CLS_ACPT] = "CLS_ACPT",
0054 [CLS_IGNR] = "CLS_IGNR"
0055 };
0056
0057
0058 static bool rssi_threshold_check(struct ieee80211_sub_if_data *sdata,
0059 struct sta_info *sta)
0060 {
0061 s32 rssi_threshold = sdata->u.mesh.mshcfg.rssi_threshold;
0062 return rssi_threshold == 0 ||
0063 (sta &&
0064 (s8)-ewma_signal_read(&sta->deflink.rx_stats_avg.signal) >
0065 rssi_threshold);
0066 }
0067
0068
0069
0070
0071
0072
0073
0074
0075 static inline void mesh_plink_fsm_restart(struct sta_info *sta)
0076 {
0077 lockdep_assert_held(&sta->mesh->plink_lock);
0078 sta->mesh->plink_state = NL80211_PLINK_LISTEN;
0079 sta->mesh->llid = sta->mesh->plid = sta->mesh->reason = 0;
0080 sta->mesh->plink_retries = 0;
0081 }
0082
0083
0084
0085
0086
0087
0088
0089
0090
0091
0092
0093 static u32 mesh_set_short_slot_time(struct ieee80211_sub_if_data *sdata)
0094 {
0095 struct ieee80211_local *local = sdata->local;
0096 struct ieee80211_supported_band *sband;
0097 struct sta_info *sta;
0098 u32 erp_rates = 0, changed = 0;
0099 int i;
0100 bool short_slot = false;
0101
0102 sband = ieee80211_get_sband(sdata);
0103 if (!sband)
0104 return changed;
0105
0106 if (sband->band == NL80211_BAND_5GHZ) {
0107
0108 short_slot = true;
0109 goto out;
0110 } else if (sband->band != NL80211_BAND_2GHZ) {
0111 goto out;
0112 }
0113
0114 for (i = 0; i < sband->n_bitrates; i++)
0115 if (sband->bitrates[i].flags & IEEE80211_RATE_ERP_G)
0116 erp_rates |= BIT(i);
0117
0118 if (!erp_rates)
0119 goto out;
0120
0121 rcu_read_lock();
0122 list_for_each_entry_rcu(sta, &local->sta_list, list) {
0123 if (sdata != sta->sdata ||
0124 sta->mesh->plink_state != NL80211_PLINK_ESTAB)
0125 continue;
0126
0127 short_slot = false;
0128 if (erp_rates & sta->sta.deflink.supp_rates[sband->band])
0129 short_slot = true;
0130 else
0131 break;
0132 }
0133 rcu_read_unlock();
0134
0135 out:
0136 if (sdata->vif.bss_conf.use_short_slot != short_slot) {
0137 sdata->vif.bss_conf.use_short_slot = short_slot;
0138 changed = BSS_CHANGED_ERP_SLOT;
0139 mpl_dbg(sdata, "mesh_plink %pM: ERP short slot time %d\n",
0140 sdata->vif.addr, short_slot);
0141 }
0142 return changed;
0143 }
0144
0145
0146
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156 static u32 mesh_set_ht_prot_mode(struct ieee80211_sub_if_data *sdata)
0157 {
0158 struct ieee80211_local *local = sdata->local;
0159 struct sta_info *sta;
0160 u16 ht_opmode;
0161 bool non_ht_sta = false, ht20_sta = false;
0162
0163 switch (sdata->vif.bss_conf.chandef.width) {
0164 case NL80211_CHAN_WIDTH_20_NOHT:
0165 case NL80211_CHAN_WIDTH_5:
0166 case NL80211_CHAN_WIDTH_10:
0167 return 0;
0168 default:
0169 break;
0170 }
0171
0172 rcu_read_lock();
0173 list_for_each_entry_rcu(sta, &local->sta_list, list) {
0174 if (sdata != sta->sdata ||
0175 sta->mesh->plink_state != NL80211_PLINK_ESTAB)
0176 continue;
0177
0178 if (sta->sta.deflink.bandwidth > IEEE80211_STA_RX_BW_20)
0179 continue;
0180
0181 if (!sta->sta.deflink.ht_cap.ht_supported) {
0182 mpl_dbg(sdata, "nonHT sta (%pM) is present\n",
0183 sta->sta.addr);
0184 non_ht_sta = true;
0185 break;
0186 }
0187
0188 mpl_dbg(sdata, "HT20 sta (%pM) is present\n", sta->sta.addr);
0189 ht20_sta = true;
0190 }
0191 rcu_read_unlock();
0192
0193 if (non_ht_sta)
0194 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONHT_MIXED;
0195 else if (ht20_sta &&
0196 sdata->vif.bss_conf.chandef.width > NL80211_CHAN_WIDTH_20)
0197 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_20MHZ;
0198 else
0199 ht_opmode = IEEE80211_HT_OP_MODE_PROTECTION_NONE;
0200
0201 if (sdata->vif.bss_conf.ht_operation_mode == ht_opmode)
0202 return 0;
0203
0204 sdata->vif.bss_conf.ht_operation_mode = ht_opmode;
0205 sdata->u.mesh.mshcfg.ht_opmode = ht_opmode;
0206 mpl_dbg(sdata, "selected new HT protection mode %d\n", ht_opmode);
0207 return BSS_CHANGED_HT;
0208 }
0209
0210 static int mesh_plink_frame_tx(struct ieee80211_sub_if_data *sdata,
0211 struct sta_info *sta,
0212 enum ieee80211_self_protected_actioncode action,
0213 u8 *da, u16 llid, u16 plid, u16 reason)
0214 {
0215 struct ieee80211_local *local = sdata->local;
0216 struct sk_buff *skb;
0217 struct ieee80211_tx_info *info;
0218 struct ieee80211_mgmt *mgmt;
0219 bool include_plid = false;
0220 u16 peering_proto = 0;
0221 u8 *pos, ie_len = 4;
0222 u8 ie_len_he_cap;
0223 int hdr_len = offsetofend(struct ieee80211_mgmt, u.action.u.self_prot);
0224 int err = -ENOMEM;
0225
0226 ie_len_he_cap = ieee80211_ie_len_he_cap(sdata,
0227 NL80211_IFTYPE_MESH_POINT);
0228 skb = dev_alloc_skb(local->tx_headroom +
0229 hdr_len +
0230 2 +
0231 2 +
0232 2 + 8 +
0233 2 + (IEEE80211_MAX_SUPP_RATES - 8) +
0234 2 + sdata->u.mesh.mesh_id_len +
0235 2 + sizeof(struct ieee80211_meshconf_ie) +
0236 2 + sizeof(struct ieee80211_ht_cap) +
0237 2 + sizeof(struct ieee80211_ht_operation) +
0238 2 + sizeof(struct ieee80211_vht_cap) +
0239 2 + sizeof(struct ieee80211_vht_operation) +
0240 ie_len_he_cap +
0241 2 + 1 + sizeof(struct ieee80211_he_operation) +
0242 sizeof(struct ieee80211_he_6ghz_oper) +
0243 2 + 1 + sizeof(struct ieee80211_he_6ghz_capa) +
0244 2 + 8 +
0245 sdata->u.mesh.ie_len);
0246 if (!skb)
0247 return err;
0248 info = IEEE80211_SKB_CB(skb);
0249 skb_reserve(skb, local->tx_headroom);
0250 mgmt = skb_put_zero(skb, hdr_len);
0251 mgmt->frame_control = cpu_to_le16(IEEE80211_FTYPE_MGMT |
0252 IEEE80211_STYPE_ACTION);
0253 memcpy(mgmt->da, da, ETH_ALEN);
0254 memcpy(mgmt->sa, sdata->vif.addr, ETH_ALEN);
0255 memcpy(mgmt->bssid, sdata->vif.addr, ETH_ALEN);
0256 mgmt->u.action.category = WLAN_CATEGORY_SELF_PROTECTED;
0257 mgmt->u.action.u.self_prot.action_code = action;
0258
0259 if (action != WLAN_SP_MESH_PEERING_CLOSE) {
0260 struct ieee80211_supported_band *sband;
0261 enum nl80211_band band;
0262
0263 sband = ieee80211_get_sband(sdata);
0264 if (!sband) {
0265 err = -EINVAL;
0266 goto free;
0267 }
0268 band = sband->band;
0269
0270
0271 pos = skb_put_zero(skb, 2);
0272 if (action == WLAN_SP_MESH_PEERING_CONFIRM) {
0273
0274 pos = skb_put(skb, 2);
0275 put_unaligned_le16(sta->sta.aid, pos);
0276 }
0277 if (ieee80211_add_srates_ie(sdata, skb, true, band) ||
0278 ieee80211_add_ext_srates_ie(sdata, skb, true, band) ||
0279 mesh_add_rsn_ie(sdata, skb) ||
0280 mesh_add_meshid_ie(sdata, skb) ||
0281 mesh_add_meshconf_ie(sdata, skb))
0282 goto free;
0283 } else {
0284 info->flags |= IEEE80211_TX_CTL_NO_ACK;
0285 if (mesh_add_meshid_ie(sdata, skb))
0286 goto free;
0287 }
0288
0289
0290 switch (action) {
0291 case WLAN_SP_MESH_PEERING_OPEN:
0292 break;
0293 case WLAN_SP_MESH_PEERING_CONFIRM:
0294 ie_len += 2;
0295 include_plid = true;
0296 break;
0297 case WLAN_SP_MESH_PEERING_CLOSE:
0298 if (plid) {
0299 ie_len += 2;
0300 include_plid = true;
0301 }
0302 ie_len += 2;
0303 break;
0304 default:
0305 err = -EINVAL;
0306 goto free;
0307 }
0308
0309 if (WARN_ON(skb_tailroom(skb) < 2 + ie_len))
0310 goto free;
0311
0312 pos = skb_put(skb, 2 + ie_len);
0313 *pos++ = WLAN_EID_PEER_MGMT;
0314 *pos++ = ie_len;
0315 memcpy(pos, &peering_proto, 2);
0316 pos += 2;
0317 put_unaligned_le16(llid, pos);
0318 pos += 2;
0319 if (include_plid) {
0320 put_unaligned_le16(plid, pos);
0321 pos += 2;
0322 }
0323 if (action == WLAN_SP_MESH_PEERING_CLOSE) {
0324 put_unaligned_le16(reason, pos);
0325 pos += 2;
0326 }
0327
0328 if (action != WLAN_SP_MESH_PEERING_CLOSE) {
0329 if (mesh_add_ht_cap_ie(sdata, skb) ||
0330 mesh_add_ht_oper_ie(sdata, skb) ||
0331 mesh_add_vht_cap_ie(sdata, skb) ||
0332 mesh_add_vht_oper_ie(sdata, skb) ||
0333 mesh_add_he_cap_ie(sdata, skb, ie_len_he_cap) ||
0334 mesh_add_he_oper_ie(sdata, skb) ||
0335 mesh_add_he_6ghz_cap_ie(sdata, skb))
0336 goto free;
0337 }
0338
0339 if (mesh_add_vendor_ies(sdata, skb))
0340 goto free;
0341
0342 ieee80211_tx_skb(sdata, skb);
0343 return 0;
0344 free:
0345 kfree_skb(skb);
0346 return err;
0347 }
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358
0359
0360
0361 static u32 __mesh_plink_deactivate(struct sta_info *sta)
0362 {
0363 struct ieee80211_sub_if_data *sdata = sta->sdata;
0364 u32 changed = 0;
0365
0366 lockdep_assert_held(&sta->mesh->plink_lock);
0367
0368 if (sta->mesh->plink_state == NL80211_PLINK_ESTAB)
0369 changed = mesh_plink_dec_estab_count(sdata);
0370 sta->mesh->plink_state = NL80211_PLINK_BLOCKED;
0371
0372 ieee80211_mps_sta_status_update(sta);
0373 changed |= ieee80211_mps_set_sta_local_pm(sta,
0374 NL80211_MESH_POWER_UNKNOWN);
0375
0376 return changed;
0377 }
0378
0379
0380
0381
0382
0383
0384
0385
0386 u32 mesh_plink_deactivate(struct sta_info *sta)
0387 {
0388 struct ieee80211_sub_if_data *sdata = sta->sdata;
0389 u32 changed;
0390
0391 spin_lock_bh(&sta->mesh->plink_lock);
0392 changed = __mesh_plink_deactivate(sta);
0393
0394 if (!sdata->u.mesh.user_mpm) {
0395 sta->mesh->reason = WLAN_REASON_MESH_PEER_CANCELED;
0396 mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_CLOSE,
0397 sta->sta.addr, sta->mesh->llid,
0398 sta->mesh->plid, sta->mesh->reason);
0399 }
0400 spin_unlock_bh(&sta->mesh->plink_lock);
0401 if (!sdata->u.mesh.user_mpm)
0402 del_timer_sync(&sta->mesh->plink_timer);
0403 mesh_path_flush_by_nexthop(sta);
0404
0405
0406 synchronize_net();
0407
0408 return changed;
0409 }
0410
0411 static void mesh_sta_info_init(struct ieee80211_sub_if_data *sdata,
0412 struct sta_info *sta,
0413 struct ieee802_11_elems *elems)
0414 {
0415 struct ieee80211_local *local = sdata->local;
0416 struct ieee80211_supported_band *sband;
0417 u32 rates, basic_rates = 0, changed = 0;
0418 enum ieee80211_sta_rx_bandwidth bw = sta->sta.deflink.bandwidth;
0419
0420 sband = ieee80211_get_sband(sdata);
0421 if (!sband)
0422 return;
0423
0424 rates = ieee80211_sta_get_rates(sdata, elems, sband->band,
0425 &basic_rates);
0426
0427 spin_lock_bh(&sta->mesh->plink_lock);
0428 sta->deflink.rx_stats.last_rx = jiffies;
0429
0430
0431 if (sta->mesh->plink_state == NL80211_PLINK_ESTAB &&
0432 sta->mesh->processed_beacon)
0433 goto out;
0434 sta->mesh->processed_beacon = true;
0435
0436 if (sta->sta.deflink.supp_rates[sband->band] != rates)
0437 changed |= IEEE80211_RC_SUPP_RATES_CHANGED;
0438 sta->sta.deflink.supp_rates[sband->band] = rates;
0439
0440 if (ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,
0441 elems->ht_cap_elem,
0442 &sta->deflink))
0443 changed |= IEEE80211_RC_BW_CHANGED;
0444
0445 ieee80211_vht_cap_ie_to_sta_vht_cap(sdata, sband,
0446 elems->vht_cap_elem,
0447 &sta->deflink);
0448
0449 ieee80211_he_cap_ie_to_sta_he_cap(sdata, sband, elems->he_cap,
0450 elems->he_cap_len,
0451 elems->he_6ghz_capa,
0452 &sta->deflink);
0453
0454 if (bw != sta->sta.deflink.bandwidth)
0455 changed |= IEEE80211_RC_BW_CHANGED;
0456
0457
0458 if (elems->ht_operation &&
0459 !(elems->ht_operation->ht_param &
0460 IEEE80211_HT_PARAM_CHAN_WIDTH_ANY)) {
0461 if (sta->sta.deflink.bandwidth != IEEE80211_STA_RX_BW_20)
0462 changed |= IEEE80211_RC_BW_CHANGED;
0463 sta->sta.deflink.bandwidth = IEEE80211_STA_RX_BW_20;
0464 }
0465
0466 if (!test_sta_flag(sta, WLAN_STA_RATE_CONTROL))
0467 rate_control_rate_init(sta);
0468 else
0469 rate_control_rate_update(local, sband, sta, 0, changed);
0470 out:
0471 spin_unlock_bh(&sta->mesh->plink_lock);
0472 }
0473
0474 static int mesh_allocate_aid(struct ieee80211_sub_if_data *sdata)
0475 {
0476 struct sta_info *sta;
0477 unsigned long *aid_map;
0478 int aid;
0479
0480 aid_map = bitmap_zalloc(IEEE80211_MAX_AID + 1, GFP_KERNEL);
0481 if (!aid_map)
0482 return -ENOMEM;
0483
0484
0485 __set_bit(0, aid_map);
0486
0487 rcu_read_lock();
0488 list_for_each_entry_rcu(sta, &sdata->local->sta_list, list)
0489 __set_bit(sta->sta.aid, aid_map);
0490 rcu_read_unlock();
0491
0492 aid = find_first_zero_bit(aid_map, IEEE80211_MAX_AID + 1);
0493 bitmap_free(aid_map);
0494
0495 if (aid > IEEE80211_MAX_AID)
0496 return -ENOBUFS;
0497
0498 return aid;
0499 }
0500
0501 static struct sta_info *
0502 __mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *hw_addr)
0503 {
0504 struct sta_info *sta;
0505 int aid;
0506
0507 if (sdata->local->num_sta >= MESH_MAX_PLINKS)
0508 return NULL;
0509
0510 aid = mesh_allocate_aid(sdata);
0511 if (aid < 0)
0512 return NULL;
0513
0514 sta = sta_info_alloc(sdata, hw_addr, GFP_KERNEL);
0515 if (!sta)
0516 return NULL;
0517
0518 sta->mesh->plink_state = NL80211_PLINK_LISTEN;
0519 sta->sta.wme = true;
0520 sta->sta.aid = aid;
0521
0522 sta_info_pre_move_state(sta, IEEE80211_STA_AUTH);
0523 sta_info_pre_move_state(sta, IEEE80211_STA_ASSOC);
0524 sta_info_pre_move_state(sta, IEEE80211_STA_AUTHORIZED);
0525
0526 return sta;
0527 }
0528
0529 static struct sta_info *
0530 mesh_sta_info_alloc(struct ieee80211_sub_if_data *sdata, u8 *addr,
0531 struct ieee802_11_elems *elems,
0532 struct ieee80211_rx_status *rx_status)
0533 {
0534 struct sta_info *sta = NULL;
0535
0536
0537 if (sdata->u.mesh.user_mpm ||
0538 sdata->u.mesh.security & IEEE80211_MESH_SEC_AUTHED) {
0539 if (mesh_peer_accepts_plinks(elems) &&
0540 mesh_plink_availables(sdata)) {
0541 int sig = 0;
0542
0543 if (ieee80211_hw_check(&sdata->local->hw, SIGNAL_DBM))
0544 sig = rx_status->signal;
0545
0546 cfg80211_notify_new_peer_candidate(sdata->dev, addr,
0547 elems->ie_start,
0548 elems->total_len,
0549 sig, GFP_KERNEL);
0550 }
0551 } else
0552 sta = __mesh_sta_info_alloc(sdata, addr);
0553
0554 return sta;
0555 }
0556
0557
0558
0559
0560
0561
0562
0563
0564
0565
0566
0567
0568 static struct sta_info *
0569 mesh_sta_info_get(struct ieee80211_sub_if_data *sdata,
0570 u8 *addr, struct ieee802_11_elems *elems,
0571 struct ieee80211_rx_status *rx_status) __acquires(RCU)
0572 {
0573 struct sta_info *sta = NULL;
0574
0575 rcu_read_lock();
0576 sta = sta_info_get(sdata, addr);
0577 if (sta) {
0578 mesh_sta_info_init(sdata, sta, elems);
0579 } else {
0580 rcu_read_unlock();
0581
0582 sta = mesh_sta_info_alloc(sdata, addr, elems, rx_status);
0583 if (!sta) {
0584 rcu_read_lock();
0585 return NULL;
0586 }
0587
0588 mesh_sta_info_init(sdata, sta, elems);
0589
0590 if (sta_info_insert_rcu(sta))
0591 return NULL;
0592 }
0593
0594 return sta;
0595 }
0596
0597
0598
0599
0600
0601
0602
0603
0604
0605
0606
0607 void mesh_neighbour_update(struct ieee80211_sub_if_data *sdata,
0608 u8 *hw_addr,
0609 struct ieee802_11_elems *elems,
0610 struct ieee80211_rx_status *rx_status)
0611 {
0612 struct sta_info *sta;
0613 u32 changed = 0;
0614
0615 sta = mesh_sta_info_get(sdata, hw_addr, elems, rx_status);
0616 if (!sta)
0617 goto out;
0618
0619 sta->mesh->connected_to_gate = elems->mesh_config->meshconf_form &
0620 IEEE80211_MESHCONF_FORM_CONNECTED_TO_GATE;
0621
0622 if (mesh_peer_accepts_plinks(elems) &&
0623 sta->mesh->plink_state == NL80211_PLINK_LISTEN &&
0624 sdata->u.mesh.accepting_plinks &&
0625 sdata->u.mesh.mshcfg.auto_open_plinks &&
0626 rssi_threshold_check(sdata, sta))
0627 changed = mesh_plink_open(sta);
0628
0629 ieee80211_mps_frame_release(sta, elems);
0630 out:
0631 rcu_read_unlock();
0632 ieee80211_mbss_info_change_notify(sdata, changed);
0633 }
0634
0635 void mesh_plink_timer(struct timer_list *t)
0636 {
0637 struct mesh_sta *mesh = from_timer(mesh, t, plink_timer);
0638 struct sta_info *sta;
0639 u16 reason = 0;
0640 struct ieee80211_sub_if_data *sdata;
0641 struct mesh_config *mshcfg;
0642 enum ieee80211_self_protected_actioncode action = 0;
0643
0644
0645
0646
0647
0648
0649 sta = mesh->plink_sta;
0650
0651 if (sta->sdata->local->quiescing)
0652 return;
0653
0654 spin_lock_bh(&sta->mesh->plink_lock);
0655
0656
0657
0658
0659
0660
0661 if (time_before(jiffies, sta->mesh->plink_timer.expires)) {
0662 mpl_dbg(sta->sdata,
0663 "Ignoring timer for %pM in state %s (timer adjusted)",
0664 sta->sta.addr, mplstates[sta->mesh->plink_state]);
0665 spin_unlock_bh(&sta->mesh->plink_lock);
0666 return;
0667 }
0668
0669
0670 if (sta->mesh->plink_state == NL80211_PLINK_LISTEN ||
0671 sta->mesh->plink_state == NL80211_PLINK_ESTAB) {
0672 mpl_dbg(sta->sdata,
0673 "Ignoring timer for %pM in state %s (timer deleted)",
0674 sta->sta.addr, mplstates[sta->mesh->plink_state]);
0675 spin_unlock_bh(&sta->mesh->plink_lock);
0676 return;
0677 }
0678
0679 mpl_dbg(sta->sdata,
0680 "Mesh plink timer for %pM fired on state %s\n",
0681 sta->sta.addr, mplstates[sta->mesh->plink_state]);
0682 sdata = sta->sdata;
0683 mshcfg = &sdata->u.mesh.mshcfg;
0684
0685 switch (sta->mesh->plink_state) {
0686 case NL80211_PLINK_OPN_RCVD:
0687 case NL80211_PLINK_OPN_SNT:
0688
0689 if (sta->mesh->plink_retries < mshcfg->dot11MeshMaxRetries) {
0690 u32 rand;
0691 mpl_dbg(sta->sdata,
0692 "Mesh plink for %pM (retry, timeout): %d %d\n",
0693 sta->sta.addr, sta->mesh->plink_retries,
0694 sta->mesh->plink_timeout);
0695 get_random_bytes(&rand, sizeof(u32));
0696 sta->mesh->plink_timeout = sta->mesh->plink_timeout +
0697 rand % sta->mesh->plink_timeout;
0698 ++sta->mesh->plink_retries;
0699 mod_plink_timer(sta, sta->mesh->plink_timeout);
0700 action = WLAN_SP_MESH_PEERING_OPEN;
0701 break;
0702 }
0703 reason = WLAN_REASON_MESH_MAX_RETRIES;
0704 fallthrough;
0705 case NL80211_PLINK_CNF_RCVD:
0706
0707 if (!reason)
0708 reason = WLAN_REASON_MESH_CONFIRM_TIMEOUT;
0709 sta->mesh->plink_state = NL80211_PLINK_HOLDING;
0710 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
0711 action = WLAN_SP_MESH_PEERING_CLOSE;
0712 break;
0713 case NL80211_PLINK_HOLDING:
0714
0715 del_timer(&sta->mesh->plink_timer);
0716 mesh_plink_fsm_restart(sta);
0717 break;
0718 default:
0719 break;
0720 }
0721 spin_unlock_bh(&sta->mesh->plink_lock);
0722 if (action)
0723 mesh_plink_frame_tx(sdata, sta, action, sta->sta.addr,
0724 sta->mesh->llid, sta->mesh->plid, reason);
0725 }
0726
0727 static inline void mesh_plink_timer_set(struct sta_info *sta, u32 timeout)
0728 {
0729 sta->mesh->plink_timeout = timeout;
0730 mod_timer(&sta->mesh->plink_timer, jiffies + msecs_to_jiffies(timeout));
0731 }
0732
0733 static bool llid_in_use(struct ieee80211_sub_if_data *sdata,
0734 u16 llid)
0735 {
0736 struct ieee80211_local *local = sdata->local;
0737 bool in_use = false;
0738 struct sta_info *sta;
0739
0740 rcu_read_lock();
0741 list_for_each_entry_rcu(sta, &local->sta_list, list) {
0742 if (sdata != sta->sdata)
0743 continue;
0744
0745 if (!memcmp(&sta->mesh->llid, &llid, sizeof(llid))) {
0746 in_use = true;
0747 break;
0748 }
0749 }
0750 rcu_read_unlock();
0751
0752 return in_use;
0753 }
0754
0755 static u16 mesh_get_new_llid(struct ieee80211_sub_if_data *sdata)
0756 {
0757 u16 llid;
0758
0759 do {
0760 get_random_bytes(&llid, sizeof(llid));
0761 } while (llid_in_use(sdata, llid));
0762
0763 return llid;
0764 }
0765
0766 u32 mesh_plink_open(struct sta_info *sta)
0767 {
0768 struct ieee80211_sub_if_data *sdata = sta->sdata;
0769 u32 changed;
0770
0771 if (!test_sta_flag(sta, WLAN_STA_AUTH))
0772 return 0;
0773
0774 spin_lock_bh(&sta->mesh->plink_lock);
0775 sta->mesh->llid = mesh_get_new_llid(sdata);
0776 if (sta->mesh->plink_state != NL80211_PLINK_LISTEN &&
0777 sta->mesh->plink_state != NL80211_PLINK_BLOCKED) {
0778 spin_unlock_bh(&sta->mesh->plink_lock);
0779 return 0;
0780 }
0781 sta->mesh->plink_state = NL80211_PLINK_OPN_SNT;
0782 mesh_plink_timer_set(sta, sdata->u.mesh.mshcfg.dot11MeshRetryTimeout);
0783 spin_unlock_bh(&sta->mesh->plink_lock);
0784 mpl_dbg(sdata,
0785 "Mesh plink: starting establishment with %pM\n",
0786 sta->sta.addr);
0787
0788
0789 changed = ieee80211_mps_local_status_update(sdata);
0790
0791 mesh_plink_frame_tx(sdata, sta, WLAN_SP_MESH_PEERING_OPEN,
0792 sta->sta.addr, sta->mesh->llid, 0, 0);
0793 return changed;
0794 }
0795
0796 u32 mesh_plink_block(struct sta_info *sta)
0797 {
0798 u32 changed;
0799
0800 spin_lock_bh(&sta->mesh->plink_lock);
0801 changed = __mesh_plink_deactivate(sta);
0802 sta->mesh->plink_state = NL80211_PLINK_BLOCKED;
0803 spin_unlock_bh(&sta->mesh->plink_lock);
0804 mesh_path_flush_by_nexthop(sta);
0805
0806 return changed;
0807 }
0808
0809 static void mesh_plink_close(struct ieee80211_sub_if_data *sdata,
0810 struct sta_info *sta,
0811 enum plink_event event)
0812 {
0813 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
0814 u16 reason = (event == CLS_ACPT) ?
0815 WLAN_REASON_MESH_CLOSE : WLAN_REASON_MESH_CONFIG;
0816
0817 sta->mesh->reason = reason;
0818 sta->mesh->plink_state = NL80211_PLINK_HOLDING;
0819 mod_plink_timer(sta, mshcfg->dot11MeshHoldingTimeout);
0820 }
0821
0822 static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata,
0823 struct sta_info *sta)
0824 {
0825 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
0826 u32 changed = 0;
0827
0828 del_timer(&sta->mesh->plink_timer);
0829 sta->mesh->plink_state = NL80211_PLINK_ESTAB;
0830 changed |= mesh_plink_inc_estab_count(sdata);
0831 changed |= mesh_set_ht_prot_mode(sdata);
0832 changed |= mesh_set_short_slot_time(sdata);
0833 mpl_dbg(sdata, "Mesh plink with %pM ESTABLISHED\n", sta->sta.addr);
0834 ieee80211_mps_sta_status_update(sta);
0835 changed |= ieee80211_mps_set_sta_local_pm(sta, mshcfg->power_mode);
0836 return changed;
0837 }
0838
0839
0840
0841
0842
0843
0844
0845
0846
0847
0848 static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
0849 struct sta_info *sta, enum plink_event event)
0850 {
0851 struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
0852 enum ieee80211_self_protected_actioncode action = 0;
0853 u32 changed = 0;
0854 bool flush = false;
0855
0856 mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
0857 mplstates[sta->mesh->plink_state], mplevents[event]);
0858
0859 spin_lock_bh(&sta->mesh->plink_lock);
0860 switch (sta->mesh->plink_state) {
0861 case NL80211_PLINK_LISTEN:
0862 switch (event) {
0863 case CLS_ACPT:
0864 mesh_plink_fsm_restart(sta);
0865 break;
0866 case OPN_ACPT:
0867 sta->mesh->plink_state = NL80211_PLINK_OPN_RCVD;
0868 sta->mesh->llid = mesh_get_new_llid(sdata);
0869 mesh_plink_timer_set(sta,
0870 mshcfg->dot11MeshRetryTimeout);
0871
0872
0873 changed |= ieee80211_mps_local_status_update(sdata);
0874 action = WLAN_SP_MESH_PEERING_OPEN;
0875 break;
0876 default:
0877 break;
0878 }
0879 break;
0880 case NL80211_PLINK_OPN_SNT:
0881 switch (event) {
0882 case OPN_RJCT:
0883 case CNF_RJCT:
0884 case CLS_ACPT:
0885 mesh_plink_close(sdata, sta, event);
0886 action = WLAN_SP_MESH_PEERING_CLOSE;
0887 break;
0888 case OPN_ACPT:
0889
0890 sta->mesh->plink_state = NL80211_PLINK_OPN_RCVD;
0891 action = WLAN_SP_MESH_PEERING_CONFIRM;
0892 break;
0893 case CNF_ACPT:
0894 sta->mesh->plink_state = NL80211_PLINK_CNF_RCVD;
0895 mod_plink_timer(sta, mshcfg->dot11MeshConfirmTimeout);
0896 break;
0897 default:
0898 break;
0899 }
0900 break;
0901 case NL80211_PLINK_OPN_RCVD:
0902 switch (event) {
0903 case OPN_RJCT:
0904 case CNF_RJCT:
0905 case CLS_ACPT:
0906 mesh_plink_close(sdata, sta, event);
0907 action = WLAN_SP_MESH_PEERING_CLOSE;
0908 break;
0909 case OPN_ACPT:
0910 action = WLAN_SP_MESH_PEERING_CONFIRM;
0911 break;
0912 case CNF_ACPT:
0913 changed |= mesh_plink_establish(sdata, sta);
0914 break;
0915 default:
0916 break;
0917 }
0918 break;
0919 case NL80211_PLINK_CNF_RCVD:
0920 switch (event) {
0921 case OPN_RJCT:
0922 case CNF_RJCT:
0923 case CLS_ACPT:
0924 mesh_plink_close(sdata, sta, event);
0925 action = WLAN_SP_MESH_PEERING_CLOSE;
0926 break;
0927 case OPN_ACPT:
0928 changed |= mesh_plink_establish(sdata, sta);
0929 action = WLAN_SP_MESH_PEERING_CONFIRM;
0930 break;
0931 default:
0932 break;
0933 }
0934 break;
0935 case NL80211_PLINK_ESTAB:
0936 switch (event) {
0937 case CLS_ACPT:
0938 changed |= __mesh_plink_deactivate(sta);
0939 changed |= mesh_set_ht_prot_mode(sdata);
0940 changed |= mesh_set_short_slot_time(sdata);
0941 mesh_plink_close(sdata, sta, event);
0942 action = WLAN_SP_MESH_PEERING_CLOSE;
0943 flush = true;
0944 break;
0945 case OPN_ACPT:
0946 action = WLAN_SP_MESH_PEERING_CONFIRM;
0947 break;
0948 default:
0949 break;
0950 }
0951 break;
0952 case NL80211_PLINK_HOLDING:
0953 switch (event) {
0954 case CLS_ACPT:
0955 del_timer(&sta->mesh->plink_timer);
0956 mesh_plink_fsm_restart(sta);
0957 break;
0958 case OPN_ACPT:
0959 case CNF_ACPT:
0960 case OPN_RJCT:
0961 case CNF_RJCT:
0962 action = WLAN_SP_MESH_PEERING_CLOSE;
0963 break;
0964 default:
0965 break;
0966 }
0967 break;
0968 default:
0969
0970
0971
0972 break;
0973 }
0974 spin_unlock_bh(&sta->mesh->plink_lock);
0975 if (flush)
0976 mesh_path_flush_by_nexthop(sta);
0977 if (action) {
0978 mesh_plink_frame_tx(sdata, sta, action, sta->sta.addr,
0979 sta->mesh->llid, sta->mesh->plid,
0980 sta->mesh->reason);
0981
0982
0983 if (action == WLAN_SP_MESH_PEERING_OPEN) {
0984 mesh_plink_frame_tx(sdata, sta,
0985 WLAN_SP_MESH_PEERING_CONFIRM,
0986 sta->sta.addr, sta->mesh->llid,
0987 sta->mesh->plid, 0);
0988 }
0989 }
0990
0991 return changed;
0992 }
0993
0994
0995
0996
0997
0998
0999
1000
1001
1002
1003
1004
1005
1006
1007 static enum plink_event
1008 mesh_plink_get_event(struct ieee80211_sub_if_data *sdata,
1009 struct sta_info *sta,
1010 struct ieee802_11_elems *elems,
1011 enum ieee80211_self_protected_actioncode ftype,
1012 u16 llid, u16 plid)
1013 {
1014 enum plink_event event = PLINK_UNDEFINED;
1015 u8 ie_len = elems->peering_len;
1016 bool matches_local;
1017
1018 matches_local = (ftype == WLAN_SP_MESH_PEERING_CLOSE ||
1019 mesh_matches_local(sdata, elems));
1020
1021
1022 if (!matches_local && !sta) {
1023 event = OPN_RJCT;
1024 goto out;
1025 }
1026
1027 if (!sta) {
1028 if (ftype != WLAN_SP_MESH_PEERING_OPEN) {
1029 mpl_dbg(sdata, "Mesh plink: cls or cnf from unknown peer\n");
1030 goto out;
1031 }
1032
1033 if (!mesh_plink_free_count(sdata)) {
1034 mpl_dbg(sdata, "Mesh plink error: no more free plinks\n");
1035 goto out;
1036 }
1037
1038
1039 event = OPN_ACPT;
1040 goto out;
1041 } else {
1042 if (!test_sta_flag(sta, WLAN_STA_AUTH)) {
1043 mpl_dbg(sdata, "Mesh plink: Action frame from non-authed peer\n");
1044 goto out;
1045 }
1046 if (sta->mesh->plink_state == NL80211_PLINK_BLOCKED)
1047 goto out;
1048 }
1049
1050 switch (ftype) {
1051 case WLAN_SP_MESH_PEERING_OPEN:
1052 if (!matches_local)
1053 event = OPN_RJCT;
1054 if (!mesh_plink_free_count(sdata) ||
1055 (sta->mesh->plid && sta->mesh->plid != plid))
1056 event = OPN_IGNR;
1057 else
1058 event = OPN_ACPT;
1059 break;
1060 case WLAN_SP_MESH_PEERING_CONFIRM:
1061 if (!matches_local)
1062 event = CNF_RJCT;
1063 if (!mesh_plink_free_count(sdata) ||
1064 sta->mesh->llid != llid ||
1065 (sta->mesh->plid && sta->mesh->plid != plid))
1066 event = CNF_IGNR;
1067 else
1068 event = CNF_ACPT;
1069 break;
1070 case WLAN_SP_MESH_PEERING_CLOSE:
1071 if (sta->mesh->plink_state == NL80211_PLINK_ESTAB)
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081 event = CLS_ACPT;
1082 else if (sta->mesh->plid != plid)
1083 event = CLS_IGNR;
1084 else if (ie_len == 8 && sta->mesh->llid != llid)
1085 event = CLS_IGNR;
1086 else
1087 event = CLS_ACPT;
1088 break;
1089 default:
1090 mpl_dbg(sdata, "Mesh plink: unknown frame subtype\n");
1091 break;
1092 }
1093
1094 out:
1095 return event;
1096 }
1097
1098 static void
1099 mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
1100 struct ieee80211_mgmt *mgmt,
1101 struct ieee802_11_elems *elems,
1102 struct ieee80211_rx_status *rx_status)
1103 {
1104
1105 struct sta_info *sta;
1106 enum plink_event event;
1107 enum ieee80211_self_protected_actioncode ftype;
1108 u32 changed = 0;
1109 u8 ie_len = elems->peering_len;
1110 u16 plid, llid = 0;
1111
1112 if (!elems->peering) {
1113 mpl_dbg(sdata,
1114 "Mesh plink: missing necessary peer link ie\n");
1115 return;
1116 }
1117
1118 if (elems->rsn_len &&
1119 sdata->u.mesh.security == IEEE80211_MESH_SEC_NONE) {
1120 mpl_dbg(sdata,
1121 "Mesh plink: can't establish link with secure peer\n");
1122 return;
1123 }
1124
1125 ftype = mgmt->u.action.u.self_prot.action_code;
1126 if ((ftype == WLAN_SP_MESH_PEERING_OPEN && ie_len != 4) ||
1127 (ftype == WLAN_SP_MESH_PEERING_CONFIRM && ie_len != 6) ||
1128 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len != 6
1129 && ie_len != 8)) {
1130 mpl_dbg(sdata,
1131 "Mesh plink: incorrect plink ie length %d %d\n",
1132 ftype, ie_len);
1133 return;
1134 }
1135
1136 if (ftype != WLAN_SP_MESH_PEERING_CLOSE &&
1137 (!elems->mesh_id || !elems->mesh_config)) {
1138 mpl_dbg(sdata, "Mesh plink: missing necessary ie\n");
1139 return;
1140 }
1141
1142
1143
1144 plid = get_unaligned_le16(PLINK_GET_LLID(elems->peering));
1145 if (ftype == WLAN_SP_MESH_PEERING_CONFIRM ||
1146 (ftype == WLAN_SP_MESH_PEERING_CLOSE && ie_len == 8))
1147 llid = get_unaligned_le16(PLINK_GET_PLID(elems->peering));
1148
1149
1150 rcu_read_lock();
1151
1152 sta = sta_info_get(sdata, mgmt->sa);
1153
1154 if (ftype == WLAN_SP_MESH_PEERING_OPEN &&
1155 !rssi_threshold_check(sdata, sta)) {
1156 mpl_dbg(sdata, "Mesh plink: %pM does not meet rssi threshold\n",
1157 mgmt->sa);
1158 goto unlock_rcu;
1159 }
1160
1161
1162 event = mesh_plink_get_event(sdata, sta, elems, ftype, llid, plid);
1163
1164 if (event == OPN_ACPT) {
1165 rcu_read_unlock();
1166
1167 sta = mesh_sta_info_get(sdata, mgmt->sa, elems, rx_status);
1168 if (!sta) {
1169 mpl_dbg(sdata, "Mesh plink: failed to init peer!\n");
1170 goto unlock_rcu;
1171 }
1172 sta->mesh->plid = plid;
1173 } else if (!sta && event == OPN_RJCT) {
1174 mesh_plink_frame_tx(sdata, NULL, WLAN_SP_MESH_PEERING_CLOSE,
1175 mgmt->sa, 0, plid,
1176 WLAN_REASON_MESH_CONFIG);
1177 goto unlock_rcu;
1178 } else if (!sta || event == PLINK_UNDEFINED) {
1179
1180 goto unlock_rcu;
1181 }
1182
1183 if (event == CNF_ACPT) {
1184
1185 if (!sta->mesh->plid)
1186 sta->mesh->plid = plid;
1187
1188 sta->mesh->aid = get_unaligned_le16(PLINK_CNF_AID(mgmt));
1189 }
1190
1191 changed |= mesh_plink_fsm(sdata, sta, event);
1192
1193 unlock_rcu:
1194 rcu_read_unlock();
1195
1196 if (changed)
1197 ieee80211_mbss_info_change_notify(sdata, changed);
1198 }
1199
1200 void mesh_rx_plink_frame(struct ieee80211_sub_if_data *sdata,
1201 struct ieee80211_mgmt *mgmt, size_t len,
1202 struct ieee80211_rx_status *rx_status)
1203 {
1204 struct ieee802_11_elems *elems;
1205 size_t baselen;
1206 u8 *baseaddr;
1207
1208
1209 if (len < IEEE80211_MIN_ACTION_SIZE + 3)
1210 return;
1211
1212 if (sdata->u.mesh.user_mpm)
1213
1214 return;
1215
1216 if (is_multicast_ether_addr(mgmt->da)) {
1217 mpl_dbg(sdata,
1218 "Mesh plink: ignore frame from multicast address\n");
1219 return;
1220 }
1221
1222 baseaddr = mgmt->u.action.u.self_prot.variable;
1223 baselen = (u8 *) mgmt->u.action.u.self_prot.variable - (u8 *) mgmt;
1224 if (mgmt->u.action.u.self_prot.action_code ==
1225 WLAN_SP_MESH_PEERING_CONFIRM) {
1226 baseaddr += 4;
1227 baselen += 4;
1228
1229 if (baselen > len)
1230 return;
1231 }
1232 elems = ieee802_11_parse_elems(baseaddr, len - baselen, true, NULL);
1233 mesh_process_plink_frame(sdata, mgmt, elems, rx_status);
1234 kfree(elems);
1235 }