|  | #!/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, IPv6: 1::22 (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, IPv6: 1::11 (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.100 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 | 
|  |  | 
|  | BPF_FILE="test_tunnel_kern.bpf.o" | 
|  | BPF_PIN_TUNNEL_DIR="/sys/fs/bpf/tc/tunnel" | 
|  | 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_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_ip6tnl_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 addr add dev $DEV_NS 1::11/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 1::22/96 | 
|  | 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_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_ip6tnl_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} | 
|  | } | 
|  |  | 
|  | test_ip6ip6() | 
|  | { | 
|  | TYPE=ip6tnl | 
|  | DEV_NS=ip6ip6tnl00 | 
|  | DEV=ip6ip6tnl11 | 
|  | ret=0 | 
|  |  | 
|  | check $TYPE | 
|  | config_device | 
|  | add_ip6tnl_tunnel | 
|  | ip link set dev veth1 mtu 1500 | 
|  | attach_bpf $DEV ip6ip6_set_tunnel ip6ip6_get_tunnel | 
|  | # underlay | 
|  | ping6 $PING_ARG ::11 | 
|  | # ip6 over ip6 | 
|  | ping6 $PING_ARG 1::11 | 
|  | check_err $? | 
|  | ip netns exec at_ns0 ping6 $PING_ARG 1::22 | 
|  | 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} | 
|  | } | 
|  |  | 
|  | 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 | 
|  | > /sys/kernel/debug/tracing/trace | 
|  | setup_xfrm_tunnel | 
|  | mkdir -p ${BPF_PIN_TUNNEL_DIR} | 
|  | bpftool prog loadall ${BPF_FILE} ${BPF_PIN_TUNNEL_DIR} | 
|  | tc qdisc add dev veth1 clsact | 
|  | tc filter add dev veth1 proto ip ingress bpf da object-pinned \ | 
|  | ${BPF_PIN_TUNNEL_DIR}/xfrm_get_state | 
|  | ip netns exec at_ns0 ping $PING_ARG 10.1.1.200 | 
|  | sleep 1 | 
|  | grep "reqid 1" /sys/kernel/debug/tracing/trace | 
|  | check_err $? | 
|  | grep "spi 0x1" /sys/kernel/debug/tracing/trace | 
|  | check_err $? | 
|  | grep "remote ip 0xac100164" /sys/kernel/debug/tracing/trace | 
|  | 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 | 
|  | mkdir -p ${BPF_PIN_TUNNEL_DIR} | 
|  | bpftool prog loadall ${BPF_FILE} ${BPF_PIN_TUNNEL_DIR}/ | 
|  | tc qdisc add dev $DEV clsact | 
|  | tc filter add dev $DEV egress bpf da object-pinned ${BPF_PIN_TUNNEL_DIR}/$SET | 
|  | tc filter add dev $DEV ingress bpf da object-pinned ${BPF_PIN_TUNNEL_DIR}/$GET | 
|  | } | 
|  |  | 
|  | cleanup() | 
|  | { | 
|  | rm -rf ${BPF_PIN_TUNNEL_DIR} | 
|  |  | 
|  | 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 ip6ip6tnl11 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 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 | 
|  | ip xfrm policy delete dir out src 10.1.1.200/32 dst 10.1.1.100/32 2> /dev/null | 
|  | ip xfrm policy delete dir in src 10.1.1.100/32 dst 10.1.1.200/32 2> /dev/null | 
|  | ip xfrm state delete src 172.16.1.100 dst 172.16.1.200 proto esp spi 0x1 2> /dev/null | 
|  | ip xfrm state delete src 172.16.1.200 dst 172.16.1.100 proto esp spi 0x2 2> /dev/null | 
|  | } | 
|  |  | 
|  | cleanup_exit() | 
|  | { | 
|  | echo "CATCH SIGKILL or SIGINT, cleanup and exit" | 
|  | cleanup | 
|  | exit 0 | 
|  | } | 
|  |  | 
|  | check() | 
|  | { | 
|  | ip link help 2>&1 | grep -q "\s$1\s" | 
|  | 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 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() | 
|  | { | 
|  | local errors=0 | 
|  |  | 
|  | echo "Testing GRE tunnel..." | 
|  | test_gre | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing IP6GRE tunnel..." | 
|  | test_ip6gre | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing IP6GRETAP tunnel..." | 
|  | test_ip6gretap | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing ERSPAN tunnel..." | 
|  | test_erspan v2 | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing IP6ERSPAN tunnel..." | 
|  | test_ip6erspan v2 | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing GENEVE tunnel..." | 
|  | test_geneve | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing IP6GENEVE tunnel..." | 
|  | test_ip6geneve | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing IPIP tunnel..." | 
|  | test_ipip | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing IPIP6 tunnel..." | 
|  | test_ipip6 | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing IP6IP6 tunnel..." | 
|  | test_ip6ip6 | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | echo "Testing IPSec tunnel..." | 
|  | test_xfrm_tunnel | 
|  | errors=$(( $errors + $? )) | 
|  |  | 
|  | return $errors | 
|  | } | 
|  |  | 
|  | trap cleanup 0 3 6 | 
|  | trap cleanup_exit 2 9 | 
|  |  | 
|  | cleanup | 
|  | bpf_tunnel_test | 
|  |  | 
|  | if [ $? -ne 0 ]; then | 
|  | echo -e "$(basename $0): ${RED}FAIL${NC}" | 
|  | exit 1 | 
|  | fi | 
|  | echo -e "$(basename $0): ${GREEN}PASS${NC}" | 
|  | exit 0 |