hc
2024-12-19 9370bb92b2d16684ee45cf24e879c93c509162da
kernel/lib/test_bpf.c
....@@ -1,16 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Testsuite for BPF interpreter and BPF JIT compiler
34 *
45 * Copyright (c) 2011-2014 PLUMgrid, http://plumgrid.com
5
- *
6
- * This program is free software; you can redistribute it and/or
7
- * modify it under the terms of version 2 of the GNU General Public
8
- * License as published by the Free Software Foundation.
9
- *
10
- * This program is distributed in the hope that it will be useful, but
11
- * WITHOUT ANY WARRANTY; without even the implied warranty of
12
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
- * General Public License for more details.
146 */
157
168 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
....@@ -39,6 +31,7 @@
3931 #define SKB_HASH 0x1234aaab
4032 #define SKB_QUEUE_MAP 123
4133 #define SKB_VLAN_TCI 0xffff
34
+#define SKB_VLAN_PRESENT 1
4235 #define SKB_DEV_IFINDEX 577
4336 #define SKB_DEV_TYPE 588
4437
....@@ -725,8 +718,8 @@
725718 CLASSIC,
726719 { },
727720 {
728
- { 1, SKB_VLAN_TCI & ~VLAN_TAG_PRESENT },
729
- { 10, SKB_VLAN_TCI & ~VLAN_TAG_PRESENT }
721
+ { 1, SKB_VLAN_TCI },
722
+ { 10, SKB_VLAN_TCI }
730723 },
731724 },
732725 {
....@@ -739,8 +732,8 @@
739732 CLASSIC,
740733 { },
741734 {
742
- { 1, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) },
743
- { 10, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) }
735
+ { 1, SKB_VLAN_PRESENT },
736
+ { 10, SKB_VLAN_PRESENT }
744737 },
745738 },
746739 {
....@@ -874,7 +867,7 @@
874867 },
875868 CLASSIC,
876869 { },
877
- { { 4, 10 ^ 300 }, { 20, 10 ^ 300 } },
870
+ { { 4, 0xA ^ 300 }, { 20, 0xA ^ 300 } },
878871 },
879872 {
880873 "SPILL_FILL",
....@@ -5282,31 +5275,21 @@
52825275 { /* Mainly checking JIT here. */
52835276 "BPF_MAXINSNS: Ctx heavy transformations",
52845277 { },
5285
-#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_S390)
5286
- CLASSIC | FLAG_EXPECTED_FAIL,
5287
-#else
52885278 CLASSIC,
5289
-#endif
52905279 { },
52915280 {
5292
- { 1, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) },
5293
- { 10, !!(SKB_VLAN_TCI & VLAN_TAG_PRESENT) }
5281
+ { 1, SKB_VLAN_PRESENT },
5282
+ { 10, SKB_VLAN_PRESENT }
52945283 },
52955284 .fill_helper = bpf_fill_maxinsns6,
5296
- .expected_errcode = -ENOTSUPP,
52975285 },
52985286 { /* Mainly checking JIT here. */
52995287 "BPF_MAXINSNS: Call heavy transformations",
53005288 { },
5301
-#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_S390)
5302
- CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL,
5303
-#else
53045289 CLASSIC | FLAG_NO_DATA,
5305
-#endif
53065290 { },
53075291 { { 1, 0 }, { 10, 0 } },
53085292 .fill_helper = bpf_fill_maxinsns7,
5309
- .expected_errcode = -ENOTSUPP,
53105293 },
53115294 { /* Mainly checking JIT here. */
53125295 "BPF_MAXINSNS: Jump heavy test",
....@@ -5357,28 +5340,18 @@
53575340 {
53585341 "BPF_MAXINSNS: exec all MSH",
53595342 { },
5360
-#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_S390)
5361
- CLASSIC | FLAG_EXPECTED_FAIL,
5362
-#else
53635343 CLASSIC,
5364
-#endif
53655344 { 0xfa, 0xfb, 0xfc, 0xfd, },
53665345 { { 4, 0xababab83 } },
53675346 .fill_helper = bpf_fill_maxinsns13,
5368
- .expected_errcode = -ENOTSUPP,
53695347 },
53705348 {
53715349 "BPF_MAXINSNS: ld_abs+get_processor_id",
53725350 { },
5373
-#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_S390)
5374
- CLASSIC | FLAG_EXPECTED_FAIL,
5375
-#else
53765351 CLASSIC,
5377
-#endif
53785352 { },
53795353 { { 1, 0xbee } },
53805354 .fill_helper = bpf_fill_ld_abs_get_processor_id,
5381
- .expected_errcode = -ENOTSUPP,
53825355 },
53835356 /*
53845357 * LD_IND / LD_ABS on fragmented SKBs
....@@ -6493,7 +6466,9 @@
64936466 skb->hash = SKB_HASH;
64946467 skb->queue_mapping = SKB_QUEUE_MAP;
64956468 skb->vlan_tci = SKB_VLAN_TCI;
6469
+ skb->vlan_present = SKB_VLAN_PRESENT;
64966470 skb->vlan_proto = htons(ETH_P_IP);
6471
+ dev_net_set(&dev, &init_net);
64976472 skb->dev = &dev;
64986473 skb->dev->ifindex = SKB_DEV_IFINDEX;
64996474 skb->dev->type = SKB_DEV_TYPE;
....@@ -6665,12 +6640,14 @@
66656640 u64 start, finish;
66666641 int ret = 0, i;
66676642
6643
+ migrate_disable();
66686644 start = ktime_get_ns();
66696645
66706646 for (i = 0; i < runs; i++)
66716647 ret = BPF_PROG_RUN(fp, data);
66726648
66736649 finish = ktime_get_ns();
6650
+ migrate_enable();
66746651
66756652 *duration = finish - start;
66766653 do_div(*duration, runs);
....@@ -6869,34 +6846,128 @@
68696846 return NULL;
68706847 }
68716848
6872
-static __init int test_skb_segment(void)
6849
+static __init struct sk_buff *build_test_skb_linear_no_head_frag(void)
68736850 {
6851
+ unsigned int alloc_size = 2000;
6852
+ unsigned int headroom = 102, doffset = 72, data_size = 1308;
6853
+ struct sk_buff *skb[2];
6854
+ int i;
6855
+
6856
+ /* skbs linked in a frag_list, both with linear data, with head_frag=0
6857
+ * (data allocated by kmalloc), both have tcp data of 1308 bytes
6858
+ * (total payload is 2616 bytes).
6859
+ * Data offset is 72 bytes (40 ipv6 hdr, 32 tcp hdr). Some headroom.
6860
+ */
6861
+ for (i = 0; i < 2; i++) {
6862
+ skb[i] = alloc_skb(alloc_size, GFP_KERNEL);
6863
+ if (!skb[i]) {
6864
+ if (i == 0)
6865
+ goto err_skb0;
6866
+ else
6867
+ goto err_skb1;
6868
+ }
6869
+
6870
+ skb[i]->protocol = htons(ETH_P_IPV6);
6871
+ skb_reserve(skb[i], headroom);
6872
+ skb_put(skb[i], doffset + data_size);
6873
+ skb_reset_network_header(skb[i]);
6874
+ if (i == 0)
6875
+ skb_reset_mac_header(skb[i]);
6876
+ else
6877
+ skb_set_mac_header(skb[i], -ETH_HLEN);
6878
+ __skb_pull(skb[i], doffset);
6879
+ }
6880
+
6881
+ /* setup shinfo.
6882
+ * mimic bpf_skb_proto_4_to_6, which resets gso_segs and assigns a
6883
+ * reduced gso_size.
6884
+ */
6885
+ skb_shinfo(skb[0])->gso_size = 1288;
6886
+ skb_shinfo(skb[0])->gso_type = SKB_GSO_TCPV6 | SKB_GSO_DODGY;
6887
+ skb_shinfo(skb[0])->gso_segs = 0;
6888
+ skb_shinfo(skb[0])->frag_list = skb[1];
6889
+
6890
+ /* adjust skb[0]'s len */
6891
+ skb[0]->len += skb[1]->len;
6892
+ skb[0]->data_len += skb[1]->len;
6893
+ skb[0]->truesize += skb[1]->truesize;
6894
+
6895
+ return skb[0];
6896
+
6897
+err_skb1:
6898
+ kfree_skb(skb[0]);
6899
+err_skb0:
6900
+ return NULL;
6901
+}
6902
+
6903
+struct skb_segment_test {
6904
+ const char *descr;
6905
+ struct sk_buff *(*build_skb)(void);
68746906 netdev_features_t features;
6907
+};
6908
+
6909
+static struct skb_segment_test skb_segment_tests[] __initconst = {
6910
+ {
6911
+ .descr = "gso_with_rx_frags",
6912
+ .build_skb = build_test_skb,
6913
+ .features = NETIF_F_SG | NETIF_F_GSO_PARTIAL | NETIF_F_IP_CSUM |
6914
+ NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM
6915
+ },
6916
+ {
6917
+ .descr = "gso_linear_no_head_frag",
6918
+ .build_skb = build_test_skb_linear_no_head_frag,
6919
+ .features = NETIF_F_SG | NETIF_F_FRAGLIST |
6920
+ NETIF_F_HW_VLAN_CTAG_TX | NETIF_F_GSO |
6921
+ NETIF_F_LLTX | NETIF_F_GRO |
6922
+ NETIF_F_IPV6_CSUM | NETIF_F_RXCSUM |
6923
+ NETIF_F_HW_VLAN_STAG_TX
6924
+ }
6925
+};
6926
+
6927
+static __init int test_skb_segment_single(const struct skb_segment_test *test)
6928
+{
68756929 struct sk_buff *skb, *segs;
68766930 int ret = -1;
68776931
6878
- features = NETIF_F_SG | NETIF_F_GSO_PARTIAL | NETIF_F_IP_CSUM |
6879
- NETIF_F_IPV6_CSUM;
6880
- features |= NETIF_F_RXCSUM;
6881
- skb = build_test_skb();
6932
+ skb = test->build_skb();
68826933 if (!skb) {
68836934 pr_info("%s: failed to build_test_skb", __func__);
68846935 goto done;
68856936 }
68866937
6887
- segs = skb_segment(skb, features);
6938
+ segs = skb_segment(skb, test->features);
68886939 if (!IS_ERR(segs)) {
68896940 kfree_skb_list(segs);
68906941 ret = 0;
6891
- pr_info("%s: success in skb_segment!", __func__);
6892
- } else {
6893
- pr_info("%s: failed in skb_segment!", __func__);
68946942 }
68956943 kfree_skb(skb);
68966944 done:
68976945 return ret;
68986946 }
68996947
6948
+static __init int test_skb_segment(void)
6949
+{
6950
+ int i, err_cnt = 0, pass_cnt = 0;
6951
+
6952
+ for (i = 0; i < ARRAY_SIZE(skb_segment_tests); i++) {
6953
+ const struct skb_segment_test *test = &skb_segment_tests[i];
6954
+
6955
+ pr_info("#%d %s ", i, test->descr);
6956
+
6957
+ if (test_skb_segment_single(test)) {
6958
+ pr_cont("FAIL\n");
6959
+ err_cnt++;
6960
+ } else {
6961
+ pr_cont("PASS\n");
6962
+ pass_cnt++;
6963
+ }
6964
+ }
6965
+
6966
+ pr_info("%s: Summary: %d PASSED, %d FAILED\n", __func__,
6967
+ pass_cnt, err_cnt);
6968
+ return err_cnt ? -EINVAL : 0;
6969
+}
6970
+
69006971 static __init int test_bpf(void)
69016972 {
69026973 int i, err_cnt = 0, pass_cnt = 0;