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