1 | // SPDX-License-Identifier: GPL-2.0-only |
2 | /* |
3 | * KUnit tests for element parsing |
4 | * |
5 | * Copyright (C) 2023-2024 Intel Corporation |
6 | */ |
7 | #include <kunit/test.h> |
8 | #include "../ieee80211_i.h" |
9 | |
10 | MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING); |
11 | |
12 | static void mle_defrag(struct kunit *test) |
13 | { |
14 | struct ieee80211_elems_parse_params parse_params = { |
15 | .link_id = 12, |
16 | .from_ap = true, |
17 | .mode = IEEE80211_CONN_MODE_EHT, |
18 | }; |
19 | struct ieee802_11_elems *parsed; |
20 | struct sk_buff *skb; |
21 | u8 *len_mle, *len_prof; |
22 | int i; |
23 | |
24 | skb = alloc_skb(size: 1024, GFP_KERNEL); |
25 | KUNIT_ASSERT_NOT_NULL(test, skb); |
26 | |
27 | if (skb_pad(skb, pad: skb_tailroom(skb))) { |
28 | KUNIT_FAIL(test, "failed to pad skb" ); |
29 | return; |
30 | } |
31 | |
32 | /* build a multi-link element */ |
33 | skb_put_u8(skb, val: WLAN_EID_EXTENSION); |
34 | len_mle = skb_put(skb, len: 1); |
35 | skb_put_u8(skb, val: WLAN_EID_EXT_EHT_MULTI_LINK); |
36 | |
37 | put_unaligned_le16(IEEE80211_ML_CONTROL_TYPE_BASIC, |
38 | p: skb_put(skb, len: 2)); |
39 | /* struct ieee80211_mle_basic_common_info */ |
40 | skb_put_u8(skb, val: 7); /* includes len field */ |
41 | skb_put_data(skb, data: "\x00\x00\x00\x00\x00\x00" , ETH_ALEN); /* MLD addr */ |
42 | |
43 | /* with a STA profile inside */ |
44 | skb_put_u8(skb, val: IEEE80211_MLE_SUBELEM_PER_STA_PROFILE); |
45 | len_prof = skb_put(skb, len: 1); |
46 | put_unaligned_le16(IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE | |
47 | parse_params.link_id, |
48 | p: skb_put(skb, len: 2)); |
49 | skb_put_u8(skb, val: 1); /* fake sta_info_len - includes itself */ |
50 | /* put a bunch of useless elements into it */ |
51 | for (i = 0; i < 20; i++) { |
52 | skb_put_u8(skb, val: WLAN_EID_SSID); |
53 | skb_put_u8(skb, val: 20); |
54 | skb_put(skb, len: 20); |
55 | } |
56 | |
57 | /* fragment STA profile */ |
58 | ieee80211_fragment_element(skb, len_pos: len_prof, |
59 | frag_id: IEEE80211_MLE_SUBELEM_FRAGMENT); |
60 | /* fragment MLE */ |
61 | ieee80211_fragment_element(skb, len_pos: len_mle, frag_id: WLAN_EID_FRAGMENT); |
62 | |
63 | parse_params.start = skb->data; |
64 | parse_params.len = skb->len; |
65 | parsed = ieee802_11_parse_elems_full(params: &parse_params); |
66 | /* should return ERR_PTR or valid, not NULL */ |
67 | KUNIT_EXPECT_NOT_NULL(test, parsed); |
68 | |
69 | if (IS_ERR_OR_NULL(ptr: parsed)) |
70 | goto free_skb; |
71 | |
72 | KUNIT_EXPECT_NOT_NULL(test, parsed->ml_basic); |
73 | KUNIT_EXPECT_EQ(test, |
74 | parsed->ml_basic_len, |
75 | 2 /* control */ + |
76 | 7 /* common info */ + |
77 | 2 /* sta profile element header */ + |
78 | 3 /* sta profile header */ + |
79 | 20 * 22 /* sta profile data */ + |
80 | 2 /* sta profile fragment element */); |
81 | KUNIT_EXPECT_NOT_NULL(test, parsed->prof); |
82 | KUNIT_EXPECT_EQ(test, |
83 | parsed->sta_prof_len, |
84 | 3 /* sta profile header */ + |
85 | 20 * 22 /* sta profile data */); |
86 | |
87 | kfree(objp: parsed); |
88 | free_skb: |
89 | kfree_skb(skb); |
90 | } |
91 | |
92 | static struct kunit_case element_parsing_test_cases[] = { |
93 | KUNIT_CASE(mle_defrag), |
94 | {} |
95 | }; |
96 | |
97 | static struct kunit_suite element_parsing = { |
98 | .name = "mac80211-element-parsing" , |
99 | .test_cases = element_parsing_test_cases, |
100 | }; |
101 | |
102 | kunit_test_suite(element_parsing); |
103 | |