| // SPDX-License-Identifier: GPL-2.0-only |
| /* |
| * KUnit tests for element fragmentation |
| * |
| * Copyright (C) 2023-2024 Intel Corporation |
| */ |
| #include <linux/ieee80211.h> |
| #include <net/cfg80211.h> |
| #include <kunit/test.h> |
| |
| static void defragment_0(struct kunit *test) |
| { |
| ssize_t ret; |
| static const u8 input[] = { |
| [0] = WLAN_EID_EXTENSION, |
| [1] = 254, |
| [2] = WLAN_EID_EXT_EHT_MULTI_LINK, |
| [27] = 27, |
| [123] = 123, |
| [254 + 2] = WLAN_EID_FRAGMENT, |
| [254 + 3] = 7, |
| [254 + 3 + 7] = 0, /* for size */ |
| }; |
| u8 *data = kunit_kzalloc(test, sizeof(input), GFP_KERNEL); |
| |
| KUNIT_ASSERT_NOT_NULL(test, data); |
| |
| ret = cfg80211_defragment_element((void *)input, |
| input, sizeof(input), |
| NULL, 0, |
| WLAN_EID_FRAGMENT); |
| KUNIT_EXPECT_EQ(test, ret, 253); |
| ret = cfg80211_defragment_element((void *)input, |
| input, sizeof(input), |
| data, ret, |
| WLAN_EID_FRAGMENT); |
| KUNIT_EXPECT_EQ(test, ret, 253); |
| KUNIT_EXPECT_MEMEQ(test, data, input + 3, 253); |
| } |
| |
| static void defragment_1(struct kunit *test) |
| { |
| ssize_t ret; |
| static const u8 input[] = { |
| [0] = WLAN_EID_EXTENSION, |
| [1] = 255, |
| [2] = WLAN_EID_EXT_EHT_MULTI_LINK, |
| [27] = 27, |
| [123] = 123, |
| [255 + 2] = WLAN_EID_FRAGMENT, |
| [255 + 3] = 7, |
| [255 + 3 + 1] = 0xaa, |
| [255 + 3 + 8] = WLAN_EID_FRAGMENT, /* not used */ |
| [255 + 3 + 9] = 1, |
| [255 + 3 + 10] = 0, /* for size */ |
| }; |
| u8 *data = kunit_kzalloc(test, sizeof(input), GFP_KERNEL); |
| const struct element *elem; |
| int count = 0; |
| |
| KUNIT_ASSERT_NOT_NULL(test, data); |
| |
| for_each_element(elem, input, sizeof(input)) |
| count++; |
| |
| /* check the elements are right */ |
| KUNIT_ASSERT_EQ(test, count, 3); |
| |
| ret = cfg80211_defragment_element((void *)input, |
| input, sizeof(input), |
| NULL, 0, |
| WLAN_EID_FRAGMENT); |
| KUNIT_EXPECT_EQ(test, ret, 254 + 7); |
| ret = cfg80211_defragment_element((void *)input, |
| input, sizeof(input), |
| data, ret, |
| WLAN_EID_FRAGMENT); |
| /* this means the last fragment was not used */ |
| KUNIT_EXPECT_EQ(test, ret, 254 + 7); |
| KUNIT_EXPECT_MEMEQ(test, data, input + 3, 254); |
| KUNIT_EXPECT_MEMEQ(test, data + 254, input + 255 + 4, 7); |
| } |
| |
| static void defragment_2(struct kunit *test) |
| { |
| ssize_t ret; |
| static const u8 input[] = { |
| [0] = WLAN_EID_EXTENSION, |
| [1] = 255, |
| [2] = WLAN_EID_EXT_EHT_MULTI_LINK, |
| [27] = 27, |
| [123] = 123, |
| |
| [257 + 0] = WLAN_EID_FRAGMENT, |
| [257 + 1] = 255, |
| [257 + 20] = 0xaa, |
| |
| [2 * 257 + 0] = WLAN_EID_FRAGMENT, |
| [2 * 257 + 1] = 1, |
| [2 * 257 + 2] = 0xcc, |
| [2 * 257 + 3] = WLAN_EID_FRAGMENT, /* not used */ |
| [2 * 257 + 4] = 1, |
| [2 * 257 + 5] = 0, /* for size */ |
| }; |
| u8 *data = kunit_kzalloc(test, sizeof(input), GFP_KERNEL); |
| const struct element *elem; |
| int count = 0; |
| |
| KUNIT_ASSERT_NOT_NULL(test, data); |
| |
| for_each_element(elem, input, sizeof(input)) |
| count++; |
| |
| /* check the elements are right */ |
| KUNIT_ASSERT_EQ(test, count, 4); |
| |
| ret = cfg80211_defragment_element((void *)input, |
| input, sizeof(input), |
| NULL, 0, |
| WLAN_EID_FRAGMENT); |
| /* this means the last fragment was not used */ |
| KUNIT_EXPECT_EQ(test, ret, 254 + 255 + 1); |
| ret = cfg80211_defragment_element((void *)input, |
| input, sizeof(input), |
| data, ret, |
| WLAN_EID_FRAGMENT); |
| KUNIT_EXPECT_EQ(test, ret, 254 + 255 + 1); |
| KUNIT_EXPECT_MEMEQ(test, data, input + 3, 254); |
| KUNIT_EXPECT_MEMEQ(test, data + 254, input + 257 + 2, 255); |
| KUNIT_EXPECT_MEMEQ(test, data + 254 + 255, input + 2 * 257 + 2, 1); |
| } |
| |
| static void defragment_at_end(struct kunit *test) |
| { |
| ssize_t ret; |
| static const u8 input[] = { |
| [0] = WLAN_EID_EXTENSION, |
| [1] = 255, |
| [2] = WLAN_EID_EXT_EHT_MULTI_LINK, |
| [27] = 27, |
| [123] = 123, |
| [255 + 2] = WLAN_EID_FRAGMENT, |
| [255 + 3] = 7, |
| [255 + 3 + 7] = 0, /* for size */ |
| }; |
| u8 *data = kunit_kzalloc(test, sizeof(input), GFP_KERNEL); |
| |
| KUNIT_ASSERT_NOT_NULL(test, data); |
| |
| ret = cfg80211_defragment_element((void *)input, |
| input, sizeof(input), |
| NULL, 0, |
| WLAN_EID_FRAGMENT); |
| KUNIT_EXPECT_EQ(test, ret, 254 + 7); |
| ret = cfg80211_defragment_element((void *)input, |
| input, sizeof(input), |
| data, ret, |
| WLAN_EID_FRAGMENT); |
| KUNIT_EXPECT_EQ(test, ret, 254 + 7); |
| KUNIT_EXPECT_MEMEQ(test, data, input + 3, 254); |
| KUNIT_EXPECT_MEMEQ(test, data + 254, input + 255 + 4, 7); |
| } |
| |
| static struct kunit_case element_fragmentation_test_cases[] = { |
| KUNIT_CASE(defragment_0), |
| KUNIT_CASE(defragment_1), |
| KUNIT_CASE(defragment_2), |
| KUNIT_CASE(defragment_at_end), |
| {} |
| }; |
| |
| static struct kunit_suite element_fragmentation = { |
| .name = "cfg80211-element-defragmentation", |
| .test_cases = element_fragmentation_test_cases, |
| }; |
| |
| kunit_test_suite(element_fragmentation); |