1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3# 4# In-place tunneling 5 6# must match the port that the bpf program filters on 7readonly port=8000 8 9readonly ns_prefix="ns-$$-" 10readonly ns1="${ns_prefix}1" 11readonly ns2="${ns_prefix}2" 12 13readonly ns1_v4=192.168.1.1 14readonly ns2_v4=192.168.1.2 15readonly ns1_v6=fd::1 16readonly ns2_v6=fd::2 17 18readonly infile="$(mktemp)" 19readonly outfile="$(mktemp)" 20 21setup() { 22 ip netns add "${ns1}" 23 ip netns add "${ns2}" 24 25 ip link add dev veth1 mtu 1500 netns "${ns1}" type veth \ 26 peer name veth2 mtu 1500 netns "${ns2}" 27 28 ip netns exec "${ns1}" ethtool -K veth1 tso off 29 30 ip -netns "${ns1}" link set veth1 up 31 ip -netns "${ns2}" link set veth2 up 32 33 ip -netns "${ns1}" -4 addr add "${ns1_v4}/24" dev veth1 34 ip -netns "${ns2}" -4 addr add "${ns2_v4}/24" dev veth2 35 ip -netns "${ns1}" -6 addr add "${ns1_v6}/64" dev veth1 nodad 36 ip -netns "${ns2}" -6 addr add "${ns2_v6}/64" dev veth2 nodad 37 38 # clamp route to reserve room for tunnel headers 39 ip -netns "${ns1}" -4 route flush table main 40 ip -netns "${ns1}" -6 route flush table main 41 ip -netns "${ns1}" -4 route add "${ns2_v4}" mtu 1476 dev veth1 42 ip -netns "${ns1}" -6 route add "${ns2_v6}" mtu 1456 dev veth1 43 44 sleep 1 45 46 dd if=/dev/urandom of="${infile}" bs="${datalen}" count=1 status=none 47} 48 49cleanup() { 50 ip netns del "${ns2}" 51 ip netns del "${ns1}" 52 53 if [[ -f "${outfile}" ]]; then 54 rm "${outfile}" 55 fi 56 if [[ -f "${infile}" ]]; then 57 rm "${infile}" 58 fi 59} 60 61server_listen() { 62 ip netns exec "${ns2}" nc "${netcat_opt}" -l -p "${port}" > "${outfile}" & 63 server_pid=$! 64 sleep 0.2 65} 66 67client_connect() { 68 ip netns exec "${ns1}" timeout 2 nc "${netcat_opt}" -w 1 "${addr2}" "${port}" < "${infile}" 69 echo $? 70} 71 72verify_data() { 73 wait "${server_pid}" 74 # sha1sum returns two fields [sha1] [filepath] 75 # convert to bash array and access first elem 76 insum=($(sha1sum ${infile})) 77 outsum=($(sha1sum ${outfile})) 78 if [[ "${insum[0]}" != "${outsum[0]}" ]]; then 79 echo "data mismatch" 80 exit 1 81 fi 82} 83 84set -e 85 86# no arguments: automated test, run all 87if [[ "$#" -eq "0" ]]; then 88 echo "ipip" 89 $0 ipv4 ipip 100 90 91 echo "ip6ip6" 92 $0 ipv6 ip6tnl 100 93 94 echo "ip gre" 95 $0 ipv4 gre 100 96 97 echo "ip6 gre" 98 $0 ipv6 ip6gre 100 99 100 echo "ip gre gso" 101 $0 ipv4 gre 2000 102 103 echo "ip6 gre gso" 104 $0 ipv6 ip6gre 2000 105 106 echo "OK. All tests passed" 107 exit 0 108fi 109 110if [[ "$#" -ne "3" ]]; then 111 echo "Usage: $0" 112 echo " or: $0 <ipv4|ipv6> <tuntype> <data_len>" 113 exit 1 114fi 115 116case "$1" in 117"ipv4") 118 readonly addr1="${ns1_v4}" 119 readonly addr2="${ns2_v4}" 120 readonly netcat_opt=-4 121 ;; 122"ipv6") 123 readonly addr1="${ns1_v6}" 124 readonly addr2="${ns2_v6}" 125 readonly netcat_opt=-6 126 ;; 127*) 128 echo "unknown arg: $1" 129 exit 1 130 ;; 131esac 132 133readonly tuntype=$2 134readonly datalen=$3 135 136echo "encap ${addr1} to ${addr2}, type ${tuntype}, len ${datalen}" 137 138trap cleanup EXIT 139 140setup 141 142# basic communication works 143echo "test basic connectivity" 144server_listen 145client_connect 146verify_data 147 148# clientside, insert bpf program to encap all TCP to port ${port} 149# client can no longer connect 150ip netns exec "${ns1}" tc qdisc add dev veth1 clsact 151ip netns exec "${ns1}" tc filter add dev veth1 egress \ 152 bpf direct-action object-file ./test_tc_tunnel.o \ 153 section "encap_${tuntype}" 154echo "test bpf encap without decap (expect failure)" 155server_listen 156! client_connect 157 158# serverside, insert decap module 159# server is still running 160# client can connect again 161ip netns exec "${ns2}" ip link add dev testtun0 type "${tuntype}" \ 162 remote "${addr1}" local "${addr2}" 163# Because packets are decapped by the tunnel they arrive on testtun0 from 164# the IP stack perspective. Ensure reverse path filtering is disabled 165# otherwise we drop the TCP SYN as arriving on testtun0 instead of the 166# expected veth2 (veth2 is where 192.168.1.2 is configured). 167ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.all.rp_filter=0 168# rp needs to be disabled for both all and testtun0 as the rp value is 169# selected as the max of the "all" and device-specific values. 170ip netns exec "${ns2}" sysctl -qw net.ipv4.conf.testtun0.rp_filter=0 171ip netns exec "${ns2}" ip link set dev testtun0 up 172echo "test bpf encap with tunnel device decap" 173client_connect 174verify_data 175 176# serverside, use BPF for decap 177ip netns exec "${ns2}" ip link del dev testtun0 178ip netns exec "${ns2}" tc qdisc add dev veth2 clsact 179ip netns exec "${ns2}" tc filter add dev veth2 ingress \ 180 bpf direct-action object-file ./test_tc_tunnel.o section decap 181server_listen 182echo "test bpf encap with bpf decap" 183client_connect 184verify_data 185 186echo OK 187