mirror of
				https://github.com/torvalds/linux.git
				synced 2025-11-04 02:30:34 +02:00 
			
		
		
		
	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>
			
			
This commit is contained in:
		
						commit
						3f13de6d6f
					
				
					 5 changed files with 906 additions and 466 deletions
				
			
		| 
						 | 
					@ -114,7 +114,6 @@ always += sock_flags_kern.o
 | 
				
			||||||
always += test_probe_write_user_kern.o
 | 
					always += test_probe_write_user_kern.o
 | 
				
			||||||
always += trace_output_kern.o
 | 
					always += trace_output_kern.o
 | 
				
			||||||
always += tcbpf1_kern.o
 | 
					always += tcbpf1_kern.o
 | 
				
			||||||
always += tcbpf2_kern.o
 | 
					 | 
				
			||||||
always += tc_l2_redirect_kern.o
 | 
					always += tc_l2_redirect_kern.o
 | 
				
			||||||
always += lathist_kern.o
 | 
					always += lathist_kern.o
 | 
				
			||||||
always += offwaketime_kern.o
 | 
					always += offwaketime_kern.o
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1,390 +0,0 @@
 | 
				
			||||||
#!/bin/bash
 | 
					 | 
				
			||||||
# SPDX-License-Identifier: GPL-2.0
 | 
					 | 
				
			||||||
# In Namespace 0 (at_ns0) using native tunnel
 | 
					 | 
				
			||||||
# Overlay IP: 10.1.1.100
 | 
					 | 
				
			||||||
# local 192.16.1.100 remote 192.16.1.200
 | 
					 | 
				
			||||||
# veth0 IP: 172.16.1.100, tunnel dev <type>00
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
# Out of Namespace using BPF set/get on lwtunnel
 | 
					 | 
				
			||||||
# Overlay IP: 10.1.1.200
 | 
					 | 
				
			||||||
# local 172.16.1.200 remote 172.16.1.100
 | 
					 | 
				
			||||||
