xref: /linux/net/wireless/tests/fragmentation.c (revision 594ce0b8a998aa4d05827cd7c0d0dcec9a1e3ae2)
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, 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 
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 
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 
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