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
11static 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
41static 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
84static 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
133static 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
164static 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
172static struct kunit_suite element_fragmentation = {
173 .name = "cfg80211-element-defragmentation",
174 .test_cases = element_fragmentation_test_cases,
175};
176
177kunit_test_suite(element_fragmentation);
178

source code of linux/net/wireless/tests/fragmentation.c