Loading net/mac80211/mesh_plink.c +155 −143 Original line number Diff line number Diff line Loading @@ -691,21 +691,172 @@ static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata, return changed; } /** * mesh_plink_fsm - step @sta MPM based on @event * * @sdata: interface * @sta: mesh neighbor * @event: peering event * * Return: changed MBSS flags */ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, enum plink_event event) { struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; enum ieee80211_self_protected_actioncode action = 0; u32 changed = 0; mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr, mplstates[sta->plink_state], mplevents[event]); spin_lock_bh(&sta->lock); switch (sta->plink_state) { case NL80211_PLINK_LISTEN: switch (event) { case CLS_ACPT: mesh_plink_fsm_restart(sta); break; case OPN_ACPT: sta->plink_state = NL80211_PLINK_OPN_RCVD; get_random_bytes(&sta->llid, 2); mesh_plink_timer_set(sta, mshcfg->dot11MeshRetryTimeout); /* set the non-peer mode to active during peering */ changed |= ieee80211_mps_local_status_update(sdata); action = WLAN_SP_MESH_PEERING_OPEN; break; default: break; } break; case NL80211_PLINK_OPN_SNT: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: /* retry timer is left untouched */ sta->plink_state = NL80211_PLINK_OPN_RCVD; action = WLAN_SP_MESH_PEERING_CONFIRM; break; case CNF_ACPT: sta->plink_state = NL80211_PLINK_CNF_RCVD; if (!mod_plink_timer(sta, mshcfg->dot11MeshConfirmTimeout)) sta->ignore_plink_timer = true; break; default: break; } break; case NL80211_PLINK_OPN_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: action = WLAN_SP_MESH_PEERING_CONFIRM; break; case CNF_ACPT: changed |= mesh_plink_establish(sdata, sta); break; default: break; } break; case NL80211_PLINK_CNF_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: changed |= mesh_plink_establish(sdata, sta); action = WLAN_SP_MESH_PEERING_CONFIRM; break; default: break; } break; case NL80211_PLINK_ESTAB: switch (event) { case CLS_ACPT: changed |= __mesh_plink_deactivate(sta); changed |= mesh_set_ht_prot_mode(sdata); changed |= mesh_set_short_slot_time(sdata); mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: action = WLAN_SP_MESH_PEERING_CONFIRM; break; default: break; } break; case NL80211_PLINK_HOLDING: switch (event) { case CLS_ACPT: if (del_timer(&sta->plink_timer)) sta->ignore_plink_timer = 1; mesh_plink_fsm_restart(sta); break; case OPN_ACPT: case CNF_ACPT: case OPN_RJCT: case CNF_RJCT: action = WLAN_SP_MESH_PEERING_CLOSE; break; default: break; } break; default: /* should not get here, PLINK_BLOCKED is dealt with at the * beginning of the function */ break; } spin_unlock_bh(&sta->lock); if (action) { mesh_plink_frame_tx(sdata, action, sta->sta.addr, sta->llid, sta->plid, sta->reason); /* also send confirm in open case */ if (action == WLAN_SP_MESH_PEERING_OPEN) { mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, sta->sta.addr, sta->llid, sta->plid, 0); } } return changed; } static void mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, struct ieee802_11_elems *elems) { struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; enum ieee80211_self_protected_actioncode action = 0; struct sta_info *sta; enum plink_event event; enum ieee80211_self_protected_actioncode ftype; bool matches_local; u32 changed = 0; u8 ie_len; __le16 plid, llid; __le16 plid, llid = 0; if (!elems->peering) { mpl_dbg(sdata, Loading Loading @@ -847,146 +998,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, sta->plid = plid; } mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa, mplstates[sta->plink_state], mplevents[event]); spin_lock_bh(&sta->lock); switch (sta->plink_state) { case NL80211_PLINK_LISTEN: switch (event) { case CLS_ACPT: mesh_plink_fsm_restart(sta); break; case OPN_ACPT: sta->plink_state = NL80211_PLINK_OPN_RCVD; get_random_bytes(&llid, 2); sta->llid = llid; mesh_plink_timer_set(sta, mshcfg->dot11MeshRetryTimeout); /* set the non-peer mode to active during peering */ changed |= ieee80211_mps_local_status_update(sdata); action = WLAN_SP_MESH_PEERING_OPEN; break; default: break; } break; case NL80211_PLINK_OPN_SNT: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: /* retry timer is left untouched */ sta->plink_state = NL80211_PLINK_OPN_RCVD; action = WLAN_SP_MESH_PEERING_CONFIRM; break; case CNF_ACPT: sta->plink_state = NL80211_PLINK_CNF_RCVD; if (!mod_plink_timer(sta, mshcfg->dot11MeshConfirmTimeout)) sta->ignore_plink_timer = true; break; default: break; } break; case NL80211_PLINK_OPN_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: action = WLAN_SP_MESH_PEERING_CONFIRM; break; case CNF_ACPT: changed |= mesh_plink_establish(sdata, sta); break; default: break; } break; case NL80211_PLINK_CNF_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: changed |= mesh_plink_establish(sdata, sta); action = WLAN_SP_MESH_PEERING_CONFIRM; break; default: break; } break; case NL80211_PLINK_ESTAB: switch (event) { case CLS_ACPT: changed |= __mesh_plink_deactivate(sta); changed |= mesh_set_ht_prot_mode(sdata); changed |= mesh_set_short_slot_time(sdata); mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: action = WLAN_SP_MESH_PEERING_CONFIRM; break; default: break; } break; case NL80211_PLINK_HOLDING: switch (event) { case CLS_ACPT: if (del_timer(&sta->plink_timer)) sta->ignore_plink_timer = 1; mesh_plink_fsm_restart(sta); break; case OPN_ACPT: case CNF_ACPT: case OPN_RJCT: case CNF_RJCT: action = WLAN_SP_MESH_PEERING_CLOSE; break; default: break; } break; default: /* should not get here, PLINK_BLOCKED is dealt with at the * beginning of the function */ break; } spin_unlock_bh(&sta->lock); if (action) { mesh_plink_frame_tx(sdata, action, sta->sta.addr, sta->llid, sta->plid, sta->reason); /* also send confirm in open case */ if (action == WLAN_SP_MESH_PEERING_OPEN) { mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, sta->sta.addr, sta->llid, sta->plid, 0); } } changed |= mesh_plink_fsm(sdata, sta, event); unlock_rcu: rcu_read_unlock(); Loading Loading
net/mac80211/mesh_plink.c +155 −143 Original line number Diff line number Diff line Loading @@ -691,21 +691,172 @@ static u32 mesh_plink_establish(struct ieee80211_sub_if_data *sdata, return changed; } /** * mesh_plink_fsm - step @sta MPM based on @event * * @sdata: interface * @sta: mesh neighbor * @event: peering event * * Return: changed MBSS flags */ static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata, struct sta_info *sta, enum plink_event event) { struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; enum ieee80211_self_protected_actioncode action = 0; u32 changed = 0; mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr, mplstates[sta->plink_state], mplevents[event]); spin_lock_bh(&sta->lock); switch (sta->plink_state) { case NL80211_PLINK_LISTEN: switch (event) { case CLS_ACPT: mesh_plink_fsm_restart(sta); break; case OPN_ACPT: sta->plink_state = NL80211_PLINK_OPN_RCVD; get_random_bytes(&sta->llid, 2); mesh_plink_timer_set(sta, mshcfg->dot11MeshRetryTimeout); /* set the non-peer mode to active during peering */ changed |= ieee80211_mps_local_status_update(sdata); action = WLAN_SP_MESH_PEERING_OPEN; break; default: break; } break; case NL80211_PLINK_OPN_SNT: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: /* retry timer is left untouched */ sta->plink_state = NL80211_PLINK_OPN_RCVD; action = WLAN_SP_MESH_PEERING_CONFIRM; break; case CNF_ACPT: sta->plink_state = NL80211_PLINK_CNF_RCVD; if (!mod_plink_timer(sta, mshcfg->dot11MeshConfirmTimeout)) sta->ignore_plink_timer = true; break; default: break; } break; case NL80211_PLINK_OPN_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: action = WLAN_SP_MESH_PEERING_CONFIRM; break; case CNF_ACPT: changed |= mesh_plink_establish(sdata, sta); break; default: break; } break; case NL80211_PLINK_CNF_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: changed |= mesh_plink_establish(sdata, sta); action = WLAN_SP_MESH_PEERING_CONFIRM; break; default: break; } break; case NL80211_PLINK_ESTAB: switch (event) { case CLS_ACPT: changed |= __mesh_plink_deactivate(sta); changed |= mesh_set_ht_prot_mode(sdata); changed |= mesh_set_short_slot_time(sdata); mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: action = WLAN_SP_MESH_PEERING_CONFIRM; break; default: break; } break; case NL80211_PLINK_HOLDING: switch (event) { case CLS_ACPT: if (del_timer(&sta->plink_timer)) sta->ignore_plink_timer = 1; mesh_plink_fsm_restart(sta); break; case OPN_ACPT: case CNF_ACPT: case OPN_RJCT: case CNF_RJCT: action = WLAN_SP_MESH_PEERING_CLOSE; break; default: break; } break; default: /* should not get here, PLINK_BLOCKED is dealt with at the * beginning of the function */ break; } spin_unlock_bh(&sta->lock); if (action) { mesh_plink_frame_tx(sdata, action, sta->sta.addr, sta->llid, sta->plid, sta->reason); /* also send confirm in open case */ if (action == WLAN_SP_MESH_PEERING_OPEN) { mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, sta->sta.addr, sta->llid, sta->plid, 0); } } return changed; } static void mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, struct ieee80211_mgmt *mgmt, struct ieee802_11_elems *elems) { struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg; enum ieee80211_self_protected_actioncode action = 0; struct sta_info *sta; enum plink_event event; enum ieee80211_self_protected_actioncode ftype; bool matches_local; u32 changed = 0; u8 ie_len; __le16 plid, llid; __le16 plid, llid = 0; if (!elems->peering) { mpl_dbg(sdata, Loading Loading @@ -847,146 +998,7 @@ mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata, sta->plid = plid; } mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa, mplstates[sta->plink_state], mplevents[event]); spin_lock_bh(&sta->lock); switch (sta->plink_state) { case NL80211_PLINK_LISTEN: switch (event) { case CLS_ACPT: mesh_plink_fsm_restart(sta); break; case OPN_ACPT: sta->plink_state = NL80211_PLINK_OPN_RCVD; get_random_bytes(&llid, 2); sta->llid = llid; mesh_plink_timer_set(sta, mshcfg->dot11MeshRetryTimeout); /* set the non-peer mode to active during peering */ changed |= ieee80211_mps_local_status_update(sdata); action = WLAN_SP_MESH_PEERING_OPEN; break; default: break; } break; case NL80211_PLINK_OPN_SNT: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: /* retry timer is left untouched */ sta->plink_state = NL80211_PLINK_OPN_RCVD; action = WLAN_SP_MESH_PEERING_CONFIRM; break; case CNF_ACPT: sta->plink_state = NL80211_PLINK_CNF_RCVD; if (!mod_plink_timer(sta, mshcfg->dot11MeshConfirmTimeout)) sta->ignore_plink_timer = true; break; default: break; } break; case NL80211_PLINK_OPN_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: action = WLAN_SP_MESH_PEERING_CONFIRM; break; case CNF_ACPT: changed |= mesh_plink_establish(sdata, sta); break; default: break; } break; case NL80211_PLINK_CNF_RCVD: switch (event) { case OPN_RJCT: case CNF_RJCT: case CLS_ACPT: mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: changed |= mesh_plink_establish(sdata, sta); action = WLAN_SP_MESH_PEERING_CONFIRM; break; default: break; } break; case NL80211_PLINK_ESTAB: switch (event) { case CLS_ACPT: changed |= __mesh_plink_deactivate(sta); changed |= mesh_set_ht_prot_mode(sdata); changed |= mesh_set_short_slot_time(sdata); mesh_plink_close(sdata, sta, event); action = WLAN_SP_MESH_PEERING_CLOSE; break; case OPN_ACPT: action = WLAN_SP_MESH_PEERING_CONFIRM; break; default: break; } break; case NL80211_PLINK_HOLDING: switch (event) { case CLS_ACPT: if (del_timer(&sta->plink_timer)) sta->ignore_plink_timer = 1; mesh_plink_fsm_restart(sta); break; case OPN_ACPT: case CNF_ACPT: case OPN_RJCT: case CNF_RJCT: action = WLAN_SP_MESH_PEERING_CLOSE; break; default: break; } break; default: /* should not get here, PLINK_BLOCKED is dealt with at the * beginning of the function */ break; } spin_unlock_bh(&sta->lock); if (action) { mesh_plink_frame_tx(sdata, action, sta->sta.addr, sta->llid, sta->plid, sta->reason); /* also send confirm in open case */ if (action == WLAN_SP_MESH_PEERING_OPEN) { mesh_plink_frame_tx(sdata, WLAN_SP_MESH_PEERING_CONFIRM, sta->sta.addr, sta->llid, sta->plid, 0); } } changed |= mesh_plink_fsm(sdata, sta, event); unlock_rcu: rcu_read_unlock(); Loading