1 // SPDX-License-Identifier: GPL-2.0
2 #include <test_progs.h>
4 #define CHECK_FLOW_KEYS(desc, got, expected) \
5 CHECK(memcmp(&got, &expected, sizeof(got)) != 0, \
9 "addr_proto=0x%x/0x%x " \
11 "is_first_frag=%u/%u " \
13 "n_proto=0x%x/0x%x " \
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)
26 static struct bpf_flow_keys pkt_v4_flow_keys
= {
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
),
34 static struct bpf_flow_keys pkt_v6_flow_keys
= {
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
),
50 } __packed pkt_vlan_v4
= {
51 .eth
.h_proto
= __bpf_constant_htons(ETH_P_8021Q
),
52 .vlan_proto
= __bpf_constant_htons(ETH_P_IP
),
54 .iph
.protocol
= IPPROTO_TCP
,
55 .iph
.tot_len
= __bpf_constant_htons(MAGIC_BYTES
),
60 static struct bpf_flow_keys pkt_vlan_v4_flow_keys
= {
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
),
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
),
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
),
94 void test_flow_dissector(void)
96 struct bpf_flow_keys flow_keys
;
97 struct bpf_object
*obj
;
98 __u32 duration
, retval
;
102 err
= bpf_flow_load(&obj
, "./bpf_flow.o", "flow_dissector",
103 "jmp_table", &prog_fd
);
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
);
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
);
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
);
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
);
139 bpf_object__close(obj
);