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 | |
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, size: sizeof(input), GFP_KERNEL); |
25 | |
26 | KUNIT_ASSERT_NOT_NULL(test, data); |
27 | |
28 | ret = cfg80211_defragment_element(elem: (void *)input, |
29 | ies: input, ieslen: sizeof(input), |
30 | NULL, data_len: 0, |
31 | frag_id: WLAN_EID_FRAGMENT); |
32 | KUNIT_EXPECT_EQ(test, ret, 253); |
33 | ret = cfg80211_defragment_element(elem: (void *)input, |
34 | ies: input, ieslen: sizeof(input), |
35 | data, data_len: ret, |
36 | frag_id: WLAN_EID_FRAGMENT); |
37 | KUNIT_EXPECT_EQ(test, ret, 253); |
38 | KUNIT_EXPECT_MEMEQ(test, data, input + 3, 253); |
39 | } |
40 | |
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, size: 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(elem: (void *)input, |
70 | ies: input, ieslen: sizeof(input), |
71 | NULL, data_len: 0, |
72 | frag_id: WLAN_EID_FRAGMENT); |
73 | KUNIT_EXPECT_EQ(test, ret, 254 + 7); |
74 | ret = cfg80211_defragment_element(elem: (void *)input, |
75 | ies: input, ieslen: sizeof(input), |
76 | data, data_len: ret, |
77 | frag_id: 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 | |
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, size: 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(elem: (void *)input, |
118 | ies: input, ieslen: sizeof(input), |
119 | NULL, data_len: 0, |
120 | frag_id: 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(elem: (void *)input, |
124 | ies: input, ieslen: sizeof(input), |
125 | data, data_len: ret, |
126 | frag_id: 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 | |
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, size: sizeof(input), GFP_KERNEL); |
147 | |
148 | KUNIT_ASSERT_NOT_NULL(test, data); |
149 | |
150 | ret = cfg80211_defragment_element(elem: (void *)input, |
151 | ies: input, ieslen: sizeof(input), |
152 | NULL, data_len: 0, |
153 | frag_id: WLAN_EID_FRAGMENT); |
154 | KUNIT_EXPECT_EQ(test, ret, 254 + 7); |
155 | ret = cfg80211_defragment_element(elem: (void *)input, |
156 | ies: input, ieslen: sizeof(input), |
157 | data, data_len: ret, |
158 | frag_id: 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 | |