Commit c7e678115a2693782a9950d33b1a2e602e2c6b70
Committed by
Johannes Berg
1 parent
5bbdd6c646
Exists in
smarc-imx_3.14.28_1.0.0_ga
and in
1 other branch
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(); |