10fde56e4SPeter Oskolkov#!/bin/bash
20fde56e4SPeter Oskolkov# SPDX-License-Identifier: GPL-2.0
30fde56e4SPeter Oskolkov#
40fde56e4SPeter Oskolkov# Setup/topology:
50fde56e4SPeter Oskolkov#
60fde56e4SPeter Oskolkov#    NS1             NS2             NS3
70fde56e4SPeter Oskolkov#   veth1 <---> veth2   veth3 <---> veth4 (the top route)
80fde56e4SPeter Oskolkov#   veth5 <---> veth6   veth7 <---> veth8 (the bottom route)
90fde56e4SPeter Oskolkov#
100fde56e4SPeter Oskolkov#   each vethN gets IPv[4|6]_N address
110fde56e4SPeter Oskolkov#
120fde56e4SPeter Oskolkov#   IPv*_SRC = IPv*_1
130fde56e4SPeter Oskolkov#   IPv*_DST = IPv*_4
140fde56e4SPeter Oskolkov#
150fde56e4SPeter Oskolkov#   all tests test pings from IPv*_SRC to IPv*_DST
160fde56e4SPeter Oskolkov#
170fde56e4SPeter Oskolkov#   by default, routes are configured to allow packets to go
180fde56e4SPeter Oskolkov#   IP*_1 <=> IP*_2 <=> IP*_3 <=> IP*_4 (the top route)
190fde56e4SPeter Oskolkov#
200fde56e4SPeter Oskolkov#   a GRE device is installed in NS3 with IPv*_GRE, and
210fde56e4SPeter Oskolkov#   NS1/NS2 are configured to route packets to IPv*_GRE via IP*_8
220fde56e4SPeter Oskolkov#   (the bottom route)
230fde56e4SPeter Oskolkov#
240fde56e4SPeter Oskolkov# Tests:
250fde56e4SPeter Oskolkov#
260fde56e4SPeter Oskolkov#   1. routes NS2->IPv*_DST are brought down, so the only way a ping
270fde56e4SPeter Oskolkov#      from IP*_SRC to IP*_DST can work is via IPv*_GRE
280fde56e4SPeter Oskolkov#
290fde56e4SPeter Oskolkov#   2a. in an egress test, a bpf LWT_XMIT program is installed on veth1
300fde56e4SPeter Oskolkov#       that encaps the packets with an IP/GRE header to route to IPv*_GRE
310fde56e4SPeter Oskolkov#
320fde56e4SPeter Oskolkov#       ping: SRC->[encap at veth1:egress]->GRE:decap->DST
330fde56e4SPeter Oskolkov#       ping replies go DST->SRC directly
340fde56e4SPeter Oskolkov#
350fde56e4SPeter Oskolkov#   2b. in an ingress test, a bpf LWT_IN program is installed on veth2
360fde56e4SPeter Oskolkov#       that encaps the packets with an IP/GRE header to route to IPv*_GRE
370fde56e4SPeter Oskolkov#
380fde56e4SPeter Oskolkov#       ping: SRC->[encap at veth2:ingress]->GRE:decap->DST
390fde56e4SPeter Oskolkov#       ping replies go DST->SRC directly
400fde56e4SPeter Oskolkov
41*98af3746SWang YufenBPF_FILE="test_lwt_ip_encap.bpf.o"
420fde56e4SPeter Oskolkovif [[ $EUID -ne 0 ]]; then
430fde56e4SPeter Oskolkov	echo "This script must be run as root"
440fde56e4SPeter Oskolkov	echo "FAIL"
450fde56e4SPeter Oskolkov	exit 1
460fde56e4SPeter Oskolkovfi
470fde56e4SPeter Oskolkov
480fde56e4SPeter Oskolkovreadonly NS1="ns1-$(mktemp -u XXXXXX)"
490fde56e4SPeter Oskolkovreadonly NS2="ns2-$(mktemp -u XXXXXX)"
500fde56e4SPeter Oskolkovreadonly NS3="ns3-$(mktemp -u XXXXXX)"
510fde56e4SPeter Oskolkov
520fde56e4SPeter Oskolkovreadonly IPv4_1="172.16.1.100"
530fde56e4SPeter Oskolkovreadonly IPv4_2="172.16.2.100"
540fde56e4SPeter Oskolkovreadonly IPv4_3="172.16.3.100"
550fde56e4SPeter Oskolkovreadonly IPv4_4="172.16.4.100"
560fde56e4SPeter Oskolkovreadonly IPv4_5="172.16.5.100"
570fde56e4SPeter Oskolkovreadonly IPv4_6="172.16.6.100"
580fde56e4SPeter Oskolkovreadonly IPv4_7="172.16.7.100"
590fde56e4SPeter Oskolkovreadonly IPv4_8="172.16.8.100"
600fde56e4SPeter Oskolkovreadonly IPv4_GRE="172.16.16.100"
610fde56e4SPeter Oskolkov
620fde56e4SPeter Oskolkovreadonly IPv4_SRC=$IPv4_1
630fde56e4SPeter Oskolkovreadonly IPv4_DST=$IPv4_4
640fde56e4SPeter Oskolkov
650fde56e4SPeter Oskolkovreadonly IPv6_1="fb01::1"
660fde56e4SPeter Oskolkovreadonly IPv6_2="fb02::1"
670fde56e4SPeter Oskolkovreadonly IPv6_3="fb03::1"
680fde56e4SPeter Oskolkovreadonly IPv6_4="fb04::1"
690fde56e4SPeter Oskolkovreadonly IPv6_5="fb05::1"
700fde56e4SPeter Oskolkovreadonly IPv6_6="fb06::1"
710fde56e4SPeter Oskolkovreadonly IPv6_7="fb07::1"
720fde56e4SPeter Oskolkovreadonly IPv6_8="fb08::1"
730fde56e4SPeter Oskolkovreadonly IPv6_GRE="fb10::1"
740fde56e4SPeter Oskolkov
750fde56e4SPeter Oskolkovreadonly IPv6_SRC=$IPv6_1
760fde56e4SPeter Oskolkovreadonly IPv6_DST=$IPv6_4
770fde56e4SPeter Oskolkov
789d6b3584SPeter OskolkovTEST_STATUS=0
799d6b3584SPeter OskolkovTESTS_SUCCEEDED=0
809d6b3584SPeter OskolkovTESTS_FAILED=0
819d6b3584SPeter Oskolkov
8217a90a78SPeter OskolkovTMPFILE=""
8317a90a78SPeter Oskolkov
849d6b3584SPeter Oskolkovprocess_test_results()
859d6b3584SPeter Oskolkov{
869d6b3584SPeter Oskolkov	if [[ "${TEST_STATUS}" -eq 0 ]] ; then
879d6b3584SPeter Oskolkov		echo "PASS"
889d6b3584SPeter Oskolkov		TESTS_SUCCEEDED=$((TESTS_SUCCEEDED+1))
899d6b3584SPeter Oskolkov	else
909d6b3584SPeter Oskolkov		echo "FAIL"
919d6b3584SPeter Oskolkov		TESTS_FAILED=$((TESTS_FAILED+1))
929d6b3584SPeter Oskolkov	fi
939d6b3584SPeter Oskolkov}
949d6b3584SPeter Oskolkov
959d6b3584SPeter Oskolkovprint_test_summary_and_exit()
969d6b3584SPeter Oskolkov{
979d6b3584SPeter Oskolkov	echo "passed tests: ${TESTS_SUCCEEDED}"
989d6b3584SPeter Oskolkov	echo "failed tests: ${TESTS_FAILED}"
999d6b3584SPeter Oskolkov	if [ "${TESTS_FAILED}" -eq "0" ] ; then
1009d6b3584SPeter Oskolkov		exit 0
1019d6b3584SPeter Oskolkov	else
1029d6b3584SPeter Oskolkov		exit 1
1039d6b3584SPeter Oskolkov	fi
1049d6b3584SPeter Oskolkov}
1059d6b3584SPeter Oskolkov
1069d6b3584SPeter Oskolkovsetup()
1079d6b3584SPeter Oskolkov{
1080fde56e4SPeter Oskolkov	set -e  # exit on error
1099d6b3584SPeter Oskolkov	TEST_STATUS=0
1109d6b3584SPeter Oskolkov
1110fde56e4SPeter Oskolkov	# create devices and namespaces
1120fde56e4SPeter Oskolkov	ip netns add "${NS1}"
1130fde56e4SPeter Oskolkov	ip netns add "${NS2}"
1140fde56e4SPeter Oskolkov	ip netns add "${NS3}"
1150fde56e4SPeter Oskolkov
11679e2c306SJiri Benc	# rp_filter gets confused by what these tests are doing, so disable it
11779e2c306SJiri Benc	ip netns exec ${NS1} sysctl -wq net.ipv4.conf.all.rp_filter=0
11879e2c306SJiri Benc	ip netns exec ${NS2} sysctl -wq net.ipv4.conf.all.rp_filter=0
11979e2c306SJiri Benc	ip netns exec ${NS3} sysctl -wq net.ipv4.conf.all.rp_filter=0
12079e2c306SJiri Benc	ip netns exec ${NS1} sysctl -wq net.ipv4.conf.default.rp_filter=0
12179e2c306SJiri Benc	ip netns exec ${NS2} sysctl -wq net.ipv4.conf.default.rp_filter=0
12279e2c306SJiri Benc	ip netns exec ${NS3} sysctl -wq net.ipv4.conf.default.rp_filter=0
12379e2c306SJiri Benc
124d23a8720SFelix Maurer	# disable IPv6 DAD because it sometimes takes too long and fails tests
125d23a8720SFelix Maurer	ip netns exec ${NS1} sysctl -wq net.ipv6.conf.all.accept_dad=0
126d23a8720SFelix Maurer	ip netns exec ${NS2} sysctl -wq net.ipv6.conf.all.accept_dad=0
127d23a8720SFelix Maurer	ip netns exec ${NS3} sysctl -wq net.ipv6.conf.all.accept_dad=0
128d23a8720SFelix Maurer	ip netns exec ${NS1} sysctl -wq net.ipv6.conf.default.accept_dad=0
129d23a8720SFelix Maurer	ip netns exec ${NS2} sysctl -wq net.ipv6.conf.default.accept_dad=0
130d23a8720SFelix Maurer	ip netns exec ${NS3} sysctl -wq net.ipv6.conf.default.accept_dad=0
131d23a8720SFelix Maurer
1320fde56e4SPeter Oskolkov	ip link add veth1 type veth peer name veth2
1330fde56e4SPeter Oskolkov	ip link add veth3 type veth peer name veth4
1340fde56e4SPeter Oskolkov	ip link add veth5 type veth peer name veth6
1350fde56e4SPeter Oskolkov	ip link add veth7 type veth peer name veth8
1360fde56e4SPeter Oskolkov
1370fde56e4SPeter Oskolkov	ip netns exec ${NS2} sysctl -wq net.ipv4.ip_forward=1
1380fde56e4SPeter Oskolkov	ip netns exec ${NS2} sysctl -wq net.ipv6.conf.all.forwarding=1
1390fde56e4SPeter Oskolkov
1400fde56e4SPeter Oskolkov	ip link set veth1 netns ${NS1}
1410fde56e4SPeter Oskolkov	ip link set veth2 netns ${NS2}
1420fde56e4SPeter Oskolkov	ip link set veth3 netns ${NS2}
1430fde56e4SPeter Oskolkov	ip link set veth4 netns ${NS3}
1440fde56e4SPeter Oskolkov	ip link set veth5 netns ${NS1}
1450fde56e4SPeter Oskolkov	ip link set veth6 netns ${NS2}
1460fde56e4SPeter Oskolkov	ip link set veth7 netns ${NS2}
1470fde56e4SPeter Oskolkov	ip link set veth8 netns ${NS3}
1480fde56e4SPeter Oskolkov
149809041e7SPeter Oskolkov	if [ ! -z "${VRF}" ] ; then
150809041e7SPeter Oskolkov		ip -netns ${NS1} link add red type vrf table 1001
151809041e7SPeter Oskolkov		ip -netns ${NS1} link set red up
152809041e7SPeter Oskolkov		ip -netns ${NS1} route add table 1001 unreachable default metric 8192
153809041e7SPeter Oskolkov		ip -netns ${NS1} -6 route add table 1001 unreachable default metric 8192
154809041e7SPeter Oskolkov		ip -netns ${NS1} link set veth1 vrf red
155809041e7SPeter Oskolkov		ip -netns ${NS1} link set veth5 vrf red
156809041e7SPeter Oskolkov
157809041e7SPeter Oskolkov		ip -netns ${NS2} link add red type vrf table 1001
158809041e7SPeter Oskolkov		ip -netns ${NS2} link set red up
159809041e7SPeter Oskolkov		ip -netns ${NS2} route add table 1001 unreachable default metric 8192
160809041e7SPeter Oskolkov		ip -netns ${NS2} -6 route add table 1001 unreachable default metric 8192
161809041e7SPeter Oskolkov		ip -netns ${NS2} link set veth2 vrf red
162809041e7SPeter Oskolkov		ip -netns ${NS2} link set veth3 vrf red
163809041e7SPeter Oskolkov		ip -netns ${NS2} link set veth6 vrf red
164809041e7SPeter Oskolkov		ip -netns ${NS2} link set veth7 vrf red
165809041e7SPeter Oskolkov	fi
166809041e7SPeter Oskolkov
1670fde56e4SPeter Oskolkov	# configure addesses: the top route (1-2-3-4)
1680fde56e4SPeter Oskolkov	ip -netns ${NS1}    addr add ${IPv4_1}/24  dev veth1
1690fde56e4SPeter Oskolkov	ip -netns ${NS2}    addr add ${IPv4_2}/24  dev veth2
1700fde56e4SPeter Oskolkov	ip -netns ${NS2}    addr add ${IPv4_3}/24  dev veth3
1710fde56e4SPeter Oskolkov	ip -netns ${NS3}    addr add ${IPv4_4}/24  dev veth4
1720fde56e4SPeter Oskolkov	ip -netns ${NS1} -6 addr add ${IPv6_1}/128 nodad dev veth1
1730fde56e4SPeter Oskolkov	ip -netns ${NS2} -6 addr add ${IPv6_2}/128 nodad dev veth2
1740fde56e4SPeter Oskolkov	ip -netns ${NS2} -6 addr add ${IPv6_3}/128 nodad dev veth3
1750fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 addr add ${IPv6_4}/128 nodad dev veth4
1760fde56e4SPeter Oskolkov
1770fde56e4SPeter Oskolkov	# configure addresses: the bottom route (5-6-7-8)
1780fde56e4SPeter Oskolkov	ip -netns ${NS1}    addr add ${IPv4_5}/24  dev veth5
1790fde56e4SPeter Oskolkov	ip -netns ${NS2}    addr add ${IPv4_6}/24  dev veth6
1800fde56e4SPeter Oskolkov	ip -netns ${NS2}    addr add ${IPv4_7}/24  dev veth7
1810fde56e4SPeter Oskolkov	ip -netns ${NS3}    addr add ${IPv4_8}/24  dev veth8
1820fde56e4SPeter Oskolkov	ip -netns ${NS1} -6 addr add ${IPv6_5}/128 nodad dev veth5
1830fde56e4SPeter Oskolkov	ip -netns ${NS2} -6 addr add ${IPv6_6}/128 nodad dev veth6
1840fde56e4SPeter Oskolkov	ip -netns ${NS2} -6 addr add ${IPv6_7}/128 nodad dev veth7
1850fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 addr add ${IPv6_8}/128 nodad dev veth8
1860fde56e4SPeter Oskolkov
1870fde56e4SPeter Oskolkov	ip -netns ${NS1} link set dev veth1 up
1880fde56e4SPeter Oskolkov	ip -netns ${NS2} link set dev veth2 up
1890fde56e4SPeter Oskolkov	ip -netns ${NS2} link set dev veth3 up
1900fde56e4SPeter Oskolkov	ip -netns ${NS3} link set dev veth4 up
1910fde56e4SPeter Oskolkov	ip -netns ${NS1} link set dev veth5 up
1920fde56e4SPeter Oskolkov	ip -netns ${NS2} link set dev veth6 up
1930fde56e4SPeter Oskolkov	ip -netns ${NS2} link set dev veth7 up
1940fde56e4SPeter Oskolkov	ip -netns ${NS3} link set dev veth8 up
1950fde56e4SPeter Oskolkov
1960fde56e4SPeter Oskolkov	# configure routes: IP*_SRC -> veth1/IP*_2 (= top route) default;
1970fde56e4SPeter Oskolkov	# the bottom route to specific bottom addresses
1980fde56e4SPeter Oskolkov
1990fde56e4SPeter Oskolkov	# NS1
2000fde56e4SPeter Oskolkov	# top route
201809041e7SPeter Oskolkov	ip -netns ${NS1}    route add ${IPv4_2}/32  dev veth1 ${VRF}
202809041e7SPeter Oskolkov	ip -netns ${NS1}    route add default dev veth1 via ${IPv4_2} ${VRF}  # go top by default
203809041e7SPeter Oskolkov	ip -netns ${NS1} -6 route add ${IPv6_2}/128 dev veth1 ${VRF}
204809041e7SPeter Oskolkov	ip -netns ${NS1} -6 route add default dev veth1 via ${IPv6_2} ${VRF}  # go top by default
2050fde56e4SPeter Oskolkov	# bottom route
206809041e7SPeter Oskolkov	ip -netns ${NS1}    route add ${IPv4_6}/32  dev veth5 ${VRF}
207809041e7SPeter Oskolkov	ip -netns ${NS1}    route add ${IPv4_7}/32  dev veth5 via ${IPv4_6} ${VRF}
208809041e7SPeter Oskolkov	ip -netns ${NS1}    route add ${IPv4_8}/32  dev veth5 via ${IPv4_6} ${VRF}
209809041e7SPeter Oskolkov	ip -netns ${NS1} -6 route add ${IPv6_6}/128 dev veth5 ${VRF}
210809041e7SPeter Oskolkov	ip -netns ${NS1} -6 route add ${IPv6_7}/128 dev veth5 via ${IPv6_6} ${VRF}
211809041e7SPeter Oskolkov	ip -netns ${NS1} -6 route add ${IPv6_8}/128 dev veth5 via ${IPv6_6} ${VRF}
2120fde56e4SPeter Oskolkov
2130fde56e4SPeter Oskolkov	# NS2
2140fde56e4SPeter Oskolkov	# top route
215809041e7SPeter Oskolkov	ip -netns ${NS2}    route add ${IPv4_1}/32  dev veth2 ${VRF}
216809041e7SPeter Oskolkov	ip -netns ${NS2}    route add ${IPv4_4}/32  dev veth3 ${VRF}
217809041e7SPeter Oskolkov	ip -netns ${NS2} -6 route add ${IPv6_1}/128 dev veth2 ${VRF}
218809041e7SPeter Oskolkov	ip -netns ${NS2} -6 route add ${IPv6_4}/128 dev veth3 ${VRF}
2190fde56e4SPeter Oskolkov	# bottom route
220809041e7SPeter Oskolkov	ip -netns ${NS2}    route add ${IPv4_5}/32  dev veth6 ${VRF}
221809041e7SPeter Oskolkov	ip -netns ${NS2}    route add ${IPv4_8}/32  dev veth7 ${VRF}
222809041e7SPeter Oskolkov	ip -netns ${NS2} -6 route add ${IPv6_5}/128 dev veth6 ${VRF}
223809041e7SPeter Oskolkov	ip -netns ${NS2} -6 route add ${IPv6_8}/128 dev veth7 ${VRF}
2240fde56e4SPeter Oskolkov
2250fde56e4SPeter Oskolkov	# NS3
2260fde56e4SPeter Oskolkov	# top route
2270fde56e4SPeter Oskolkov	ip -netns ${NS3}    route add ${IPv4_3}/32  dev veth4
2280fde56e4SPeter Oskolkov	ip -netns ${NS3}    route add ${IPv4_1}/32  dev veth4 via ${IPv4_3}
2290fde56e4SPeter Oskolkov	ip -netns ${NS3}    route add ${IPv4_2}/32  dev veth4 via ${IPv4_3}
2300fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 route add ${IPv6_3}/128 dev veth4
2310fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 route add ${IPv6_1}/128 dev veth4 via ${IPv6_3}
2320fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 route add ${IPv6_2}/128 dev veth4 via ${IPv6_3}
2330fde56e4SPeter Oskolkov	# bottom route
2340fde56e4SPeter Oskolkov	ip -netns ${NS3}    route add ${IPv4_7}/32  dev veth8
2350fde56e4SPeter Oskolkov	ip -netns ${NS3}    route add ${IPv4_5}/32  dev veth8 via ${IPv4_7}
2360fde56e4SPeter Oskolkov	ip -netns ${NS3}    route add ${IPv4_6}/32  dev veth8 via ${IPv4_7}
2370fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 route add ${IPv6_7}/128 dev veth8
2380fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 route add ${IPv6_5}/128 dev veth8 via ${IPv6_7}
2390fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 route add ${IPv6_6}/128 dev veth8 via ${IPv6_7}
2400fde56e4SPeter Oskolkov
2410fde56e4SPeter Oskolkov	# configure IPv4 GRE device in NS3, and a route to it via the "bottom" route
2420fde56e4SPeter Oskolkov	ip -netns ${NS3} tunnel add gre_dev mode gre remote ${IPv4_1} local ${IPv4_GRE} ttl 255
2430fde56e4SPeter Oskolkov	ip -netns ${NS3} link set gre_dev up
24417a90a78SPeter Oskolkov	ip -netns ${NS3} addr add ${IPv4_GRE} dev gre_dev
245809041e7SPeter Oskolkov	ip -netns ${NS1} route add ${IPv4_GRE}/32 dev veth5 via ${IPv4_6} ${VRF}
246809041e7SPeter Oskolkov	ip -netns ${NS2} route add ${IPv4_GRE}/32 dev veth7 via ${IPv4_8} ${VRF}
2470fde56e4SPeter Oskolkov
2480fde56e4SPeter Oskolkov
2490fde56e4SPeter Oskolkov	# configure IPv6 GRE device in NS3, and a route to it via the "bottom" route
2500fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 tunnel add name gre6_dev mode ip6gre remote ${IPv6_1} local ${IPv6_GRE} ttl 255
2510fde56e4SPeter Oskolkov	ip -netns ${NS3} link set gre6_dev up
2520fde56e4SPeter Oskolkov	ip -netns ${NS3} -6 addr add ${IPv6_GRE} nodad dev gre6_dev
253809041e7SPeter Oskolkov	ip -netns ${NS1} -6 route add ${IPv6_GRE}/128 dev veth5 via ${IPv6_6} ${VRF}
254809041e7SPeter Oskolkov	ip -netns ${NS2} -6 route add ${IPv6_GRE}/128 dev veth7 via ${IPv6_8} ${VRF}
2550fde56e4SPeter Oskolkov
25617a90a78SPeter Oskolkov	TMPFILE=$(mktemp /tmp/test_lwt_ip_encap.XXXXXX)
25717a90a78SPeter Oskolkov
2589d6b3584SPeter Oskolkov	sleep 1  # reduce flakiness
2599d6b3584SPeter Oskolkov	set +e
2600fde56e4SPeter Oskolkov}
2610fde56e4SPeter Oskolkov
2629d6b3584SPeter Oskolkovcleanup()
2639d6b3584SPeter Oskolkov{
26417a90a78SPeter Oskolkov	if [ -f ${TMPFILE} ] ; then
26517a90a78SPeter Oskolkov		rm ${TMPFILE}
26617a90a78SPeter Oskolkov	fi
26717a90a78SPeter Oskolkov
2680fde56e4SPeter Oskolkov	ip netns del ${NS1} 2> /dev/null
2690fde56e4SPeter Oskolkov	ip netns del ${NS2} 2> /dev/null
2700fde56e4SPeter Oskolkov	ip netns del ${NS3} 2> /dev/null
2710fde56e4SPeter Oskolkov}
2720fde56e4SPeter Oskolkov
2730fde56e4SPeter Oskolkovtrap cleanup EXIT
2740fde56e4SPeter Oskolkov
2759d6b3584SPeter Oskolkovremove_routes_to_gredev()
2769d6b3584SPeter Oskolkov{
277809041e7SPeter Oskolkov	ip -netns ${NS1} route del ${IPv4_GRE} dev veth5 ${VRF}
278809041e7SPeter Oskolkov	ip -netns ${NS2} route del ${IPv4_GRE} dev veth7 ${VRF}
279809041e7SPeter Oskolkov	ip -netns ${NS1} -6 route del ${IPv6_GRE}/128 dev veth5 ${VRF}
280809041e7SPeter Oskolkov	ip -netns ${NS2} -6 route del ${IPv6_GRE}/128 dev veth7 ${VRF}
2819d6b3584SPeter Oskolkov}
2829d6b3584SPeter Oskolkov
2839d6b3584SPeter Oskolkovadd_unreachable_routes_to_gredev()
2849d6b3584SPeter Oskolkov{
285809041e7SPeter Oskolkov	ip -netns ${NS1} route add unreachable ${IPv4_GRE}/32 ${VRF}
286809041e7SPeter Oskolkov	ip -netns ${NS2} route add unreachable ${IPv4_GRE}/32 ${VRF}
287809041e7SPeter Oskolkov	ip -netns ${NS1} -6 route add unreachable ${IPv6_GRE}/128 ${VRF}
288809041e7SPeter Oskolkov	ip -netns ${NS2} -6 route add unreachable ${IPv6_GRE}/128 ${VRF}
2899d6b3584SPeter Oskolkov}
2909d6b3584SPeter Oskolkov
2919d6b3584SPeter Oskolkovtest_ping()
2929d6b3584SPeter Oskolkov{
2930fde56e4SPeter Oskolkov	local readonly PROTO=$1
2940fde56e4SPeter Oskolkov	local readonly EXPECTED=$2
2950fde56e4SPeter Oskolkov	local RET=0
2960fde56e4SPeter Oskolkov
2970fde56e4SPeter Oskolkov	if [ "${PROTO}" == "IPv4" ] ; then
298809041e7SPeter Oskolkov		ip netns exec ${NS1} ping  -c 1 -W 1 -I veth1 ${IPv4_DST} 2>&1 > /dev/null
2990fde56e4SPeter Oskolkov		RET=$?
3000fde56e4SPeter Oskolkov	elif [ "${PROTO}" == "IPv6" ] ; then
301d23a8720SFelix Maurer		ip netns exec ${NS1} ping6 -c 1 -W 1 -I veth1 ${IPv6_DST} 2>&1 > /dev/null
3020fde56e4SPeter Oskolkov		RET=$?
3030fde56e4SPeter Oskolkov	else
3040fde56e4SPeter Oskolkov		echo "    test_ping: unknown PROTO: ${PROTO}"
3059d6b3584SPeter Oskolkov		TEST_STATUS=1
3060fde56e4SPeter Oskolkov	fi
3070fde56e4SPeter Oskolkov
3080fde56e4SPeter Oskolkov	if [ "0" != "${RET}" ]; then
3090fde56e4SPeter Oskolkov		RET=1
3100fde56e4SPeter Oskolkov	fi
3110fde56e4SPeter Oskolkov
3120fde56e4SPeter Oskolkov	if [ "${EXPECTED}" != "${RET}" ] ; then
3139d6b3584SPeter Oskolkov		echo "    test_ping failed: expected: ${EXPECTED}; got ${RET}"
3149d6b3584SPeter Oskolkov		TEST_STATUS=1
3150fde56e4SPeter Oskolkov	fi
3160fde56e4SPeter Oskolkov}
3170fde56e4SPeter Oskolkov
31817a90a78SPeter Oskolkovtest_gso()
31917a90a78SPeter Oskolkov{
32017a90a78SPeter Oskolkov	local readonly PROTO=$1
32117a90a78SPeter Oskolkov	local readonly PKT_SZ=5000
32217a90a78SPeter Oskolkov	local IP_DST=""
32317a90a78SPeter Oskolkov	: > ${TMPFILE}  # trim the capture file
32417a90a78SPeter Oskolkov
32517a90a78SPeter Oskolkov	# check that nc is present
32617a90a78SPeter Oskolkov	command -v nc >/dev/null 2>&1 || \
32717a90a78SPeter Oskolkov		{ echo >&2 "nc is not available: skipping TSO tests"; return; }
32817a90a78SPeter Oskolkov
329106c35ddSJiri Benc	# listen on port 9000, capture TCP into $TMPFILE
33017a90a78SPeter Oskolkov	if [ "${PROTO}" == "IPv4" ] ; then
33117a90a78SPeter Oskolkov		IP_DST=${IPv4_DST}
33217a90a78SPeter Oskolkov		ip netns exec ${NS3} bash -c \
333106c35ddSJiri Benc			"nc -4 -l -p 9000 > ${TMPFILE} &"
33417a90a78SPeter Oskolkov	elif [ "${PROTO}" == "IPv6" ] ; then
33517a90a78SPeter Oskolkov		IP_DST=${IPv6_DST}
33617a90a78SPeter Oskolkov		ip netns exec ${NS3} bash -c \
337106c35ddSJiri Benc			"nc -6 -l -p 9000 > ${TMPFILE} &"
33817a90a78SPeter Oskolkov		RET=$?
33917a90a78SPeter Oskolkov	else
34017a90a78SPeter Oskolkov		echo "    test_gso: unknown PROTO: ${PROTO}"
34117a90a78SPeter Oskolkov		TEST_STATUS=1
34217a90a78SPeter Oskolkov	fi
34317a90a78SPeter Oskolkov	sleep 1  # let nc start listening
34417a90a78SPeter Oskolkov
34517a90a78SPeter Oskolkov	# send a packet larger than MTU
34617a90a78SPeter Oskolkov	ip netns exec ${NS1} bash -c \
34717a90a78SPeter Oskolkov		"dd if=/dev/zero bs=$PKT_SZ count=1 > /dev/tcp/${IP_DST}/9000 2>/dev/null"
34817a90a78SPeter Oskolkov	sleep 2 # let the packet get delivered
34917a90a78SPeter Oskolkov
35017a90a78SPeter Oskolkov	# verify we received all expected bytes
35117a90a78SPeter Oskolkov	SZ=$(stat -c %s ${TMPFILE})
35217a90a78SPeter Oskolkov	if [ "$SZ" != "$PKT_SZ" ] ; then
35317a90a78SPeter Oskolkov		echo "    test_gso failed: ${PROTO}"
35417a90a78SPeter Oskolkov		TEST_STATUS=1
35517a90a78SPeter Oskolkov	fi
35617a90a78SPeter Oskolkov}
35717a90a78SPeter Oskolkov
3589d6b3584SPeter Oskolkovtest_egress()
3599d6b3584SPeter Oskolkov{
3600fde56e4SPeter Oskolkov	local readonly ENCAP=$1
361809041e7SPeter Oskolkov	echo "starting egress ${ENCAP} encap test ${VRF}"
3620fde56e4SPeter Oskolkov	setup
3630fde56e4SPeter Oskolkov
3640fde56e4SPeter Oskolkov	# by default, pings work
3650fde56e4SPeter Oskolkov	test_ping IPv4 0
3660fde56e4SPeter Oskolkov	test_ping IPv6 0
3670fde56e4SPeter Oskolkov
3680fde56e4SPeter Oskolkov	# remove NS2->DST routes, ping fails
369809041e7SPeter Oskolkov	ip -netns ${NS2}    route del ${IPv4_DST}/32  dev veth3 ${VRF}
370809041e7SPeter Oskolkov	ip -netns ${NS2} -6 route del ${IPv6_DST}/128 dev veth3 ${VRF}
3710fde56e4SPeter Oskolkov	test_ping IPv4 1
3720fde56e4SPeter Oskolkov	test_ping IPv6 1
3730fde56e4SPeter Oskolkov
3740fde56e4SPeter Oskolkov	# install replacement routes (LWT/eBPF), pings succeed
3750fde56e4SPeter Oskolkov	if [ "${ENCAP}" == "IPv4" ] ; then
376809041e7SPeter Oskolkov		ip -netns ${NS1} route add ${IPv4_DST} encap bpf xmit obj \
377*98af3746SWang Yufen			${BPF_FILE} sec encap_gre dev veth1 ${VRF}
378809041e7SPeter Oskolkov		ip -netns ${NS1} -6 route add ${IPv6_DST} encap bpf xmit obj \
379*98af3746SWang Yufen			${BPF_FILE} sec encap_gre dev veth1 ${VRF}
3800fde56e4SPeter Oskolkov	elif [ "${ENCAP}" == "IPv6" ] ; then
381809041e7SPeter Oskolkov		ip -netns ${NS1} route add ${IPv4_DST} encap bpf xmit obj \
382*98af3746SWang Yufen			${BPF_FILE} sec encap_gre6 dev veth1 ${VRF}
383809041e7SPeter Oskolkov		ip -netns ${NS1} -6 route add ${IPv6_DST} encap bpf xmit obj \
384*98af3746SWang Yufen			${BPF_FILE} sec encap_gre6 dev veth1 ${VRF}
3850fde56e4SPeter Oskolkov	else
3869d6b3584SPeter Oskolkov		echo "    unknown encap ${ENCAP}"
3879d6b3584SPeter Oskolkov		TEST_STATUS=1
3880fde56e4SPeter Oskolkov	fi
3890fde56e4SPeter Oskolkov	test_ping IPv4 0
3900fde56e4SPeter Oskolkov	test_ping IPv6 0
391809041e7SPeter Oskolkov
392809041e7SPeter Oskolkov	# skip GSO tests with VRF: VRF routing needs properly assigned
393809041e7SPeter Oskolkov	# source IP/device, which is easy to do with ping and hard with dd/nc.
394809041e7SPeter Oskolkov	if [ -z "${VRF}" ] ; then
39517a90a78SPeter Oskolkov		test_gso IPv4
39617a90a78SPeter Oskolkov		test_gso IPv6
397809041e7SPeter Oskolkov	fi
3980fde56e4SPeter Oskolkov
3999d6b3584SPeter Oskolkov	# a negative test: remove routes to GRE devices: ping fails
4009d6b3584SPeter Oskolkov	remove_routes_to_gredev
4019d6b3584SPeter Oskolkov	test_ping IPv4 1
4029d6b3584SPeter Oskolkov	test_ping IPv6 1
4039d6b3584SPeter Oskolkov
4049d6b3584SPeter Oskolkov	# another negative test
4059d6b3584SPeter Oskolkov	add_unreachable_routes_to_gredev
4069d6b3584SPeter Oskolkov	test_ping IPv4 1
4079d6b3584SPeter Oskolkov	test_ping IPv6 1
4089d6b3584SPeter Oskolkov
4090fde56e4SPeter Oskolkov	cleanup
4109d6b3584SPeter Oskolkov	process_test_results
4110fde56e4SPeter Oskolkov}
4120fde56e4SPeter Oskolkov
4139d6b3584SPeter Oskolkovtest_ingress()
4149d6b3584SPeter Oskolkov{
4150fde56e4SPeter Oskolkov	local readonly ENCAP=$1
416809041e7SPeter Oskolkov	echo "starting ingress ${ENCAP} encap test ${VRF}"
4170fde56e4SPeter Oskolkov	setup
4180fde56e4SPeter Oskolkov
4190fde56e4SPeter Oskolkov	# need to wait a bit for IPv6 to autoconf, otherwise
4200fde56e4SPeter Oskolkov	# ping6 sometimes fails with "unable to bind to address"
4210fde56e4SPeter Oskolkov
4220fde56e4SPeter Oskolkov	# by default, pings work
4230fde56e4SPeter Oskolkov	test_ping IPv4 0
4240fde56e4SPeter Oskolkov	test_ping IPv6 0
4250fde56e4SPeter Oskolkov
4260fde56e4SPeter Oskolkov	# remove NS2->DST routes, pings fail
427809041e7SPeter Oskolkov	ip -netns ${NS2}    route del ${IPv4_DST}/32  dev veth3 ${VRF}
428809041e7SPeter Oskolkov	ip -netns ${NS2} -6 route del ${IPv6_DST}/128 dev veth3 ${VRF}
4290fde56e4SPeter Oskolkov	test_ping IPv4 1
4300fde56e4SPeter Oskolkov	test_ping IPv6 1
4310fde56e4SPeter Oskolkov
4320fde56e4SPeter Oskolkov	# install replacement routes (LWT/eBPF), pings succeed
4330fde56e4SPeter Oskolkov	if [ "${ENCAP}" == "IPv4" ] ; then
434809041e7SPeter Oskolkov		ip -netns ${NS2} route add ${IPv4_DST} encap bpf in obj \
435*98af3746SWang Yufen			${BPF_FILE} sec encap_gre dev veth2 ${VRF}
436809041e7SPeter Oskolkov		ip -netns ${NS2} -6 route add ${IPv6_DST} encap bpf in obj \
437*98af3746SWang Yufen			${BPF_FILE} sec encap_gre dev veth2 ${VRF}
4380fde56e4SPeter Oskolkov	elif [ "${ENCAP}" == "IPv6" ] ; then
439809041e7SPeter Oskolkov		ip -netns ${NS2} route add ${IPv4_DST} encap bpf in obj \
440*98af3746SWang Yufen			${BPF_FILE} sec encap_gre6 dev veth2 ${VRF}
441809041e7SPeter Oskolkov		ip -netns ${NS2} -6 route add ${IPv6_DST} encap bpf in obj \
442*98af3746SWang Yufen			${BPF_FILE} sec encap_gre6 dev veth2 ${VRF}
4430fde56e4SPeter Oskolkov	else
4440fde56e4SPeter Oskolkov		echo "FAIL: unknown encap ${ENCAP}"
44517a90a78SPeter Oskolkov		TEST_STATUS=1
4460fde56e4SPeter Oskolkov	fi
4470fde56e4SPeter Oskolkov	test_ping IPv4 0
4480fde56e4SPeter Oskolkov	test_ping IPv6 0
4490fde56e4SPeter Oskolkov
4509d6b3584SPeter Oskolkov	# a negative test: remove routes to GRE devices: ping fails
4519d6b3584SPeter Oskolkov	remove_routes_to_gredev
4529d6b3584SPeter Oskolkov	test_ping IPv4 1
4539d6b3584SPeter Oskolkov	test_ping IPv6 1
4549d6b3584SPeter Oskolkov
4559d6b3584SPeter Oskolkov	# another negative test
4569d6b3584SPeter Oskolkov	add_unreachable_routes_to_gredev
4579d6b3584SPeter Oskolkov	test_ping IPv4 1
4589d6b3584SPeter Oskolkov	test_ping IPv6 1
4599d6b3584SPeter Oskolkov
4600fde56e4SPeter Oskolkov	cleanup
4619d6b3584SPeter Oskolkov	process_test_results
4620fde56e4SPeter Oskolkov}
4630fde56e4SPeter Oskolkov
464809041e7SPeter OskolkovVRF=""
465809041e7SPeter Oskolkovtest_egress IPv4
466809041e7SPeter Oskolkovtest_egress IPv6
467809041e7SPeter Oskolkovtest_ingress IPv4
468809041e7SPeter Oskolkovtest_ingress IPv6
469809041e7SPeter Oskolkov
470809041e7SPeter OskolkovVRF="vrf red"
4710fde56e4SPeter Oskolkovtest_egress IPv4
4720fde56e4SPeter Oskolkovtest_egress IPv6
4730fde56e4SPeter Oskolkovtest_ingress IPv4
4740fde56e4SPeter Oskolkovtest_ingress IPv6
4750fde56e4SPeter Oskolkov
4769d6b3584SPeter Oskolkovprint_test_summary_and_exit
477