# veth1 IP: 172.16.1.200, tunnel dev <type>11
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function config_device {
 | 
					 | 
				
			||||||
	ip netns add at_ns0
 | 
					 | 
				
			||||||
	ip link add veth0 type veth peer name veth1
 | 
					 | 
				
			||||||
	ip link set veth0 netns at_ns0
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev veth0 up
 | 
					 | 
				
			||||||
	ip link set dev veth1 up mtu 1500
 | 
					 | 
				
			||||||
	ip addr add dev veth1 172.16.1.200/24
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function add_gre_tunnel {
 | 
					 | 
				
			||||||
	# in namespace
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
        ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
					 | 
				
			||||||
		local 172.16.1.100 remote 172.16.1.200
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# out of namespace
 | 
					 | 
				
			||||||
	ip link add dev $DEV type $TYPE key 2 external
 | 
					 | 
				
			||||||
	ip link set dev $DEV up
 | 
					 | 
				
			||||||
	ip addr add dev $DEV 10.1.1.200/24
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function add_ip6gretap_tunnel {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# assign ipv6 address
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add ::11/96 dev veth0
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev veth0 up
 | 
					 | 
				
			||||||
	ip addr add dev veth1 ::22/96
 | 
					 | 
				
			||||||
	ip link set dev veth1 up
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# in namespace
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip link add dev $DEV_NS type $TYPE seq flowlabel 0xbcdef key 2 \
 | 
					 | 
				
			||||||
		local ::11 remote ::22
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add dev $DEV_NS fc80::100/96
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# out of namespace
 | 
					 | 
				
			||||||
	ip link add dev $DEV type $TYPE external
 | 
					 | 
				
			||||||
	ip addr add dev $DEV 10.1.1.200/24
 | 
					 | 
				
			||||||
	ip addr add dev $DEV fc80::200/24
 | 
					 | 
				
			||||||
	ip link set dev $DEV up
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function add_erspan_tunnel {
 | 
					 | 
				
			||||||
	# in namespace
 | 
					 | 
				
			||||||
	if [ "$1" == "v1" ]; then
 | 
					 | 
				
			||||||
		ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
					 | 
				
			||||||
		local 172.16.1.100 remote 172.16.1.200 \
 | 
					 | 
				
			||||||
		erspan_ver 1 erspan 123
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
					 | 
				
			||||||
		local 172.16.1.100 remote 172.16.1.200 \
 | 
					 | 
				
			||||||
		erspan_ver 2 erspan_dir egress erspan_hwid 3
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# out of namespace
 | 
					 | 
				
			||||||
	ip link add dev $DEV type $TYPE external
 | 
					 | 
				
			||||||
	ip link set dev $DEV up
 | 
					 | 
				
			||||||
	ip addr add dev $DEV 10.1.1.200/24
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function add_ip6erspan_tunnel {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# assign ipv6 address
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add ::11/96 dev veth0
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev veth0 up
 | 
					 | 
				
			||||||
	ip addr add dev veth1 ::22/96
 | 
					 | 
				
			||||||
	ip link set dev veth1 up
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# in namespace
 | 
					 | 
				
			||||||
	if [ "$1" == "v1" ]; then
 | 
					 | 
				
			||||||
		ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
					 | 
				
			||||||
		local ::11 remote ::22 \
 | 
					 | 
				
			||||||
		erspan_ver 1 erspan 123
 | 
					 | 
				
			||||||
	else
 | 
					 | 
				
			||||||
		ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
					 | 
				
			||||||
		local ::11 remote ::22 \
 | 
					 | 
				
			||||||
		erspan_ver 2 erspan_dir egress erspan_hwid 7
 | 
					 | 
				
			||||||
	fi
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# out of namespace
 | 
					 | 
				
			||||||
	ip link add dev $DEV type $TYPE external
 | 
					 | 
				
			||||||
	ip addr add dev $DEV 10.1.1.200/24
 | 
					 | 
				
			||||||
	ip link set dev $DEV up
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function add_vxlan_tunnel {
 | 
					 | 
				
			||||||
	# Set static ARP entry here because iptables set-mark works
 | 
					 | 
				
			||||||
	# on L3 packet, as a result not applying to ARP packets,
 | 
					 | 
				
			||||||
	# causing errors at get_tunnel_{key/opt}.
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# in namespace
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip link add dev $DEV_NS type $TYPE id 2 dstport 4789 gbp remote 172.16.1.200
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev $DEV_NS address 52:54:00:d9:01:00 up
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 arp -s 10.1.1.200 52:54:00:d9:02:00
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 iptables -A OUTPUT -j MARK --set-mark 0x800FF
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# out of namespace
 | 
					 | 
				
			||||||
	ip link add dev $DEV type $TYPE external gbp dstport 4789
 | 
					 | 
				
			||||||
	ip link set dev $DEV address 52:54:00:d9:02:00 up
 | 
					 | 
				
			||||||
	ip addr add dev $DEV 10.1.1.200/24
 | 
					 | 
				
			||||||
	arp -s 10.1.1.100 52:54:00:d9:01:00
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function add_geneve_tunnel {
 | 
					 | 
				
			||||||
	# in namespace
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip link add dev $DEV_NS type $TYPE id 2 dstport 6081 remote 172.16.1.200
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# out of namespace
 | 
					 | 
				
			||||||
	ip link add dev $DEV type $TYPE dstport 6081 external
 | 
					 | 
				
			||||||
	ip link set dev $DEV up
 | 
					 | 
				
			||||||
	ip addr add dev $DEV 10.1.1.200/24
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function add_ipip_tunnel {
 | 
					 | 
				
			||||||
	# in namespace
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip link add dev $DEV_NS type $TYPE local 172.16.1.100 remote 172.16.1.200
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# out of namespace
 | 
					 | 
				
			||||||
	ip link add dev $DEV type $TYPE external
 | 
					 | 
				
			||||||
	ip link set dev $DEV up
 | 
					 | 
				
			||||||
	ip addr add dev $DEV 10.1.1.200/24
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function setup_xfrm_tunnel {
 | 
					 | 
				
			||||||
	auth=0x$(printf '1%.0s' {1..40})
 | 
					 | 
				
			||||||
	enc=0x$(printf '2%.0s' {1..32})
 | 
					 | 
				
			||||||
	spi_in_to_out=0x1
 | 
					 | 
				
			||||||
	spi_out_to_in=0x2
 | 
					 | 
				
			||||||
	# in namespace
 | 
					 | 
				
			||||||
	# in -> out
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
 | 
					 | 
				
			||||||
			spi $spi_in_to_out reqid 1 mode tunnel \
 | 
					 | 
				
			||||||
			auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir out \
 | 
					 | 
				
			||||||
		tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
 | 
					 | 
				
			||||||
		mode tunnel
 | 
					 | 
				
			||||||
	# out -> in
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
 | 
					 | 
				
			||||||
			spi $spi_out_to_in reqid 2 mode tunnel \
 | 
					 | 
				
			||||||
			auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir in \
 | 
					 | 
				
			||||||
		tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
 | 
					 | 
				
			||||||
		mode tunnel
 | 
					 | 
				
			||||||
	# address & route
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip addr add dev veth0 10.1.1.100/32
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 \
 | 
					 | 
				
			||||||
		ip route add 10.1.1.200 dev veth0 via 172.16.1.200 \
 | 
					 | 
				
			||||||
			src 10.1.1.100
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	# out of namespace
 | 
					 | 
				
			||||||
	# in -> out
 | 
					 | 
				
			||||||
	ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
 | 
					 | 
				
			||||||
		spi $spi_in_to_out reqid 1 mode tunnel \
 | 
					 | 
				
			||||||
		auth-trunc 'hmac(sha1)' $auth 96  enc 'cbc(aes)' $enc
 | 
					 | 
				
			||||||
	ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir in \
 | 
					 | 
				
			||||||
		tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
 | 
					 | 
				
			||||||
		mode tunnel
 | 
					 | 
				
			||||||
	# out -> in
 | 
					 | 
				
			||||||
	ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
 | 
					 | 
				
			||||||
		spi $spi_out_to_in reqid 2 mode tunnel \
 | 
					 | 
				
			||||||
		auth-trunc 'hmac(sha1)' $auth 96  enc 'cbc(aes)' $enc
 | 
					 | 
				
			||||||
	ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir out \
 | 
					 | 
				
			||||||
		tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
 | 
					 | 
				
			||||||
		mode tunnel
 | 
					 | 
				
			||||||
	# address & route
 | 
					 | 
				
			||||||
	ip addr add dev veth1 10.1.1.200/32
 | 
					 | 
				
			||||||
	ip route add 10.1.1.100 dev veth1 via 172.16.1.100 src 10.1.1.200
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function attach_bpf {
 | 
					 | 
				
			||||||
	DEV=$1
 | 
					 | 
				
			||||||
	SET_TUNNEL=$2
 | 
					 | 
				
			||||||
	GET_TUNNEL=$3
 | 
					 | 
				
			||||||
	tc qdisc add dev $DEV clsact
 | 
					 | 
				
			||||||
	tc filter add dev $DEV egress bpf da obj tcbpf2_kern.o sec $SET_TUNNEL
 | 
					 | 
				
			||||||
	tc filter add dev $DEV ingress bpf da obj tcbpf2_kern.o sec $GET_TUNNEL
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_gre {
 | 
					 | 
				
			||||||
	TYPE=gretap
 | 
					 | 
				
			||||||
	DEV_NS=gretap00
 | 
					 | 
				
			||||||
	DEV=gretap11
 | 
					 | 
				
			||||||
	config_device
 | 
					 | 
				
			||||||
	add_gre_tunnel
 | 
					 | 
				
			||||||
	attach_bpf $DEV gre_set_tunnel gre_get_tunnel
 | 
					 | 
				
			||||||
	ping -c 1 10.1.1.100
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping -c 1 10.1.1.200
 | 
					 | 
				
			||||||
	cleanup
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_ip6gre {
 | 
					 | 
				
			||||||
	TYPE=ip6gre
 | 
					 | 
				
			||||||
	DEV_NS=ip6gre00
 | 
					 | 
				
			||||||
	DEV=ip6gre11
 | 
					 | 
				
			||||||
	config_device
 | 
					 | 
				
			||||||
	# reuse the ip6gretap function
 | 
					 | 
				
			||||||
	add_ip6gretap_tunnel
 | 
					 | 
				
			||||||
	attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
 | 
					 | 
				
			||||||
	# underlay
 | 
					 | 
				
			||||||
	ping6 -c 4 ::11
 | 
					 | 
				
			||||||
	# overlay: ipv4 over ipv6
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping -c 1 10.1.1.200
 | 
					 | 
				
			||||||
	ping -c 1 10.1.1.100
 | 
					 | 
				
			||||||
	# overlay: ipv6 over ipv6
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping6 -c 1 fc80::200
 | 
					 | 
				
			||||||
	cleanup
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_ip6gretap {
 | 
					 | 
				
			||||||
	TYPE=ip6gretap
 | 
					 | 
				
			||||||
	DEV_NS=ip6gretap00
 | 
					 | 
				
			||||||
	DEV=ip6gretap11
 | 
					 | 
				
			||||||
	config_device
 | 
					 | 
				
			||||||
	add_ip6gretap_tunnel
 | 
					 | 
				
			||||||
	attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
 | 
					 | 
				
			||||||
	# underlay
 | 
					 | 
				
			||||||
	ping6 -c 4 ::11
 | 
					 | 
				
			||||||
	# overlay: ipv4 over ipv6
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping -i .2 -c 1 10.1.1.200
 | 
					 | 
				
			||||||
	ping -c 1 10.1.1.100
 | 
					 | 
				
			||||||
	# overlay: ipv6 over ipv6
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping6 -c 1 fc80::200
 | 
					 | 
				
			||||||
	cleanup
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_erspan {
 | 
					 | 
				
			||||||
	TYPE=erspan
 | 
					 | 
				
			||||||
	DEV_NS=erspan00
 | 
					 | 
				
			||||||
	DEV=erspan11
 | 
					 | 
				
			||||||
	config_device
 | 
					 | 
				
			||||||
	add_erspan_tunnel $1
 | 
					 | 
				
			||||||
	attach_bpf $DEV erspan_set_tunnel erspan_get_tunnel
 | 
					 | 
				
			||||||
	ping -c 1 10.1.1.100
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping -c 1 10.1.1.200
 | 
					 | 
				
			||||||
	cleanup
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_ip6erspan {
 | 
					 | 
				
			||||||
	TYPE=ip6erspan
 | 
					 | 
				
			||||||
	DEV_NS=ip6erspan00
 | 
					 | 
				
			||||||
	DEV=ip6erspan11
 | 
					 | 
				
			||||||
	config_device
 | 
					 | 
				
			||||||
	add_ip6erspan_tunnel $1
 | 
					 | 
				
			||||||
	attach_bpf $DEV ip4ip6erspan_set_tunnel ip4ip6erspan_get_tunnel
 | 
					 | 
				
			||||||
	ping6 -c 3 ::11
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping -c 1 10.1.1.200
 | 
					 | 
				
			||||||
	cleanup
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_vxlan {
 | 
					 | 
				
			||||||
	TYPE=vxlan
 | 
					 | 
				
			||||||
	DEV_NS=vxlan00
 | 
					 | 
				
			||||||
	DEV=vxlan11
 | 
					 | 
				
			||||||
	config_device
 | 
					 | 
				
			||||||
	add_vxlan_tunnel
 | 
					 | 
				
			||||||
	attach_bpf $DEV vxlan_set_tunnel vxlan_get_tunnel
 | 
					 | 
				
			||||||
	ping -c 1 10.1.1.100
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping -c 1 10.1.1.200
 | 
					 | 
				
			||||||
	cleanup
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_geneve {
 | 
					 | 
				
			||||||
	TYPE=geneve
 | 
					 | 
				
			||||||
	DEV_NS=geneve00
 | 
					 | 
				
			||||||
	DEV=geneve11
 | 
					 | 
				
			||||||
	config_device
 | 
					 | 
				
			||||||
	add_geneve_tunnel
 | 
					 | 
				
			||||||
	attach_bpf $DEV geneve_set_tunnel geneve_get_tunnel
 | 
					 | 
				
			||||||
	ping -c 1 10.1.1.100
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping -c 1 10.1.1.200
 | 
					 | 
				
			||||||
	cleanup
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_ipip {
 | 
					 | 
				
			||||||
	TYPE=ipip
 | 
					 | 
				
			||||||
	DEV_NS=ipip00
 | 
					 | 
				
			||||||
	DEV=ipip11
 | 
					 | 
				
			||||||
	config_device
 | 
					 | 
				
			||||||
	tcpdump -nei veth1 &
 | 
					 | 
				
			||||||
	cat /sys/kernel/debug/tracing/trace_pipe &
 | 
					 | 
				
			||||||
	add_ipip_tunnel
 | 
					 | 
				
			||||||
	ethtool -K veth1 gso off gro off rx off tx off
 | 
					 | 
				
			||||||
	ip link set dev veth1 mtu 1500
 | 
					 | 
				
			||||||
	attach_bpf $DEV ipip_set_tunnel ipip_get_tunnel
 | 
					 | 
				
			||||||
	ping -c 1 10.1.1.100
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping -c 1 10.1.1.200
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 iperf -sD -p 5200 > /dev/null
 | 
					 | 
				
			||||||
	sleep 0.2
 | 
					 | 
				
			||||||
	iperf -c 10.1.1.100 -n 5k -p 5200
 | 
					 | 
				
			||||||
	cleanup
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function test_xfrm_tunnel {
 | 
					 | 
				
			||||||
	config_device
 | 
					 | 
				
			||||||
        tcpdump -nei veth1 ip &
 | 
					 | 
				
			||||||
	output=$(mktemp)
 | 
					 | 
				
			||||||
	cat /sys/kernel/debug/tracing/trace_pipe | tee $output &
 | 
					 | 
				
			||||||
        setup_xfrm_tunnel
 | 
					 | 
				
			||||||
	tc qdisc add dev veth1 clsact
 | 
					 | 
				
			||||||
	tc filter add dev veth1 proto ip ingress bpf da obj tcbpf2_kern.o \
 | 
					 | 
				
			||||||
		sec xfrm_get_state
 | 
					 | 
				
			||||||
	ip netns exec at_ns0 ping -c 1 10.1.1.200
 | 
					 | 
				
			||||||
	grep "reqid 1" $output
 | 
					 | 
				
			||||||
	grep "spi 0x1" $output
 | 
					 | 
				
			||||||
	grep "remote ip 0xac100164" $output
 | 
					 | 
				
			||||||
	cleanup
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
function cleanup {
 | 
					 | 
				
			||||||
	set +ex
 | 
					 | 
				
			||||||
	pkill iperf
 | 
					 | 
				
			||||||
	ip netns delete at_ns0
 | 
					 | 
				
			||||||
	ip link del veth1
 | 
					 | 
				
			||||||
	ip link del ipip11
 | 
					 | 
				
			||||||
	ip link del gretap11
 | 
					 | 
				
			||||||
	ip link del ip6gre11
 | 
					 | 
				
			||||||
	ip link del ip6gretap11
 | 
					 | 
				
			||||||
	ip link del vxlan11
 | 
					 | 
				
			||||||
	ip link del geneve11
 | 
					 | 
				
			||||||
	ip link del erspan11
 | 
					 | 
				
			||||||
	ip link del ip6erspan11
 | 
					 | 
				
			||||||
	ip x s flush
 | 
					 | 
				
			||||||
	ip x p flush
 | 
					 | 
				
			||||||
	pkill tcpdump
 | 
					 | 
				
			||||||
	pkill cat
 | 
					 | 
				
			||||||
	set -ex
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
trap cleanup 0 2 3 6 9
 | 
					 | 
				
			||||||
cleanup
 | 
					 | 
				
			||||||
echo "Testing GRE tunnel..."
 | 
					 | 
				
			||||||
test_gre
 | 
					 | 
				
			||||||
echo "Testing IP6GRE tunnel..."
 | 
					 | 
				
			||||||
test_ip6gre
 | 
					 | 
				
			||||||
echo "Testing IP6GRETAP tunnel..."
 | 
					 | 
				
			||||||
test_ip6gretap
 | 
					 | 
				
			||||||
echo "Testing ERSPAN tunnel..."
 | 
					 | 
				
			||||||
test_erspan v1
 | 
					 | 
				
			||||||
test_erspan v2
 | 
					 | 
				
			||||||
echo "Testing IP6ERSPAN tunnel..."
 | 
					 | 
				
			||||||
test_ip6erspan v1
 | 
					 | 
				
			||||||
test_ip6erspan v2
 | 
					 | 
				
			||||||
echo "Testing VXLAN tunnel..."
 | 
					 | 
				
			||||||
test_vxlan
 | 
					 | 
				
			||||||
echo "Testing GENEVE tunnel..."
 | 
					 | 
				
			||||||
test_geneve
 | 
					 | 
				
			||||||
echo "Testing IPIP tunnel..."
 | 
					 | 
				
			||||||
test_ipip
 | 
					 | 
				
			||||||
echo "Testing IPSec tunnel..."
 | 
					 | 
				
			||||||
test_xfrm_tunnel
 | 
					 | 
				
			||||||
echo "*** PASS ***"
 | 
					 | 
				
			||||||
| 
						 | 
					@ -32,7 +32,7 @@ TEST_GEN_FILES = test_pkt_access.o test_xdp.o test_l4lb.o test_tcp_estats.o test
 | 
				
			||||||
	test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \
 | 
						test_l4lb_noinline.o test_xdp_noinline.o test_stacktrace_map.o \
 | 
				
			||||||
	sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \
 | 
						sample_map_ret0.o test_tcpbpf_kern.o test_stacktrace_build_id.o \
 | 
				
			||||||
	sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o \
 | 
						sockmap_tcp_msg_prog.o connect4_prog.o connect6_prog.o test_adjust_tail.o \
 | 
				
			||||||
	test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o
 | 
						test_btf_haskv.o test_btf_nokv.o test_sockmap_kern.o test_tunnel_kern.o
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Order correspond to 'make run_tests' order
 | 
					# Order correspond to 'make run_tests' order
 | 
				
			||||||
TEST_PROGS := test_kmod.sh \
 | 
					TEST_PROGS := test_kmod.sh \
 | 
				
			||||||
| 
						 | 
					@ -40,7 +40,8 @@ TEST_PROGS := test_kmod.sh \
 | 
				
			||||||
	test_xdp_redirect.sh \
 | 
						test_xdp_redirect.sh \
 | 
				
			||||||
	test_xdp_meta.sh \
 | 
						test_xdp_meta.sh \
 | 
				
			||||||
	test_offload.py \
 | 
						test_offload.py \
 | 
				
			||||||
	test_sock_addr.sh
 | 
						test_sock_addr.sh \
 | 
				
			||||||
 | 
						test_tunnel.sh
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Compile but not part of 'make run_tests'
 | 
					# Compile but not part of 'make run_tests'
 | 
				
			||||||
TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr
 | 
					TEST_GEN_PROGS_EXTENDED = test_libbpf_open test_sock_addr
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										729
									
								
								tools/testing/selftests/bpf/test_tunnel.sh
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										729
									
								
								tools/testing/selftests/bpf/test_tunnel.sh
									
									
									
									
									
										Executable file
									
								
							| 
						 | 
					@ -0,0 +1,729 @@
 | 
				
			||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					# SPDX-License-Identifier: GPL-2.0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# End-to-end eBPF tunnel test suite
 | 
				
			||||||
 | 
					#   The script tests BPF network tunnel implementation.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# 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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PING_ARG="-c 3 -w 10 -q"
 | 
				
			||||||
 | 
					ret=0
 | 
				
			||||||
 | 
					GREEN='\033[0;92m'
 | 
				
			||||||
 | 
					RED='\033[0;31m'
 | 
				
			||||||
 | 
					NC='\033[0m' # No Color
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					config_device()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ip netns add at_ns0
 | 
				
			||||||
 | 
						ip link add veth0 type veth peer name veth1
 | 
				
			||||||
 | 
						ip link set veth0 netns at_ns0
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add 172.16.1.100/24 dev veth0
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev veth0 up
 | 
				
			||||||
 | 
						ip link set dev veth1 up mtu 1500
 | 
				
			||||||
 | 
						ip addr add dev veth1 172.16.1.200/24
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_gre_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
					        ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
				
			||||||
 | 
							local 172.16.1.100 remote 172.16.1.200
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE key 2 external
 | 
				
			||||||
 | 
						ip link set dev $DEV up
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_ip6gretap_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# assign ipv6 address
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add ::11/96 dev veth0
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev veth0 up
 | 
				
			||||||
 | 
						ip addr add dev veth1 ::22/96
 | 
				
			||||||
 | 
						ip link set dev veth1 up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE seq flowlabel 0xbcdef key 2 \
 | 
				
			||||||
 | 
							local ::11 remote ::22
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS fc80::100/96
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE external
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
						ip addr add dev $DEV fc80::200/24
 | 
				
			||||||
 | 
						ip link set dev $DEV up
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_erspan_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						if [ "$1" == "v1" ]; then
 | 
				
			||||||
 | 
							ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
				
			||||||
 | 
							local 172.16.1.100 remote 172.16.1.200 \
 | 
				
			||||||
 | 
							erspan_ver 1 erspan 123
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
				
			||||||
 | 
							local 172.16.1.100 remote 172.16.1.200 \
 | 
				
			||||||
 | 
							erspan_ver 2 erspan_dir egress erspan_hwid 3
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE external
 | 
				
			||||||
 | 
						ip link set dev $DEV up
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_ip6erspan_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# assign ipv6 address
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add ::11/96 dev veth0
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev veth0 up
 | 
				
			||||||
 | 
						ip addr add dev veth1 ::22/96
 | 
				
			||||||
 | 
						ip link set dev veth1 up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						if [ "$1" == "v1" ]; then
 | 
				
			||||||
 | 
							ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
				
			||||||
 | 
							local ::11 remote ::22 \
 | 
				
			||||||
 | 
							erspan_ver 1 erspan 123
 | 
				
			||||||
 | 
						else
 | 
				
			||||||
 | 
							ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE seq key 2 \
 | 
				
			||||||
 | 
							local ::11 remote ::22 \
 | 
				
			||||||
 | 
							erspan_ver 2 erspan_dir egress erspan_hwid 7
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE external
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
						ip link set dev $DEV up
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_vxlan_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						# Set static ARP entry here because iptables set-mark works
 | 
				
			||||||
 | 
						# on L3 packet, as a result not applying to ARP packets,
 | 
				
			||||||
 | 
						# causing errors at get_tunnel_{key/opt}.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE \
 | 
				
			||||||
 | 
							id 2 dstport 4789 gbp remote 172.16.1.200
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link set dev $DEV_NS address 52:54:00:d9:01:00 up
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
						ip netns exec at_ns0 arp -s 10.1.1.200 52:54:00:d9:02:00
 | 
				
			||||||
 | 
						ip netns exec at_ns0 iptables -A OUTPUT -j MARK --set-mark 0x800FF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE external gbp dstport 4789
 | 
				
			||||||
 | 
						ip link set dev $DEV address 52:54:00:d9:02:00 up
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
						arp -s 10.1.1.100 52:54:00:d9:01:00
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_ip6vxlan_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						#ip netns exec at_ns0 ip -4 addr del 172.16.1.100 dev veth0
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip -6 addr add ::11/96 dev veth0
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev veth0 up
 | 
				
			||||||
 | 
						#ip -4 addr del 172.16.1.200 dev veth1
 | 
				
			||||||
 | 
						ip -6 addr add dev veth1 ::22/96
 | 
				
			||||||
 | 
						ip link set dev veth1 up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE id 22 dstport 4789 \
 | 
				
			||||||
 | 
							local ::11 remote ::22
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE external dstport 4789
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
						ip link set dev $DEV up
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_geneve_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE \
 | 
				
			||||||
 | 
							id 2 dstport 6081 remote 172.16.1.200
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE dstport 6081 external
 | 
				
			||||||
 | 
						ip link set dev $DEV up
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_ip6geneve_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add ::11/96 dev veth0
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev veth0 up
 | 
				
			||||||
 | 
						ip addr add dev veth1 ::22/96
 | 
				
			||||||
 | 
						ip link set dev veth1 up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE id 22 \
 | 
				
			||||||
 | 
							remote ::22     # geneve has no local option
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE external
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
						ip link set dev $DEV up
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_ipip_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE \
 | 
				
			||||||
 | 
							local 172.16.1.100 remote 172.16.1.200
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE external
 | 
				
			||||||
 | 
						ip link set dev $DEV up
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					add_ipip6tnl_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add ::11/96 dev veth0
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev veth0 up
 | 
				
			||||||
 | 
						ip addr add dev veth1 ::22/96
 | 
				
			||||||
 | 
						ip link set dev veth1 up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip link add dev $DEV_NS type $TYPE \
 | 
				
			||||||
 | 
							local ::11 remote ::22
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip addr add dev $DEV_NS 10.1.1.100/24
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ip link set dev $DEV_NS up
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						ip link add dev $DEV type $TYPE external
 | 
				
			||||||
 | 
						ip addr add dev $DEV 10.1.1.200/24
 | 
				
			||||||
 | 
						ip link set dev $DEV up
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_gre()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=gretap
 | 
				
			||||||
 | 
						DEV_NS=gretap00
 | 
				
			||||||
 | 
						DEV=gretap11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_gre_tunnel
 | 
				
			||||||
 | 
						attach_bpf $DEV gre_set_tunnel gre_get_tunnel
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: $TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: $TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_ip6gre()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=ip6gre
 | 
				
			||||||
 | 
						DEV_NS=ip6gre00
 | 
				
			||||||
 | 
						DEV=ip6gre11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						# reuse the ip6gretap function
 | 
				
			||||||
 | 
						add_ip6gretap_tunnel
 | 
				
			||||||
 | 
						attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
 | 
				
			||||||
 | 
						# underlay
 | 
				
			||||||
 | 
						ping6 $PING_ARG ::11
 | 
				
			||||||
 | 
						# overlay: ipv4 over ipv6
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						# overlay: ipv6 over ipv6
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping6 $PING_ARG fc80::200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: $TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: $TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_ip6gretap()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=ip6gretap
 | 
				
			||||||
 | 
						DEV_NS=ip6gretap00
 | 
				
			||||||
 | 
						DEV=ip6gretap11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_ip6gretap_tunnel
 | 
				
			||||||
 | 
						attach_bpf $DEV ip6gretap_set_tunnel ip6gretap_get_tunnel
 | 
				
			||||||
 | 
						# underlay
 | 
				
			||||||
 | 
						ping6 $PING_ARG ::11
 | 
				
			||||||
 | 
						# overlay: ipv4 over ipv6
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						# overlay: ipv6 over ipv6
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping6 $PING_ARG fc80::200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: $TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: $TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_erspan()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=erspan
 | 
				
			||||||
 | 
						DEV_NS=erspan00
 | 
				
			||||||
 | 
						DEV=erspan11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_erspan_tunnel $1
 | 
				
			||||||
 | 
						attach_bpf $DEV erspan_set_tunnel erspan_get_tunnel
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: $TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: $TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_ip6erspan()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=ip6erspan
 | 
				
			||||||
 | 
						DEV_NS=ip6erspan00
 | 
				
			||||||
 | 
						DEV=ip6erspan11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_ip6erspan_tunnel $1
 | 
				
			||||||
 | 
						attach_bpf $DEV ip4ip6erspan_set_tunnel ip4ip6erspan_get_tunnel
 | 
				
			||||||
 | 
						ping6 $PING_ARG ::11
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: $TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: $TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_vxlan()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=vxlan
 | 
				
			||||||
 | 
						DEV_NS=vxlan00
 | 
				
			||||||
 | 
						DEV=vxlan11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_vxlan_tunnel
 | 
				
			||||||
 | 
						attach_bpf $DEV vxlan_set_tunnel vxlan_get_tunnel
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: $TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: $TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_ip6vxlan()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=vxlan
 | 
				
			||||||
 | 
						DEV_NS=ip6vxlan00
 | 
				
			||||||
 | 
						DEV=ip6vxlan11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_ip6vxlan_tunnel
 | 
				
			||||||
 | 
						ip link set dev veth1 mtu 1500
 | 
				
			||||||
 | 
						attach_bpf $DEV ip6vxlan_set_tunnel ip6vxlan_get_tunnel
 | 
				
			||||||
 | 
						# underlay
 | 
				
			||||||
 | 
						ping6 $PING_ARG ::11
 | 
				
			||||||
 | 
						# ip4 over ip6
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: ip6$TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: ip6$TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_geneve()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=geneve
 | 
				
			||||||
 | 
						DEV_NS=geneve00
 | 
				
			||||||
 | 
						DEV=geneve11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_geneve_tunnel
 | 
				
			||||||
 | 
						attach_bpf $DEV geneve_set_tunnel geneve_get_tunnel
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: $TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: $TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_ip6geneve()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=geneve
 | 
				
			||||||
 | 
						DEV_NS=ip6geneve00
 | 
				
			||||||
 | 
						DEV=ip6geneve11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_ip6geneve_tunnel
 | 
				
			||||||
 | 
						attach_bpf $DEV ip6geneve_set_tunnel ip6geneve_get_tunnel
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: ip6$TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: ip6$TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_ipip()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=ipip
 | 
				
			||||||
 | 
						DEV_NS=ipip00
 | 
				
			||||||
 | 
						DEV=ipip11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_ipip_tunnel
 | 
				
			||||||
 | 
						ip link set dev veth1 mtu 1500
 | 
				
			||||||
 | 
						attach_bpf $DEV ipip_set_tunnel ipip_get_tunnel
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: $TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: $TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_ipip6()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						TYPE=ip6tnl
 | 
				
			||||||
 | 
						DEV_NS=ipip6tnl00
 | 
				
			||||||
 | 
						DEV=ipip6tnl11
 | 
				
			||||||
 | 
						ret=0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						check $TYPE
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
						add_ipip6tnl_tunnel
 | 
				
			||||||
 | 
						ip link set dev veth1 mtu 1500
 | 
				
			||||||
 | 
						attach_bpf $DEV ipip6_set_tunnel ipip6_get_tunnel
 | 
				
			||||||
 | 
						# underlay
 | 
				
			||||||
 | 
						ping6 $PING_ARG ::11
 | 
				
			||||||
 | 
						# ip4 over ip6
 | 
				
			||||||
 | 
						ping $PING_ARG 10.1.1.100
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: $TYPE"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: $TYPE"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					setup_xfrm_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						auth=0x$(printf '1%.0s' {1..40})
 | 
				
			||||||
 | 
						enc=0x$(printf '2%.0s' {1..32})
 | 
				
			||||||
 | 
						spi_in_to_out=0x1
 | 
				
			||||||
 | 
						spi_out_to_in=0x2
 | 
				
			||||||
 | 
						# at_ns0 namespace
 | 
				
			||||||
 | 
						# at_ns0 -> root
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
 | 
				
			||||||
 | 
								spi $spi_in_to_out reqid 1 mode tunnel \
 | 
				
			||||||
 | 
								auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir out \
 | 
				
			||||||
 | 
							tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
 | 
				
			||||||
 | 
							mode tunnel
 | 
				
			||||||
 | 
						# root -> at_ns0
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
 | 
				
			||||||
 | 
								spi $spi_out_to_in reqid 2 mode tunnel \
 | 
				
			||||||
 | 
								auth-trunc 'hmac(sha1)' $auth 96 enc 'cbc(aes)' $enc
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir in \
 | 
				
			||||||
 | 
							tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
 | 
				
			||||||
 | 
							mode tunnel
 | 
				
			||||||
 | 
						# address & route
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip addr add dev veth0 10.1.1.100/32
 | 
				
			||||||
 | 
						ip netns exec at_ns0 \
 | 
				
			||||||
 | 
							ip route add 10.1.1.200 dev veth0 via 172.16.1.200 \
 | 
				
			||||||
 | 
								src 10.1.1.100
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						# root namespace
 | 
				
			||||||
 | 
						# at_ns0 -> root
 | 
				
			||||||
 | 
						ip xfrm state add src 172.16.1.100 dst 172.16.1.200 proto esp \
 | 
				
			||||||
 | 
							spi $spi_in_to_out reqid 1 mode tunnel \
 | 
				
			||||||
 | 
							auth-trunc 'hmac(sha1)' $auth 96  enc 'cbc(aes)' $enc
 | 
				
			||||||
 | 
						ip xfrm policy add src 10.1.1.100/32 dst 10.1.1.200/32 dir in \
 | 
				
			||||||
 | 
							tmpl src 172.16.1.100 dst 172.16.1.200 proto esp reqid 1 \
 | 
				
			||||||
 | 
							mode tunnel
 | 
				
			||||||
 | 
						# root -> at_ns0
 | 
				
			||||||
 | 
						ip xfrm state add src 172.16.1.200 dst 172.16.1.100 proto esp \
 | 
				
			||||||
 | 
							spi $spi_out_to_in reqid 2 mode tunnel \
 | 
				
			||||||
 | 
							auth-trunc 'hmac(sha1)' $auth 96  enc 'cbc(aes)' $enc
 | 
				
			||||||
 | 
						ip xfrm policy add src 10.1.1.200/32 dst 10.1.1.100/32 dir out \
 | 
				
			||||||
 | 
							tmpl src 172.16.1.200 dst 172.16.1.100 proto esp reqid 2 \
 | 
				
			||||||
 | 
							mode tunnel
 | 
				
			||||||
 | 
						# address & route
 | 
				
			||||||
 | 
						ip addr add dev veth1 10.1.1.200/32
 | 
				
			||||||
 | 
						ip route add 10.1.1.100 dev veth1 via 172.16.1.100 src 10.1.1.200
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test_xfrm_tunnel()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						config_device
 | 
				
			||||||
 | 
					        #tcpdump -nei veth1 ip &
 | 
				
			||||||
 | 
						output=$(mktemp)
 | 
				
			||||||
 | 
						cat /sys/kernel/debug/tracing/trace_pipe | tee $output &
 | 
				
			||||||
 | 
					        setup_xfrm_tunnel
 | 
				
			||||||
 | 
						tc qdisc add dev veth1 clsact
 | 
				
			||||||
 | 
						tc filter add dev veth1 proto ip ingress bpf da obj test_tunnel_kern.o \
 | 
				
			||||||
 | 
							sec xfrm_get_state
 | 
				
			||||||
 | 
						ip netns exec at_ns0 ping $PING_ARG 10.1.1.200
 | 
				
			||||||
 | 
						sleep 1
 | 
				
			||||||
 | 
						grep "reqid 1" $output
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						grep "spi 0x1" $output
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						grep "remote ip 0xac100164" $output
 | 
				
			||||||
 | 
						check_err $?
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if [ $ret -ne 0 ]; then
 | 
				
			||||||
 | 
					                echo -e ${RED}"FAIL: xfrm tunnel"${NC}
 | 
				
			||||||
 | 
					                return 1
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo -e ${GREEN}"PASS: xfrm tunnel"${NC}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					attach_bpf()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						DEV=$1
 | 
				
			||||||
 | 
						SET=$2
 | 
				
			||||||
 | 
						GET=$3
 | 
				
			||||||
 | 
						tc qdisc add dev $DEV clsact
 | 
				
			||||||
 | 
						tc filter add dev $DEV egress bpf da obj test_tunnel_kern.o sec $SET
 | 
				
			||||||
 | 
						tc filter add dev $DEV ingress bpf da obj test_tunnel_kern.o sec $GET
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ip netns delete at_ns0 2> /dev/null
 | 
				
			||||||
 | 
						ip link del veth1 2> /dev/null
 | 
				
			||||||
 | 
						ip link del ipip11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del ipip6tnl11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del gretap11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del ip6gre11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del ip6gretap11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del vxlan11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del ip6vxlan11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del geneve11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del ip6geneve11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del erspan11 2> /dev/null
 | 
				
			||||||
 | 
						ip link del ip6erspan11 2> /dev/null
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup_exit()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						echo "CATCH SIGKILL or SIGINT, cleanup and exit"
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
						exit 0
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						ip link help $1 2>&1 | grep -q "^Usage:"
 | 
				
			||||||
 | 
						if [ $? -ne 0 ];then
 | 
				
			||||||
 | 
							echo "SKIP $1: iproute2 not support"
 | 
				
			||||||
 | 
						cleanup
 | 
				
			||||||
 | 
						return 1
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enable_debug()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						echo 'file ip_gre.c +p' > /sys/kernel/debug/dynamic_debug/control
 | 
				
			||||||
 | 
						echo 'file ip6_gre.c +p' > /sys/kernel/debug/dynamic_debug/control
 | 
				
			||||||
 | 
						echo 'file vxlan.c +p' > /sys/kernel/debug/dynamic_debug/control
 | 
				
			||||||
 | 
						echo 'file geneve.c +p' > /sys/kernel/debug/dynamic_debug/control
 | 
				
			||||||
 | 
						echo 'file ipip.c +p' > /sys/kernel/debug/dynamic_debug/control
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_err()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						if [ $ret -eq 0 ]; then
 | 
				
			||||||
 | 
							ret=$1
 | 
				
			||||||
 | 
						fi
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					bpf_tunnel_test()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						echo "Testing GRE tunnel..."
 | 
				
			||||||
 | 
						test_gre
 | 
				
			||||||
 | 
						echo "Testing IP6GRE tunnel..."
 | 
				
			||||||
 | 
						test_ip6gre
 | 
				
			||||||
 | 
						echo "Testing IP6GRETAP tunnel..."
 | 
				
			||||||
 | 
						test_ip6gretap
 | 
				
			||||||
 | 
						echo "Testing ERSPAN tunnel..."
 | 
				
			||||||
 | 
						test_erspan v2
 | 
				
			||||||
 | 
						echo "Testing IP6ERSPAN tunnel..."
 | 
				
			||||||
 | 
						test_ip6erspan v2
 | 
				
			||||||
 | 
						echo "Testing VXLAN tunnel..."
 | 
				
			||||||
 | 
						test_vxlan
 | 
				
			||||||
 | 
						echo "Testing IP6VXLAN tunnel..."
 | 
				
			||||||
 | 
						test_ip6vxlan
 | 
				
			||||||
 | 
						echo "Testing GENEVE tunnel..."
 | 
				
			||||||
 | 
						test_geneve
 | 
				
			||||||
 | 
						echo "Testing IP6GENEVE tunnel..."
 | 
				
			||||||
 | 
						test_ip6geneve
 | 
				
			||||||
 | 
						echo "Testing IPIP tunnel..."
 | 
				
			||||||
 | 
						test_ipip
 | 
				
			||||||
 | 
						echo "Testing IPIP6 tunnel..."
 | 
				
			||||||
 | 
						test_ipip6
 | 
				
			||||||
 | 
						echo "Testing IPSec tunnel..."
 | 
				
			||||||
 | 
						test_xfrm_tunnel
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					trap cleanup 0 3 6
 | 
				
			||||||
 | 
					trap cleanup_exit 2 9
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					cleanup
 | 
				
			||||||
 | 
					bpf_tunnel_test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					exit 0
 | 
				
			||||||
| 
						 | 
					@ -1,3 +1,4 @@
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: GPL-2.0
 | 
				
			||||||
/* Copyright (c) 2016 VMware
 | 
					/* Copyright (c) 2016 VMware
 | 
				
			||||||
 * Copyright (c) 2016 Facebook
 | 
					 * Copyright (c) 2016 Facebook
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
| 
						 | 
					@ -5,39 +6,41 @@
 | 
				
			||||||
 * modify it under the terms of version 2 of the GNU General Public
 | 
					 * modify it under the terms of version 2 of the GNU General Public
 | 
				
			||||||
 * License as published by the Free Software Foundation.
 | 
					 * License as published by the Free Software Foundation.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#define KBUILD_MODNAME "foo"
 | 
					#include <stddef.h>
 | 
				
			||||||
#include <uapi/linux/bpf.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include <uapi/linux/if_ether.h>
 | 
					#include <arpa/inet.h>
 | 
				
			||||||
#include <uapi/linux/if_packet.h>
 | 
					#include <linux/bpf.h>
 | 
				
			||||||
#include <uapi/linux/ip.h>
 | 
					#include <linux/if_ether.h>
 | 
				
			||||||
#include <uapi/linux/ipv6.h>
 | 
					#include <linux/if_packet.h>
 | 
				
			||||||
#include <uapi/linux/in.h>
 | 
					#include <linux/ip.h>
 | 
				
			||||||
#include <uapi/linux/tcp.h>
 | 
					#include <linux/ipv6.h>
 | 
				
			||||||
#include <uapi/linux/filter.h>
 | 
					#include <linux/types.h>
 | 
				
			||||||
#include <uapi/linux/pkt_cls.h>
 | 
					#include <linux/tcp.h>
 | 
				
			||||||
#include <uapi/linux/erspan.h>
 | 
					#include <linux/socket.h>
 | 
				
			||||||
#include <net/ipv6.h>
 | 
					#include <linux/pkt_cls.h>
 | 
				
			||||||
 | 
					#include <linux/erspan.h>
 | 
				
			||||||
#include "bpf_helpers.h"
 | 
					#include "bpf_helpers.h"
 | 
				
			||||||
#include "bpf_endian.h"
 | 
					#include "bpf_endian.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#define _htonl __builtin_bswap32
 | 
					 | 
				
			||||||
#define ERROR(ret) do {\
 | 
					#define ERROR(ret) do {\
 | 
				
			||||||
		char fmt[] = "ERROR line:%d ret:%d\n";\
 | 
							char fmt[] = "ERROR line:%d ret:%d\n";\
 | 
				
			||||||
		bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
 | 
							bpf_trace_printk(fmt, sizeof(fmt), __LINE__, ret); \
 | 
				
			||||||
	} while(0)
 | 
						} while (0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					int _version SEC("version") = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct geneve_opt {
 | 
					struct geneve_opt {
 | 
				
			||||||
	__be16	opt_class;
 | 
						__be16	opt_class;
 | 
				
			||||||
	u8	type;
 | 
						__u8	type;
 | 
				
			||||||
	u8	length:5;
 | 
						__u8	length:5;
 | 
				
			||||||
	u8	r3:1;
 | 
						__u8	r3:1;
 | 
				
			||||||
	u8	r2:1;
 | 
						__u8	r2:1;
 | 
				
			||||||
	u8	r1:1;
 | 
						__u8	r1:1;
 | 
				
			||||||
	u8	opt_data[8]; /* hard-coded to 8 byte */
 | 
						__u8	opt_data[8]; /* hard-coded to 8 byte */
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct vxlan_metadata {
 | 
					struct vxlan_metadata {
 | 
				
			||||||
	u32     gbp;
 | 
						__u32     gbp;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SEC("gre_set_tunnel")
 | 
					SEC("gre_set_tunnel")
 | 
				
			||||||
| 
						 | 
					@ -86,7 +89,7 @@ int _ip6gretap_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__builtin_memset(&key, 0x0, sizeof(key));
 | 
						__builtin_memset(&key, 0x0, sizeof(key));
 | 
				
			||||||
	key.remote_ipv6[3] = _htonl(0x11); /* ::11 */
 | 
						key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
 | 
				
			||||||
	key.tunnel_id = 2;
 | 
						key.tunnel_id = 2;
 | 
				
			||||||
	key.tunnel_tos = 0;
 | 
						key.tunnel_tos = 0;
 | 
				
			||||||
	key.tunnel_ttl = 64;
 | 
						key.tunnel_ttl = 64;
 | 
				
			||||||
| 
						 | 
					@ -136,7 +139,8 @@ int _erspan_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	key.tunnel_tos = 0;
 | 
						key.tunnel_tos = 0;
 | 
				
			||||||
	key.tunnel_ttl = 64;
 | 
						key.tunnel_ttl = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
 | 
						ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_ZERO_CSUM_TX);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		ERROR(ret);
 | 
							ERROR(ret);
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
| 
						 | 
					@ -147,8 +151,8 @@ int _erspan_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	md.version = 1;
 | 
						md.version = 1;
 | 
				
			||||||
	md.u.index = bpf_htonl(123);
 | 
						md.u.index = bpf_htonl(123);
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	u8 direction = 1;
 | 
						__u8 direction = 1;
 | 
				
			||||||
	u8 hwid = 7;
 | 
						__u8 hwid = 7;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	md.version = 2;
 | 
						md.version = 2;
 | 
				
			||||||
	md.u.md2.dir = direction;
 | 
						md.u.md2.dir = direction;
 | 
				
			||||||
| 
						 | 
					@ -171,7 +175,7 @@ int _erspan_get_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
 | 
						char fmt[] = "key %d remote ip 0x%x erspan version %d\n";
 | 
				
			||||||
	struct bpf_tunnel_key key;
 | 
						struct bpf_tunnel_key key;
 | 
				
			||||||
	struct erspan_metadata md;
 | 
						struct erspan_metadata md;
 | 
				
			||||||
	u32 index;
 | 
						__u32 index;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
 | 
						ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), 0);
 | 
				
			||||||
| 
						 | 
					@ -214,7 +218,7 @@ int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__builtin_memset(&key, 0x0, sizeof(key));
 | 
						__builtin_memset(&key, 0x0, sizeof(key));
 | 
				
			||||||
	key.remote_ipv6[3] = _htonl(0x11);
 | 
						key.remote_ipv6[3] = bpf_htonl(0x11);
 | 
				
			||||||
	key.tunnel_id = 2;
 | 
						key.tunnel_id = 2;
 | 
				
			||||||
	key.tunnel_tos = 0;
 | 
						key.tunnel_tos = 0;
 | 
				
			||||||
	key.tunnel_ttl = 64;
 | 
						key.tunnel_ttl = 64;
 | 
				
			||||||
| 
						 | 
					@ -229,11 +233,11 @@ int _ip4ip6erspan_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	__builtin_memset(&md, 0, sizeof(md));
 | 
						__builtin_memset(&md, 0, sizeof(md));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef ERSPAN_V1
 | 
					#ifdef ERSPAN_V1
 | 
				
			||||||
	md.u.index = htonl(123);
 | 
						md.u.index = bpf_htonl(123);
 | 
				
			||||||
	md.version = 1;
 | 
						md.version = 1;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
	u8 direction = 0;
 | 
						__u8 direction = 0;
 | 
				
			||||||
	u8 hwid = 17;
 | 
						__u8 hwid = 17;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	md.version = 2;
 | 
						md.version = 2;
 | 
				
			||||||
	md.u.md2.dir = direction;
 | 
						md.u.md2.dir = direction;
 | 
				
			||||||
| 
						 | 
					@ -256,10 +260,11 @@ int _ip4ip6erspan_get_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
 | 
						char fmt[] = "ip6erspan get key %d remote ip6 ::%x erspan version %d\n";
 | 
				
			||||||
	struct bpf_tunnel_key key;
 | 
						struct bpf_tunnel_key key;
 | 
				
			||||||
	struct erspan_metadata md;
 | 
						struct erspan_metadata md;
 | 
				
			||||||
	u32 index;
 | 
						__u32 index;
 | 
				
			||||||
	int ret;
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
 | 
						ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_TUNINFO_IPV6);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		ERROR(ret);
 | 
							ERROR(ret);
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
| 
						 | 
					@ -304,7 +309,8 @@ int _vxlan_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	key.tunnel_tos = 0;
 | 
						key.tunnel_tos = 0;
 | 
				
			||||||
	key.tunnel_ttl = 64;
 | 
						key.tunnel_ttl = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
 | 
						ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_ZERO_CSUM_TX);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		ERROR(ret);
 | 
							ERROR(ret);
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
| 
						 | 
					@ -346,6 +352,48 @@ int _vxlan_get_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	return TC_ACT_OK;
 | 
						return TC_ACT_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SEC("ip6vxlan_set_tunnel")
 | 
				
			||||||
 | 
					int _ip6vxlan_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bpf_tunnel_key key;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__builtin_memset(&key, 0x0, sizeof(key));
 | 
				
			||||||
 | 
						key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
 | 
				
			||||||
 | 
						key.tunnel_id = 22;
 | 
				
			||||||
 | 
						key.tunnel_tos = 0;
 | 
				
			||||||
 | 
						key.tunnel_ttl = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_TUNINFO_IPV6);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							ERROR(ret);
 | 
				
			||||||
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return TC_ACT_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SEC("ip6vxlan_get_tunnel")
 | 
				
			||||||
 | 
					int _ip6vxlan_get_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char fmt[] = "key %d remote ip6 ::%x label %x\n";
 | 
				
			||||||
 | 
						struct bpf_tunnel_key key;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_TUNINFO_IPV6);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							ERROR(ret);
 | 
				
			||||||
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bpf_trace_printk(fmt, sizeof(fmt),
 | 
				
			||||||
 | 
								 key.tunnel_id, key.remote_ipv6[3], key.tunnel_label);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return TC_ACT_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SEC("geneve_set_tunnel")
 | 
					SEC("geneve_set_tunnel")
 | 
				
			||||||
int _geneve_set_tunnel(struct __sk_buff *skb)
 | 
					int _geneve_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -360,15 +408,16 @@ int _geneve_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	key.tunnel_ttl = 64;
 | 
						key.tunnel_ttl = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	__builtin_memset(&gopt, 0x0, sizeof(gopt));
 | 
						__builtin_memset(&gopt, 0x0, sizeof(gopt));
 | 
				
			||||||
	gopt.opt_class = 0x102; /* Open Virtual Networking (OVN) */
 | 
						gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
 | 
				
			||||||
	gopt.type = 0x08;
 | 
						gopt.type = 0x08;
 | 
				
			||||||
	gopt.r1 = 0;
 | 
						gopt.r1 = 0;
 | 
				
			||||||
	gopt.r2 = 0;
 | 
						gopt.r2 = 0;
 | 
				
			||||||
	gopt.r3 = 0;
 | 
						gopt.r3 = 0;
 | 
				
			||||||
	gopt.length = 2; /* 4-byte multiple */
 | 
						gopt.length = 2; /* 4-byte multiple */
 | 
				
			||||||
	*(int *) &gopt.opt_data = 0xdeadbeef;
 | 
						*(int *) &gopt.opt_data = bpf_htonl(0xdeadbeef);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_ZERO_CSUM_TX);
 | 
						ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_ZERO_CSUM_TX);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		ERROR(ret);
 | 
							ERROR(ret);
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
| 
						 | 
					@ -408,6 +457,71 @@ int _geneve_get_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	return TC_ACT_OK;
 | 
						return TC_ACT_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SEC("ip6geneve_set_tunnel")
 | 
				
			||||||
 | 
					int _ip6geneve_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						struct bpf_tunnel_key key;
 | 
				
			||||||
 | 
						struct geneve_opt gopt;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__builtin_memset(&key, 0x0, sizeof(key));
 | 
				
			||||||
 | 
						key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
 | 
				
			||||||
 | 
						key.tunnel_id = 22;
 | 
				
			||||||
 | 
						key.tunnel_tos = 0;
 | 
				
			||||||
 | 
						key.tunnel_ttl = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_TUNINFO_IPV6);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							ERROR(ret);
 | 
				
			||||||
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						__builtin_memset(&gopt, 0x0, sizeof(gopt));
 | 
				
			||||||
 | 
						gopt.opt_class = bpf_htons(0x102); /* Open Virtual Networking (OVN) */
 | 
				
			||||||
 | 
						gopt.type = 0x08;
 | 
				
			||||||
 | 
						gopt.r1 = 0;
 | 
				
			||||||
 | 
						gopt.r2 = 0;
 | 
				
			||||||
 | 
						gopt.r3 = 0;
 | 
				
			||||||
 | 
						gopt.length = 2; /* 4-byte multiple */
 | 
				
			||||||
 | 
						*(int *) &gopt.opt_data = bpf_htonl(0xfeedbeef);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = bpf_skb_set_tunnel_opt(skb, &gopt, sizeof(gopt));
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							ERROR(ret);
 | 
				
			||||||
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return TC_ACT_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					SEC("ip6geneve_get_tunnel")
 | 
				
			||||||
 | 
					int _ip6geneve_get_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						char fmt[] = "key %d remote ip 0x%x geneve class 0x%x\n";
 | 
				
			||||||
 | 
						struct bpf_tunnel_key key;
 | 
				
			||||||
 | 
						struct geneve_opt gopt;
 | 
				
			||||||
 | 
						int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_TUNINFO_IPV6);
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							ERROR(ret);
 | 
				
			||||||
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						ret = bpf_skb_get_tunnel_opt(skb, &gopt, sizeof(gopt));
 | 
				
			||||||
 | 
						if (ret < 0) {
 | 
				
			||||||
 | 
							ERROR(ret);
 | 
				
			||||||
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bpf_trace_printk(fmt, sizeof(fmt),
 | 
				
			||||||
 | 
								key.tunnel_id, key.remote_ipv4, gopt.opt_class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return TC_ACT_OK;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
SEC("ipip_set_tunnel")
 | 
					SEC("ipip_set_tunnel")
 | 
				
			||||||
int _ipip_set_tunnel(struct __sk_buff *skb)
 | 
					int _ipip_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
| 
						 | 
					@ -431,9 +545,9 @@ int _ipip_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
		if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
 | 
							if (iph->protocol != IPPROTO_TCP || iph->ihl != 5)
 | 
				
			||||||
			return TC_ACT_SHOT;
 | 
								return TC_ACT_SHOT;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (tcp->dest == htons(5200))
 | 
							if (tcp->dest == bpf_htons(5200))
 | 
				
			||||||
			key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
 | 
								key.remote_ipv4 = 0xac100164; /* 172.16.1.100 */
 | 
				
			||||||
		else if (tcp->dest == htons(5201))
 | 
							else if (tcp->dest == bpf_htons(5201))
 | 
				
			||||||
			key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
 | 
								key.remote_ipv4 = 0xac100165; /* 172.16.1.101 */
 | 
				
			||||||
		else
 | 
							else
 | 
				
			||||||
			return TC_ACT_SHOT;
 | 
								return TC_ACT_SHOT;
 | 
				
			||||||
| 
						 | 
					@ -481,28 +595,12 @@ int _ipip6_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	key.remote_ipv6[0] = _htonl(0x2401db00);
 | 
						__builtin_memset(&key, 0x0, sizeof(key));
 | 
				
			||||||
 | 
						key.remote_ipv6[3] = bpf_htonl(0x11); /* ::11 */
 | 
				
			||||||
	key.tunnel_ttl = 64;
 | 
						key.tunnel_ttl = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (iph->protocol == IPPROTO_ICMP) {
 | 
						ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
		key.remote_ipv6[3] = _htonl(1);
 | 
									     BPF_F_TUNINFO_IPV6);
 | 
				
			||||||
	} else {
 | 
					 | 
				
			||||||
		if (iph->protocol != IPPROTO_TCP || iph->ihl != 5) {
 | 
					 | 
				
			||||||
			ERROR(iph->protocol);
 | 
					 | 
				
			||||||
			return TC_ACT_SHOT;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		if (tcp->dest == htons(5200)) {
 | 
					 | 
				
			||||||
			key.remote_ipv6[3] = _htonl(1);
 | 
					 | 
				
			||||||
		} else if (tcp->dest == htons(5201)) {
 | 
					 | 
				
			||||||
			key.remote_ipv6[3] = _htonl(2);
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			ERROR(tcp->dest);
 | 
					 | 
				
			||||||
			return TC_ACT_SHOT;
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
 | 
					 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		ERROR(ret);
 | 
							ERROR(ret);
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
| 
						 | 
					@ -518,14 +616,15 @@ int _ipip6_get_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	struct bpf_tunnel_key key;
 | 
						struct bpf_tunnel_key key;
 | 
				
			||||||
	char fmt[] = "remote ip6 %x::%x\n";
 | 
						char fmt[] = "remote ip6 %x::%x\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
 | 
						ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_TUNINFO_IPV6);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		ERROR(ret);
 | 
							ERROR(ret);
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
 | 
						bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
 | 
				
			||||||
			 _htonl(key.remote_ipv6[3]));
 | 
								 bpf_htonl(key.remote_ipv6[3]));
 | 
				
			||||||
	return TC_ACT_OK;
 | 
						return TC_ACT_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -545,28 +644,29 @@ int _ip6ip6_set_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	key.remote_ipv6[0] = _htonl(0x2401db00);
 | 
						key.remote_ipv6[0] = bpf_htonl(0x2401db00);
 | 
				
			||||||
	key.tunnel_ttl = 64;
 | 
						key.tunnel_ttl = 64;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (iph->nexthdr == NEXTHDR_ICMP) {
 | 
						if (iph->nexthdr == 58 /* NEXTHDR_ICMP */) {
 | 
				
			||||||
		key.remote_ipv6[3] = _htonl(1);
 | 
							key.remote_ipv6[3] = bpf_htonl(1);
 | 
				
			||||||
	} else {
 | 
						} else {
 | 
				
			||||||
		if (iph->nexthdr != NEXTHDR_TCP) {
 | 
							if (iph->nexthdr != 6 /* NEXTHDR_TCP */) {
 | 
				
			||||||
			ERROR(iph->nexthdr);
 | 
								ERROR(iph->nexthdr);
 | 
				
			||||||
			return TC_ACT_SHOT;
 | 
								return TC_ACT_SHOT;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		if (tcp->dest == htons(5200)) {
 | 
							if (tcp->dest == bpf_htons(5200)) {
 | 
				
			||||||
			key.remote_ipv6[3] = _htonl(1);
 | 
								key.remote_ipv6[3] = bpf_htonl(1);
 | 
				
			||||||
		} else if (tcp->dest == htons(5201)) {
 | 
							} else if (tcp->dest == bpf_htons(5201)) {
 | 
				
			||||||
			key.remote_ipv6[3] = _htonl(2);
 | 
								key.remote_ipv6[3] = bpf_htonl(2);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			ERROR(tcp->dest);
 | 
								ERROR(tcp->dest);
 | 
				
			||||||
			return TC_ACT_SHOT;
 | 
								return TC_ACT_SHOT;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
 | 
						ret = bpf_skb_set_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_TUNINFO_IPV6);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		ERROR(ret);
 | 
							ERROR(ret);
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
| 
						 | 
					@ -582,14 +682,15 @@ int _ip6ip6_get_tunnel(struct __sk_buff *skb)
 | 
				
			||||||
	struct bpf_tunnel_key key;
 | 
						struct bpf_tunnel_key key;
 | 
				
			||||||
	char fmt[] = "remote ip6 %x::%x\n";
 | 
						char fmt[] = "remote ip6 %x::%x\n";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key), BPF_F_TUNINFO_IPV6);
 | 
						ret = bpf_skb_get_tunnel_key(skb, &key, sizeof(key),
 | 
				
			||||||
 | 
									     BPF_F_TUNINFO_IPV6);
 | 
				
			||||||
	if (ret < 0) {
 | 
						if (ret < 0) {
 | 
				
			||||||
		ERROR(ret);
 | 
							ERROR(ret);
 | 
				
			||||||
		return TC_ACT_SHOT;
 | 
							return TC_ACT_SHOT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	bpf_trace_printk(fmt, sizeof(fmt), _htonl(key.remote_ipv6[0]),
 | 
						bpf_trace_printk(fmt, sizeof(fmt), bpf_htonl(key.remote_ipv6[0]),
 | 
				
			||||||
			 _htonl(key.remote_ipv6[3]));
 | 
								 bpf_htonl(key.remote_ipv6[3]));
 | 
				
			||||||
	return TC_ACT_OK;
 | 
						return TC_ACT_OK;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in a new issue