| // SPDX-License-Identifier: GPL-2.0-only | |
| /* | |
| * KUnit tests for element parsing | |
| * | |
| * Copyright (C) 2023-2024 Intel Corporation | |
| */ | |
| #include <kunit/test.h> | |
| #include "../ieee80211_i.h" | |
| MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); | |
| static void mle_defrag(struct kunit *test) | |
| { | |
| struct ieee80211_elems_parse_params parse_params = { | |
| .link_id = 12, | |
| .from_ap = true, | |
| .mode = IEEE80211_CONN_MODE_EHT, | |
| }; | |
| struct ieee802_11_elems *parsed; | |
| struct sk_buff *skb; | |
| u8 *len_mle, *len_prof; | |
| int i; | |
| skb = alloc_skb(1024, GFP_KERNEL); | |
| KUNIT_ASSERT_NOT_NULL(test, skb); | |
| if (skb_pad(skb, skb_tailroom(skb))) { | |
| KUNIT_FAIL(test, "failed to pad skb"); | |
| return; | |
| } | |
| /* build a multi-link element */ | |
| skb_put_u8(skb, WLAN_EID_EXTENSION); | |
| len_mle = skb_put(skb, 1); | |
| skb_put_u8(skb, WLAN_EID_EXT_EHT_MULTI_LINK); | |
| put_unaligned_le16(IEEE80211_ML_CONTROL_TYPE_BASIC, | |
| skb_put(skb, 2)); | |
| /* struct ieee80211_mle_basic_common_info */ | |
| skb_put_u8(skb, 7); /* includes len field */ | |
| skb_put_data(skb, "\x00\x00\x00\x00\x00\x00", ETH_ALEN); /* MLD addr */ | |
| /* with a STA profile inside */ | |
| skb_put_u8(skb, IEEE80211_MLE_SUBELEM_PER_STA_PROFILE); | |
| len_prof = skb_put(skb, 1); | |
| put_unaligned_le16(IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE | | |
| parse_params.link_id, | |
| skb_put(skb, 2)); | |
| skb_put_u8(skb, 1); /* fake sta_info_len - includes itself */ | |
| /* put a bunch of useless elements into it */ | |
| for (i = 0; i < 20; i++) { | |
| skb_put_u8(skb, WLAN_EID_SSID); | |
| skb_put_u8(skb, 20); | |
| skb_put(skb, 20); | |
| } | |
| /* fragment STA profile */ | |
| ieee80211_fragment_element(skb, len_prof, | |
| IEEE80211_MLE_SUBELEM_FRAGMENT); | |
| /* fragment MLE */ | |
| ieee80211_fragment_element(skb, len_mle, WLAN_EID_FRAGMENT); | |
| parse_params.start = skb->data; | |
| parse_params.len = skb->len; | |
| parsed = ieee802_11_parse_elems_full(&parse_params); | |
| /* should return ERR_PTR or valid, not NULL */ | |
| KUNIT_EXPECT_NOT_NULL(test, parsed); | |
| if (IS_ERR_OR_NULL(parsed)) | |
| goto free_skb; | |
| KUNIT_EXPECT_NOT_NULL(test, parsed->ml_basic); | |
| KUNIT_EXPECT_EQ(test, | |
| parsed->ml_basic_len, | |
| 2 /* control */ + | |
| 7 /* common info */ + | |
| 2 /* sta profile element header */ + | |
| 3 /* sta profile header */ + | |
| 20 * 22 /* sta profile data */ + | |
| 2 /* sta profile fragment element */); | |
| KUNIT_EXPECT_NOT_NULL(test, parsed->prof); | |
| KUNIT_EXPECT_EQ(test, | |
| parsed->sta_prof_len, | |
| 3 /* sta profile header */ + | |
| 20 * 22 /* sta profile data */); | |
| kfree(parsed); | |
| free_skb: | |
| kfree_skb(skb); | |
| } | |
| static struct kunit_case element_parsing_test_cases[] = { | |
| KUNIT_CASE(mle_defrag), | |
| {} | |
| }; | |
| static struct kunit_suite element_parsing = { | |
| .name = "mac80211-element-parsing", | |
| .test_cases = element_parsing_test_cases, | |
| }; | |
| kunit_test_suite(element_parsing); |