.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
---|
1 | 2 | /* |
---|
2 | 3 | * Testsuite for BPF interpreter and BPF JIT compiler |
---|
3 | 4 | * |
---|
4 | 5 | * 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. |
---|
14 | 6 | */ |
---|
15 | 7 | |
---|
16 | 8 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
---|
.. | .. |
---|
39 | 31 | #define SKB_HASH 0x1234aaab |
---|
40 | 32 | #define SKB_QUEUE_MAP 123 |
---|
41 | 33 | #define SKB_VLAN_TCI 0xffff |
---|
| 34 | +#define SKB_VLAN_PRESENT 1 |
---|
42 | 35 | #define SKB_DEV_IFINDEX 577 |
---|
43 | 36 | #define SKB_DEV_TYPE 588 |
---|
44 | 37 | |
---|
.. | .. |
---|
725 | 718 | CLASSIC, |
---|
726 | 719 | { }, |
---|
727 | 720 | { |
---|
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 } |
---|
730 | 723 | }, |
---|
731 | 724 | }, |
---|
732 | 725 | { |
---|
.. | .. |
---|
739 | 732 | CLASSIC, |
---|
740 | 733 | { }, |
---|
741 | 734 | { |
---|
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 } |
---|
744 | 737 | }, |
---|
745 | 738 | }, |
---|
746 | 739 | { |
---|
.. | .. |
---|
874 | 867 | }, |
---|
875 | 868 | CLASSIC, |
---|
876 | 869 | { }, |
---|
877 | | - { { 4, 10 ^ 300 }, { 20, 10 ^ 300 } }, |
---|
| 870 | + { { 4, 0xA ^ 300 }, { 20, 0xA ^ 300 } }, |
---|
878 | 871 | }, |
---|
879 | 872 | { |
---|
880 | 873 | "SPILL_FILL", |
---|
.. | .. |
---|
5282 | 5275 | { /* Mainly checking JIT here. */ |
---|
5283 | 5276 | "BPF_MAXINSNS: Ctx heavy transformations", |
---|
5284 | 5277 | { }, |
---|
5285 | | -#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_S390) |
---|
5286 | | - CLASSIC | FLAG_EXPECTED_FAIL, |
---|
5287 | | -#else |
---|
5288 | 5278 | CLASSIC, |
---|
5289 | | -#endif |
---|
5290 | 5279 | { }, |
---|
5291 | 5280 | { |
---|
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 } |
---|
5294 | 5283 | }, |
---|
5295 | 5284 | .fill_helper = bpf_fill_maxinsns6, |
---|
5296 | | - .expected_errcode = -ENOTSUPP, |
---|
5297 | 5285 | }, |
---|
5298 | 5286 | { /* Mainly checking JIT here. */ |
---|
5299 | 5287 | "BPF_MAXINSNS: Call heavy transformations", |
---|
5300 | 5288 | { }, |
---|
5301 | | -#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_S390) |
---|
5302 | | - CLASSIC | FLAG_NO_DATA | FLAG_EXPECTED_FAIL, |
---|
5303 | | -#else |
---|
5304 | 5289 | CLASSIC | FLAG_NO_DATA, |
---|
5305 | | -#endif |
---|
5306 | 5290 | { }, |
---|
5307 | 5291 | { { 1, 0 }, { 10, 0 } }, |
---|
5308 | 5292 | .fill_helper = bpf_fill_maxinsns7, |
---|
5309 | | - .expected_errcode = -ENOTSUPP, |
---|
5310 | 5293 | }, |
---|
5311 | 5294 | { /* Mainly checking JIT here. */ |
---|
5312 | 5295 | "BPF_MAXINSNS: Jump heavy test", |
---|
.. | .. |
---|
5357 | 5340 | { |
---|
5358 | 5341 | "BPF_MAXINSNS: exec all MSH", |
---|
5359 | 5342 | { }, |
---|
5360 | | -#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_S390) |
---|
5361 | | - CLASSIC | FLAG_EXPECTED_FAIL, |
---|
5362 | | -#else |
---|
5363 | 5343 | CLASSIC, |
---|
5364 | | -#endif |
---|
5365 | 5344 | { 0xfa, 0xfb, 0xfc, 0xfd, }, |
---|
5366 | 5345 | { { 4, 0xababab83 } }, |
---|
5367 | 5346 | .fill_helper = bpf_fill_maxinsns13, |
---|
5368 | | - .expected_errcode = -ENOTSUPP, |
---|
5369 | 5347 | }, |
---|
5370 | 5348 | { |
---|
5371 | 5349 | "BPF_MAXINSNS: ld_abs+get_processor_id", |
---|
5372 | 5350 | { }, |
---|
5373 | | -#if defined(CONFIG_BPF_JIT_ALWAYS_ON) && defined(CONFIG_S390) |
---|
5374 | | - CLASSIC | FLAG_EXPECTED_FAIL, |
---|
5375 | | -#else |
---|
5376 | 5351 | CLASSIC, |
---|
5377 | | -#endif |
---|
5378 | 5352 | { }, |
---|
5379 | 5353 | { { 1, 0xbee } }, |
---|
5380 | 5354 | .fill_helper = bpf_fill_ld_abs_get_processor_id, |
---|
5381 | | - .expected_errcode = -ENOTSUPP, |
---|
5382 | 5355 | }, |
---|
5383 | 5356 | /* |
---|
5384 | 5357 | * LD_IND / LD_ABS on fragmented SKBs |
---|
.. | .. |
---|
6493 | 6466 | skb->hash = SKB_HASH; |
---|
6494 | 6467 | skb->queue_mapping = SKB_QUEUE_MAP; |
---|
6495 | 6468 | skb->vlan_tci = SKB_VLAN_TCI; |
---|
| 6469 | + skb->vlan_present = SKB_VLAN_PRESENT; |
---|
6496 | 6470 | skb->vlan_proto = htons(ETH_P_IP); |
---|
| 6471 | + dev_net_set(&dev, &init_net); |
---|
6497 | 6472 | skb->dev = &dev; |
---|
6498 | 6473 | skb->dev->ifindex = SKB_DEV_IFINDEX; |
---|
6499 | 6474 | skb->dev->type = SKB_DEV_TYPE; |
---|
.. | .. |
---|
6665 | 6640 | u64 start, finish; |
---|
6666 | 6641 | int ret = 0, i; |
---|
6667 | 6642 | |
---|
| 6643 | + migrate_disable(); |
---|
6668 | 6644 | start = ktime_get_ns(); |
---|
6669 | 6645 | |
---|
6670 | 6646 | for (i = 0; i < runs; i++) |
---|
6671 | 6647 | ret = BPF_PROG_RUN(fp, data); |
---|
6672 | 6648 | |
---|
6673 | 6649 | finish = ktime_get_ns(); |
---|
| 6650 | + migrate_enable(); |
---|
6674 | 6651 | |
---|
6675 | 6652 | *duration = finish - start; |
---|
6676 | 6653 | do_div(*duration, runs); |
---|
.. | .. |
---|
6869 | 6846 | return NULL; |
---|
6870 | 6847 | } |
---|
6871 | 6848 | |
---|
6872 | | -static __init int test_skb_segment(void) |
---|
| 6849 | +static __init struct sk_buff *build_test_skb_linear_no_head_frag(void) |
---|
6873 | 6850 | { |
---|
| 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); |
---|
6874 | 6906 | 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 | +{ |
---|
6875 | 6929 | struct sk_buff *skb, *segs; |
---|
6876 | 6930 | int ret = -1; |
---|
6877 | 6931 | |
---|
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(); |
---|
6882 | 6933 | if (!skb) { |
---|
6883 | 6934 | pr_info("%s: failed to build_test_skb", __func__); |
---|
6884 | 6935 | goto done; |
---|
6885 | 6936 | } |
---|
6886 | 6937 | |
---|
6887 | | - segs = skb_segment(skb, features); |
---|
| 6938 | + segs = skb_segment(skb, test->features); |
---|
6888 | 6939 | if (!IS_ERR(segs)) { |
---|
6889 | 6940 | kfree_skb_list(segs); |
---|
6890 | 6941 | ret = 0; |
---|
6891 | | - pr_info("%s: success in skb_segment!", __func__); |
---|
6892 | | - } else { |
---|
6893 | | - pr_info("%s: failed in skb_segment!", __func__); |
---|
6894 | 6942 | } |
---|
6895 | 6943 | kfree_skb(skb); |
---|
6896 | 6944 | done: |
---|
6897 | 6945 | return ret; |
---|
6898 | 6946 | } |
---|
6899 | 6947 | |
---|
| 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 | + |
---|
6900 | 6971 | static __init int test_bpf(void) |
---|
6901 | 6972 | { |
---|
6902 | 6973 | int i, err_cnt = 0, pass_cnt = 0; |
---|