wifi: mac80211: add an element parsing unit test
authorJohannes Berg <johannes.berg@intel.com>
Sun, 27 Aug 2023 11:05:21 +0000 (14:05 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Mon, 11 Sep 2023 10:32:16 +0000 (12:32 +0200)
Add a unit test for the parsing of a fragmented sta profile
sub-element inside a fragmented multi-link element.

Signed-off-by: Johannes Berg <johannes.berg@intel.com>
Signed-off-by: Gregory Greenman <gregory.greenman@intel.com>
Link: https://lore.kernel.org/r/20230827135854.333bc75df13f.I0ddfeb6a88a4d89e7c7850e8ef45a4b19b5a061a@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
net/mac80211/Kconfig
net/mac80211/Makefile
net/mac80211/tests/Makefile [new file with mode: 0644]
net/mac80211/tests/elems.c [new file with mode: 0644]
net/mac80211/tests/module.c [new file with mode: 0644]
net/mac80211/util.c

index 51ec8256b7fa9e45455e10c0f16448c12e87b4dd..037ab74f5ade5b1961ff7292c4113f7aae4ef2d2 100644 (file)
@@ -57,6 +57,17 @@ endif
 comment "Some wireless drivers require a rate control algorithm"
        depends on MAC80211 && MAC80211_HAS_RC=n
 
+config MAC80211_KUNIT_TEST
+       tristate "KUnit tests for mac80211" if !KUNIT_ALL_TESTS
+       depends on KUNIT
+       depends on MAC80211
+       default KUNIT_ALL_TESTS
+       depends on !KERNEL_6_2
+       help
+         Enable this option to test mac80211 internals with kunit.
+
+         If unsure, say N.
+
 config MAC80211_MESH
        bool "Enable mac80211 mesh networking support"
        depends on MAC80211
index b8de44da1fb87fbf5a1db982c2d8eef50acaa3c8..c9eb52768133d068f11f817391556686b8b9ddb4 100644 (file)
@@ -65,4 +65,6 @@ rc80211_minstrel-$(CONFIG_MAC80211_DEBUGFS) += \
 
 mac80211-$(CONFIG_MAC80211_RC_MINSTREL) += $(rc80211_minstrel-y)
 
+obj-y += tests/
+
 ccflags-y += -DDEBUG
diff --git a/net/mac80211/tests/Makefile b/net/mac80211/tests/Makefile
new file mode 100644 (file)
index 0000000..4814584
--- /dev/null
@@ -0,0 +1,3 @@
+mac80211-tests-y += module.o elems.o
+
+obj-$(CONFIG_MAC80211_KUNIT_TEST) += mac80211-tests.o
diff --git a/net/mac80211/tests/elems.c b/net/mac80211/tests/elems.c
new file mode 100644 (file)
index 0000000..997d0cd
--- /dev/null
@@ -0,0 +1,101 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * KUnit tests for element parsing
+ *
+ * Copyright (C) 2023 Intel Corporation
+ */
+#include <kunit/test.h>
+#include "../ieee80211_i.h"
+
+MODULE_IMPORT_NS(EXPORTED_FOR_KUNIT_TESTING);
+
+static void mle_defrag(struct kunit *test)
+{
+       struct ieee80211_elems_parse_params parse_params = {
+               .link_id = 12,
+               .from_ap = true,
+       };
+       struct ieee802_11_elems *parsed;
+       struct sk_buff *skb;
+       u8 *len_mle, *len_prof;
+       int i;
+
+       skb = alloc_skb(1024, GFP_KERNEL);
+       KUNIT_ASSERT_NOT_NULL(test, skb);
+
+       if (skb_pad(skb, skb_tailroom(skb))) {
+               KUNIT_FAIL(test, "failed to pad skb");
+               return;
+       }
+
+       /* build a multi-link element */
+       skb_put_u8(skb, WLAN_EID_EXTENSION);
+       len_mle = skb_put(skb, 1);
+       skb_put_u8(skb, WLAN_EID_EXT_EHT_MULTI_LINK);
+
+       put_unaligned_le16(IEEE80211_ML_CONTROL_TYPE_BASIC,
+                          skb_put(skb, 2));
+       /* struct ieee80211_mle_basic_common_info */
+       skb_put_u8(skb, 7); /* includes len field */
+       skb_put_data(skb, "\x00\x00\x00\x00\x00\x00", ETH_ALEN); /* MLD addr */
+
+       /* with a STA profile inside */
+       skb_put_u8(skb, IEEE80211_MLE_SUBELEM_PER_STA_PROFILE);
+       len_prof = skb_put(skb, 1);
+       put_unaligned_le16(IEEE80211_MLE_STA_CONTROL_COMPLETE_PROFILE |
+                          parse_params.link_id,
+                          skb_put(skb, 2));
+       skb_put_u8(skb, 1); /* fake sta_info_len - includes itself */
+       /* put a bunch of useless elements into it */
+       for (i = 0; i < 20; i++) {
+               skb_put_u8(skb, WLAN_EID_SSID);
+               skb_put_u8(skb, 20);
+               skb_put(skb, 20);
+       }
+
+       /* fragment STA profile */
+       ieee80211_fragment_element(skb, len_prof,
+                                  IEEE80211_MLE_SUBELEM_FRAGMENT);
+       /* fragment MLE */
+       ieee80211_fragment_element(skb, len_mle, WLAN_EID_FRAGMENT);
+
+       parse_params.start = skb->data;
+       parse_params.len = skb->len;
+       parsed = ieee802_11_parse_elems_full(&parse_params);
+       /* should return ERR_PTR or valid, not NULL */
+       KUNIT_EXPECT_NOT_NULL(test, parsed);
+
+       if (IS_ERR_OR_NULL(parsed))
+               goto free_skb;
+
+       KUNIT_EXPECT_NOT_NULL(test, parsed->ml_basic_elem);
+       KUNIT_EXPECT_EQ(test,
+                       parsed->ml_basic_len,
+                       2 /* control */ +
+                       7 /* common info */ +
+                       2 /* sta profile element header */ +
+                       3 /* sta profile header */ +
+                       20 * 22 /* sta profile data */ +
+                       2 /* sta profile fragment element */);
+       KUNIT_EXPECT_NOT_NULL(test, parsed->prof);
+       KUNIT_EXPECT_EQ(test,
+                       parsed->sta_prof_len,
+                       3 /* sta profile header */ +
+                       20 * 22 /* sta profile data */);
+
+       kfree(parsed);
+free_skb:
+       kfree_skb(skb);
+}
+
+static struct kunit_case element_parsing_test_cases[] = {
+       KUNIT_CASE(mle_defrag),
+       {}
+};
+
+static struct kunit_suite element_parsing = {
+       .name = "mac80211-element-parsing",
+       .test_cases = element_parsing_test_cases,
+};
+
+kunit_test_suite(element_parsing);
diff --git a/net/mac80211/tests/module.c b/net/mac80211/tests/module.c
new file mode 100644 (file)
index 0000000..9d05f29
--- /dev/null
@@ -0,0 +1,10 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * This is just module boilerplate for the mac80211 kunit module.
+ *
+ * Copyright (C) 2023 Intel Corporation
+ */
+#include <linux/module.h>
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("tests for mac80211");
index 4aefb9483aa99e9a497b06eafc104bfc3d56cd3e..b0232a2b963e948ab24e5836606faa9c8b065d9c 100644 (file)
@@ -24,6 +24,7 @@
 #include <net/net_namespace.h>
 #include <net/cfg80211.h>
 #include <net/rtnetlink.h>
+#include <kunit/visibility.h>
 
 #include "ieee80211_i.h"
 #include "driver-ops.h"
@@ -1654,6 +1655,7 @@ ieee802_11_parse_elems_full(struct ieee80211_elems_parse_params *params)
 
        return elems;
 }
+EXPORT_SYMBOL_IF_KUNIT(ieee802_11_parse_elems_full);
 
 void ieee80211_regulatory_limit_wmm_params(struct ieee80211_sub_if_data *sdata,
                                           struct ieee80211_tx_queue_params
@@ -5127,3 +5129,4 @@ void ieee80211_fragment_element(struct sk_buff *skb, u8 *len_pos, u8 frag_id)
 
        *len_pos = elem_len;
 }
+EXPORT_SYMBOL_IF_KUNIT(ieee80211_fragment_element);