Commit c7e678115a2693782a9950d33b1a2e602e2c6b70

Authored by Thomas Pedersen
Committed by Johannes Berg
1 parent 5bbdd6c646

mac80211: factor out peering FSM

Signed-off-by: Thomas Pedersen <thomas@cozybit.com>
[fix some indentation, squash llid assignment]
Signed-off-by: Johannes Berg <johannes.berg@intel.com>

Showing 1 changed file with 155 additions and 143 deletions Side-by-side Diff

net/mac80211/mesh_plink.c
... ... @@ -691,21 +691,172 @@
691 691 return changed;
692 692 }
693 693  
  694 +/**
  695 + * mesh_plink_fsm - step @sta MPM based on @event
  696 + *
  697 + * @sdata: interface
  698 + * @sta: mesh neighbor
  699 + * @event: peering event
  700 + *
  701 + * Return: changed MBSS flags
  702 + */
  703 +static u32 mesh_plink_fsm(struct ieee80211_sub_if_data *sdata,
  704 + struct sta_info *sta, enum plink_event event)
  705 +{
  706 + struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
  707 + enum ieee80211_self_protected_actioncode action = 0;
  708 + u32 changed = 0;
  709 +
  710 + mpl_dbg(sdata, "peer %pM in state %s got event %s\n", sta->sta.addr,
  711 + mplstates[sta->plink_state], mplevents[event]);
  712 +
  713 + spin_lock_bh(&sta->lock);
  714 + switch (sta->plink_state) {
  715 + case NL80211_PLINK_LISTEN:
  716 + switch (event) {
  717 + case CLS_ACPT:
  718 + mesh_plink_fsm_restart(sta);
  719 + break;
  720 + case OPN_ACPT:
  721 + sta->plink_state = NL80211_PLINK_OPN_RCVD;
  722 + get_random_bytes(&sta->llid, 2);
  723 + mesh_plink_timer_set(sta,
  724 + mshcfg->dot11MeshRetryTimeout);
  725 +
  726 + /* set the non-peer mode to active during peering */
  727 + changed |= ieee80211_mps_local_status_update(sdata);
  728 + action = WLAN_SP_MESH_PEERING_OPEN;
  729 + break;
  730 + default:
  731 + break;
  732 + }
  733 + break;
  734 + case NL80211_PLINK_OPN_SNT:
  735 + switch (event) {
  736 + case OPN_RJCT:
  737 + case CNF_RJCT:
  738 + case CLS_ACPT:
  739 + mesh_plink_close(sdata, sta, event);
  740 + action = WLAN_SP_MESH_PEERING_CLOSE;
  741 + break;
  742 + case OPN_ACPT:
  743 + /* retry timer is left untouched */
  744 + sta->plink_state = NL80211_PLINK_OPN_RCVD;
  745 + action = WLAN_SP_MESH_PEERING_CONFIRM;
  746 + break;
  747 + case CNF_ACPT:
  748 + sta->plink_state = NL80211_PLINK_CNF_RCVD;
  749 + if (!mod_plink_timer(sta,
  750 + mshcfg->dot11MeshConfirmTimeout))
  751 + sta->ignore_plink_timer = true;
  752 + break;
  753 + default:
  754 + break;
  755 + }
  756 + break;
  757 + case NL80211_PLINK_OPN_RCVD:
  758 + switch (event) {
  759 + case OPN_RJCT:
  760 + case CNF_RJCT:
  761 + case CLS_ACPT:
  762 + mesh_plink_close(sdata, sta, event);
  763 + action = WLAN_SP_MESH_PEERING_CLOSE;
  764 + break;
  765 + case OPN_ACPT:
  766 + action = WLAN_SP_MESH_PEERING_CONFIRM;
  767 + break;
  768 + case CNF_ACPT:
  769 + changed |= mesh_plink_establish(sdata, sta);
  770 + break;
  771 + default:
  772 + break;
  773 + }
  774 + break;
  775 + case NL80211_PLINK_CNF_RCVD:
  776 + switch (event) {
  777 + case OPN_RJCT:
  778 + case CNF_RJCT:
  779 + case CLS_ACPT:
  780 + mesh_plink_close(sdata, sta, event);
  781 + action = WLAN_SP_MESH_PEERING_CLOSE;
  782 + break;
  783 + case OPN_ACPT:
  784 + changed |= mesh_plink_establish(sdata, sta);
  785 + action = WLAN_SP_MESH_PEERING_CONFIRM;
  786 + break;
  787 + default:
  788 + break;
  789 + }
  790 + break;
  791 + case NL80211_PLINK_ESTAB:
  792 + switch (event) {
  793 + case CLS_ACPT:
  794 + changed |= __mesh_plink_deactivate(sta);
  795 + changed |= mesh_set_ht_prot_mode(sdata);
  796 + changed |= mesh_set_short_slot_time(sdata);
  797 + mesh_plink_close(sdata, sta, event);
  798 + action = WLAN_SP_MESH_PEERING_CLOSE;
  799 + break;
  800 + case OPN_ACPT:
  801 + action = WLAN_SP_MESH_PEERING_CONFIRM;
  802 + break;
  803 + default:
  804 + break;
  805 + }
  806 + break;
  807 + case NL80211_PLINK_HOLDING:
  808 + switch (event) {
  809 + case CLS_ACPT:
  810 + if (del_timer(&sta->plink_timer))
  811 + sta->ignore_plink_timer = 1;
  812 + mesh_plink_fsm_restart(sta);
  813 + break;
  814 + case OPN_ACPT:
  815 + case CNF_ACPT:
  816 + case OPN_RJCT:
  817 + case CNF_RJCT:
  818 + action = WLAN_SP_MESH_PEERING_CLOSE;
  819 + break;
  820 + default:
  821 + break;
  822 + }
  823 + break;
  824 + default:
  825 + /* should not get here, PLINK_BLOCKED is dealt with at the
  826 + * beginning of the function
  827 + */
  828 + break;
  829 + }
  830 + spin_unlock_bh(&sta->lock);
  831 + if (action) {
  832 + mesh_plink_frame_tx(sdata, action, sta->sta.addr,
  833 + sta->llid, sta->plid, sta->reason);
  834 +
  835 + /* also send confirm in open case */
  836 + if (action == WLAN_SP_MESH_PEERING_OPEN) {
  837 + mesh_plink_frame_tx(sdata,
  838 + WLAN_SP_MESH_PEERING_CONFIRM,
  839 + sta->sta.addr, sta->llid,
  840 + sta->plid, 0);
  841 + }
  842 + }
  843 +
  844 + return changed;
  845 +}
  846 +
