aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDaniel Borkmann <daniel@iogearbox.net>2018-04-26 18:11:15 -0400
committerDaniel Borkmann <daniel@iogearbox.net>2018-04-26 18:11:16 -0400
commit3f13de6d6f3cfabbc94e7e6495540cca46a8682f (patch)
tree25452421c187400bbf655d09425bd64e1f5a739f
parentf761312023a1f0d625e34daadd54c3f9cb2a4ac2 (diff)
parentb05cd74043236e7427a71fc7c59deee4588a7c91 (diff)
Merge branch 'bpf-tunnel-metadata-selftests'
William Tu says: ==================== The patch series provide end-to-end eBPF tunnel testsute. A common topology is created below for all types of tunnels: Topology: --------- root namespace | at_ns0 namespace | ----------- | ----------- | tnl dev | | | tnl dev | (overlay network) ----------- | ----------- metadata-mode | native-mode with bpf | | ---------- | ---------- | veth1 | --------- | veth0 | (underlay network) ---------- peer ---------- Device Configuration -------------------- Root namespace with metadata-mode tunnel + BPF Device names and addresses: veth1 IP: 172.16.1.200, IPv6: 00::22 (underlay) tunnel dev <type>11, ex: gre11, IPv4: 10.1.1.200 (overlay) Namespace at_ns0 with native tunnel Device names and addresses: veth0 IPv4: 172.16.1.100, IPv6: 00::11 (underlay) tunnel dev <type>00, ex: gre00, IPv4: 10.1.1.100 (overlay) End-to-end ping packet flow --------------------------- Most of the tests start by namespace creation, device configuration, then ping the underlay and overlay network. When doing 'ping 10.1.1.100' from root namespace, the following operations happen: 1) Route lookup shows 10.1.1.100/24 belongs to tnl dev, fwd to tnl dev. 2) Tnl device's egress BPF program is triggered and set the tunnel metadata, with remote_ip=172.16.1.200 and others. 3) Outer tunnel header is prepended and route the packet to veth1's egress 4) veth0's ingress queue receive the tunneled packet at namespace at_ns0 5) Tunnel protocol handler, ex: vxlan_rcv, decap the packet 6) Forward the packet to the overlay tnl dev Test Cases ----------------------------- Tunnel Type | BPF Programs ----------------------------- GRE: gre_set_tunnel, gre_get_tunnel IP6GRE: ip6gretap_set_tunnel, ip6gretap_get_tunnel ERSPAN: erspan_set_tunnel, erspan_get_tunnel IP6ERSPAN: ip4ip6erspan_set_tunnel, ip4ip6erspan_get_tunnel VXLAN: vxlan_set_tunnel, vxlan_get_tunnel IP6VXLAN: ip6vxlan_set_tunnel, ip6vxlan_get_tunnel GENEVE: geneve_set_tunnel, geneve_get_tunnel IP6GENEVE: ip6geneve_set_tunnel, ip6geneve_get_tunnel IPIP: ipip_set_tunnel, ipip_get_tunnel IP6IP: ipip6_set_tunnel, ipip6_get_tunnel, ip6ip6_set_tunnel, ip6ip6_get_tunnel XFRM: xfrm_get_state ==================== Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
-rw-r--r--samples/bpf/Makefile1
-rwxr-xr-xsamples/bpf/test_tunnel_bpf.sh390
-rw-r--r--tools/testing/selftests/bpf/Makefile5
-rwxr-xr-xtools/testing/selftests/bpf/test_tunnel.sh729
-rw-r--r--tools/testing/selftests/bpf/test_tunnel_kern.c (renamed from samples/bpf/tcbpf2_kern.c)247
5 files changed, 906 insertions, 466 deletions
diff --git a/samples/bpf/Makefile b/samples/bpf/Makefile
index aa8c392e2e52..b853581592fd 100644
--- a/samples/bpf/Makefile
+++ b/samples/bpf/Makefile
@@ -114,7 +114,6 @@ always += sock_flags_kern.o
114always += test_probe_write_user_kern.o 114always += test_probe_write_user_kern.o
115always += trace_output_kern.o 115always += trace_output_kern.o
116always += tcbpf1_kern.o 116always += tcbpf1_kern.o
117always += tcbpf2_kern.o
118always += tc_l2_redirect_kern.o 117always += tc_l2_redirect_kern.o
119always += lathist_kern.o 118always += lathist_kern.o
120always += offwaketime_kern.o 119always += offwaketime_kern.o
diff --git a/samples/bpf/test_tunnel_bpf.sh b/samples/bpf/test_tunnel_bpf.sh
deleted file mode 100755
index 9c534dc07b36..000000000000
--- a/samples/bpf/test_tunnel_bpf.sh
+++ /dev/null
@@ -1,390 +0,0 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3# In Namespace 0 (at_ns0) using native tunnel
4# Overlay IP: 10.1.1.100
5# local 192.16.1.100 remote 192.16.1.200
6# veth0 IP: 172.16.1.100, tunnel dev <type>00
7
8# Out of Namespace using BPF set/get on lwtunnel
9# Overlay IP: 10.1.1.200
10# local 172.16.1.200 remote 172.16.1.100
11# veth1 IP: 172.16.1.200, tunnel dev <type>11
12
13function config_device {
14 ip netns add at_ns0
15 ip link add veth0 type veth peer name veth1
16 ip link set veth0 netns at_ns0
17 ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0
18 ip netns exec at_ns0 ip link set dev veth0 up
19 ip link set dev veth1 up mtu 1500
20 ip addr add dev veth1 172.16.1.200/24
21}
22
23function add_gre_tunnel {
24 # in namespace
25 ip netns exec at_ns0 \
26 ip link add dev $DEV_NS type $TYPE seq key 2 \
27 local 172.16.1.100 remote 172.16.1.200
28 ip netns exec at_ns0 ip link set dev $DEV_NS up
29 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
30
31 # out of namespace
32 ip link add dev $DEV type $TYPE key 2 external
33 ip link set dev $DEV up
34 ip addr add dev $DEV 10.1.1.200/24
35}
36
37function add_ip6gretap_tunnel {
38
39 # assign ipv6 address
40 ip netns exec at_ns0 ip addr add ::11/96 dev veth0
41 ip netns exec at_ns0 ip link set dev veth0 up
42 ip addr add dev veth1 ::22/96
43 ip link set dev veth1 up
44
45 # in namespace
46 ip netns exec at_ns0 \
47 ip link add dev $DEV_NS type $TYPE seq flowlabel 0xbcdef key 2 \
48 local ::11 remote ::22
49
50 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
51 ip netns exec at_ns0 ip addr add dev $DEV_NS fc80::100/96
52 ip netns exec at_ns0 ip link set dev $DEV_NS up
53
54 # out of namespace
55 ip link add dev $DEV type $TYPE external
56 ip addr add dev $DEV 10.1.1.200/24
57 ip addr add dev $DEV fc80::200/24
58 ip link set dev $DEV up
59}
60
61function add_erspan_tunnel {
62 # in namespace
63 if [ "$1" == "v1" ]; then
64 ip netns exec at_ns0 \
65 ip link add dev $DEV_NS type $TYPE seq key 2 \
66 local 172.16.1.100 remote 172.16.1.200 \
67 erspan_ver 1 erspan 123
68 else
69 ip netns exec at_ns0 \
70 ip link add dev $DEV_NS type $TYPE seq key 2 \
71 local 172.16.1.100 remote 172.16.1.200 \
72 erspan_ver 2 erspan_dir egress erspan_hwid 3
73 fi
74 ip netns exec at_ns0 ip link set dev $DEV_NS up
75 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
76
77 # out of namespace
78 ip link add dev $DEV type $TYPE external
79 ip link set dev $DEV up
80 ip addr add dev $DEV 10.1.1.200/24
81}
82
83function add_ip6erspan_tunnel {
84
85 # assign ipv6 address
86 ip netns exec at_ns0 ip addr add ::11/96 dev veth0
87 ip netns exec at_ns0 ip link set dev veth0 up
88 ip addr add dev veth1 ::22/96
89 ip link set dev veth1 up
90
91 # in namespace
92 if [ "$1" == "v1" ]; then
93 ip netns exec at_ns0 \
94 ip link add dev $DEV_NS type $TYPE seq key 2 \
95 local ::11 remote ::22 \
96 erspan_ver 1 erspan 123
97 else
98 ip netns exec at_ns0 \
99 ip link add dev $DEV_NS type $TYPE seq key 2 \
100 local ::11 remote ::22 \
101 erspan_ver 2 erspan_dir egress erspan_hwid 7
102 fi
103 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
104 ip netns exec at_ns0 ip link set dev $DEV_NS up
105
106 # out of namespace
107 ip link add dev $DEV type $TYPE external
108 ip addr add dev $DEV 10.1.1.200/24
109 ip link set dev $DEV up
110}
111
112function add_vxlan_tunnel {
113 # Set static ARP entry here because iptables set-mark works
114 # on L3 packet, as a result not applying to ARP packets,
115 # causing errors at get_tunnel_{key/opt}.
116
117 # in namespace
118 ip netns exec at_ns0 \
119 ip link add dev $DEV_NS type $TYPE id 2 dstport 4789 gbp remote 172.16.1.200
120 ip netns exec at_ns0 ip link set dev $DEV_NS address 52:54:00:d9:01:00 up
121 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
122 ip netns exec at_ns0 arp -s 10.1.1.200 52:54:00:d9:02:00
123 ip netns exec at_ns0 iptables -A OUTPUT -j MARK --set-mark 0x800FF
124
125 # out of namespace
126 ip link add dev $DEV type $TYPE external gbp dstport 4789
127 ip link set dev $DEV address 52:54:00:d9:02:00 up
128 ip addr add dev $DEV 10.1.1.200/24
129 arp -s 10.1.1.100 52:54:00:d9:01:00
130}
131
132function add_geneve_tunnel {
133 # in namespace
134 ip netns exec at_ns0 \
135 ip link add dev $DEV_NS type $TYPE id 2 dstport 6081 remote 172.16.1.200
136 ip netns exec at_ns0 ip link set dev $DEV_NS up
137 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
138
139 # out of namespace
140 ip link add dev $DEV type $TYPE dstport 6081 external
141 ip link set dev $DEV up
142 ip addr add dev $DEV 10.1.1.200/24
143}
144
145function add_ipip_tunnel {
146 # in namespace
147 ip netns exec at_ns0 \
148 ip link add dev $DEV_NS type $TYPE local 172.16.1.100 remote 172.16.1.200
149 ip netns exec at_ns0 ip link set dev $DEV_NS up
150 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
151
152 # out of namespace
153 ip link add dev $DEV type $TYPE external
154 ip link set dev $DEV up
155 ip addr add dev $DEV 10.1.1.200/24
156}
157
158function setup_xfrm_tunnel {
159 auth=0x$(printf '1%.0s' {1..40})
160 enc=0x$(printf '2%.0s' {1..32})
161 spi_in_to_out=0x1
162 spi_out_to_in=0x2
163 # in namespace
164 # in -> out
165 ip netns exec at_ns0 \
166 ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
167 spi $spi_in_to_out reqid 1 mode tunnel \
168 auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
169 ip netns exec at_ns0 \
170 ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir out \
171 tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
172 mode tunnel
173 # out -> in
174 ip netns exec at_ns0 \
175 ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
176 spi $spi_out_to_in reqid 2 mode tunnel \
177 auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
178 ip netns exec at_ns0 \
179 ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir in \
180 tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
181 mode tunnel
182 # address & route
183 ip netns exec at_ns0 \
184 ip addr add dev veth0 10.1.1.100/32
185 ip netns exec at_ns0 \
186 ip route add 10.1.1.200 dev veth0 via 172.16.1.200 \
187 src 10.1.1.100
188
189 # out of namespace
190 # in -> out
191 ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
192 spi $spi_in_to_out reqid 1 mode tunnel \
193 auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
194 ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir in \
195 tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
196 mode tunnel
197 # out -> in
198 ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
199 spi $spi_out_to_in reqid 2 mode tunnel \
200 auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
201 ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir out \
202 tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
203 mode tunnel
204 # address & route
205 ip addr add dev veth1 10.1.1.200/32
206 ip route add 10.1.1.100 dev veth1 via 172.16.1.100 src 10.1.1.200
207}
208
209function attach_bpf {
210 DEV=$1
211 SET_TUNNEL=$2
212 GET_TUNNEL=$3
213 tc qdisc add dev $DEV clsact
214 tc filter add dev $DEV egress bpf da obj tcbpf2_kern.o sec $SET_TUNNEL
215 tc filter add dev $DEV ingress bpf da obj tcbpf2_kern.o sec $GET_TUNNEL
216}
217
218function test_gre {
219 TYPE=gretap
220 DEV_NS=gretap00
221 DEV=gretap11
222 config_device
223 add_gre_tunnel
224 attach_bpf $DEV gre_set_tunnel gre_get_tunnel
225 ping -c 1 10.1.1.100
226 ip netns exec at_ns0 ping -c 1 10.1.1.200
227 cleanup
228}
229
230function test_ip6gre {
231 TYPE=ip6gre
232 DEV_NS=ip6gre00
233 DEV=ip6gre11
234 config_device
235 # reuse the ip6gretap function
236 add_ip6gretap_tunnel
237 attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
238 # underlay
239 ping6 -c 4 ::11
240 # overlay: ipv4 over ipv6
241 ip netns exec at_ns0 ping -c 1 10.1.1.200
242 ping -c 1 10.1.1.100
243 # overlay: ipv6 over ipv6
244 ip netns exec at_ns0 ping6 -c 1 fc80::200
245 cleanup
246}
247
248function test_ip6gretap {
249 TYPE=ip6gretap
250 DEV_NS=ip6gretap00
251 DEV=ip6gretap11
252 config_device
253 add_ip6gretap_tunnel
254 attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
255 # underlay
256 ping6 -c 4 ::11
257 # overlay: ipv4 over ipv6
258 ip netns exec at_ns0 ping -i .2 -c 1 10.1.1.200
259 ping -c 1 10.1.1.100
260 # overlay: ipv6 over ipv6
261 ip netns exec at_ns0 ping6 -c 1 fc80::200
262 cleanup
263}
264
265function test_erspan {
266 TYPE=erspan
267 DEV_NS=erspan00
268 DEV=erspan11
269 config_device
270 add_erspan_tunnel $1
271 attach_bpf $DEV erspan_set_tunnel erspan_get_tunnel
272 ping -c 1 10.1.1.100
273 ip netns exec at_ns0 ping -c 1 10.1.1.200
274 cleanup
275}
276
277function test_ip6erspan {
278 TYPE=ip6erspan
279 DEV_NS=ip6erspan00
280 DEV=ip6erspan11
281 config_device
282 add_ip6erspan_tunnel $1
283 attach_bpf $DEV ip4ip6erspan_set_tunnel ip4ip6erspan_get_tunnel
284 ping6 -c 3 ::11
285 ip netns exec at_ns0 ping -c 1 10.1.1.200
286 cleanup
287}
288
289function test_vxlan {
290 TYPE=vxlan
291 DEV_NS=vxlan00
292 DEV=vxlan11
293 config_device
294 add_vxlan_tunnel
295 attach_bpf $DEV vxlan_set_tunnel vxlan_get_tunnel
296 ping -c 1 10.1.1.100
297 ip netns exec at_ns0 ping -c 1 10.1.1.200
298 cleanup
299}
300
301function test_geneve {
302 TYPE=geneve
303 DEV_NS=geneve00
304 DEV=geneve11
305 config_device
306 add_geneve_tunnel
307 attach_bpf $DEV geneve_set_tunnel geneve_get_tunnel
308 ping -c 1 10.1.1.100
309 ip netns exec at_ns0 ping -c 1 10.1.1.200
310 cleanup
311}
312
313function test_ipip {
314 TYPE=ipip
315 DEV_NS=ipip00
316 DEV=ipip11
317 config_device
318 tcpdump -nei veth1 &
319 cat /sys/kernel/debug/tracing/trace_pipe &
320 add_ipip_tunnel
321 ethtool -K veth1 gso off gro off rx off tx off
322 ip link set dev veth1 mtu 1500
323 attach_bpf $DEV ipip_set_tunnel ipip_get_tunnel
324 ping -c 1 10.1.1.100
325 ip netns exec at_ns0 ping -c 1 10.1.1.200
326 ip netns exec at_ns0 iperf -sD -p 5200 > /dev/null
327 sleep 0.2
328 iperf -c 10.1.1.100 -n 5k -p 5200
329 cleanup
330}
331
332function test_xfrm_tunnel {
333 config_device
334 tcpdump -nei veth1 ip &
335 output=$(mktemp)
336 cat /sys/kernel/debug/tracing/trace_pipe | tee $output &
337 setup_xfrm_tunnel
338 tc qdisc add dev veth1 clsact
339 tc filter add dev veth1 proto ip ingress bpf da obj tcbpf2_kern.o \
340 sec xfrm_get_state
341 ip netns exec at_ns0 ping -c 1 10.1.1.200
342 grep "reqid 1" $output
343 grep "spi 0x1" $output
344 grep "remote ip 0xac100164" $output
345 cleanup
346}
347
348function cleanup {
349 set +ex
350 pkill iperf
351 ip netns delete at_ns0
352 ip link del veth1
353 ip link del ipip11
354 ip link del gretap11
355 ip link del ip6gre11
356 ip link del ip6gretap11
357 ip link del vxlan11
358 ip link del geneve11
359 ip link del erspan11
360 ip link del ip6erspan11
361 ip x s flush
362 ip x p flush
363 pkill tcpdump
364 pkill cat
365 set -ex
366}
367
368trap cleanup 0 2 3 6 9
369cleanup
370echo "Testing GRE tunnel..."
371test_gre
372echo "Testing IP6GRE tunnel..."
373test_ip6gre
374echo "Testing IP6GRETAP tunnel..."
375test_ip6gretap
376echo "Testing ERSPAN tunnel..."
377test_erspan v1
378test_erspan v2
379echo "Testing IP6ERSPAN tunnel..."
380test_ip6erspan v1
381test_ip6erspan v2
382echo "Testing VXLAN tunnel..."
383test_vxlan
384echo "Testing GENEVE tunnel..."
385test_geneve
386echo "Testing IPIP tunnel..."
387test_ipip
388echo "Testing IPSec tunnel..."
389test_xfrm_tunnel
390echo "*** PASS ***"
diff --git a/tools/testing/selftests/bpf/Makefile b/tools/testing/selftests/bpf/Makefile
index 0c19d5e08f08..b64a7a39cbc8 100644
--- a/tools/testing/selftests/bpf/Makefile
+++ b/tools/testing/selftests/bpf/Makefile
@@ -32,7 +32,7 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
32 test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \ 32 test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \
33 sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \ 33 sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \
34 sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o \ 34 sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o \
35 test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o 35 test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o
36 36
37# Order correspond to 'make run_tests' order 37# Order correspond to 'make run_tests' order
38TEST_PROGS := test_kmod.sh \ 38TEST_PROGS := test_kmod.sh \
@@ -40,7 +40,8 @@ TEST_PROGS := test_kmod.sh \
40 test_xdp_redirect.sh \ 40 test_xdp_redirect.sh \
41 test_xdp_meta.sh \ 41 test_xdp_meta.sh \
42 test_offload.py \ 42 test_offload.py \
43 test_sock_addr.sh 43 test_sock_addr.sh \
44 test_tunnel.sh
44 45
45# Compile but not part of 'make run_tests' 46# Compile but not part of 'make run_tests'
46TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr 47TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr
diff --git a/tools/testing/selftests/bpf/test_tunnel.sh b/tools/testing/selftests/bpf/test_tunnel.sh
new file mode 100755
index 000000000000..aeb2901f21f4
--- /dev/null
+++ b/tools/testing/selftests/bpf/test_tunnel.sh
@@ -0,0 +1,729 @@
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# End-to-end eBPF tunnel test suite
5# The script tests BPF network tunnel implementation.
6#
7# Topology:
8# ---------
9# root namespace | at_ns0 namespace
10# |
11# ----------- | -----------
12# | tnl dev | | | tnl dev | (overlay network)
13# ----------- | -----------
14# metadata-mode | native-mode
15# with bpf |
16# |
17# ---------- | ----------
18# | veth1 | --------- | veth0 | (underlay network)
19# ---------- peer ----------
20#
21#
22# Device Configuration
23# --------------------
24# Root namespace with metadata-mode tunnel + BPF
25# Device names and addresses:
26# veth1 IP: 172.16.1.200, IPv6: 00::22 (underlay)
27# tunnel dev <type>11, ex: gre11, IPv4: 10.1.1.200 (overlay)
28#
29# Namespace at_ns0 with native tunnel
30# Device names and addresses:
31# veth0 IPv4: 172.16.1.100, IPv6: 00::11 (underlay)
32# tunnel dev <type>00, ex: gre00, IPv4: 10.1.1.100 (overlay)
33#
34#
35# End-to-end ping packet flow
36# ---------------------------
37# Most of the tests start by namespace creation, device configuration,
38# then ping the underlay and overlay network. When doing 'ping 10.1.1.100'
39# from root namespace, the following operations happen:
40# 1) Route lookup shows 10.1.1.100/24 belongs to tnl dev, fwd to tnl dev.
41# 2) Tnl device's egress BPF program is triggered and set the tunnel metadata,
42# with remote_ip=172.16.1.200 and others.
43# 3) Outer tunnel header is prepended and route the packet to veth1's egress
44# 4) veth0's ingress queue receive the tunneled packet at namespace at_ns0
45# 5) Tunnel protocol handler, ex: vxlan_rcv, decap the packet
46# 6) Forward the packet to the overlay tnl dev
47
48PING_ARG="-c 3 -w 10 -q"
49ret=0
50GREEN='\033[0;92m'
51RED='\033[0;31m'
52NC='\033[0m' # No Color
53
54config_device()
55{
56 ip netns add at_ns0
57 ip link add veth0 type veth peer name veth1
58 ip link set veth0 netns at_ns0
59 ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0
60 ip netns exec at_ns0 ip link set dev veth0 up
61 ip link set dev veth1 up mtu 1500
62 ip addr add dev veth1 172.16.1.200/24
63}
64
65add_gre_tunnel()
66{
67 # at_ns0 namespace
68 ip netns exec at_ns0 \
69 ip link add dev $DEV_NS type $TYPE seq key 2 \
70 local 172.16.1.100 remote 172.16.1.200
71 ip netns exec at_ns0 ip link set dev $DEV_NS up
72 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
73
74 # root namespace
75 ip link add dev $DEV type $TYPE key 2 external
76 ip link set dev $DEV up
77 ip addr add dev $DEV 10.1.1.200/24
78}
79
80add_ip6gretap_tunnel()
81{
82
83 # assign ipv6 address
84 ip netns exec at_ns0 ip addr add ::11/96 dev veth0
85 ip netns exec at_ns0 ip link set dev veth0 up
86 ip addr add dev veth1 ::22/96
87 ip link set dev veth1 up
88
89 # at_ns0 namespace
90 ip netns exec at_ns0 \
91 ip link add dev $DEV_NS type $TYPE seq flowlabel 0xbcdef key 2 \
92 local ::11 remote ::22
93
94 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
95 ip netns exec at_ns0 ip addr add dev $DEV_NS fc80::100/96
96 ip netns exec at_ns0 ip link set dev $DEV_NS up
97
98 # root namespace
99 ip link add dev $DEV type $TYPE external
100 ip addr add dev $DEV 10.1.1.200/24
101 ip addr add dev $DEV fc80::200/24
102 ip link set dev $DEV up
103}
104
105add_erspan_tunnel()
106{
107 # at_ns0 namespace
108 if [ "$1" == "v1" ]; then
109 ip netns exec at_ns0 \
110 ip link add dev $DEV_NS type $TYPE seq key 2 \
111 local 172.16.1.100 remote 172.16.1.200 \
112 erspan_ver 1 erspan 123
113 else
114 ip netns exec at_ns0 \
115 ip link add dev $DEV_NS type $TYPE seq key 2 \
116 local 172.16.1.100 remote 172.16.1.200 \
117 erspan_ver 2 erspan_dir egress erspan_hwid 3
118 fi
119 ip netns exec at_ns0 ip link set dev $DEV_NS up
120 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
121
122 # root namespace
123 ip link add dev $DEV type $TYPE external
124 ip link set dev $DEV up
125 ip addr add dev $DEV 10.1.1.200/24
126}
127
128add_ip6erspan_tunnel()
129{
130
131 # assign ipv6 address
132 ip netns exec at_ns0 ip addr add ::11/96 dev veth0
133 ip netns exec at_ns0 ip link set dev veth0 up
134 ip addr add dev veth1 ::22/96
135 ip link set dev veth1 up
136
137 # at_ns0 namespace
138 if [ "$1" == "v1" ]; then
139 ip netns exec at_ns0 \
140 ip link add dev $DEV_NS type $TYPE seq key 2 \
141 local ::11 remote ::22 \
142 erspan_ver 1 erspan 123
143 else
144 ip netns exec at_ns0 \
145 ip link add dev $DEV_NS type $TYPE seq key 2 \
146 local ::11 remote ::22 \
147 erspan_ver 2 erspan_dir egress erspan_hwid 7
148 fi
149 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
150 ip netns exec at_ns0 ip link set dev $DEV_NS up
151
152 # root namespace
153 ip link add dev $DEV type $TYPE external
154 ip addr add dev $DEV 10.1.1.200/24
155 ip link set dev $DEV up
156}
157
158add_vxlan_tunnel()
159{
160 # Set static ARP entry here because iptables set-mark works
161 # on L3 packet, as a result not applying to ARP packets,
162 # causing errors at get_tunnel_{key/opt}.
163
164 # at_ns0 namespace
165 ip netns exec at_ns0 \
166 ip link add dev $DEV_NS type $TYPE \
167 id 2 dstport 4789 gbp remote 172.16.1.200
168 ip netns exec at_ns0 \
169 ip link set dev $DEV_NS address 52:54:00:d9:01:00 up
170 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
171 ip netns exec at_ns0 arp -s 10.1.1.200 52:54:00:d9:02:00
172 ip netns exec at_ns0 iptables -A OUTPUT -j MARK --set-mark 0x800FF
173
174 # root namespace
175 ip link add dev $DEV type $TYPE external gbp dstport 4789
176 ip link set dev $DEV address 52:54:00:d9:02:00 up
177 ip addr add dev $DEV 10.1.1.200/24
178 arp -s 10.1.1.100 52:54:00:d9:01:00
179}
180
181add_ip6vxlan_tunnel()
182{
183 #ip netns exec at_ns0 ip -4 addr del 172.16.1.100 dev veth0
184 ip netns exec at_ns0 ip -6 addr add ::11/96 dev veth0
185 ip netns exec at_ns0 ip link set dev veth0 up
186 #ip -4 addr del 172.16.1.200 dev veth1
187 ip -6 addr add dev veth1 ::22/96
188 ip link set dev veth1 up
189
190 # at_ns0 namespace
191 ip netns exec at_ns0 \
192 ip link add dev $DEV_NS type $TYPE id 22 dstport 4789 \
193 local ::11 remote ::22
194 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
195 ip netns exec at_ns0 ip link set dev $DEV_NS up
196
197 # root namespace
198 ip link add dev $DEV type $TYPE external dstport 4789
199 ip addr add dev $DEV 10.1.1.200/24
200 ip link set dev $DEV up
201}
202
203add_geneve_tunnel()
204{
205 # at_ns0 namespace
206 ip netns exec at_ns0 \
207 ip link add dev $DEV_NS type $TYPE \
208 id 2 dstport 6081 remote 172.16.1.200
209 ip netns exec at_ns0 ip link set dev $DEV_NS up
210 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
211
212 # root namespace
213 ip link add dev $DEV type $TYPE dstport 6081 external
214 ip link set dev $DEV up
215 ip addr add dev $DEV 10.1.1.200/24
216}
217
218add_ip6geneve_tunnel()
219{
220 ip netns exec at_ns0 ip addr add ::11/96 dev veth0
221 ip netns exec at_ns0 ip link set dev veth0 up
222 ip addr add dev veth1 ::22/96
223 ip link set dev veth1 up
224
225 # at_ns0 namespace
226 ip netns exec at_ns0 \
227 ip link add dev $DEV_NS type $TYPE id 22 \
228 remote ::22 # geneve has no local option
229 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
230 ip netns exec at_ns0 ip link set dev $DEV_NS up
231
232 # root namespace
233 ip link add dev $DEV type $TYPE external
234 ip addr add dev $DEV 10.1.1.200/24
235 ip link set dev $DEV up
236}
237
238add_ipip_tunnel()
239{
240 # at_ns0 namespace
241 ip netns exec at_ns0 \
242 ip link add dev $DEV_NS type $TYPE \
243 local 172.16.1.100 remote 172.16.1.200
244 ip netns exec at_ns0 ip link set dev $DEV_NS up
245 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
246
247 # root namespace
248 ip link add dev $DEV type $TYPE external
249 ip link set dev $DEV up
250 ip addr add dev $DEV 10.1.1.200/24
251}
252
253add_ipip6tnl_tunnel()
254{
255 ip netns exec at_ns0 ip addr add ::11/96 dev veth0
256 ip netns exec at_ns0 ip link set dev veth0 up
257 ip addr add dev veth1 ::22/96
258 ip link set dev veth1 up
259
260 # at_ns0 namespace
261 ip netns exec at_ns0 \
262 ip link add dev $DEV_NS type $TYPE \
263 local ::11 remote ::22
264 ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
265 ip netns exec at_ns0 ip link set dev $DEV_NS up
266
267 # root namespace
268 ip link add dev $DEV type $TYPE external
269 ip addr add dev $DEV 10.1.1.200/24
270 ip link set dev $DEV up
271}
272
273test_gre()
274{
275 TYPE=gretap
276 DEV_NS=gretap00
277 DEV=gretap11
278 ret=0
279
280 check $TYPE
281 config_device
282 add_gre_tunnel
283 attach_bpf $DEV gre_set_tunnel gre_get_tunnel
284 ping $PING_ARG 10.1.1.100
285 check_err $?
286 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
287 check_err $?
288 cleanup
289
290 if [ $ret -ne 0 ]; then
291 echo -e ${RED}"FAIL: $TYPE"${NC}
292 return 1
293 fi
294 echo -e ${GREEN}"PASS: $TYPE"${NC}
295}
296
297test_ip6gre()
298{
299 TYPE=ip6gre
300 DEV_NS=ip6gre00
301 DEV=ip6gre11
302 ret=0
303
304 check $TYPE
305 config_device
306 # reuse the ip6gretap function
307 add_ip6gretap_tunnel
308 attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
309 # underlay
310 ping6 $PING_ARG ::11
311 # overlay: ipv4 over ipv6
312 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
313 ping $PING_ARG 10.1.1.100
314 check_err $?
315 # overlay: ipv6 over ipv6
316 ip netns exec at_ns0 ping6 $PING_ARG fc80::200
317 check_err $?
318 cleanup
319
320 if [ $ret -ne 0 ]; then
321 echo -e ${RED}"FAIL: $TYPE"${NC}
322 return 1
323 fi
324 echo -e ${GREEN}"PASS: $TYPE"${NC}
325}
326
327test_ip6gretap()
328{
329 TYPE=ip6gretap
330 DEV_NS=ip6gretap00
331 DEV=ip6gretap11
332 ret=0
333
334 check $TYPE
335 config_device
336 add_ip6gretap_tunnel
337 attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
338 # underlay
339 ping6 $PING_ARG ::11
340 # overlay: ipv4 over ipv6
341 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
342 ping $PING_ARG 10.1.1.100
343 check_err $?
344 # overlay: ipv6 over ipv6
345 ip netns exec at_ns0 ping6 $PING_ARG fc80::200
346 check_err $?
347 cleanup
348
349 if [ $ret -ne 0 ]; then
350 echo -e ${RED}"FAIL: $TYPE"${NC}
351 return 1
352 fi
353 echo -e ${GREEN}"PASS: $TYPE"${NC}
354}
355
356test_erspan()
357{
358 TYPE=erspan
359 DEV_NS=erspan00
360 DEV=erspan11
361 ret=0
362
363 check $TYPE
364 config_device
365 add_erspan_tunnel $1
366 attach_bpf $DEV erspan_set_tunnel erspan_get_tunnel
367 ping $PING_ARG 10.1.1.100
368 check_err $?
369 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
370 check_err $?
371 cleanup
372
373 if [ $ret -ne 0 ]; then
374 echo -e ${RED}"FAIL: $TYPE"${NC}
375 return 1
376 fi
377 echo -e ${GREEN}"PASS: $TYPE"${NC}
378}
379
380test_ip6erspan()
381{
382 TYPE=ip6erspan
383 DEV_NS=ip6erspan00
384 DEV=ip6erspan11
385 ret=0
386
387 check $TYPE
388 config_device
389 add_ip6erspan_tunnel $1
390 attach_bpf $DEV ip4ip6erspan_set_tunnel ip4ip6erspan_get_tunnel
391 ping6 $PING_ARG ::11
392 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
393 check_err $?
394 cleanup
395
396 if [ $ret -ne 0 ]; then
397 echo -e ${RED}"FAIL: $TYPE"${NC}
398 return 1
399 fi
400 echo -e ${GREEN}"PASS: $TYPE"${NC}
401}
402
403test_vxlan()
404{
405 TYPE=vxlan
406 DEV_NS=vxlan00
407 DEV=vxlan11
408 ret=0
409
410 check $TYPE
411 config_device
412 add_vxlan_tunnel
413 attach_bpf $DEV vxlan_set_tunnel vxlan_get_tunnel
414 ping $PING_ARG 10.1.1.100
415 check_err $?
416 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
417 check_err $?
418 cleanup
419
420 if [ $ret -ne 0 ]; then
421 echo -e ${RED}"FAIL: $TYPE"${NC}
422 return 1
423 fi
424 echo -e ${GREEN}"PASS: $TYPE"${NC}
425}
426
427test_ip6vxlan()
428{
429 TYPE=vxlan
430 DEV_NS=ip6vxlan00
431 DEV=ip6vxlan11
432 ret=0
433
434 check $TYPE
435 config_device
436 add_ip6vxlan_tunnel
437 ip link set dev veth1 mtu 1500
438 attach_bpf $DEV ip6vxlan_set_tunnel ip6vxlan_get_tunnel
439 # underlay
440 ping6 $PING_ARG ::11
441 # ip4 over ip6
442 ping $PING_ARG 10.1.1.100
443 check_err $?
444 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
445 check_err $?
446 cleanup
447
448 if [ $ret -ne 0 ]; then
449 echo -e ${RED}"FAIL: ip6$TYPE"${NC}
450 return 1
451 fi
452 echo -e ${GREEN}"PASS: ip6$TYPE"${NC}
453}
454
455test_geneve()
456{
457 TYPE=geneve
458 DEV_NS=geneve00
459 DEV=geneve11
460 ret=0
461
462 check $TYPE
463 config_device
464 add_geneve_tunnel
465 attach_bpf $DEV geneve_set_tunnel geneve_get_tunnel
466 ping $PING_ARG 10.1.1.100
467 check_err $?
468 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
469 check_err $?
470 cleanup
471
472 if [ $ret -ne 0 ]; then
473 echo -e ${RED}"FAIL: $TYPE"${NC}
474 return 1
475 fi
476 echo -e ${GREEN}"PASS: $TYPE"${NC}
477}
478
479test_ip6geneve()
480{
481 TYPE=geneve
482 DEV_NS=ip6geneve00
483 DEV=ip6geneve11
484 ret=0
485
486 check $TYPE
487 config_device
488 add_ip6geneve_tunnel
489 attach_bpf $DEV ip6geneve_set_tunnel ip6geneve_get_tunnel
490 ping $PING_ARG 10.1.1.100
491 check_err $?
492 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
493 check_err $?
494 cleanup
495
496 if [ $ret -ne 0 ]; then
497 echo -e ${RED}"FAIL: ip6$TYPE"${NC}
498 return 1
499 fi
500 echo -e ${GREEN}"PASS: ip6$TYPE"${NC}
501}
502
503test_ipip()
504{
505 TYPE=ipip
506 DEV_NS=ipip00
507 DEV=ipip11
508 ret=0
509
510 check $TYPE
511 config_device
512 add_ipip_tunnel
513 ip link set dev veth1 mtu 1500
514 attach_bpf $DEV ipip_set_tunnel ipip_get_tunnel
515 ping $PING_ARG 10.1.1.100
516 check_err $?
517 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
518 check_err $?
519 cleanup
520
521 if [ $ret -ne 0 ]; then
522 echo -e ${RED}"FAIL: $TYPE"${NC}
523 return 1
524 fi
525 echo -e ${GREEN}"PASS: $TYPE"${NC}
526}
527
528test_ipip6()
529{
530 TYPE=ip6tnl
531 DEV_NS=ipip6tnl00
532 DEV=ipip6tnl11
533 ret=0
534
535 check $TYPE
536 config_device
537 add_ipip6tnl_tunnel
538 ip link set dev veth1 mtu 1500
539 attach_bpf $DEV ipip6_set_tunnel ipip6_get_tunnel
540 # underlay
541 ping6 $PING_ARG ::11
542 # ip4 over ip6
543 ping $PING_ARG 10.1.1.100
544 check_err $?
545 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
546 check_err $?
547 cleanup
548
549 if [ $ret -ne 0 ]; then
550 echo -e ${RED}"FAIL: $TYPE"${NC}
551 return 1
552 fi
553 echo -e ${GREEN}"PASS: $TYPE"${NC}
554}
555
556setup_xfrm_tunnel()
557{
558 auth=0x$(printf '1%.0s' {1..40})
559 enc=0x$(printf '2%.0s' {1..32})
560 spi_in_to_out=0x1
561 spi_out_to_in=0x2
562 # at_ns0 namespace
563 # at_ns0 -> root
564 ip netns exec at_ns0 \
565 ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
566 spi $spi_in_to_out reqid 1 mode tunnel \
567 auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
568 ip netns exec at_ns0 \
569 ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir out \
570 tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
571 mode tunnel
572 # root -> at_ns0
573 ip netns exec at_ns0 \
574 ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
575 spi $spi_out_to_in reqid 2 mode tunnel \
576 auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
577 ip netns exec at_ns0 \
578 ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir in \
579 tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
580 mode tunnel
581 # address & route
582 ip netns exec at_ns0 \
583 ip addr add dev veth0 10.1.1.100/32
584 ip netns exec at_ns0 \
585 ip route add 10.1.1.200 dev veth0 via 172.16.1.200 \
586 src 10.1.1.100
587
588 # root namespace
589 # at_ns0 -> root
590 ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
591 spi $spi_in_to_out reqid 1 mode tunnel \
592 auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
593 ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir in \
594 tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
595 mode tunnel
596 # root -> at_ns0
597 ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
598 spi $spi_out_to_in reqid 2 mode tunnel \
599 auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
600 ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir out \
601 tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
602 mode tunnel
603 # address & route
604 ip addr add dev veth1 10.1.1.200/32
605 ip route add 10.1.1.100 dev veth1 via 172.16.1.100 src 10.1.1.200
606}
607
608test_xfrm_tunnel()
609{
610 config_device
611 #tcpdump -nei veth1 ip &
612 output=$(mktemp)
613 cat /sys/kernel/debug/tracing/trace_pipe | tee $output &
614 setup_xfrm_tunnel
615 tc qdisc add dev veth1 clsact
616 tc filter add dev veth1 proto ip ingress bpf da obj test_tunnel_kern.o \
617 sec xfrm_get_state
618 ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
619 sleep 1
620 grep "reqid 1" $output
621 check_err $?
622 grep "spi 0x1" $output
623 check_err $?
624 grep "remote ip 0xac100164" $output
625 check_err $?
626 cleanup
627
628 if [ $ret -ne 0 ]; then
629 echo -e ${RED}"FAIL: xfrm tunnel"${NC}
630 return 1
631 fi
632 echo -e ${GREEN}"PASS: xfrm tunnel"${NC}
633}
634
635attach_bpf()
636{
637 DEV=$1
638 SET=$2
639 GET=$3
640 tc qdisc add dev $DEV clsact
641 tc filter add dev $DEV egress bpf da obj test_tunnel_kern.o sec $SET
642 tc filter add dev $DEV ingress bpf da obj test_tunnel_kern.o sec $GET
643}
644
645cleanup()
646{
647 ip netns delete at_ns0 2> /dev/null
648 ip link del veth1 2> /dev/null
649 ip link del ipip11 2> /dev/null
650 ip link del ipip6tnl11 2> /dev/null
651 ip link del gretap11 2> /dev/null
652 ip link del ip6gre11 2> /dev/null
653 ip link del ip6gretap11 2> /dev/null
654 ip link del vxlan11 2> /dev/null
655 ip link del ip6vxlan11 2> /dev/null
656 ip link del geneve11 2> /dev/null
657 ip link del ip6geneve11 2> /dev/null
658 ip link del erspan11 2> /dev/null
659 ip link del ip6erspan11 2> /dev/null
660}
661
662cleanup_exit()
663{
664 echo "CATCH SIGKILL or SIGINT, cleanup and exit"
665 cleanup
666 exit 0
667}
668
669check()
670{
671 ip link help $1 2>&1 | grep -q "^Usage:"
672 if [ $? -ne 0 ];then
673 echo "SKIP $1: iproute2 not support"
674 cleanup
675 return 1
676 fi
677}
678
679enable_debug()
680{
681 echo 'file ip_gre.c +p' > /sys/kernel/debug/dynamic_debug/control
682 echo 'file ip6_gre.c +p' > /sys/kernel/debug/dynamic_debug/control
683 echo 'file vxlan.c +p' > /sys/kernel/debug/dynamic_debug/control
684 echo 'file geneve.c +p' > /sys/kernel/debug/dynamic_debug/control
685 echo 'file ipip.c +p' > /sys/kernel/debug/dynamic_debug/control
686}
687
688check_err()
689{
690 if [ $ret -eq 0 ]; then
691 ret=$1
692 fi
693}
694
695bpf_tunnel_test()
696{
697 echo "Testing GRE tunnel..."
698 test_gre
699 echo "Testing IP6GRE tunnel..."
700 test_ip6gre
701 echo "Testing IP6GRETAP tunnel..."
702 test_ip6gretap
703 echo "Testing ERSPAN tunnel..."
704 test_erspan v2
705 echo "Testing IP6ERSPAN tunnel..."
706 test_ip6erspan v2
707 echo "Testing VXLAN tunnel..."
708 test_vxlan
709 echo "Testing IP6VXLAN tunnel..."
710 test_ip6vxlan
711 echo "Testing GENEVE tunnel..."
712 test_geneve
713 echo "Testing IP6GENEVE tunnel..."
714 test_ip6geneve
715 echo "Testing IPIP tunnel..."
716 test_ipip
717 echo "Testing IPIP6 tunnel..."
718 test_ipip6
719 echo "Testing IPSec tunnel..."
720 test_xfrm_tunnel
721}
722
723trap cleanup 0 3 6
724trap cleanup_exit 2 9
725
726cleanup
727bpf_tunnel_test
728
729exit 0
diff --git a/samples/bpf/tcbpf2_kern.c b/tools/testing/selftests/bpf/test_tunnel_kern.c
index fa260c750fb1..504df69c83df 100644
--- a/samples/bpf/tcbpf2_kern.c
+++ b/tools/testing/selftests/bpf/test_tunnel_kern.c
@@ -1,3 +1,4 @@
1// SPDX-License-Identifier: GPL-2.0
1/* Copyright (c) 2016 VMware 2/* Copyright (c) 2016 VMware
2 * Copyright (c) 2016 Facebook 3 * Copyright (c) 2016 Facebook
3 * 4 *
@@ -5,39 +6,41 @@
5 * modify it under the terms of version 2 of the GNU General Public 6 * modify it under the terms of version 2 of the GNU General Public
6 * License as published by the Free Software Foundation. 7 * License as published by the Free Software Foundation.
7 */ 8 */
8#define KBUILD_MODNAME "foo" 9#include <stddef.h>
9#include <uapi/linux/bpf.h> 10#include <string.h>
10#include <uapi/linux/if_ether.h> 11#include <arpa/inet.h>
11#include <uapi/linux/if_packet.h> 12#include <linux/bpf.h>
12#include <uapi/linux/ip.h> 13#include <linux/if_ether.h>
13#include <uapi/linux/ipv6.h> 14#include <linux/if_packet.h>
14#include <uapi/linux/in.h> 15#include <linux/ip.h>
15#include <uapi/linux/tcp.h> 16#include <linux/ipv6.h>
16#include <uapi/linux/filter.h> 17#include <linux/types.h>
17#include <uapi/linux/pkt_cls.h> 18#include <linux/tcp.h>
18#include <uapi/linux/erspan.h> 19#include <linux/socket.h>
19#include <net/ipv6.h> 20#include <linux/pkt_cls.h>
21#include <linux/erspan.h>
20#include "bpf_helpers.h" 22#include "bpf_helpers.h"
21#include "bpf_endian.h" 23#include "bpf_endian.h"
22 24
23#define _htonl __builtin_bswap32
24#define ERROR(ret) do {\ 25#define ERROR(ret) do {\
25 char fmt[] = "ERROR line:%d ret:%d\n";\ 26 char fmt[] = "ERROR line:%d ret:%d\n";\
26 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \ 27 bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
27 } while(0) 28 } while (0)
29
30int _version SEC("version") = 1;
28 31
29struct geneve_opt { 32struct geneve_opt {
30 __be16 opt_class; 33 __be16 opt_class;
31 u8 type; 34 __u8 type;
32 u8 length:5; 35 __u8 length:5;
33 u8 r3:1; 36 __u8 r3:1;
34 u8 r2:1; 37 __u8 r2:1;
35 u8 r1:1; 38 __u8 r1:1;
36 u8 opt_data[8]; /* hard-coded to 8 byte */ 39 __u8 opt_data[8]; /* hard-coded to 8 byte */
37}; 40};
38 41
39struct vxlan_metadata { 42struct vxlan_metadata {
40 u32 gbp; 43 __u32 gbp;
41}; 44};
42 45
43SEC("gre_set_tunnel") 46SEC("gre_set_tunnel")
@@ -86,7 +89,7 @@ int _ip6gretap_set_tunnel(struct __sk_buff *skb)
86 int ret; 89 int ret;
87 90
88 __builtin_memset(&key, 0x0, sizeof(key)); 91 __builtin_memset(&key, 0x0, sizeof(key));
89 key.remote_ipv6[3] = _htonl(0x11); /* ::11 */ 92 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
90 key.tunnel_id = 2; 93 key.tunnel_id = 2;
91 key.tunnel_tos = 0; 94 key.tunnel_tos = 0;
92 key.tunnel_ttl = 64; 95 key.tunnel_ttl = 64;
@@ -136,7 +139,8 @@ int _erspan_set_tunnel(struct __sk_buff *skb)
136 key.tunnel_tos = 0; 139 key.tunnel_tos = 0;
137 key.tunnel_ttl = 64; 140 key.tunnel_ttl = 64;
138 141
139 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX); 142 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
143 BPF_F_ZERO_CSUM_TX);
140 if (ret < 0) { 144 if (ret < 0) {
141 ERROR(ret); 145 ERROR(ret);
142 return TC_ACT_SHOT; 146 return TC_ACT_SHOT;
@@ -147,8 +151,8 @@ int _erspan_set_tunnel(struct __sk_buff *skb)
147 md.version = 1; 151 md.version = 1;
148 md.u.index = bpf_htonl(123); 152 md.u.index = bpf_htonl(123);
149#else 153#else
150 u8 direction = 1; 154 __u8 direction = 1;
151 u8 hwid = 7; 155 __u8 hwid = 7;
152 156
153 md.version = 2; 157 md.version = 2;
154 md.u.md2.dir = direction; 158 md.u.md2.dir = direction;
@@ -171,7 +175,7 @@ int _erspan_get_tunnel(struct __sk_buff *skb)
171 char fmt[] = "key %d remote ip 0x%x erspan version %d\n"; 175 char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
172 struct bpf_tunnel_key key; 176 struct bpf_tunnel_key key;
173 struct erspan_metadata md; 177 struct erspan_metadata md;
174 u32 index; 178 __u32 index;
175 int ret; 179 int ret;
176 180
177 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0); 181 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
@@ -214,7 +218,7 @@ int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
214 int ret; 218 int ret;
215 219
216 __builtin_memset(&key, 0x0, sizeof(key)); 220 __builtin_memset(&key, 0x0, sizeof(key));
217 key.remote_ipv6[3] = _htonl(0x11); 221 key.remote_ipv6[3] = bpf_htonl(0x11);
218 key.tunnel_id = 2; 222 key.tunnel_id = 2;
219 key.tunnel_tos = 0; 223 key.tunnel_tos = 0;
220 key.tunnel_ttl = 64; 224 key.tunnel_ttl = 64;
@@ -229,11 +233,11 @@ int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
229 __builtin_memset(&md, 0, sizeof(md)); 233 __builtin_memset(&md, 0, sizeof(md));
230 234
231#ifdef ERSPAN_V1 235#ifdef ERSPAN_V1
232 md.u.index = htonl(123); 236 md.u.index = bpf_htonl(123);
233 md.version = 1; 237 md.version = 1;
234#else 238#else
235 u8 direction = 0; 239 __u8 direction = 0;
236 u8 hwid = 17; 240 __u8 hwid = 17;
237 241
238 md.version = 2; 242 md.version = 2;
239 md.u.md2.dir = direction; 243 md.u.md2.dir = direction;
@@ -256,10 +260,11 @@ int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
256 char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n"; 260 char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
257 struct bpf_tunnel_key key; 261 struct bpf_tunnel_key key;
258 struct erspan_metadata md; 262 struct erspan_metadata md;
259 u32 index; 263 __u32 index;
260 int ret; 264 int ret;
261 265
262 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6); 266 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
267 BPF_F_TUNINFO_IPV6);
263 if (ret < 0) { 268 if (ret < 0) {
264 ERROR(ret); 269 ERROR(ret);
265 return TC_ACT_SHOT; 270 return TC_ACT_SHOT;
@@ -304,7 +309,8 @@ int _vxlan_set_tunnel(struct __sk_buff *skb)
304 key.tunnel_tos = 0; 309 key.tunnel_tos = 0;
305 key.tunnel_ttl = 64; 310 key.tunnel_ttl = 64;
306 311
307 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX); 312 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
313 BPF_F_ZERO_CSUM_TX);
308 if (ret < 0) { 314 if (ret < 0) {
309 ERROR(ret); 315 ERROR(ret);
310 return TC_ACT_SHOT; 316 return TC_ACT_SHOT;
@@ -346,6 +352,48 @@ int _vxlan_get_tunnel(struct __sk_buff *skb)
346 return TC_ACT_OK; 352 return TC_ACT_OK;
347} 353}
348 354
355SEC("ip6vxlan_set_tunnel")
356int _ip6vxlan_set_tunnel(struct __sk_buff *skb)
357{
358 struct bpf_tunnel_key key;
359 int ret;
360
361 __builtin_memset(&key, 0x0, sizeof(key));
362 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
363 key.tunnel_id = 22;
364 key.tunnel_tos = 0;
365 key.tunnel_ttl = 64;
366
367 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
368 BPF_F_TUNINFO_IPV6);
369 if (ret < 0) {
370 ERROR(ret);
371 return TC_ACT_SHOT;
372 }
373
374 return TC_ACT_OK;
375}
376
377SEC("ip6vxlan_get_tunnel")
378int _ip6vxlan_get_tunnel(struct __sk_buff *skb)
379{
380 char fmt[] = "key %d remote ip6 ::%x label %x\n";
381 struct bpf_tunnel_key key;
382 int ret;
383
384 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
385 BPF_F_TUNINFO_IPV6);
386 if (ret < 0) {
387 ERROR(ret);
388 return TC_ACT_SHOT;
389 }
390
391 bpf_trace_printk(fmt, sizeof(fmt),
392 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
393
394 return TC_ACT_OK;
395}
396
349SEC("geneve_set_tunnel") 397SEC("geneve_set_tunnel")
350int _geneve_set_tunnel(struct __sk_buff *skb) 398int _geneve_set_tunnel(struct __sk_buff *skb)
351{ 399{
@@ -360,15 +408,16 @@ int _geneve_set_tunnel(struct __sk_buff *skb)
360 key.tunnel_ttl = 64; 408 key.tunnel_ttl = 64;
361 409
362 __builtin_memset(&gopt, 0x0, sizeof(gopt)); 410 __builtin_memset(&gopt, 0x0, sizeof(gopt));
363 gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */ 411 gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
364 gopt.type = 0x08; 412 gopt.type = 0x08;
365 gopt.r1 = 0; 413 gopt.r1 = 0;
366 gopt.r2 = 0; 414 gopt.r2 = 0;
367 gopt.r3 = 0; 415 gopt.r3 = 0;
368 gopt.length = 2; /* 4-byte multiple */ 416 gopt.length = 2; /* 4-byte multiple */
369 *(int *) &gopt.opt_data = 0xdeadbeef; 417 *(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef);
370 418
371 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX); 419 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
420 BPF_F_ZERO_CSUM_TX);
372 if (ret < 0) { 421 if (ret < 0) {
373 ERROR(ret); 422 ERROR(ret);
374 return TC_ACT_SHOT; 423 return TC_ACT_SHOT;
@@ -408,6 +457,71 @@ int _geneve_get_tunnel(struct __sk_buff *skb)
408 return TC_ACT_OK; 457 return TC_ACT_OK;
409} 458}
410 459
460SEC("ip6geneve_set_tunnel")
461int _ip6geneve_set_tunnel(struct __sk_buff *skb)
462{
463 struct bpf_tunnel_key key;
464 struct geneve_opt gopt;
465 int ret;
466
467 __builtin_memset(&key, 0x0, sizeof(key));
468 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
469 key.tunnel_id = 22;
470 key.tunnel_tos = 0;
471 key.tunnel_ttl = 64;
472
473 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
474 BPF_F_TUNINFO_IPV6);
475 if (ret < 0) {
476 ERROR(ret);
477 return TC_ACT_SHOT;
478 }
479
480 __builtin_memset(&gopt, 0x0, sizeof(gopt));
481 gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
482 gopt.type = 0x08;
483 gopt.r1 = 0;
484 gopt.r2 = 0;
485 gopt.r3 = 0;
486 gopt.length = 2; /* 4-byte multiple */
487 *(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
488
489 ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
490 if (ret < 0) {
491 ERROR(ret);
492 return TC_ACT_SHOT;
493 }
494
495 return TC_ACT_OK;
496}
497
498SEC("ip6geneve_get_tunnel")
499int _ip6geneve_get_tunnel(struct __sk_buff *skb)
500{
501 char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
502 struct bpf_tunnel_key key;
503 struct geneve_opt gopt;
504 int ret;
505
506 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
507 BPF_F_TUNINFO_IPV6);
508 if (ret < 0) {
509 ERROR(ret);
510 return TC_ACT_SHOT;
511 }
512
513 ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
514 if (ret < 0) {
515 ERROR(ret);
516 return TC_ACT_SHOT;
517 }
518
519 bpf_trace_printk(fmt, sizeof(fmt),
520 key.tunnel_id, key.remote_ipv4, gopt.opt_class);
521
522 return TC_ACT_OK;
523}
524
411SEC("ipip_set_tunnel") 525SEC("ipip_set_tunnel")
412int _ipip_set_tunnel(struct __sk_buff *skb) 526int _ipip_set_tunnel(struct __sk_buff *skb)
413{ 527{
@@ -431,9 +545,9 @@ int _ipip_set_tunnel(struct __sk_buff *skb)
431 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) 545 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
432 return TC_ACT_SHOT; 546 return TC_ACT_SHOT;
433 547
434 if (tcp->dest == htons(5200)) 548 if (tcp->dest == bpf_htons(5200))
435 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */ 549 key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
436 else if (tcp->dest == htons(5201)) 550 else if (tcp->dest == bpf_htons(5201))
437 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */ 551 key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
438 else 552 else
439 return TC_ACT_SHOT; 553 return TC_ACT_SHOT;
@@ -481,28 +595,12 @@ int _ipip6_set_tunnel(struct __sk_buff *skb)
481 return TC_ACT_SHOT; 595 return TC_ACT_SHOT;
482 } 596 }
483 597
484 key.remote_ipv6[0] = _htonl(0x2401db00); 598 __builtin_memset(&key, 0x0, sizeof(key));
599 key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
485 key.tunnel_ttl = 64; 600 key.tunnel_ttl = 64;
486 601
487 if (iph->protocol == IPPROTO_ICMP) { 602 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
488 key.remote_ipv6[3] = _htonl(1); 603 BPF_F_TUNINFO_IPV6);
489 } else {
490 if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
491 ERROR(iph->protocol);
492 return TC_ACT_SHOT;
493 }
494
495 if (tcp->dest == htons(5200)) {
496 key.remote_ipv6[3] = _htonl(1);
497 } else if (tcp->dest == htons(5201)) {
498 key.remote_ipv6[3] = _htonl(2);
499 } else {
500 ERROR(tcp->dest);
501 return TC_ACT_SHOT;
502 }
503 }
504
505 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
506 if (ret < 0) { 604 if (ret < 0) {
507 ERROR(ret); 605 ERROR(ret);
508 return TC_ACT_SHOT; 606 return TC_ACT_SHOT;
@@ -518,14 +616,15 @@ int _ipip6_get_tunnel(struct __sk_buff *skb)
518 struct bpf_tunnel_key key; 616 struct bpf_tunnel_key key;
519 char fmt[] = "remote ip6 %x::%x\n"; 617 char fmt[] = "remote ip6 %x::%x\n";
520 618
521 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6); 619 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
620 BPF_F_TUNINFO_IPV6);
522 if (ret < 0) { 621 if (ret < 0) {
523 ERROR(ret); 622 ERROR(ret);
524 return TC_ACT_SHOT; 623 return TC_ACT_SHOT;
525 } 624 }
526 625
527 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]), 626 bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
528 _htonl(key.remote_ipv6[3])); 627 bpf_htonl(key.remote_ipv6[3]));
529 return TC_ACT_OK; 628 return TC_ACT_OK;
530} 629}
531 630
@@ -545,28 +644,29 @@ int _ip6ip6_set_tunnel(struct __sk_buff *skb)
545 return TC_ACT_SHOT; 644 return TC_ACT_SHOT;
546 } 645 }
547 646
548 key.remote_ipv6[0] = _htonl(0x2401db00); 647 key.remote_ipv6[0] = bpf_htonl(0x2401db00);
549 key.tunnel_ttl = 64; 648 key.tunnel_ttl = 64;
550 649
551 if (iph->nexthdr == NEXTHDR_ICMP) { 650 if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
552 key.remote_ipv6[3] = _htonl(1); 651 key.remote_ipv6[3] = bpf_htonl(1);
553 } else { 652 } else {
554 if (iph->nexthdr != NEXTHDR_TCP) { 653 if (iph->nexthdr != 6 /* NEXTHDR_TCP */) {
555 ERROR(iph->nexthdr); 654 ERROR(iph->nexthdr);
556 return TC_ACT_SHOT; 655 return TC_ACT_SHOT;
557 } 656 }
558 657
559 if (tcp->dest == htons(5200)) { 658 if (tcp->dest == bpf_htons(5200)) {
560 key.remote_ipv6[3] = _htonl(1); 659 key.remote_ipv6[3] = bpf_htonl(1);
561 } else if (tcp->dest == htons(5201)) { 660 } else if (tcp->dest == bpf_htons(5201)) {
562 key.remote_ipv6[3] = _htonl(2); 661 key.remote_ipv6[3] = bpf_htonl(2);
563 } else { 662 } else {
564 ERROR(tcp->dest); 663 ERROR(tcp->dest);
565 return TC_ACT_SHOT; 664 return TC_ACT_SHOT;
566 } 665 }
567 } 666 }
568 667
569 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6); 668 ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
669 BPF_F_TUNINFO_IPV6);
570 if (ret < 0) { 670 if (ret < 0) {
571 ERROR(ret); 671 ERROR(ret);
572 return TC_ACT_SHOT; 672 return TC_ACT_SHOT;
@@ -582,14 +682,15 @@ int _ip6ip6_get_tunnel(struct __sk_buff *skb)
582 struct bpf_tunnel_key key; 682 struct bpf_tunnel_key key;
583 char fmt[] = "remote ip6 %x::%x\n"; 683 char fmt[] = "remote ip6 %x::%x\n";
584 684
585 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6); 685 ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
686 BPF_F_TUNINFO_IPV6);
586 if (ret < 0) { 687 if (ret < 0) {
587 ERROR(ret); 688 ERROR(ret);
588 return TC_ACT_SHOT; 689 return TC_ACT_SHOT;
589 } 690 }
590 691
591 bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]), 692 bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
592 _htonl(key.remote_ipv6[3])); 693 bpf_htonl(key.remote_ipv6[3]));
593 return TC_ACT_OK; 694 return TC_ACT_OK;
594} 695}
595 696