1 // SPDX-License-Identifier: GPL-2.0-only
3 * KUnit tests for inform_bss functions
5 * Copyright (C) 2023-2024 Intel Corporation
7 #include <linux/ieee80211.h>
8 #include <net/cfg80211.h>
9 #include <kunit/test.h>
10 #include <kunit/skbuff.h>
14 /* mac80211 helpers for element building */
15 #include "../../mac80211/ieee80211_i.h"
17 MODULE_IMPORT_NS("EXPORTED_FOR_KUNIT_TESTING");
31 static struct gen_new_ie_case
{
33 struct test_elem parent_ies
[16];
34 struct test_elem child_ies
[16];
35 struct test_elem result_ies
[16];
36 } gen_new_ie_cases
[] = {
38 .desc
= "ML not inherited",
40 { .id
= WLAN_EID_EXTENSION
, .len
= 255,
41 .eid
= WLAN_EID_EXT_EHT_MULTI_LINK
},
44 { .id
= WLAN_EID_SSID
, .len
= 2 },
47 { .id
= WLAN_EID_SSID
, .len
= 2 },
51 .desc
= "fragments are ignored if previous len not 255",
53 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 254, },
54 { .id
= WLAN_EID_FRAGMENT
, .len
= 125, },
57 { .id
= WLAN_EID_SSID
, .len
= 2 },
58 { .id
= WLAN_EID_FRAGMENT
, .len
= 125, },
61 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 254, },
62 { .id
= WLAN_EID_SSID
, .len
= 2 },
66 .desc
= "fragments inherited",
68 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 255, },
69 { .id
= WLAN_EID_FRAGMENT
, .len
= 125, },
72 { .id
= WLAN_EID_SSID
, .len
= 2 },
75 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 255, },
76 { .id
= WLAN_EID_FRAGMENT
, .len
= 125, },
77 { .id
= WLAN_EID_SSID
, .len
= 2 },
81 .desc
= "fragments copied",
83 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 255, },
84 { .id
= WLAN_EID_FRAGMENT
, .len
= 125, },
87 { .id
= WLAN_EID_SSID
, .len
= 2 },
90 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 255, },
91 { .id
= WLAN_EID_FRAGMENT
, .len
= 125, },
92 { .id
= WLAN_EID_SSID
, .len
= 2 },
96 .desc
= "multiple elements inherit",
98 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 255, },
99 { .id
= WLAN_EID_FRAGMENT
, .len
= 125, },
100 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 123, },
103 { .id
= WLAN_EID_SSID
, .len
= 2 },
106 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 255, },
107 { .id
= WLAN_EID_FRAGMENT
, .len
= 125, },
108 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 123, },
109 { .id
= WLAN_EID_SSID
, .len
= 2 },
113 .desc
= "one child element overrides",
115 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 255, },
116 { .id
= WLAN_EID_FRAGMENT
, .len
= 125, },
117 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 123, },
120 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 127, },
121 { .id
= WLAN_EID_SSID
, .len
= 2 },
124 { .id
= WLAN_EID_REDUCED_NEIGHBOR_REPORT
, .len
= 127, },
125 { .id
= WLAN_EID_SSID
, .len
= 2 },
129 .desc
= "empty elements from parent",
131 { .id
= 0x1, .len
= 0, },
132 { .id
= WLAN_EID_EXTENSION
, .len
= 1, .eid
= 0x10 },
137 { .id
= 0x1, .len
= 0, },
138 { .id
= WLAN_EID_EXTENSION
, .len
= 1, .eid
= 0x10 },
142 .desc
= "empty elements from child",
146 { .id
= 0x1, .len
= 0, },
147 { .id
= WLAN_EID_EXTENSION
, .len
= 1, .eid
= 0x10 },
150 { .id
= 0x1, .len
= 0, },
151 { .id
= WLAN_EID_EXTENSION
, .len
= 1, .eid
= 0x10 },
155 .desc
= "invalid extended elements ignored",
157 { .id
= WLAN_EID_EXTENSION
, .len
= 0 },
160 { .id
= WLAN_EID_EXTENSION
, .len
= 0 },
166 .desc
= "multiple extended elements",
168 { .id
= WLAN_EID_EXTENSION
, .len
= 3,
169 .eid
= WLAN_EID_EXT_HE_CAPABILITY
},
170 { .id
= WLAN_EID_EXTENSION
, .len
= 5,
171 .eid
= WLAN_EID_EXT_ASSOC_DELAY_INFO
},
172 { .id
= WLAN_EID_EXTENSION
, .len
= 7,
173 .eid
= WLAN_EID_EXT_HE_OPERATION
},
174 { .id
= WLAN_EID_EXTENSION
, .len
= 11,
175 .eid
= WLAN_EID_EXT_FILS_REQ_PARAMS
},
178 { .id
= WLAN_EID_SSID
, .len
= 13 },
179 { .id
= WLAN_EID_EXTENSION
, .len
= 17,
180 .eid
= WLAN_EID_EXT_HE_CAPABILITY
},
181 { .id
= WLAN_EID_EXTENSION
, .len
= 11,
182 .eid
= WLAN_EID_EXT_FILS_KEY_CONFIRM
},
183 { .id
= WLAN_EID_EXTENSION
, .len
= 19,
184 .eid
= WLAN_EID_EXT_HE_OPERATION
},
187 { .id
= WLAN_EID_EXTENSION
, .len
= 17,
188 .eid
= WLAN_EID_EXT_HE_CAPABILITY
},
189 { .id
= WLAN_EID_EXTENSION
, .len
= 5,
190 .eid
= WLAN_EID_EXT_ASSOC_DELAY_INFO
},
191 { .id
= WLAN_EID_EXTENSION
, .len
= 19,
192 .eid
= WLAN_EID_EXT_HE_OPERATION
},
193 { .id
= WLAN_EID_EXTENSION
, .len
= 11,
194 .eid
= WLAN_EID_EXT_FILS_REQ_PARAMS
},
195 { .id
= WLAN_EID_SSID
, .len
= 13 },
196 { .id
= WLAN_EID_EXTENSION
, .len
= 11,
197 .eid
= WLAN_EID_EXT_FILS_KEY_CONFIRM
},
201 .desc
= "non-inherit element",
203 { .id
= 0x1, .len
= 7, },
204 { .id
= 0x2, .len
= 11, },
205 { .id
= 0x3, .len
= 13, },
206 { .id
= WLAN_EID_EXTENSION
, .len
= 17, .eid
= 0x10 },
207 { .id
= WLAN_EID_EXTENSION
, .len
= 19, .eid
= 0x11 },
208 { .id
= WLAN_EID_EXTENSION
, .len
= 23, .eid
= 0x12 },
209 { .id
= WLAN_EID_EXTENSION
, .len
= 29, .eid
= 0x14 },
212 { .id
= WLAN_EID_EXTENSION
,
213 .eid
= WLAN_EID_EXT_NON_INHERITANCE
,
215 .edata
= { 0x3, 0x1, 0x2, 0x3,
216 0x4, 0x10, 0x11, 0x13, 0x14 } },
217 { .id
= WLAN_EID_SSID
, .len
= 2 },
220 { .id
= WLAN_EID_EXTENSION
, .len
= 23, .eid
= 0x12 },
221 { .id
= WLAN_EID_SSID
, .len
= 2 },
225 KUNIT_ARRAY_PARAM_DESC(gen_new_ie
, gen_new_ie_cases
, desc
)
227 static void test_gen_new_ie(struct kunit
*test
)
229 const struct gen_new_ie_case
*params
= test
->param_value
;
230 struct sk_buff
*parent
= kunit_zalloc_skb(test
, 1024, GFP_KERNEL
);
231 struct sk_buff
*child
= kunit_zalloc_skb(test
, 1024, GFP_KERNEL
);
232 struct sk_buff
*reference
= kunit_zalloc_skb(test
, 1024, GFP_KERNEL
);
233 u8
*out
= kunit_kzalloc(test
, IEEE80211_MAX_DATA_LEN
, GFP_KERNEL
);
237 KUNIT_ASSERT_NOT_NULL(test
, parent
);
238 KUNIT_ASSERT_NOT_NULL(test
, child
);
239 KUNIT_ASSERT_NOT_NULL(test
, reference
);
240 KUNIT_ASSERT_NOT_NULL(test
, out
);
242 for (i
= 0; i
< ARRAY_SIZE(params
->parent_ies
); i
++) {
243 if (params
->parent_ies
[i
].len
!= 0) {
244 skb_put_u8(parent
, params
->parent_ies
[i
].id
);
245 skb_put_u8(parent
, params
->parent_ies
[i
].len
);
246 skb_put_data(parent
, params
->parent_ies
[i
].data
,
247 params
->parent_ies
[i
].len
);
250 if (params
->child_ies
[i
].len
!= 0) {
251 skb_put_u8(child
, params
->child_ies
[i
].id
);
252 skb_put_u8(child
, params
->child_ies
[i
].len
);
253 skb_put_data(child
, params
->child_ies
[i
].data
,
254 params
->child_ies
[i
].len
);
257 if (params
->result_ies
[i
].len
!= 0) {
258 skb_put_u8(reference
, params
->result_ies
[i
].id
);
259 skb_put_u8(reference
, params
->result_ies
[i
].len
);
260 skb_put_data(reference
, params
->result_ies
[i
].data
,
261 params
->result_ies
[i
].len
);
265 len
= cfg80211_gen_new_ie(parent
->data
, parent
->len
,
266 child
->data
, child
->len
,
267 out
, IEEE80211_MAX_DATA_LEN
);
268 KUNIT_EXPECT_EQ(test
, len
, reference
->len
);
269 KUNIT_EXPECT_MEMEQ(test
, out
, reference
->data
, reference
->len
);
270 memset(out
, 0, IEEE80211_MAX_DATA_LEN
);
272 /* Exactly enough space */
273 len
= cfg80211_gen_new_ie(parent
->data
, parent
->len
,
274 child
->data
, child
->len
,
275 out
, reference
->len
);
276 KUNIT_EXPECT_EQ(test
, len
, reference
->len
);
277 KUNIT_EXPECT_MEMEQ(test
, out
, reference
->data
, reference
->len
);
278 memset(out
, 0, IEEE80211_MAX_DATA_LEN
);
280 /* Not enough space (or expected zero length) */
281 len
= cfg80211_gen_new_ie(parent
->data
, parent
->len
,
282 child
->data
, child
->len
,
283 out
, reference
->len
- 1);
284 KUNIT_EXPECT_EQ(test
, len
, 0);
287 static void test_gen_new_ie_malformed(struct kunit
*test
)
289 struct sk_buff
*malformed
= kunit_zalloc_skb(test
, 1024, GFP_KERNEL
);
290 u8
*out
= kunit_kzalloc(test
, IEEE80211_MAX_DATA_LEN
, GFP_KERNEL
);
293 KUNIT_ASSERT_NOT_NULL(test
, malformed
);
294 KUNIT_ASSERT_NOT_NULL(test
, out
);
296 skb_put_u8(malformed
, WLAN_EID_SSID
);
297 skb_put_u8(malformed
, 3);
298 skb_put(malformed
, 3);
299 skb_put_u8(malformed
, WLAN_EID_REDUCED_NEIGHBOR_REPORT
);
300 skb_put_u8(malformed
, 10);
301 skb_put(malformed
, 9);
303 len
= cfg80211_gen_new_ie(malformed
->data
, malformed
->len
,
305 out
, IEEE80211_MAX_DATA_LEN
);
306 KUNIT_EXPECT_EQ(test
, len
, 5);
308 len
= cfg80211_gen_new_ie(out
, 0,
309 malformed
->data
, malformed
->len
,
310 out
, IEEE80211_MAX_DATA_LEN
);
311 KUNIT_EXPECT_EQ(test
, len
, 5);
317 int inform_bss_count
;
320 static void inform_bss_inc_counter(struct wiphy
*wiphy
,
321 struct cfg80211_bss
*bss
,
322 const struct cfg80211_bss_ies
*ies
,
325 struct inform_bss
*ctx
= t_wiphy_ctx(wiphy
);
327 ctx
->inform_bss_count
++;
330 KUNIT_EXPECT_PTR_EQ(ctx
->test
, drv_data
, ctx
);
331 KUNIT_EXPECT_PTR_EQ(ctx
->test
, ies
, rcu_dereference(bss
->ies
));
335 static void test_inform_bss_ssid_only(struct kunit
*test
)
337 struct inform_bss ctx
= {
340 struct wiphy
*wiphy
= T_WIPHY(test
, ctx
);
341 struct t_wiphy_priv
*w_priv
= wiphy_priv(wiphy
);
342 struct cfg80211_inform_bss inform_bss
= {
346 const u8 bssid
[ETH_ALEN
] = { 0x10, 0x22, 0x33, 0x44, 0x55, 0x66 };
347 u64 tsf
= 0x1000000000000000ULL
;
348 int beacon_int
= 100;
349 u16 capability
= 0x1234;
350 static const u8 input
[] = {
353 [2] = 'T', 'E', 'S', 'T'
355 struct cfg80211_bss
*bss
, *other
;
356 const struct cfg80211_bss_ies
*ies
;
358 w_priv
->ops
->inform_bss
= inform_bss_inc_counter
;
360 inform_bss
.chan
= ieee80211_get_channel_khz(wiphy
, MHZ_TO_KHZ(2412));
361 KUNIT_ASSERT_NOT_NULL(test
, inform_bss
.chan
);
363 bss
= cfg80211_inform_bss_data(wiphy
, &inform_bss
,
364 CFG80211_BSS_FTYPE_PRESP
, bssid
, tsf
,
365 capability
, beacon_int
,
366 input
, sizeof(input
),
368 KUNIT_EXPECT_NOT_NULL(test
, bss
);
369 KUNIT_EXPECT_EQ(test
, ctx
.inform_bss_count
, 1);
371 /* Check values in returned bss are correct */
372 KUNIT_EXPECT_EQ(test
, bss
->signal
, inform_bss
.signal
);
373 KUNIT_EXPECT_EQ(test
, bss
->beacon_interval
, beacon_int
);
374 KUNIT_EXPECT_EQ(test
, bss
->capability
, capability
);
375 KUNIT_EXPECT_EQ(test
, bss
->bssid_index
, 0);
376 KUNIT_EXPECT_PTR_EQ(test
, bss
->channel
, inform_bss
.chan
);
377 KUNIT_EXPECT_MEMEQ(test
, bssid
, bss
->bssid
, sizeof(bssid
));
379 /* Check the IEs have the expected value */
381 ies
= rcu_dereference(bss
->ies
);
382 KUNIT_EXPECT_NOT_NULL(test
, ies
);
383 KUNIT_EXPECT_EQ(test
, ies
->tsf
, tsf
);
384 KUNIT_EXPECT_EQ(test
, ies
->len
, sizeof(input
));
385 KUNIT_EXPECT_MEMEQ(test
, ies
->data
, input
, sizeof(input
));
388 /* Check we can look up the BSS - by SSID */
389 other
= cfg80211_get_bss(wiphy
, NULL
, NULL
, "TEST", 4,
390 IEEE80211_BSS_TYPE_ANY
,
391 IEEE80211_PRIVACY_ANY
);
392 KUNIT_EXPECT_PTR_EQ(test
, bss
, other
);
393 cfg80211_put_bss(wiphy
, other
);
395 /* Check we can look up the BSS - by BSSID */
396 other
= cfg80211_get_bss(wiphy
, NULL
, bssid
, NULL
, 0,
397 IEEE80211_BSS_TYPE_ANY
,
398 IEEE80211_PRIVACY_ANY
);
399 KUNIT_EXPECT_PTR_EQ(test
, bss
, other
);
400 cfg80211_put_bss(wiphy
, other
);
402 cfg80211_put_bss(wiphy
, bss
);
405 static struct inform_bss_ml_sta_case
{
408 bool sta_prof_vendor_elems
;
409 bool include_oper_class
;
411 } inform_bss_ml_sta_cases
[] = {
413 .desc
= "zero_mld_id",
415 .sta_prof_vendor_elems
= false,
417 .desc
= "zero_mld_id_with_oper_class",
419 .sta_prof_vendor_elems
= false,
420 .include_oper_class
= true,
422 .desc
= "mld_id_eq_1",
424 .sta_prof_vendor_elems
= true,
426 .desc
= "mld_id_eq_1_with_oper_class",
428 .sta_prof_vendor_elems
= true,
429 .include_oper_class
= true,
436 KUNIT_ARRAY_PARAM_DESC(inform_bss_ml_sta
, inform_bss_ml_sta_cases
, desc
)
438 static void test_inform_bss_ml_sta(struct kunit
*test
)
440 const struct inform_bss_ml_sta_case
*params
= test
->param_value
;
441 struct inform_bss ctx
= {
444 struct wiphy
*wiphy
= T_WIPHY(test
, ctx
);
445 struct t_wiphy_priv
*w_priv
= wiphy_priv(wiphy
);
446 struct cfg80211_inform_bss inform_bss
= {
450 struct cfg80211_bss
*bss
, *link_bss
;
451 const struct cfg80211_bss_ies
*ies
;
453 /* sending station */
454 const u8 bssid
[ETH_ALEN
] = { 0x10, 0x22, 0x33, 0x44, 0x55, 0x66 };
455 u64 tsf
= 0x1000000000000000ULL
;
456 int beacon_int
= 100;
457 u16 capability
= 0x1234;
459 /* Building the frame *************************************************/
460 struct sk_buff
*input
= kunit_zalloc_skb(test
, 1024, GFP_KERNEL
);
461 u8
*len_mle
, *len_prof
;
464 struct ieee80211_neighbor_ap_info info
;
465 struct ieee80211_tbtt_info_ge_11 ap
;
466 } __packed rnr_normal
= {
468 .tbtt_info_hdr
= u8_encode_bits(0, IEEE80211_AP_INFO_TBTT_HDR_COUNT
),
469 .tbtt_info_len
= sizeof(struct ieee80211_tbtt_info_ge_11
),
475 .bssid
= { 0x10, 0x22, 0x33, 0x44, 0x55, 0x67 },
476 .short_ssid
= 0, /* unused */
479 .mld_params
.mld_id
= params
->mld_id
,
481 le16_encode_bits(link_id
,
482 IEEE80211_RNR_MLD_PARAMS_LINK_ID
),
486 struct ieee80211_neighbor_ap_info info
;
487 struct ieee80211_rnr_mld_params mld_params
;
488 } __packed rnr_nstr
= {
491 u8_encode_bits(0, IEEE80211_AP_INFO_TBTT_HDR_COUNT
) |
492 u8_encode_bits(IEEE80211_TBTT_INFO_TYPE_MLD
,
493 IEEE80211_AP_INFO_TBTT_HDR_TYPE
),
494 .tbtt_info_len
= sizeof(struct ieee80211_rnr_mld_params
),
499 .mld_id
= params
->mld_id
,
501 le16_encode_bits(link_id
,
502 IEEE80211_RNR_MLD_PARAMS_LINK_ID
),
505 size_t rnr_len
= params
->nstr
? sizeof(rnr_nstr
) : sizeof(rnr_normal
);
506 void *rnr
= params
->nstr
? (void *)&rnr_nstr
: (void *)&rnr_normal
;
510 u8 mld_mac_addr
[ETH_ALEN
];
512 u8 params_change_count
;
513 __le16 mld_caps_and_ops
;
515 __le16 ext_mld_caps_and_ops
;
516 } __packed mle_basic_common_info
= {
518 cpu_to_le16(IEEE80211_ML_CONTROL_TYPE_BASIC
|
519 IEEE80211_MLC_BASIC_PRES_BSS_PARAM_CH_CNT
|
520 IEEE80211_MLC_BASIC_PRES_LINK_ID
|
521 (params
->mld_id
? IEEE80211_MLC_BASIC_PRES_MLD_ID
: 0) |
522 IEEE80211_MLC_BASIC_PRES_MLD_CAPA_OP
),
523 .mld_id
= params
->mld_id
,
524 .mld_caps_and_ops
= cpu_to_le16(0x0102),
525 .ext_mld_caps_and_ops
= cpu_to_le16(0x0304),
526 .var_len
= sizeof(mle_basic_common_info
) - 2 -
527 (params
->mld_id
? 0 : 1),
528 .mld_mac_addr
= { 0x10, 0x22, 0x33, 0x44, 0x55, 0x60 },
536 __le16 capabilities
; /* already part of payload */
537 } __packed sta_prof
= {
539 cpu_to_le16(IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE
|
540 IEEE80211_MLE_STA_CONTROL_STA_MAC_ADDR_PRESENT
|
541 IEEE80211_MLE_STA_CONTROL_BEACON_INT_PRESENT
|
542 IEEE80211_MLE_STA_CONTROL_TSF_OFFS_PRESENT
|
543 u16_encode_bits(link_id
,
544 IEEE80211_MLE_STA_CONTROL_LINK_ID
)),
545 .var_len
= sizeof(sta_prof
) - 2 - 2,
546 .bssid
= { *rnr_normal
.ap
.bssid
},
547 .beacon_int
= cpu_to_le16(101),
548 .tsf_offset
= cpu_to_le64(-123ll),
549 .capabilities
= cpu_to_le16(0xdead),
552 KUNIT_ASSERT_NOT_NULL(test
, input
);
554 w_priv
->ops
->inform_bss
= inform_bss_inc_counter
;
556 inform_bss
.chan
= ieee80211_get_channel_khz(wiphy
, MHZ_TO_KHZ(2412));
557 KUNIT_ASSERT_NOT_NULL(test
, inform_bss
.chan
);
559 skb_put_u8(input
, WLAN_EID_SSID
);
560 skb_put_u8(input
, 4);
561 skb_put_data(input
, "TEST", 4);
563 if (params
->include_oper_class
) {
564 skb_put_u8(input
, WLAN_EID_SUPPORTED_REGULATORY_CLASSES
);
565 skb_put_u8(input
, 1);
566 skb_put_u8(input
, 81);
569 skb_put_u8(input
, WLAN_EID_REDUCED_NEIGHBOR_REPORT
);
570 skb_put_u8(input
, rnr_len
);
571 skb_put_data(input
, rnr
, rnr_len
);
573 /* build a multi-link element */
574 skb_put_u8(input
, WLAN_EID_EXTENSION
);
575 len_mle
= skb_put(input
, 1);
576 skb_put_u8(input
, WLAN_EID_EXT_EHT_MULTI_LINK
);
577 skb_put_data(input
, &mle_basic_common_info
, sizeof(mle_basic_common_info
));
579 t_skb_remove_member(input
, typeof(mle_basic_common_info
), mld_id
);
580 /* with a STA profile inside */
581 skb_put_u8(input
, IEEE80211_MLE_SUBELEM_PER_STA_PROFILE
);
582 len_prof
= skb_put(input
, 1);
583 skb_put_data(input
, &sta_prof
, sizeof(sta_prof
));
585 if (params
->sta_prof_vendor_elems
) {
586 /* Put two (vendor) element into sta_prof */
587 skb_put_u8(input
, WLAN_EID_VENDOR_SPECIFIC
);
588 skb_put_u8(input
, 160);
591 skb_put_u8(input
, WLAN_EID_VENDOR_SPECIFIC
);
592 skb_put_u8(input
, 165);
596 /* fragment STA profile */
597 ieee80211_fragment_element(input
, len_prof
,
598 IEEE80211_MLE_SUBELEM_FRAGMENT
);
600 ieee80211_fragment_element(input
, len_mle
, WLAN_EID_FRAGMENT
);
602 /* Put a (vendor) element after the ML element */
603 skb_put_u8(input
, WLAN_EID_VENDOR_SPECIFIC
);
604 skb_put_u8(input
, 155);
607 /* Submit *************************************************************/
608 bss
= cfg80211_inform_bss_data(wiphy
, &inform_bss
,
609 CFG80211_BSS_FTYPE_PRESP
, bssid
, tsf
,
610 capability
, beacon_int
,
611 input
->data
, input
->len
,
613 KUNIT_EXPECT_NOT_NULL(test
, bss
);
614 KUNIT_EXPECT_EQ(test
, ctx
.inform_bss_count
, 2);
616 /* Check link_bss *****************************************************/
617 link_bss
= __cfg80211_get_bss(wiphy
, NULL
, sta_prof
.bssid
, NULL
, 0,
618 IEEE80211_BSS_TYPE_ANY
,
619 IEEE80211_PRIVACY_ANY
,
621 KUNIT_ASSERT_NOT_NULL(test
, link_bss
);
622 KUNIT_EXPECT_EQ(test
, link_bss
->signal
, 0);
623 KUNIT_EXPECT_EQ(test
, link_bss
->beacon_interval
,
624 le16_to_cpu(sta_prof
.beacon_int
));
625 KUNIT_EXPECT_EQ(test
, link_bss
->capability
,
626 le16_to_cpu(sta_prof
.capabilities
));
627 KUNIT_EXPECT_EQ(test
, link_bss
->bssid_index
, 0);
628 KUNIT_EXPECT_PTR_EQ(test
, link_bss
->channel
,
629 ieee80211_get_channel_khz(wiphy
, MHZ_TO_KHZ(2462)));
631 /* Test wiphy does not set WIPHY_FLAG_SUPPORTS_NSTR_NONPRIMARY */
633 KUNIT_EXPECT_EQ(test
, link_bss
->use_for
, 0);
634 KUNIT_EXPECT_EQ(test
, link_bss
->cannot_use_reasons
,
635 NL80211_BSS_CANNOT_USE_NSTR_NONPRIMARY
);
636 KUNIT_EXPECT_NULL(test
,
637 cfg80211_get_bss(wiphy
, NULL
, sta_prof
.bssid
,
639 IEEE80211_BSS_TYPE_ANY
,
640 IEEE80211_PRIVACY_ANY
));
642 KUNIT_EXPECT_EQ(test
, link_bss
->use_for
,
643 NL80211_BSS_USE_FOR_ALL
);
644 KUNIT_EXPECT_EQ(test
, link_bss
->cannot_use_reasons
, 0);
648 ies
= rcu_dereference(link_bss
->ies
);
649 KUNIT_EXPECT_NOT_NULL(test
, ies
);
650 KUNIT_EXPECT_EQ(test
, ies
->tsf
, tsf
+ le64_to_cpu(sta_prof
.tsf_offset
));
651 /* Resulting length should be:
652 * SSID (inherited) + RNR (inherited) + vendor element(s) +
653 * operating class (if requested) +
654 * generated RNR (if MLD ID == 0 and not NSTR) +
655 * MLE common info + MLE header and control
657 if (params
->sta_prof_vendor_elems
)
658 KUNIT_EXPECT_EQ(test
, ies
->len
,
659 6 + 2 + rnr_len
+ 2 + 160 + 2 + 165 +
660 (params
->include_oper_class
? 3 : 0) +
661 (!params
->mld_id
&& !params
->nstr
? 22 : 0) +
662 mle_basic_common_info
.var_len
+ 5);
664 KUNIT_EXPECT_EQ(test
, ies
->len
,
665 6 + 2 + rnr_len
+ 2 + 155 +
666 (params
->include_oper_class
? 3 : 0) +
667 (!params
->mld_id
&& !params
->nstr
? 22 : 0) +
668 mle_basic_common_info
.var_len
+ 5);
671 cfg80211_put_bss(wiphy
, bss
);
672 cfg80211_put_bss(wiphy
, link_bss
);
675 static struct cfg80211_parse_colocated_ap_case
{
679 struct ieee80211_neighbor_ap_info info
;
681 struct ieee80211_tbtt_info_ge_11 tbtt_long
;
682 struct ieee80211_tbtt_info_7_8_9 tbtt_short
;
687 } cfg80211_parse_colocated_ap_cases
[] = {
689 .desc
= "wrong_band",
693 .bssid
= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
694 .bss_params
= IEEE80211_RNR_TBTT_PARAMS_COLOC_AP
,
699 .desc
= "wrong_type",
700 /* IEEE80211_AP_INFO_TBTT_HDR_TYPE is in the least significant bits */
701 .info
.tbtt_info_hdr
= IEEE80211_TBTT_INFO_TYPE_MLD
,
703 .bssid
= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
704 .bss_params
= IEEE80211_RNR_TBTT_PARAMS_COLOC_AP
,
709 .desc
= "colocated_invalid_len_short",
710 .info
.tbtt_info_len
= 6,
712 .bssid
= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
713 .bss_params
= IEEE80211_RNR_TBTT_PARAMS_COLOC_AP
|
714 IEEE80211_RNR_TBTT_PARAMS_SAME_SSID
,
719 .desc
= "colocated_invalid_len_short_mld",
720 .info
.tbtt_info_len
= 10,
722 .bssid
= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
723 .bss_params
= IEEE80211_RNR_TBTT_PARAMS_COLOC_AP
,
728 .desc
= "colocated_non_mld",
729 .info
.tbtt_info_len
= sizeof(struct ieee80211_tbtt_info_7_8_9
),
731 .bssid
= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
732 .bss_params
= IEEE80211_RNR_TBTT_PARAMS_COLOC_AP
|
733 IEEE80211_RNR_TBTT_PARAMS_SAME_SSID
,
739 .desc
= "colocated_non_mld_invalid_bssid",
740 .info
.tbtt_info_len
= sizeof(struct ieee80211_tbtt_info_7_8_9
),
742 .bssid
= { 0xff, 0x11, 0x22, 0x33, 0x44, 0x55 },
743 .bss_params
= IEEE80211_RNR_TBTT_PARAMS_COLOC_AP
|
744 IEEE80211_RNR_TBTT_PARAMS_SAME_SSID
,
750 .desc
= "colocated_mld",
752 .bssid
= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
753 .bss_params
= IEEE80211_RNR_TBTT_PARAMS_COLOC_AP
,
758 .desc
= "colocated_mld",
760 .bssid
= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
761 .bss_params
= IEEE80211_RNR_TBTT_PARAMS_COLOC_AP
,
767 .desc
= "colocated_disabled_mld",
769 .bssid
= { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55 },
770 .bss_params
= IEEE80211_RNR_TBTT_PARAMS_COLOC_AP
,
771 .mld_params
.params
= cpu_to_le16(IEEE80211_RNR_MLD_PARAMS_DISABLED_LINK
),
776 KUNIT_ARRAY_PARAM_DESC(cfg80211_parse_colocated_ap
, cfg80211_parse_colocated_ap_cases
, desc
)
778 static void test_cfg80211_parse_colocated_ap(struct kunit
*test
)
780 const struct cfg80211_parse_colocated_ap_case
*params
= test
->param_value
;
781 struct sk_buff
*input
= kunit_zalloc_skb(test
, 1024, GFP_KERNEL
);
782 struct cfg80211_bss_ies
*ies
;
783 struct ieee80211_neighbor_ap_info info
;
784 LIST_HEAD(coloc_ap_list
);
787 KUNIT_ASSERT_NOT_NULL(test
, input
);
791 /* Reasonable values for a colocated AP */
792 if (!info
.tbtt_info_len
)
793 info
.tbtt_info_len
= sizeof(params
->tbtt_long
);
798 /* Zero is the correct default for .btt_info_hdr (one entry, TBTT type) */
800 skb_put_u8(input
, WLAN_EID_SSID
);
801 skb_put_u8(input
, 4);
802 skb_put_data(input
, "TEST", 4);
804 skb_put_u8(input
, WLAN_EID_REDUCED_NEIGHBOR_REPORT
);
805 skb_put_u8(input
, sizeof(info
) + info
.tbtt_info_len
+ (params
->add_junk
? 3 : 0));
806 skb_put_data(input
, &info
, sizeof(info
));
807 skb_put_data(input
, ¶ms
->tbtt_long
, info
.tbtt_info_len
);
809 if (params
->add_junk
)
810 skb_put_data(input
, "123", 3);
812 ies
= kunit_kzalloc(test
, struct_size(ies
, data
, input
->len
), GFP_KERNEL
);
813 ies
->len
= input
->len
;
814 memcpy(ies
->data
, input
->data
, input
->len
);
816 count
= cfg80211_parse_colocated_ap(ies
, &coloc_ap_list
);
818 KUNIT_EXPECT_EQ(test
, count
, params
->valid
);
819 KUNIT_EXPECT_EQ(test
, list_count_nodes(&coloc_ap_list
), params
->valid
);
821 if (params
->valid
&& !list_empty(&coloc_ap_list
)) {
822 struct cfg80211_colocated_ap
*ap
;
824 ap
= list_first_entry(&coloc_ap_list
, typeof(*ap
), list
);
825 if (info
.tbtt_info_len
<= sizeof(params
->tbtt_short
))
826 KUNIT_EXPECT_MEMEQ(test
, ap
->bssid
, params
->tbtt_short
.bssid
, ETH_ALEN
);
828 KUNIT_EXPECT_MEMEQ(test
, ap
->bssid
, params
->tbtt_long
.bssid
, ETH_ALEN
);
830 if (params
->same_ssid
) {
831 KUNIT_EXPECT_EQ(test
, ap
->ssid_len
, 4);
832 KUNIT_EXPECT_MEMEQ(test
, ap
->ssid
, "TEST", 4);
834 KUNIT_EXPECT_EQ(test
, ap
->ssid_len
, 0);
838 cfg80211_free_coloc_ap_list(&coloc_ap_list
);
841 static struct kunit_case gen_new_ie_test_cases
[] = {
842 KUNIT_CASE_PARAM(test_gen_new_ie
, gen_new_ie_gen_params
),
843 KUNIT_CASE(test_gen_new_ie_malformed
),
847 static struct kunit_suite gen_new_ie
= {
848 .name
= "cfg80211-ie-generation",
849 .test_cases
= gen_new_ie_test_cases
,
852 kunit_test_suite(gen_new_ie
);
854 static struct kunit_case inform_bss_test_cases
[] = {
855 KUNIT_CASE(test_inform_bss_ssid_only
),
856 KUNIT_CASE_PARAM(test_inform_bss_ml_sta
, inform_bss_ml_sta_gen_params
),
860 static struct kunit_suite inform_bss
= {
861 .name
= "cfg80211-inform-bss",
862 .test_cases
= inform_bss_test_cases
,
865 kunit_test_suite(inform_bss
);
867 static struct kunit_case scan_6ghz_cases
[] = {
868 KUNIT_CASE_PARAM(test_cfg80211_parse_colocated_ap
,
869 cfg80211_parse_colocated_ap_gen_params
),
873 static struct kunit_suite scan_6ghz
= {
874 .name
= "cfg80211-scan-6ghz",
875 .test_cases
= scan_6ghz_cases
,
878 kunit_test_suite(scan_6ghz
);