694 847 static void
695 848 mesh_process_plink_frame(struct ieee80211_sub_if_data *sdata,
696 849 struct ieee80211_mgmt *mgmt,
697 850 struct ieee802_11_elems *elems)
698 851 {
699 852  
700   - struct mesh_config *mshcfg = &sdata->u.mesh.mshcfg;
701   - enum ieee80211_self_protected_actioncode action = 0;
702 853 struct sta_info *sta;
703 854 enum plink_event event;
704 855 enum ieee80211_self_protected_actioncode ftype;
705 856 bool matches_local;
706 857 u32 changed = 0;
707 858 u8 ie_len;
708   - __le16 plid, llid;
  859 + __le16 plid, llid = 0;
709 860  
710 861 if (!elems->peering) {
711 862 mpl_dbg(sdata,
... ... @@ -847,146 +998,7 @@
847 998 sta->plid = plid;
848 999 }
849 1000  
850   - mpl_dbg(sdata, "peer %pM in state %s got event %s\n", mgmt->sa,
851   - mplstates[sta->plink_state], mplevents[event]);
852   - spin_lock_bh(&sta->lock);
853   - switch (sta->plink_state) {
854   - case NL80211_PLINK_LISTEN:
855   - switch (event) {
856   - case CLS_ACPT:
857   - mesh_plink_fsm_restart(sta);
858   - break;
859   - case OPN_ACPT:
860   - sta->plink_state = NL80211_PLINK_OPN_RCVD;
861   - get_random_bytes(&llid, 2);
862   - sta->llid = llid;
863   - mesh_plink_timer_set(sta,
864   - mshcfg->dot11MeshRetryTimeout);
865   -
866   - /* set the non-peer mode to active during peering */
867   - changed |= ieee80211_mps_local_status_update(sdata);
868   -
869   - action = WLAN_SP_MESH_PEERING_OPEN;
870   - break;
871   - default:
872   - break;
873   - }
874   - break;
875   -
876   - case NL80211_PLINK_OPN_SNT:
877   - switch (event) {
878   - case OPN_RJCT:
879   - case CNF_RJCT:
880   - case CLS_ACPT:
881   - mesh_plink_close(sdata, sta, event);
882   - action = WLAN_SP_MESH_PEERING_CLOSE;
883   - break;
884   -
885   - case OPN_ACPT:
886   - /* retry timer is left untouched */
887   - sta->plink_state = NL80211_PLINK_OPN_RCVD;
888   - action = WLAN_SP_MESH_PEERING_CONFIRM;
889   - break;
890   - case CNF_ACPT:
891   - sta->plink_state = NL80211_PLINK_CNF_RCVD;
892   - if (!mod_plink_timer(sta,
893   - mshcfg->dot11MeshConfirmTimeout))
894   - sta->ignore_plink_timer = true;
895   -
896   - break;
897   - default:
898   - break;
899   - }
900   - break;
901   -
902   - case NL80211_PLINK_OPN_RCVD:
903   - switch (event) {
904   - case OPN_RJCT:
905   - case CNF_RJCT:
906   - case CLS_ACPT:
907   - mesh_plink_close(sdata, sta, event);
908   - action = WLAN_SP_MESH_PEERING_CLOSE;
909   - break;
910   - case OPN_ACPT:
911   - action = WLAN_SP_MESH_PEERING_CONFIRM;
912   - break;
913   - case CNF_ACPT:
914   - changed |= mesh_plink_establish(sdata, sta);
915   - break;
916   - default:
917   - break;
918   - }
919   - break;
920   -
921   - case NL80211_PLINK_CNF_RCVD:
922   - switch (event) {
923   - case OPN_RJCT:
924   - case CNF_RJCT:
925   - case CLS_ACPT:
926   - mesh_plink_close(sdata, sta, event);
927   - action = WLAN_SP_MESH_PEERING_CLOSE;
928   - break;
929   - case OPN_ACPT:
930   - changed |= mesh_plink_establish(sdata, sta);
931   - action = WLAN_SP_MESH_PEERING_CONFIRM;
932   - break;
933   - default:
934   - break;
935   - }
936   - break;
937   -
938   - case NL80211_PLINK_ESTAB:
939   - switch (event) {
940   - case CLS_ACPT:
941   - changed |= __mesh_plink_deactivate(sta);
942   - changed |= mesh_set_ht_prot_mode(sdata);
943   - changed |= mesh_set_short_slot_time(sdata);
944   - mesh_plink_close(sdata, sta, event);
945   - action = WLAN_SP_MESH_PEERING_CLOSE;
946   - break;
947   - case OPN_ACPT:
948   - action = WLAN_SP_MESH_PEERING_CONFIRM;
949   - break;
950   - default:
951   - break;
952   - }
953   - break;
954   - case NL80211_PLINK_HOLDING:
955   - switch (event) {
956   - case CLS_ACPT:
957   - if (del_timer(&sta->plink_timer))
958   - sta->ignore_plink_timer = 1;
959   - mesh_plink_fsm_restart(sta);
960   - break;
961   - case OPN_ACPT:
962   - case CNF_ACPT:
963   - case OPN_RJCT:
964   - case CNF_RJCT:
965   - action = WLAN_SP_MESH_PEERING_CLOSE;
966   - break;
967   - default:
968   - break;
969   - }
970   - break;
971   - default:
972   - /* should not get here, PLINK_BLOCKED is dealt with at the
973   - * beginning of the function
974   - */
975   - break;
976   - }
977   - spin_unlock_bh(&sta->lock);
978   - if (action) {
979   - mesh_plink_frame_tx(sdata, action, sta->sta.addr,
980   - sta->llid, sta->plid, sta->reason);
981   -
982   - /* also send confirm in open case */
983   - if (action == WLAN_SP_MESH_PEERING_OPEN) {
984   - mesh_plink_frame_tx(sdata,
985   - WLAN_SP_MESH_PEERING_CONFIRM,
986   - sta->sta.addr, sta->llid,
987   - sta->plid, 0);
988   - }
989   - }
  1001 + changed |= mesh_plink_fsm(sdata, sta, event);
990 1002  
991 1003 unlock_rcu:
992 1004 rcu_read_unlock();