Merge tag 's390-5.2-1' of git://git.kernel.org/pub/scm/linux/kernel/git/s390/linux
[linux-2.6-microblaze.git] / tools / testing / selftests / bpf / prog_tests / flow_dissector.c
1 // SPDX-License-Identifier: GPL-2.0
2 #include <test_progs.h>
3
4 #define CHECK_FLOW_KEYS(desc, got, expected)                            \
5         CHECK(memcmp(&got, &expected, sizeof(got)) != 0,                \
6               desc,                                                     \
7               "nhoff=%u/%u "                                            \
8               "thoff=%u/%u "                                            \
9               "addr_proto=0x%x/0x%x "                                   \
10               "is_frag=%u/%u "                                          \
11               "is_first_frag=%u/%u "                                    \
12               "is_encap=%u/%u "                                         \
13               "n_proto=0x%x/0x%x "                                      \
14               "sport=%u/%u "                                            \
15               "dport=%u/%u\n",                                          \
16               got.nhoff, expected.nhoff,                                \
17               got.thoff, expected.thoff,                                \
18               got.addr_proto, expected.addr_proto,                      \
19               got.is_frag, expected.is_frag,                            \
20               got.is_first_frag, expected.is_first_frag,                \
21               got.is_encap, expected.is_encap,                          \
22               got.n_proto, expected.n_proto,                            \
23               got.sport, expected.sport,                                \
24               got.dport, expected.dport)
25
26 static struct bpf_flow_keys pkt_v4_flow_keys = {
27         .nhoff = 0,
28         .thoff = sizeof(struct iphdr),
29         .addr_proto = ETH_P_IP,
30         .ip_proto = IPPROTO_TCP,
31         .n_proto = __bpf_constant_htons(ETH_P_IP),
32 };
33
34 static struct bpf_flow_keys pkt_v6_flow_keys = {
35         .nhoff = 0,
36         .thoff = sizeof(struct ipv6hdr),
37         .addr_proto = ETH_P_IPV6,
38         .ip_proto = IPPROTO_TCP,
39         .n_proto = __bpf_constant_htons(ETH_P_IPV6),
40 };
41
42 #define VLAN_HLEN       4
43
44 static struct {
45         struct ethhdr eth;
46         __u16 vlan_tci;
47         __u16 vlan_proto;
48         struct iphdr iph;
49         struct tcphdr tcp;
50 } __packed pkt_vlan_v4 = {
51         .eth.h_proto = __bpf_constant_htons(ETH_P_8021Q),
52         .vlan_proto = __bpf_constant_htons(ETH_P_IP),
53         .iph.ihl = 5,
54         .iph.protocol = IPPROTO_TCP,
55         .iph.tot_len = __bpf_constant_htons(MAGIC_BYTES),
56         .tcp.urg_ptr = 123,
57         .tcp.doff = 5,
58 };
59
60 static struct bpf_flow_keys pkt_vlan_v4_flow_keys = {
61         .nhoff = VLAN_HLEN,
62         .thoff = VLAN_HLEN + sizeof(struct iphdr),
63         .addr_proto = ETH_P_IP,
64         .ip_proto = IPPROTO_TCP,
65         .n_proto = __bpf_constant_htons(ETH_P_IP),
66 };
67
68 static struct {
69         struct ethhdr eth;
70         __u16 vlan_tci;
71         __u16 vlan_proto;
72         __u16 vlan_tci2;
73         __u16 vlan_proto2;
74         struct ipv6hdr iph;
75         struct tcphdr tcp;
76 } __packed pkt_vlan_v6 = {
77         .eth.h_proto = __bpf_constant_htons(ETH_P_8021AD),
78         .vlan_proto = __bpf_constant_htons(ETH_P_8021Q),
79         .vlan_proto2 = __bpf_constant_htons(ETH_P_IPV6),
80         .iph.nexthdr = IPPROTO_TCP,
81         .iph.payload_len = __bpf_constant_htons(MAGIC_BYTES),
82         .tcp.urg_ptr = 123,
83         .tcp.doff = 5,
84 };
85
86 static struct bpf_flow_keys pkt_vlan_v6_flow_keys = {
87         .nhoff = VLAN_HLEN * 2,
88         .thoff = VLAN_HLEN * 2 + sizeof(struct ipv6hdr),
89         .addr_proto = ETH_P_IPV6,
90         .ip_proto = IPPROTO_TCP,
91         .n_proto = __bpf_constant_htons(ETH_P_IPV6),
92 };
93
94 void test_flow_dissector(void)
95 {
96         struct bpf_flow_keys flow_keys;
97         struct bpf_object *obj;
98         __u32 duration, retval;
99         int err, prog_fd;
100         __u32 size;
101
102         err = bpf_flow_load(&obj, "./bpf_flow.o", "flow_dissector",
103                             "jmp_table", &prog_fd);
104         if (err) {
105                 error_cnt++;
106                 return;
107         }
108
109         err = bpf_prog_test_run(prog_fd, 10, &pkt_v4, sizeof(pkt_v4),
110                                 &flow_keys, &size, &retval, &duration);
111         CHECK(size != sizeof(flow_keys) || err || retval != 1, "ipv4",
112               "err %d errno %d retval %d duration %d size %u/%lu\n",
113               err, errno, retval, duration, size, sizeof(flow_keys));
114         CHECK_FLOW_KEYS("ipv4_flow_keys", flow_keys, pkt_v4_flow_keys);
115
116         err = bpf_prog_test_run(prog_fd, 10, &pkt_v6, sizeof(pkt_v6),
117                                 &flow_keys, &size, &retval, &duration);
118         CHECK(size != sizeof(flow_keys) || err || retval != 1, "ipv6",
119               "err %d errno %d retval %d duration %d size %u/%lu\n",
120               err, errno, retval, duration, size, sizeof(flow_keys));
121         CHECK_FLOW_KEYS("ipv6_flow_keys", flow_keys, pkt_v6_flow_keys);
122
123         err = bpf_prog_test_run(prog_fd, 10, &pkt_vlan_v4, sizeof(pkt_vlan_v4),
124                                 &flow_keys, &size, &retval, &duration);
125         CHECK(size != sizeof(flow_keys) || err || retval != 1, "vlan_ipv4",
126               "err %d errno %d retval %d duration %d size %u/%lu\n",
127               err, errno, retval, duration, size, sizeof(flow_keys));
128         CHECK_FLOW_KEYS("vlan_ipv4_flow_keys", flow_keys,
129                         pkt_vlan_v4_flow_keys);
130
131         err = bpf_prog_test_run(prog_fd, 10, &pkt_vlan_v6, sizeof(pkt_vlan_v6),
132                                 &flow_keys, &size, &retval, &duration);
133         CHECK(size != sizeof(flow_keys) || err || retval != 1, "vlan_ipv6",
134               "err %d errno %d retval %d duration %d size %u/%lu\n",
135               err, errno, retval, duration, size, sizeof(flow_keys));
136         CHECK_FLOW_KEYS("vlan_ipv6_flow_keys", flow_keys,
137                         pkt_vlan_v6_flow_keys);
138
139         bpf_object__close(obj);
140 }