1 // SPDX-License-Identifier: GPL-2.0-only
2 /*
3 * KUnit tests for element fragmentation
4 *
5 * Copyright (C) 2023-2024 Intel Corporation
6 */
7 #include <linux/ieee80211.h>
8 #include <net/cfg80211.h>
9 #include <kunit/test.h>
10
defragment_0(struct kunit * test)11 static void defragment_0(struct kunit *test)
12 {
13 ssize_t ret;
14 static const u8 input[] = {
15 [0] = WLAN_EID_EXTENSION,
16 [1] = 254,
17 [2] = WLAN_EID_EXT_EHT_MULTI_LINK,
18 [27] = 27,
19 [123] = 123,
20 [254 + 2] = WLAN_EID_FRAGMENT,
21 [254 + 3] = 7,
22 [254 + 3 + 7] = 0, /* for size */
23 };
24 u8 *data = kunit_kzalloc(test, sizeof(input), GFP_KERNEL);
25
26 KUNIT_ASSERT_NOT_NULL(test, data);
27
28 ret = cfg80211_defragment_element((void *)input,
29 input, sizeof(input),
30 NULL, 0,
31 WLAN_EID_FRAGMENT);
32 KUNIT_EXPECT_EQ(test, ret, 253);
33 ret = cfg80211_defragment_element((void *)input,
34 input, sizeof(input),
35 data, ret,
36 WLAN_EID_FRAGMENT);
37 KUNIT_EXPECT_EQ(test, ret, 253);
38 KUNIT_EXPECT_MEMEQ(test, data, input + 3, 253);
39 }
40
defragment_1(struct kunit * test)41 static void defragment_1(struct kunit *test)
42 {
43 ssize_t ret;
44 static const u8 input[] = {
45 [0] = WLAN_EID_EXTENSION,
46 [1] = 255,
47 [2] = WLAN_EID_EXT_EHT_MULTI_LINK,
48 [27] = 27,
49 [123] = 123,
50 [255 + 2] = WLAN_EID_FRAGMENT,
51 [255 + 3] = 7,
52 [255 + 3 + 1] = 0xaa,
53 [255 + 3 + 8] = WLAN_EID_FRAGMENT, /* not used */
54 [255 + 3 + 9] = 1,
55 [255 + 3 + 10] = 0, /* for size */
56 };
57 u8 *data = kunit_kzalloc(test, sizeof(input), GFP_KERNEL);
58 const struct element *elem;
59 int count = 0;
60
61 KUNIT_ASSERT_NOT_NULL(test, data);
62
63 for_each_element(elem, input, sizeof(input))
64 count++;
65
66 /* check the elements are right */
67 KUNIT_ASSERT_EQ(test, count, 3);
68
69 ret = cfg80211_defragment_element((void *)input,
70 input, sizeof(input),
71 NULL, 0,
72 WLAN_EID_FRAGMENT);
73 KUNIT_EXPECT_EQ(test, ret, 254 + 7);
74 ret = cfg80211_defragment_element((void *)input,
75 input, sizeof(input),
76 data, ret,
77 WLAN_EID_FRAGMENT);
78 /* this means the last fragment was not used */
79 KUNIT_EXPECT_EQ(test, ret, 254 + 7);
80 KUNIT_EXPECT_MEMEQ(test, data, input + 3, 254);
81 KUNIT_EXPECT_MEMEQ(test, data + 254, input + 255 + 4, 7);
82 }
83
defragment_2(struct kunit * test)84 static void defragment_2(struct kunit *test)
85 {
86 ssize_t ret;
87 static const u8 input[] = {
88 [0] = WLAN_EID_EXTENSION,
89 [1] = 255,
90 [2] = WLAN_EID_EXT_EHT_MULTI_LINK,
91 [27] = 27,
92 [123] = 123,
93
94 [257 + 0] = WLAN_EID_FRAGMENT,
95 [257 + 1] = 255,
96 [257 + 20] = 0xaa,
97
98 [2 * 257 + 0] = WLAN_EID_FRAGMENT,
99 [2 * 257 + 1] = 1,
100 [2 * 257 + 2] = 0xcc,
101 [2 * 257 + 3] = WLAN_EID_FRAGMENT, /* not used */
102 [2 * 257 + 4] = 1,
103 [2 * 257 + 5] = 0, /* for size */
104 };
105 u8 *data = kunit_kzalloc(test, sizeof(input), GFP_KERNEL);
106 const struct element *elem;
107 int count = 0;
108
109 KUNIT_ASSERT_NOT_NULL(test, data);
110
111 for_each_element(elem, input, sizeof(input))
112 count++;
113
114 /* check the elements are right */
115 KUNIT_ASSERT_EQ(test, count, 4);
116
117 ret = cfg80211_defragment_element((void *)input,
118 input, sizeof(input),
119 NULL, 0,
120 WLAN_EID_FRAGMENT);
121 /* this means the last fragment was not used */
122 KUNIT_EXPECT_EQ(test, ret, 254 + 255 + 1);
123 ret = cfg80211_defragment_element((void *)input,
124 input, sizeof(input),
125 data, ret,
126 WLAN_EID_FRAGMENT);
127 KUNIT_EXPECT_EQ(test, ret, 254 + 255 + 1);
128 KUNIT_EXPECT_MEMEQ(test, data, input + 3, 254);
129 KUNIT_EXPECT_MEMEQ(test, data + 254, input + 257 + 2, 255);
130 KUNIT_EXPECT_MEMEQ(test, data + 254 + 255, input + 2 * 257 + 2, 1);
131 }
132
defragment_at_end(struct kunit * test)133 static void defragment_at_end(struct kunit *test)
134 {
135 ssize_t ret;
136 static const u8 input[] = {
137 [0] = WLAN_EID_EXTENSION,
138 [1] = 255,
139 [2] = WLAN_EID_EXT_EHT_MULTI_LINK,
140 [27] = 27,
141 [123] = 123,
142 [255 + 2] = WLAN_EID_FRAGMENT,
143 [255 + 3] = 7,
144 [255 + 3 + 7] = 0, /* for size */
145 };
146 u8 *data = kunit_kzalloc(test, sizeof(input), GFP_KERNEL);
147
148 KUNIT_ASSERT_NOT_NULL(test, data);
149
150 ret = cfg80211_defragment_element((void *)input,
151 input, sizeof(input),
152 NULL, 0,
153 WLAN_EID_FRAGMENT);
154 KUNIT_EXPECT_EQ(test, ret, 254 + 7);
155 ret = cfg80211_defragment_element((void *)input,
156 input, sizeof(input),
157 data, ret,
158 WLAN_EID_FRAGMENT);
159 KUNIT_EXPECT_EQ(test, ret, 254 + 7);
160 KUNIT_EXPECT_MEMEQ(test, data, input + 3, 254);
161 KUNIT_EXPECT_MEMEQ(test, data + 254, input + 255 + 4, 7);
162 }
163
164 static struct kunit_case element_fragmentation_test_cases[] = {
165 KUNIT_CASE(defragment_0),
166 KUNIT_CASE(defragment_1),
167 KUNIT_CASE(defragment_2),
168 KUNIT_CASE(defragment_at_end),
169 {}
170 };
171
172 static struct kunit_suite element_fragmentation = {
173 .name = "cfg80211-element-defragmentation",
174 .test_cases = element_fragmentation_test_cases,
175 };
176
177 kunit_test_suite(element_fragmentation);
178