1 // SPDX-License-Identifier: GPL-2.0-only
3 * KUnit tests for management frame acceptance
5 * Copyright (C) 2023 Intel Corporation
7 #include <kunit/test.h>
8 #include <kunit/skbuff.h>
9 #include "../ieee80211_i.h"
10 #include "../sta_info.h"
12 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
14 static const struct mfp_test_case
{
16 bool sta
, mfp
, decrypted
, unicast
, assoc
;
20 ieee80211_rx_result result
;
21 } accept_mfp_cases
[] = {
22 /* regular public action */
24 .desc
= "public action: accept unicast from unknown peer",
25 .stype
= IEEE80211_STYPE_ACTION
,
26 .category
= WLAN_CATEGORY_PUBLIC
,
27 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
29 .result
= RX_CONTINUE
,
32 .desc
= "public action: accept multicast from unknown peer",
33 .stype
= IEEE80211_STYPE_ACTION
,
34 .category
= WLAN_CATEGORY_PUBLIC
,
35 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
37 .result
= RX_CONTINUE
,
40 .desc
= "public action: accept unicast without MFP",
41 .stype
= IEEE80211_STYPE_ACTION
,
42 .category
= WLAN_CATEGORY_PUBLIC
,
43 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
46 .result
= RX_CONTINUE
,
49 .desc
= "public action: accept multicast without MFP",
50 .stype
= IEEE80211_STYPE_ACTION
,
51 .category
= WLAN_CATEGORY_PUBLIC
,
52 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
55 .result
= RX_CONTINUE
,
58 .desc
= "public action: drop unicast with MFP",
59 .stype
= IEEE80211_STYPE_ACTION
,
60 .category
= WLAN_CATEGORY_PUBLIC
,
61 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
65 .result
= RX_DROP_U_UNPROT_UNICAST_PUB_ACTION
,
68 .desc
= "public action: accept multicast with MFP",
69 .stype
= IEEE80211_STYPE_ACTION
,
70 .category
= WLAN_CATEGORY_PUBLIC
,
71 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
75 .result
= RX_CONTINUE
,
77 /* protected dual of public action */
79 .desc
= "protected dual: drop unicast from unknown peer",
80 .stype
= IEEE80211_STYPE_ACTION
,
81 .category
= WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION
,
82 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
84 .result
= RX_DROP_U_UNPROT_DUAL
,
87 .desc
= "protected dual: drop multicast from unknown peer",
88 .stype
= IEEE80211_STYPE_ACTION
,
89 .category
= WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION
,
90 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
92 .result
= RX_DROP_U_UNPROT_DUAL
,
95 .desc
= "protected dual: drop unicast without MFP",
96 .stype
= IEEE80211_STYPE_ACTION
,
97 .category
= WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION
,
98 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
101 .result
= RX_DROP_U_UNPROT_DUAL
,
104 .desc
= "protected dual: drop multicast without MFP",
105 .stype
= IEEE80211_STYPE_ACTION
,
106 .category
= WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION
,
107 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
110 .result
= RX_DROP_U_UNPROT_DUAL
,
113 .desc
= "protected dual: drop undecrypted unicast with MFP",
114 .stype
= IEEE80211_STYPE_ACTION
,
115 .category
= WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION
,
116 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
120 .result
= RX_DROP_U_UNPROT_DUAL
,
123 .desc
= "protected dual: drop undecrypted multicast with MFP",
124 .stype
= IEEE80211_STYPE_ACTION
,
125 .category
= WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION
,
126 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
130 .result
= RX_DROP_U_UNPROT_DUAL
,
133 .desc
= "protected dual: accept unicast with MFP",
134 .stype
= IEEE80211_STYPE_ACTION
,
135 .category
= WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION
,
136 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
141 .result
= RX_CONTINUE
,
144 .desc
= "protected dual: accept multicast with MFP",
145 .stype
= IEEE80211_STYPE_ACTION
,
146 .category
= WLAN_CATEGORY_PROTECTED_DUAL_OF_ACTION
,
147 .action
= WLAN_PUB_ACTION_DSE_ENABLEMENT
,
152 .result
= RX_CONTINUE
,
154 /* deauth/disassoc before keys are set */
156 .desc
= "deauth: accept unicast with MFP but w/o key",
157 .stype
= IEEE80211_STYPE_DEAUTH
,
161 .result
= RX_CONTINUE
,
164 .desc
= "disassoc: accept unicast with MFP but w/o key",
165 .stype
= IEEE80211_STYPE_DEAUTH
,
169 .result
= RX_CONTINUE
,
171 /* non-public robust action frame ... */
173 .desc
= "BA action: drop unicast before assoc",
174 .stype
= IEEE80211_STYPE_ACTION
,
175 .category
= WLAN_CATEGORY_BACK
,
178 .result
= RX_DROP_U_UNPROT_ROBUST_ACTION
,
181 .desc
= "BA action: drop unprotected after assoc",
182 .stype
= IEEE80211_STYPE_ACTION
,
183 .category
= WLAN_CATEGORY_BACK
,
187 .result
= RX_DROP_U_UNPROT_UCAST_MGMT
,
190 .desc
= "BA action: accept unprotected without MFP",
191 .stype
= IEEE80211_STYPE_ACTION
,
192 .category
= WLAN_CATEGORY_BACK
,
197 .result
= RX_CONTINUE
,
200 .desc
= "BA action: drop unprotected with MFP",
201 .stype
= IEEE80211_STYPE_ACTION
,
202 .category
= WLAN_CATEGORY_BACK
,
206 .result
= RX_DROP_U_UNPROT_UCAST_MGMT
,
210 KUNIT_ARRAY_PARAM_DESC(accept_mfp
, accept_mfp_cases
, desc
);
212 static void accept_mfp(struct kunit
*test
)
214 static struct sta_info sta
;
215 const struct mfp_test_case
*params
= test
->param_value
;
216 struct ieee80211_rx_data rx
= {
217 .sta
= params
->sta
? &sta
: NULL
,
219 struct ieee80211_rx_status
*status
;
220 struct ieee80211_hdr_3addr hdr
= {
221 .frame_control
= cpu_to_le16(IEEE80211_FTYPE_MGMT
|
223 .addr1
= { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff },
224 .addr2
= { 0x12, 0x22, 0x33, 0x44, 0x55, 0x66 },
225 /* A3/BSSID doesn't matter here */
228 memset(&sta
, 0, sizeof(sta
));
231 KUNIT_ASSERT_FALSE(test
, params
->mfp
);
232 KUNIT_ASSERT_FALSE(test
, params
->decrypted
);
236 set_sta_flag(&sta
, WLAN_STA_MFP
);
239 set_bit(WLAN_STA_ASSOC
, &sta
._flags
);
241 rx
.skb
= kunit_zalloc_skb(test
, 128, GFP_KERNEL
);
242 KUNIT_ASSERT_NOT_NULL(test
, rx
.skb
);
243 status
= IEEE80211_SKB_RXCB(rx
.skb
);
245 if (params
->decrypted
) {
246 status
->flag
|= RX_FLAG_DECRYPTED
;
249 cpu_to_le16(IEEE80211_FCTL_PROTECTED
);
255 skb_put_data(rx
.skb
, &hdr
, sizeof(hdr
));
257 switch (params
->stype
) {
258 case IEEE80211_STYPE_ACTION
:
259 skb_put_u8(rx
.skb
, params
->category
);
260 skb_put_u8(rx
.skb
, params
->action
);
262 case IEEE80211_STYPE_DEAUTH
:
263 case IEEE80211_STYPE_DISASSOC
: {
264 __le16 reason
= cpu_to_le16(WLAN_REASON_UNSPECIFIED
);
266 skb_put_data(rx
.skb
, &reason
, sizeof(reason
));
271 KUNIT_EXPECT_EQ(test
,
272 (__force u32
)ieee80211_drop_unencrypted_mgmt(&rx
),
273 (__force u32
)params
->result
);
276 static struct kunit_case mfp_test_cases
[] = {
277 KUNIT_CASE_PARAM(accept_mfp
, accept_mfp_gen_params
),
281 static struct kunit_suite mfp
= {
282 .name
= "mac80211-mfp",
283 .test_cases
= mfp_test_cases
,
286 kunit_test_suite(mfp
);