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
10MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
11
12static 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);
88free_skb:
89 kfree_skb(skb);
90}
91
92static struct kunit_case element_parsing_test_cases[] = {
93 KUNIT_CASE(mle_defrag),
94 {}
95};
96
97static struct kunit_suite element_parsing = {
98 .name = "mac80211-element-parsing",
99 .test_cases = element_parsing_test_cases,
100};
101
102kunit_test_suite(element_parsing);
103

source code of linux/net/mac80211/tests/elems.c