198cdabcdSWillem de Bruijn#!/bin/bash 298cdabcdSWillem de Bruijn# SPDX-License-Identifier: GPL-2.0 398cdabcdSWillem de Bruijn# 498cdabcdSWillem de Bruijn# In-place tunneling 598cdabcdSWillem de Bruijn 698af3746SWang YufenBPF_FILE="test_tc_tunnel.bpf.o" 798cdabcdSWillem de Bruijn# must match the port that the bpf program filters on 898cdabcdSWillem de Bruijnreadonly port=8000 998cdabcdSWillem de Bruijn 1098cdabcdSWillem de Bruijnreadonly ns_prefix="ns-$$-" 1198cdabcdSWillem de Bruijnreadonly ns1="${ns_prefix}1" 1298cdabcdSWillem de Bruijnreadonly ns2="${ns_prefix}2" 1398cdabcdSWillem de Bruijn 1498cdabcdSWillem de Bruijnreadonly ns1_v4=192.168.1.1 1598cdabcdSWillem de Bruijnreadonly ns2_v4=192.168.1.2 16ef81bd05SWillem de Bruijnreadonly ns1_v6=fd::1 17ef81bd05SWillem de Bruijnreadonly ns2_v6=fd::2 18ef81bd05SWillem de Bruijn 19166b5a7fSAlan Maguire# Must match port used by bpf program 20166b5a7fSAlan Maguirereadonly udpport=5555 213ec61df8SAlan Maguire# MPLSoverUDP 223ec61df8SAlan Maguirereadonly mplsudpport=6635 233ec61df8SAlan Maguirereadonly mplsproto=137 24166b5a7fSAlan Maguire 2581429589SWillem de Bruijnreadonly infile="$(mktemp)" 2681429589SWillem de Bruijnreadonly outfile="$(mktemp)" 2798cdabcdSWillem de Bruijn 2898cdabcdSWillem de Bruijnsetup() { 2998cdabcdSWillem de Bruijn ip netns add "${ns1}" 3098cdabcdSWillem de Bruijn ip netns add "${ns2}" 3198cdabcdSWillem de Bruijn 3298cdabcdSWillem de Bruijn ip link add dev veth1 mtu 1500 netns "${ns1}" type veth \ 3398cdabcdSWillem de Bruijn peer name veth2 mtu 1500 netns "${ns2}" 3498cdabcdSWillem de Bruijn 3581429589SWillem de Bruijn ip netns exec "${ns1}" ethtool -K veth1 tso off 3681429589SWillem de Bruijn 3798cdabcdSWillem de Bruijn ip -netns "${ns1}" link set veth1 up 3898cdabcdSWillem de Bruijn ip -netns "${ns2}" link set veth2 up 3998cdabcdSWillem de Bruijn 4098cdabcdSWillem de Bruijn ip -netns "${ns1}" -4 addr add "${ns1_v4}/24" dev veth1 4198cdabcdSWillem de Bruijn ip -netns "${ns2}" -4 addr add "${ns2_v4}/24" dev veth2 42ef81bd05SWillem de Bruijn ip -netns "${ns1}" -6 addr add "${ns1_v6}/64" dev veth1 nodad 43ef81bd05SWillem de Bruijn ip -netns "${ns2}" -6 addr add "${ns2_v6}/64" dev veth2 nodad 4498cdabcdSWillem de Bruijn 4594f16813SWillem de Bruijn # clamp route to reserve room for tunnel headers 4694f16813SWillem de Bruijn ip -netns "${ns1}" -4 route flush table main 4794f16813SWillem de Bruijn ip -netns "${ns1}" -6 route flush table main 48256becd4SXuesen Huang ip -netns "${ns1}" -4 route add "${ns2_v4}" mtu 1450 dev veth1 49256becd4SXuesen Huang ip -netns "${ns1}" -6 route add "${ns2_v6}" mtu 1430 dev veth1 5094f16813SWillem de Bruijn 5198cdabcdSWillem de Bruijn sleep 1 5281429589SWillem de Bruijn 5381429589SWillem de Bruijn dd if=/dev/urandom of="${infile}" bs="${datalen}" count=1 status=none 5498cdabcdSWillem de Bruijn} 5598cdabcdSWillem de Bruijn 5698cdabcdSWillem de Bruijncleanup() { 5798cdabcdSWillem de Bruijn ip netns del "${ns2}" 5898cdabcdSWillem de Bruijn ip netns del "${ns1}" 5981429589SWillem de Bruijn 6081429589SWillem de Bruijn if [[ -f "${outfile}" ]]; then 6181429589SWillem de Bruijn rm "${outfile}" 6281429589SWillem de Bruijn fi 6381429589SWillem de Bruijn if [[ -f "${infile}" ]]; then 6481429589SWillem de Bruijn rm "${infile}" 6581429589SWillem de Bruijn fi 663b054b71SJiri Benc 673b054b71SJiri Benc if [[ -n $server_pid ]]; then 683b054b71SJiri Benc kill $server_pid 2> /dev/null 693b054b71SJiri Benc fi 7098cdabcdSWillem de Bruijn} 7198cdabcdSWillem de Bruijn 7298cdabcdSWillem de Bruijnserver_listen() { 73875fc315SVincent Li ip netns exec "${ns2}" nc "${netcat_opt}" -l "${port}" > "${outfile}" & 7481429589SWillem de Bruijn server_pid=$! 7598cdabcdSWillem de Bruijn} 7698cdabcdSWillem de Bruijn 7798cdabcdSWillem de Bruijnclient_connect() { 7881429589SWillem de Bruijn ip netns exec "${ns1}" timeout 2 nc "${netcat_opt}" -w 1 "${addr2}" "${port}" < "${infile}" 7998cdabcdSWillem de Bruijn echo $? 8098cdabcdSWillem de Bruijn} 8198cdabcdSWillem de Bruijn 8281429589SWillem de Bruijnverify_data() { 8381429589SWillem de Bruijn wait "${server_pid}" 843b054b71SJiri Benc server_pid= 8581429589SWillem de Bruijn # sha1sum returns two fields [sha1] [filepath] 8681429589SWillem de Bruijn # convert to bash array and access first elem 8781429589SWillem de Bruijn insum=($(sha1sum ${infile})) 8881429589SWillem de Bruijn outsum=($(sha1sum ${outfile})) 8981429589SWillem de Bruijn if [[ "${insum[0]}" != "${outsum[0]}" ]]; then 9081429589SWillem de Bruijn echo "data mismatch" 9181429589SWillem de Bruijn exit 1 9281429589SWillem de Bruijn fi 9381429589SWillem de Bruijn} 9481429589SWillem de Bruijn 95*5270950aSAlessandro Carminati (Red Hat)wait_for_port() { 96*5270950aSAlessandro Carminati (Red Hat) for i in $(seq 20); do 97*5270950aSAlessandro Carminati (Red Hat) if ip netns exec "${ns2}" ss ${2:--4}OHntl | grep -q "$1"; then 98*5270950aSAlessandro Carminati (Red Hat) return 0 99*5270950aSAlessandro Carminati (Red Hat) fi 100*5270950aSAlessandro Carminati (Red Hat) sleep 0.1 101*5270950aSAlessandro Carminati (Red Hat) done 102*5270950aSAlessandro Carminati (Red Hat) return 1 103*5270950aSAlessandro Carminati (Red Hat)} 104*5270950aSAlessandro Carminati (Red Hat) 10598cdabcdSWillem de Bruijnset -e 106ef81bd05SWillem de Bruijn 107ef81bd05SWillem de Bruijn# no arguments: automated test, run all 108ef81bd05SWillem de Bruijnif [[ "$#" -eq "0" ]]; then 109ef81bd05SWillem de Bruijn echo "ipip" 1103ec61df8SAlan Maguire $0 ipv4 ipip none 100 111ef81bd05SWillem de Bruijn 1127105f76fSZiyang Xuan echo "ipip6" 1137105f76fSZiyang Xuan $0 ipv4 ipip6 none 100 1147105f76fSZiyang Xuan 115ef81bd05SWillem de Bruijn echo "ip6ip6" 1163ec61df8SAlan Maguire $0 ipv6 ip6tnl none 100 1177255fadeSWillem de Bruijn 118f6ad6accSWillem de Bruijn echo "sit" 119f6ad6accSWillem de Bruijn $0 ipv6 sit none 100 120f6ad6accSWillem de Bruijn 121256becd4SXuesen Huang echo "ip4 vxlan" 122256becd4SXuesen Huang $0 ipv4 vxlan eth 2000 123256becd4SXuesen Huang 124256becd4SXuesen Huang echo "ip6 vxlan" 125256becd4SXuesen Huang $0 ipv6 ip6vxlan eth 2000 126256becd4SXuesen Huang 1273ec61df8SAlan Maguire for mac in none mpls eth ; do 1283ec61df8SAlan Maguire echo "ip gre $mac" 1293ec61df8SAlan Maguire $0 ipv4 gre $mac 100 1307255fadeSWillem de Bruijn 1313ec61df8SAlan Maguire echo "ip6 gre $mac" 1323ec61df8SAlan Maguire $0 ipv6 ip6gre $mac 100 13381429589SWillem de Bruijn 1343ec61df8SAlan Maguire echo "ip gre $mac gso" 1353ec61df8SAlan Maguire $0 ipv4 gre $mac 2000 13681429589SWillem de Bruijn 1373ec61df8SAlan Maguire echo "ip6 gre $mac gso" 1383ec61df8SAlan Maguire $0 ipv6 ip6gre $mac 2000 139ef81bd05SWillem de Bruijn 1403ec61df8SAlan Maguire echo "ip udp $mac" 1413ec61df8SAlan Maguire $0 ipv4 udp $mac 100 142166b5a7fSAlan Maguire 1433ec61df8SAlan Maguire echo "ip6 udp $mac" 1443ec61df8SAlan Maguire $0 ipv6 ip6udp $mac 100 145166b5a7fSAlan Maguire 1463ec61df8SAlan Maguire echo "ip udp $mac gso" 1473ec61df8SAlan Maguire $0 ipv4 udp $mac 2000 148166b5a7fSAlan Maguire 1493ec61df8SAlan Maguire echo "ip6 udp $mac gso" 1503ec61df8SAlan Maguire $0 ipv6 ip6udp $mac 2000 1513ec61df8SAlan Maguire done 152166b5a7fSAlan Maguire 153ef81bd05SWillem de Bruijn echo "OK. All tests passed" 154ef81bd05SWillem de Bruijn exit 0 155ef81bd05SWillem de Bruijnfi 156ef81bd05SWillem de Bruijn 1573ec61df8SAlan Maguireif [[ "$#" -ne "4" ]]; then 158ef81bd05SWillem de Bruijn echo "Usage: $0" 1593ec61df8SAlan Maguire echo " or: $0 <ipv4|ipv6> <tuntype> <none|mpls|eth> <data_len>" 160ef81bd05SWillem de Bruijn exit 1 161ef81bd05SWillem de Bruijnfi 162ef81bd05SWillem de Bruijn 163ef81bd05SWillem de Bruijncase "$1" in 164ef81bd05SWillem de Bruijn"ipv4") 165ef81bd05SWillem de Bruijn readonly addr1="${ns1_v4}" 166ef81bd05SWillem de Bruijn readonly addr2="${ns2_v4}" 167166b5a7fSAlan Maguire readonly ipproto=4 168166b5a7fSAlan Maguire readonly netcat_opt=-${ipproto} 169166b5a7fSAlan Maguire readonly foumod=fou 170166b5a7fSAlan Maguire readonly foutype=ipip 171166b5a7fSAlan Maguire readonly fouproto=4 1723ec61df8SAlan Maguire readonly fouproto_mpls=${mplsproto} 1733ec61df8SAlan Maguire readonly gretaptype=gretap 174ef81bd05SWillem de Bruijn ;; 175ef81bd05SWillem de Bruijn"ipv6") 176ef81bd05SWillem de Bruijn readonly addr1="${ns1_v6}" 177ef81bd05SWillem de Bruijn readonly addr2="${ns2_v6}" 178166b5a7fSAlan Maguire readonly ipproto=6 179166b5a7fSAlan Maguire readonly netcat_opt=-${ipproto} 180166b5a7fSAlan Maguire readonly foumod=fou6 181166b5a7fSAlan Maguire readonly foutype=ip6tnl 182166b5a7fSAlan Maguire readonly fouproto="41 -6" 1833ec61df8SAlan Maguire readonly fouproto_mpls="${mplsproto} -6" 1843ec61df8SAlan Maguire readonly gretaptype=ip6gretap 185ef81bd05SWillem de Bruijn ;; 186ef81bd05SWillem de Bruijn*) 187ef81bd05SWillem de Bruijn echo "unknown arg: $1" 188ef81bd05SWillem de Bruijn exit 1 189ef81bd05SWillem de Bruijn ;; 190ef81bd05SWillem de Bruijnesac 191ef81bd05SWillem de Bruijn 19281429589SWillem de Bruijnreadonly tuntype=$2 1933ec61df8SAlan Maguirereadonly mac=$3 1943ec61df8SAlan Maguirereadonly datalen=$4 19581429589SWillem de Bruijn 1963ec61df8SAlan Maguireecho "encap ${addr1} to ${addr2}, type ${tuntype}, mac ${mac} len ${datalen}" 197ef81bd05SWillem de Bruijn 19898cdabcdSWillem de Bruijntrap cleanup EXIT 19998cdabcdSWillem de Bruijn 20098cdabcdSWillem de Bruijnsetup 20198cdabcdSWillem de Bruijn 20298cdabcdSWillem de Bruijn# basic communication works 20398cdabcdSWillem de Bruijnecho "test basic connectivity" 20498cdabcdSWillem de Bruijnserver_listen 205*5270950aSAlessandro Carminati (Red Hat)wait_for_port ${port} ${netcat_opt} 20698cdabcdSWillem de Bruijnclient_connect 20781429589SWillem de Bruijnverify_data 20898cdabcdSWillem de Bruijn 20998cdabcdSWillem de Bruijn# clientside, insert bpf program to encap all TCP to port ${port} 21098cdabcdSWillem de Bruijn# client can no longer connect 21198cdabcdSWillem de Bruijnip netns exec "${ns1}" tc qdisc add dev veth1 clsact 21298cdabcdSWillem de Bruijnip netns exec "${ns1}" tc filter add dev veth1 egress \ 21398af3746SWang Yufen bpf direct-action object-file ${BPF_FILE} \ 2143ec61df8SAlan Maguire section "encap_${tuntype}_${mac}" 21598cdabcdSWillem de Bruijnecho "test bpf encap without decap (expect failure)" 21698cdabcdSWillem de Bruijnserver_listen 217*5270950aSAlessandro Carminati (Red Hat)wait_for_port ${port} ${netcat_opt} 21898cdabcdSWillem de Bruijn! client_connect 21998cdabcdSWillem de Bruijn 220166b5a7fSAlan Maguireif [[ "$tuntype" =~ "udp" ]]; then 221166b5a7fSAlan Maguire # Set up fou tunnel. 222166b5a7fSAlan Maguire ttype="${foutype}" 223166b5a7fSAlan Maguire targs="encap fou encap-sport auto encap-dport $udpport" 224166b5a7fSAlan Maguire # fou may be a module; allow this to fail. 225166b5a7fSAlan Maguire modprobe "${foumod}" ||true 2263ec61df8SAlan Maguire if [[ "$mac" == "mpls" ]]; then 2273ec61df8SAlan Maguire dport=${mplsudpport} 2283ec61df8SAlan Maguire dproto=${fouproto_mpls} 2293ec61df8SAlan Maguire tmode="mode any ttl 255" 2303ec61df8SAlan Maguire else 2313ec61df8SAlan Maguire dport=${udpport} 2323ec61df8SAlan Maguire dproto=${fouproto} 2333ec61df8SAlan Maguire fi 2343ec61df8SAlan Maguire ip netns exec "${ns2}" ip fou add port $dport ipproto ${dproto} 2353ec61df8SAlan Maguire targs="encap fou encap-sport auto encap-dport $dport" 2363ec61df8SAlan Maguireelif [[ "$tuntype" =~ "gre" && "$mac" == "eth" ]]; then 2373ec61df8SAlan Maguire ttype=$gretaptype 238256becd4SXuesen Huangelif [[ "$tuntype" =~ "vxlan" && "$mac" == "eth" ]]; then 239256becd4SXuesen Huang ttype="vxlan" 240256becd4SXuesen Huang targs="id 1 dstport 8472 udp6zerocsumrx" 2417105f76fSZiyang Xuanelif [[ "$tuntype" == "ipip6" ]]; then 2427105f76fSZiyang Xuan ttype="ip6tnl" 2437105f76fSZiyang Xuan targs="" 244166b5a7fSAlan Maguireelse 245166b5a7fSAlan Maguire ttype=$tuntype 246166b5a7fSAlan Maguire targs="" 247166b5a7fSAlan Maguirefi 248166b5a7fSAlan Maguire 249f6ad6accSWillem de Bruijn# tunnel address family differs from inner for SIT 250f6ad6accSWillem de Bruijnif [[ "${tuntype}" == "sit" ]]; then 251f6ad6accSWillem de Bruijn link_addr1="${ns1_v4}" 252f6ad6accSWillem de Bruijn link_addr2="${ns2_v4}" 2537105f76fSZiyang Xuanelif [[ "${tuntype}" == "ipip6" ]]; then 2547105f76fSZiyang Xuan link_addr1="${ns1_v6}" 2557105f76fSZiyang Xuan link_addr2="${ns2_v6}" 256f6ad6accSWillem de Bruijnelse 257f6ad6accSWillem de Bruijn link_addr1="${addr1}" 258f6ad6accSWillem de Bruijn link_addr2="${addr2}" 259f6ad6accSWillem de Bruijnfi 260f6ad6accSWillem de Bruijn 26198cdabcdSWillem de Bruijn# serverside, insert decap module 26298cdabcdSWillem de Bruijn# server is still running 26398cdabcdSWillem de Bruijn# client can connect again 264166b5a7fSAlan Maguireip netns exec "${ns2}" ip link add name testtun0 type "${ttype}" \ 265f6ad6accSWillem de Bruijn ${tmode} remote "${link_addr1}" local "${link_addr2}" $targs 2663ec61df8SAlan Maguire 2673ec61df8SAlan Maguireexpect_tun_fail=0 2683ec61df8SAlan Maguire 2693ec61df8SAlan Maguireif [[ "$tuntype" == "ip6udp" && "$mac" == "mpls" ]]; then 2703ec61df8SAlan Maguire # No support for MPLS IPv6 fou tunnel; expect failure. 2713ec61df8SAlan Maguire expect_tun_fail=1 2723ec61df8SAlan Maguireelif [[ "$tuntype" =~ "udp" && "$mac" == "eth" ]]; then 2733ec61df8SAlan Maguire # No support for TEB fou tunnel; expect failure. 2743ec61df8SAlan Maguire expect_tun_fail=1 275256becd4SXuesen Huangelif [[ "$tuntype" =~ (gre|vxlan) && "$mac" == "eth" ]]; then 2763ec61df8SAlan Maguire # Share ethernet address between tunnel/veth2 so L2 decap works. 2773ec61df8SAlan Maguire ethaddr=$(ip netns exec "${ns2}" ip link show veth2 | \ 2783ec61df8SAlan Maguire awk '/ether/ { print $2 }') 2793ec61df8SAlan Maguire ip netns exec "${ns2}" ip link set testtun0 address $ethaddr 2803ec61df8SAlan Maguireelif [[ "$mac" == "mpls" ]]; then 2813ec61df8SAlan Maguire modprobe mpls_iptunnel ||true 2823ec61df8SAlan Maguire modprobe mpls_gso ||true 2833ec61df8SAlan Maguire ip netns exec "${ns2}" sysctl -qw net.mpls.platform_labels=65536 2843ec61df8SAlan Maguire ip netns exec "${ns2}" ip -f mpls route add 1000 dev lo 2853ec61df8SAlan Maguire ip netns exec "${ns2}" ip link set lo up 2863ec61df8SAlan Maguire ip netns exec "${ns2}" sysctl -qw net.mpls.conf.testtun0.input=1 2873ec61df8SAlan Maguire ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.lo.rp_filter=0 2883ec61df8SAlan Maguirefi 2893ec61df8SAlan Maguire 2900c4ea7f8SAlan Maguire# Because packets are decapped by the tunnel they arrive on testtun0 from 2910c4ea7f8SAlan Maguire# the IP stack perspective. Ensure reverse path filtering is disabled 2920c4ea7f8SAlan Maguire# otherwise we drop the TCP SYN as arriving on testtun0 instead of the 2930c4ea7f8SAlan Maguire# expected veth2 (veth2 is where 192.168.1.2 is configured). 2940c4ea7f8SAlan Maguireip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.rp_filter=0 2950c4ea7f8SAlan Maguire# rp needs to be disabled for both all and testtun0 as the rp value is 2960c4ea7f8SAlan Maguire# selected as the max of the "all" and device-specific values. 2970c4ea7f8SAlan Maguireip netns exec "${ns2}" sysctl -qw net.ipv4.conf.testtun0.rp_filter=0 29898cdabcdSWillem de Bruijnip netns exec "${ns2}" ip link set dev testtun0 up 2993ec61df8SAlan Maguireif [[ "$expect_tun_fail" == 1 ]]; then 3003ec61df8SAlan Maguire # This tunnel mode is not supported, so we expect failure. 3013ec61df8SAlan Maguire echo "test bpf encap with tunnel device decap (expect failure)" 3023ec61df8SAlan Maguire ! client_connect 3033ec61df8SAlan Maguireelse 30498cdabcdSWillem de Bruijn echo "test bpf encap with tunnel device decap" 30598cdabcdSWillem de Bruijn client_connect 30681429589SWillem de Bruijn verify_data 3073ec61df8SAlan Maguire server_listen 3083ec61df8SAlan Maguirefi 30998cdabcdSWillem de Bruijn 310ccd34cd3SWillem de Bruijn# serverside, use BPF for decap 311ccd34cd3SWillem de Bruijnip netns exec "${ns2}" ip link del dev testtun0 312ccd34cd3SWillem de Bruijnip netns exec "${ns2}" tc qdisc add dev veth2 clsact 313ccd34cd3SWillem de Bruijnip netns exec "${ns2}" tc filter add dev veth2 ingress \ 31498af3746SWang Yufen bpf direct-action object-file ${BPF_FILE} section decap 315ccd34cd3SWillem de Bruijnecho "test bpf encap with bpf decap" 316ccd34cd3SWillem de Bruijnclient_connect 31781429589SWillem de Bruijnverify_data 318ccd34cd3SWillem de Bruijn 31998cdabcdSWillem de Bruijnecho OK 320