2019-03-22 14:32:49 -04:00
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
#
# In-place tunneling
# must match the port that the bpf program filters on
readonly port = 8000
readonly ns_prefix = " ns- $$ - "
readonly ns1 = " ${ ns_prefix } 1 "
readonly ns2 = " ${ ns_prefix } 2 "
readonly ns1_v4 = 192.168.1.1
readonly ns2_v4 = 192.168.1.2
2019-03-22 14:32:51 -04:00
readonly ns1_v6 = fd::1
readonly ns2_v6 = fd::2
2019-04-09 15:06:40 +01:00
# Must match port used by bpf program
readonly udpport = 5555
2019-04-09 15:06:43 +01:00
# MPLSoverUDP
readonly mplsudpport = 6635
readonly mplsproto = 137
2019-04-09 15:06:40 +01:00
2019-03-22 14:32:53 -04:00
readonly infile = " $( mktemp) "
readonly outfile = " $( mktemp) "
2019-03-22 14:32:49 -04:00
setup( ) {
ip netns add " ${ ns1 } "
ip netns add " ${ ns2 } "
ip link add dev veth1 mtu 1500 netns " ${ ns1 } " type veth \
peer name veth2 mtu 1500 netns " ${ ns2 } "
2019-03-22 14:32:53 -04:00
ip netns exec " ${ ns1 } " ethtool -K veth1 tso off
2019-03-22 14:32:49 -04:00
ip -netns " ${ ns1 } " link set veth1 up
ip -netns " ${ ns2 } " link set veth2 up
ip -netns " ${ ns1 } " -4 addr add " ${ ns1_v4 } /24 " dev veth1
ip -netns " ${ ns2 } " -4 addr add " ${ ns2_v4 } /24 " dev veth2
2019-03-22 14:32:51 -04:00
ip -netns " ${ ns1 } " -6 addr add " ${ ns1_v6 } /64 " dev veth1 nodad
ip -netns " ${ ns2 } " -6 addr add " ${ ns2_v6 } /64 " dev veth2 nodad
2019-03-22 14:32:49 -04:00
2019-03-22 14:32:59 -04:00
# clamp route to reserve room for tunnel headers
ip -netns " ${ ns1 } " -4 route flush table main
ip -netns " ${ ns1 } " -6 route flush table main
2021-03-05 20:33:47 +08:00
ip -netns " ${ ns1 } " -4 route add " ${ ns2_v4 } " mtu 1450 dev veth1
ip -netns " ${ ns1 } " -6 route add " ${ ns2_v6 } " mtu 1430 dev veth1
2019-03-22 14:32:59 -04:00
2019-03-22 14:32:49 -04:00
sleep 1
2019-03-22 14:32:53 -04:00
dd if = /dev/urandom of = " ${ infile } " bs = " ${ datalen } " count = 1 status = none
2019-03-22 14:32:49 -04:00
}
cleanup( ) {
ip netns del " ${ ns2 } "
ip netns del " ${ ns1 } "
2019-03-22 14:32:53 -04:00
if [ [ -f " ${ outfile } " ] ] ; then
rm " ${ outfile } "
fi
if [ [ -f " ${ infile } " ] ] ; then
rm " ${ infile } "
fi
2019-11-15 13:43:23 +01:00
if [ [ -n $server_pid ] ] ; then
kill $server_pid 2> /dev/null
fi
2019-03-22 14:32:49 -04:00
}
server_listen( ) {
2021-07-19 15:30:22 -07:00
ip netns exec " ${ ns2 } " nc " ${ netcat_opt } " -l " ${ port } " > " ${ outfile } " &
2019-03-22 14:32:53 -04:00
server_pid = $!
2019-03-22 14:32:49 -04:00
sleep 0.2
}
client_connect( ) {
2019-03-22 14:32:53 -04:00
ip netns exec " ${ ns1 } " timeout 2 nc " ${ netcat_opt } " -w 1 " ${ addr2 } " " ${ port } " < " ${ infile } "
2019-03-22 14:32:49 -04:00
echo $?
}
2019-03-22 14:32:53 -04:00
verify_data( ) {
wait " ${ server_pid } "
2019-11-15 13:43:23 +01:00
server_pid =
2019-03-22 14:32:53 -04:00
# sha1sum returns two fields [sha1] [filepath]
# convert to bash array and access first elem
insum = ( $( sha1sum ${ infile } ) )
outsum = ( $( sha1sum ${ outfile } ) )
if [ [ " ${ insum [0] } " != " ${ outsum [0] } " ] ] ; then
echo "data mismatch"
exit 1
fi
}
2019-03-22 14:32:49 -04:00
set -e
2019-03-22 14:32:51 -04:00
# no arguments: automated test, run all
if [ [ " $# " -eq "0" ] ] ; then
echo "ipip"
2019-04-09 15:06:43 +01:00
$0 ipv4 ipip none 100
2019-03-22 14:32:51 -04:00
echo "ip6ip6"
2019-04-09 15:06:43 +01:00
$0 ipv6 ip6tnl none 100
2019-03-22 14:32:52 -04:00
2019-04-23 14:43:49 -04:00
echo "sit"
$0 ipv6 sit none 100
2021-03-05 20:33:47 +08:00
echo "ip4 vxlan"
$0 ipv4 vxlan eth 2000
echo "ip6 vxlan"
$0 ipv6 ip6vxlan eth 2000
2019-04-09 15:06:43 +01:00
for mac in none mpls eth ; do
echo " ip gre $mac "
$0 ipv4 gre $mac 100
2019-03-22 14:32:52 -04:00
2019-04-09 15:06:43 +01:00
echo " ip6 gre $mac "
$0 ipv6 ip6gre $mac 100
2019-03-22 14:32:53 -04:00
2019-04-09 15:06:43 +01:00
echo " ip gre $mac gso "
$0 ipv4 gre $mac 2000
2019-03-22 14:32:53 -04:00
2019-04-09 15:06:43 +01:00
echo " ip6 gre $mac gso "
$0 ipv6 ip6gre $mac 2000
2019-03-22 14:32:51 -04:00
2019-04-09 15:06:43 +01:00
echo " ip udp $mac "
$0 ipv4 udp $mac 100
2019-04-09 15:06:40 +01:00
2019-04-09 15:06:43 +01:00
echo " ip6 udp $mac "
$0 ipv6 ip6udp $mac 100
2019-04-09 15:06:40 +01:00
2019-04-09 15:06:43 +01:00
echo " ip udp $mac gso "
$0 ipv4 udp $mac 2000
2019-04-09 15:06:40 +01:00
2019-04-09 15:06:43 +01:00
echo " ip6 udp $mac gso "
$0 ipv6 ip6udp $mac 2000
done
2019-04-09 15:06:40 +01:00
2019-03-22 14:32:51 -04:00
echo "OK. All tests passed"
exit 0
fi
2019-04-09 15:06:43 +01:00
if [ [ " $# " -ne "4" ] ] ; then
2019-03-22 14:32:51 -04:00
echo " Usage: $0 "
2019-04-09 15:06:43 +01:00
echo " or: $0 <ipv4|ipv6> <tuntype> <none|mpls|eth> <data_len> "
2019-03-22 14:32:51 -04:00
exit 1
fi
case " $1 " in
"ipv4" )
readonly addr1 = " ${ ns1_v4 } "
readonly addr2 = " ${ ns2_v4 } "
2019-04-09 15:06:40 +01:00
readonly ipproto = 4
readonly netcat_opt = -${ ipproto }
readonly foumod = fou
readonly foutype = ipip
readonly fouproto = 4
2019-04-09 15:06:43 +01:00
readonly fouproto_mpls = ${ mplsproto }
readonly gretaptype = gretap
2019-03-22 14:32:51 -04:00
; ;
"ipv6" )
readonly addr1 = " ${ ns1_v6 } "
readonly addr2 = " ${ ns2_v6 } "
2019-04-09 15:06:40 +01:00
readonly ipproto = 6
readonly netcat_opt = -${ ipproto }
readonly foumod = fou6
readonly foutype = ip6tnl
readonly fouproto = "41 -6"
2019-04-09 15:06:43 +01:00
readonly fouproto_mpls = " ${ mplsproto } -6 "
readonly gretaptype = ip6gretap
2019-03-22 14:32:51 -04:00
; ;
*)
echo " unknown arg: $1 "
exit 1
; ;
esac
2019-03-22 14:32:53 -04:00
readonly tuntype = $2
2019-04-09 15:06:43 +01:00
readonly mac = $3
readonly datalen = $4
2019-03-22 14:32:53 -04:00
2019-04-09 15:06:43 +01:00
echo " encap ${ addr1 } to ${ addr2 } , type ${ tuntype } , mac ${ mac } len ${ datalen } "
2019-03-22 14:32:51 -04:00
2019-03-22 14:32:49 -04:00
trap cleanup EXIT
setup
# basic communication works
echo "test basic connectivity"
server_listen
client_connect
2019-03-22 14:32:53 -04:00
verify_data
2019-03-22 14:32:49 -04:00
# clientside, insert bpf program to encap all TCP to port ${port}
# client can no longer connect
ip netns exec " ${ ns1 } " tc qdisc add dev veth1 clsact
ip netns exec " ${ ns1 } " tc filter add dev veth1 egress \
2019-03-22 14:32:52 -04:00
bpf direct-action object-file ./test_tc_tunnel.o \
2019-04-09 15:06:43 +01:00
section " encap_ ${ tuntype } _ ${ mac } "
2019-03-22 14:32:49 -04:00
echo "test bpf encap without decap (expect failure)"
server_listen
! client_connect
2019-04-09 15:06:40 +01:00
if [ [ " $tuntype " = ~ "udp" ] ] ; then
# Set up fou tunnel.
ttype = " ${ foutype } "
targs = " encap fou encap-sport auto encap-dport $udpport "
# fou may be a module; allow this to fail.
modprobe " ${ foumod } " || true
2019-04-09 15:06:43 +01:00
if [ [ " $mac " = = "mpls" ] ] ; then
dport = ${ mplsudpport }
dproto = ${ fouproto_mpls }
tmode = "mode any ttl 255"
else
dport = ${ udpport }
dproto = ${ fouproto }
fi
ip netns exec " ${ ns2 } " ip fou add port $dport ipproto ${ dproto }
targs = " encap fou encap-sport auto encap-dport $dport "
elif [ [ " $tuntype " = ~ "gre" && " $mac " = = "eth" ] ] ; then
ttype = $gretaptype
2021-03-05 20:33:47 +08:00
elif [ [ " $tuntype " = ~ "vxlan" && " $mac " = = "eth" ] ] ; then
ttype = "vxlan"
targs = "id 1 dstport 8472 udp6zerocsumrx"
2019-04-09 15:06:40 +01:00
else
ttype = $tuntype
targs = ""
fi
2019-04-23 14:43:49 -04:00
# tunnel address family differs from inner for SIT
if [ [ " ${ tuntype } " = = "sit" ] ] ; then
link_addr1 = " ${ ns1_v4 } "
link_addr2 = " ${ ns2_v4 } "
else
link_addr1 = " ${ addr1 } "
link_addr2 = " ${ addr2 } "
fi
2019-03-22 14:32:49 -04:00
# serverside, insert decap module
# server is still running
# client can connect again
2019-04-09 15:06:40 +01:00
ip netns exec " ${ ns2 } " ip link add name testtun0 type " ${ ttype } " \
2019-04-23 14:43:49 -04:00
${ tmode } remote " ${ link_addr1 } " local " ${ link_addr2 } " $targs
2019-04-09 15:06:43 +01:00
expect_tun_fail = 0
if [ [ " $tuntype " = = "ip6udp" && " $mac " = = "mpls" ] ] ; then
# No support for MPLS IPv6 fou tunnel; expect failure.
expect_tun_fail = 1
elif [ [ " $tuntype " = ~ "udp" && " $mac " = = "eth" ] ] ; then
# No support for TEB fou tunnel; expect failure.
expect_tun_fail = 1
2021-03-05 20:33:47 +08:00
elif [ [ " $tuntype " = ~ ( gre| vxlan) && " $mac " = = "eth" ] ] ; then
2019-04-09 15:06:43 +01:00
# Share ethernet address between tunnel/veth2 so L2 decap works.
ethaddr = $( ip netns exec " ${ ns2 } " ip link show veth2 | \
awk '/ether/ { print $2 }' )
ip netns exec " ${ ns2 } " ip link set testtun0 address $ethaddr
elif [ [ " $mac " = = "mpls" ] ] ; then
modprobe mpls_iptunnel || true
modprobe mpls_gso || true
ip netns exec " ${ ns2 } " sysctl -qw net.mpls.platform_labels= 65536
ip netns exec " ${ ns2 } " ip -f mpls route add 1000 dev lo
ip netns exec " ${ ns2 } " ip link set lo up
ip netns exec " ${ ns2 } " sysctl -qw net.mpls.conf.testtun0.input= 1
ip netns exec " ${ ns2 } " sysctl -qw net.ipv4.conf.lo.rp_filter= 0
fi
2019-03-25 09:36:37 +00:00
# Because packets are decapped by the tunnel they arrive on testtun0 from
# the IP stack perspective. Ensure reverse path filtering is disabled
# otherwise we drop the TCP SYN as arriving on testtun0 instead of the
# expected veth2 (veth2 is where 192.168.1.2 is configured).
ip netns exec " ${ ns2 } " sysctl -qw net.ipv4.conf.all.rp_filter= 0
# rp needs to be disabled for both all and testtun0 as the rp value is
# selected as the max of the "all" and device-specific values.
ip netns exec " ${ ns2 } " sysctl -qw net.ipv4.conf.testtun0.rp_filter= 0
2019-03-22 14:32:49 -04:00
ip netns exec " ${ ns2 } " ip link set dev testtun0 up
2019-04-09 15:06:43 +01:00
if [ [ " $expect_tun_fail " = = 1 ] ] ; then
# This tunnel mode is not supported, so we expect failure.
echo "test bpf encap with tunnel device decap (expect failure)"
! client_connect
else
echo "test bpf encap with tunnel device decap"
client_connect
verify_data
server_listen
fi
2019-03-22 14:32:49 -04:00
2019-04-23 14:43:49 -04:00
# bpf_skb_net_shrink does not take tunnel flags yet, cannot update L3.
if [ [ " ${ tuntype } " = = "sit" ] ] ; then
echo OK
exit 0
fi
2019-03-22 14:32:50 -04:00
# serverside, use BPF for decap
ip netns exec " ${ ns2 } " ip link del dev testtun0
ip netns exec " ${ ns2 } " tc qdisc add dev veth2 clsact
ip netns exec " ${ ns2 } " tc filter add dev veth2 ingress \
bpf direct-action object-file ./test_tc_tunnel.o section decap
echo "test bpf encap with bpf decap"
client_connect
2019-03-22 14:32:53 -04:00
verify_data
2019-03-22 14:32:50 -04:00
2019-03-22 14:32:49 -04:00
echo OK