xref: /openbmc/linux/tools/testing/selftests/net/vrf_route_leaking.sh (revision c900529f3d9161bfde5cca0754f83b4d3c3e0220)
11a017276SMichael Jeanson#!/bin/bash
21a017276SMichael Jeanson# SPDX-License-Identifier: GPL-2.0
31a017276SMichael Jeanson#
41a017276SMichael Jeanson# Copyright (c) 2019 David Ahern <dsahern@gmail.com>. All rights reserved.
51a017276SMichael Jeanson# Copyright (c) 2020 Michael Jeanson <mjeanson@efficios.com>. All rights reserved.
61a017276SMichael Jeanson#
71a017276SMichael Jeanson# Requires CONFIG_NET_VRF, CONFIG_VETH, CONFIG_BRIDGE and CONFIG_NET_NS.
81a017276SMichael Jeanson#
91a017276SMichael Jeanson#
101a017276SMichael Jeanson# Symmetric routing topology
111a017276SMichael Jeanson#
121a017276SMichael Jeanson#                     blue         red
131a017276SMichael Jeanson# +----+              .253 +----+ .253              +----+
141a017276SMichael Jeanson# | h1 |-------------------| r1 |-------------------| h2 |
151a017276SMichael Jeanson# +----+ .1                +----+                .2 +----+
161a017276SMichael Jeanson#         172.16.1/24                  172.16.2/24
171a017276SMichael Jeanson#    2001:db8:16:1/64                  2001:db8:16:2/64
181a017276SMichael Jeanson#
191a017276SMichael Jeanson#
201a017276SMichael Jeanson# Route from h1 to h2 and back goes through r1, incoming vrf blue has a route
211a017276SMichael Jeanson# to the outgoing vrf red for the n2 network and red has a route back to n1.
221a017276SMichael Jeanson# The red VRF interface has a MTU of 1400.
231a017276SMichael Jeanson#
241a017276SMichael Jeanson# The first test sends a ping with a ttl of 1 from h1 to h2 and parses the
251a017276SMichael Jeanson# output of the command to check that a ttl expired error is received.
261a017276SMichael Jeanson#
271a017276SMichael Jeanson# The second test runs traceroute from h1 to h2 and parses the output to check
281a017276SMichael Jeanson# for a hop on r1.
291a017276SMichael Jeanson#
301a017276SMichael Jeanson# The third test sends a ping with a packet size of 1450 from h1 to h2 and
311a017276SMichael Jeanson# parses the output of the command to check that a fragmentation error is
321a017276SMichael Jeanson# received.
331a017276SMichael Jeanson#
341a017276SMichael Jeanson#
351a017276SMichael Jeanson# Asymmetric routing topology
361a017276SMichael Jeanson#
371a017276SMichael Jeanson# This topology represents a customer setup where the issue with icmp errors
381a017276SMichael Jeanson# and VRF route leaking was initialy reported. The MTU test isn't done here
391a017276SMichael Jeanson# because of the lack of a return route in the red VRF.
401a017276SMichael Jeanson#
411a017276SMichael Jeanson#                     blue         red
421a017276SMichael Jeanson#                     .253 +----+ .253
431a017276SMichael Jeanson#                     +----| r1 |----+
441a017276SMichael Jeanson#                     |    +----+    |
451a017276SMichael Jeanson# +----+              |              |              +----+
461a017276SMichael Jeanson# | h1 |--------------+              +--------------| h2 |
471a017276SMichael Jeanson# +----+ .1           |              |           .2 +----+
481a017276SMichael Jeanson#         172.16.1/24 |    +----+    | 172.16.2/24
491a017276SMichael Jeanson#    2001:db8:16:1/64 +----| r2 |----+ 2001:db8:16:2/64
501a017276SMichael Jeanson#                     .254 +----+ .254
511a017276SMichael Jeanson#
521a017276SMichael Jeanson#
531a017276SMichael Jeanson# Route from h1 to h2 goes through r1, incoming vrf blue has a route to the
541a017276SMichael Jeanson# outgoing vrf red for the n2 network but red doesn't have a route back to n1.
551a017276SMichael Jeanson# Route from h2 to h1 goes through r2.
561a017276SMichael Jeanson#
571a017276SMichael Jeanson# The objective is to check that the incoming vrf routing table is selected
581a017276SMichael Jeanson# to send an ICMP error back to the source when the ttl of a packet reaches 1
591a017276SMichael Jeanson# while it is forwarded between different vrfs.
601a017276SMichael Jeanson
611a017276SMichael JeansonVERBOSE=0
621a017276SMichael JeansonPAUSE_ON_FAIL=no
631a017276SMichael JeansonDEFAULT_TTYPE=sym
641a017276SMichael Jeanson
651a017276SMichael JeansonH1_N1=172.16.1.0/24
661a017276SMichael JeansonH1_N1_6=2001:db8:16:1::/64
671a017276SMichael Jeanson
681a017276SMichael JeansonH1_N1_IP=172.16.1.1
691a017276SMichael JeansonR1_N1_IP=172.16.1.253
701a017276SMichael JeansonR2_N1_IP=172.16.1.254
711a017276SMichael Jeanson
721a017276SMichael JeansonH1_N1_IP6=2001:db8:16:1::1
731a017276SMichael JeansonR1_N1_IP6=2001:db8:16:1::253
741a017276SMichael JeansonR2_N1_IP6=2001:db8:16:1::254
751a017276SMichael Jeanson
761a017276SMichael JeansonH2_N2=172.16.2.0/24
771a017276SMichael JeansonH2_N2_6=2001:db8:16:2::/64
781a017276SMichael Jeanson
791a017276SMichael JeansonH2_N2_IP=172.16.2.2
801a017276SMichael JeansonR1_N2_IP=172.16.2.253
811a017276SMichael JeansonR2_N2_IP=172.16.2.254
821a017276SMichael Jeanson
831a017276SMichael JeansonH2_N2_IP6=2001:db8:16:2::2
841a017276SMichael JeansonR1_N2_IP6=2001:db8:16:2::253
851a017276SMichael JeansonR2_N2_IP6=2001:db8:16:2::254
861a017276SMichael Jeanson
871a017276SMichael Jeanson################################################################################
881a017276SMichael Jeanson# helpers
891a017276SMichael Jeanson
901a017276SMichael Jeansonlog_section()
911a017276SMichael Jeanson{
921a017276SMichael Jeanson	echo
931a017276SMichael Jeanson	echo "###########################################################################"
941a017276SMichael Jeanson	echo "$*"
951a017276SMichael Jeanson	echo "###########################################################################"
961a017276SMichael Jeanson	echo
971a017276SMichael Jeanson}
981a017276SMichael Jeanson
991a017276SMichael Jeansonlog_test()
1001a017276SMichael Jeanson{
1011a017276SMichael Jeanson	local rc=$1
1021a017276SMichael Jeanson	local expected=$2
1031a017276SMichael Jeanson	local msg="$3"
1041a017276SMichael Jeanson
1051a017276SMichael Jeanson	if [ "${rc}" -eq "${expected}" ]; then
1061a017276SMichael Jeanson		printf "TEST: %-60s  [ OK ]\n" "${msg}"
1071a017276SMichael Jeanson		nsuccess=$((nsuccess+1))
1081a017276SMichael Jeanson	else
1091a017276SMichael Jeanson		ret=1
1101a017276SMichael Jeanson		nfail=$((nfail+1))
1111a017276SMichael Jeanson		printf "TEST: %-60s  [FAIL]\n" "${msg}"
1121a017276SMichael Jeanson		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
1131a017276SMichael Jeanson			echo
1141a017276SMichael Jeanson			echo "hit enter to continue, 'q' to quit"
1151a017276SMichael Jeanson			read -r a
1161a017276SMichael Jeanson			[ "$a" = "q" ] && exit 1
1171a017276SMichael Jeanson		fi
1181a017276SMichael Jeanson	fi
1191a017276SMichael Jeanson}
1201a017276SMichael Jeanson
1211a017276SMichael Jeansonrun_cmd()
1221a017276SMichael Jeanson{
1231a017276SMichael Jeanson	local cmd="$*"
1241a017276SMichael Jeanson	local out
1251a017276SMichael Jeanson	local rc
1261a017276SMichael Jeanson
1271a017276SMichael Jeanson	if [ "$VERBOSE" = "1" ]; then
1281a017276SMichael Jeanson		echo "COMMAND: $cmd"
1291a017276SMichael Jeanson	fi
1301a017276SMichael Jeanson
1311a017276SMichael Jeanson	# shellcheck disable=SC2086
1321a017276SMichael Jeanson	out=$(eval $cmd 2>&1)
1331a017276SMichael Jeanson	rc=$?
1341a017276SMichael Jeanson	if [ "$VERBOSE" = "1" ] && [ -n "$out" ]; then
1351a017276SMichael Jeanson		echo "$out"
1361a017276SMichael Jeanson	fi
1371a017276SMichael Jeanson
1381a017276SMichael Jeanson	[ "$VERBOSE" = "1" ] && echo
1391a017276SMichael Jeanson
1401a017276SMichael Jeanson	return $rc
1411a017276SMichael Jeanson}
1421a017276SMichael Jeanson
1431a017276SMichael Jeansonrun_cmd_grep()
1441a017276SMichael Jeanson{
1451a017276SMichael Jeanson	local grep_pattern="$1"
1461a017276SMichael Jeanson	shift
1471a017276SMichael Jeanson	local cmd="$*"
1481a017276SMichael Jeanson	local out
1491a017276SMichael Jeanson	local rc
1501a017276SMichael Jeanson
1511a017276SMichael Jeanson	if [ "$VERBOSE" = "1" ]; then
1521a017276SMichael Jeanson		echo "COMMAND: $cmd"
1531a017276SMichael Jeanson	fi
1541a017276SMichael Jeanson
1551a017276SMichael Jeanson	# shellcheck disable=SC2086
1561a017276SMichael Jeanson	out=$(eval $cmd 2>&1)
1571a017276SMichael Jeanson	if [ "$VERBOSE" = "1" ] && [ -n "$out" ]; then
1581a017276SMichael Jeanson		echo "$out"
1591a017276SMichael Jeanson	fi
1601a017276SMichael Jeanson
1611a017276SMichael Jeanson	echo "$out" | grep -q "$grep_pattern"
1621a017276SMichael Jeanson	rc=$?
1631a017276SMichael Jeanson
1641a017276SMichael Jeanson	[ "$VERBOSE" = "1" ] && echo
1651a017276SMichael Jeanson
1661a017276SMichael Jeanson	return $rc
1671a017276SMichael Jeanson}
1681a017276SMichael Jeanson
1691a017276SMichael Jeanson################################################################################
1701a017276SMichael Jeanson# setup and teardown
1711a017276SMichael Jeanson
1721a017276SMichael Jeansoncleanup()
1731a017276SMichael Jeanson{
1741a017276SMichael Jeanson	local ns
1751a017276SMichael Jeanson
1761a017276SMichael Jeanson	for ns in h1 h2 r1 r2; do
1771a017276SMichael Jeanson		ip netns del $ns 2>/dev/null
1781a017276SMichael Jeanson	done
1791a017276SMichael Jeanson}
1801a017276SMichael Jeanson
1811a017276SMichael Jeansonsetup_vrf()
1821a017276SMichael Jeanson{
1831a017276SMichael Jeanson	local ns=$1
1841a017276SMichael Jeanson
1851a017276SMichael Jeanson	ip -netns "${ns}" rule del pref 0
1861a017276SMichael Jeanson	ip -netns "${ns}" rule add pref 32765 from all lookup local
1871a017276SMichael Jeanson	ip -netns "${ns}" -6 rule del pref 0
1881a017276SMichael Jeanson	ip -netns "${ns}" -6 rule add pref 32765 from all lookup local
1891a017276SMichael Jeanson}
1901a017276SMichael Jeanson
1911a017276SMichael Jeansoncreate_vrf()
1921a017276SMichael Jeanson{
1931a017276SMichael Jeanson	local ns=$1
1941a017276SMichael Jeanson	local vrf=$2
1951a017276SMichael Jeanson	local table=$3
1961a017276SMichael Jeanson
1971a017276SMichael Jeanson	ip -netns "${ns}" link add "${vrf}" type vrf table "${table}"
1981a017276SMichael Jeanson	ip -netns "${ns}" link set "${vrf}" up
1991a017276SMichael Jeanson	ip -netns "${ns}" route add vrf "${vrf}" unreachable default metric 8192
2001a017276SMichael Jeanson	ip -netns "${ns}" -6 route add vrf "${vrf}" unreachable default metric 8192
2011a017276SMichael Jeanson
2021a017276SMichael Jeanson	ip -netns "${ns}" addr add 127.0.0.1/8 dev "${vrf}"
2031a017276SMichael Jeanson	ip -netns "${ns}" -6 addr add ::1 dev "${vrf}" nodad
2041a017276SMichael Jeanson}
2051a017276SMichael Jeanson
2061a017276SMichael Jeansonsetup_sym()
2071a017276SMichael Jeanson{
2081a017276SMichael Jeanson	local ns
2091a017276SMichael Jeanson
2101a017276SMichael Jeanson	# make sure we are starting with a clean slate
2111a017276SMichael Jeanson	cleanup
2121a017276SMichael Jeanson
2131a017276SMichael Jeanson	#
2141a017276SMichael Jeanson	# create nodes as namespaces
2151a017276SMichael Jeanson	#
2161a017276SMichael Jeanson	for ns in h1 h2 r1; do
2171a017276SMichael Jeanson		ip netns add $ns
2181a017276SMichael Jeanson		ip -netns $ns link set lo up
2191a017276SMichael Jeanson
2201a017276SMichael Jeanson		case "${ns}" in
2211a017276SMichael Jeanson		h[12]) ip netns exec $ns sysctl -q -w net.ipv6.conf.all.forwarding=0
2221a017276SMichael Jeanson		       ip netns exec $ns sysctl -q -w net.ipv6.conf.all.keep_addr_on_down=1
2231a017276SMichael Jeanson			;;
2241a017276SMichael Jeanson		r1)    ip netns exec $ns sysctl -q -w net.ipv4.ip_forward=1
2251a017276SMichael Jeanson		       ip netns exec $ns sysctl -q -w net.ipv6.conf.all.forwarding=1
2261a017276SMichael Jeanson		esac
2271a017276SMichael Jeanson	done
2281a017276SMichael Jeanson
2291a017276SMichael Jeanson	#
2301a017276SMichael Jeanson	# create interconnects
2311a017276SMichael Jeanson	#
2321a017276SMichael Jeanson	ip -netns h1 link add eth0 type veth peer name r1h1
2331a017276SMichael Jeanson	ip -netns h1 link set r1h1 netns r1 name eth0 up
2341a017276SMichael Jeanson
2351a017276SMichael Jeanson	ip -netns h2 link add eth0 type veth peer name r1h2
2361a017276SMichael Jeanson	ip -netns h2 link set r1h2 netns r1 name eth1 up
2371a017276SMichael Jeanson
2381a017276SMichael Jeanson	#
2391a017276SMichael Jeanson	# h1
2401a017276SMichael Jeanson	#
2411a017276SMichael Jeanson	ip -netns h1 addr add dev eth0 ${H1_N1_IP}/24
2421a017276SMichael Jeanson	ip -netns h1 -6 addr add dev eth0 ${H1_N1_IP6}/64 nodad
2431a017276SMichael Jeanson	ip -netns h1 link set eth0 up
2441a017276SMichael Jeanson
2451a017276SMichael Jeanson	# h1 to h2 via r1
2461a017276SMichael Jeanson	ip -netns h1    route add ${H2_N2} via ${R1_N1_IP} dev eth0
2471a017276SMichael Jeanson	ip -netns h1 -6 route add ${H2_N2_6} via "${R1_N1_IP6}" dev eth0
2481a017276SMichael Jeanson
2491a017276SMichael Jeanson	#
2501a017276SMichael Jeanson	# h2
2511a017276SMichael Jeanson	#
2521a017276SMichael Jeanson	ip -netns h2 addr add dev eth0 ${H2_N2_IP}/24
2531a017276SMichael Jeanson	ip -netns h2 -6 addr add dev eth0 ${H2_N2_IP6}/64 nodad
2541a017276SMichael Jeanson	ip -netns h2 link set eth0 up
2551a017276SMichael Jeanson
2561a017276SMichael Jeanson	# h2 to h1 via r1
2571a017276SMichael Jeanson	ip -netns h2 route add default via ${R1_N2_IP} dev eth0
2581a017276SMichael Jeanson	ip -netns h2 -6 route add default via ${R1_N2_IP6} dev eth0
2591a017276SMichael Jeanson
2601a017276SMichael Jeanson	#
2611a017276SMichael Jeanson	# r1
2621a017276SMichael Jeanson	#
2631a017276SMichael Jeanson	setup_vrf r1
2641a017276SMichael Jeanson	create_vrf r1 blue 1101
2651a017276SMichael Jeanson	create_vrf r1 red 1102
2661a017276SMichael Jeanson	ip -netns r1 link set mtu 1400 dev eth1
2671a017276SMichael Jeanson	ip -netns r1 link set eth0 vrf blue up
2681a017276SMichael Jeanson	ip -netns r1 link set eth1 vrf red up
2691a017276SMichael Jeanson	ip -netns r1 addr add dev eth0 ${R1_N1_IP}/24
2701a017276SMichael Jeanson	ip -netns r1 -6 addr add dev eth0 ${R1_N1_IP6}/64 nodad
2711a017276SMichael Jeanson	ip -netns r1 addr add dev eth1 ${R1_N2_IP}/24
2721a017276SMichael Jeanson	ip -netns r1 -6 addr add dev eth1 ${R1_N2_IP6}/64 nodad
2731a017276SMichael Jeanson
2741a017276SMichael Jeanson	# Route leak from blue to red
2751a017276SMichael Jeanson	ip -netns r1 route add vrf blue ${H2_N2} dev red
2761a017276SMichael Jeanson	ip -netns r1 -6 route add vrf blue ${H2_N2_6} dev red
2771a017276SMichael Jeanson
2781a017276SMichael Jeanson	# Route leak from red to blue
2791a017276SMichael Jeanson	ip -netns r1 route add vrf red ${H1_N1} dev blue
2801a017276SMichael Jeanson	ip -netns r1 -6 route add vrf red ${H1_N1_6} dev blue
2811a017276SMichael Jeanson
2821a017276SMichael Jeanson
2831a017276SMichael Jeanson	# Wait for ip config to settle
2841a017276SMichael Jeanson	sleep 2
2851a017276SMichael Jeanson}
2861a017276SMichael Jeanson
2871a017276SMichael Jeansonsetup_asym()
2881a017276SMichael Jeanson{
2891a017276SMichael Jeanson	local ns
2901a017276SMichael Jeanson
2911a017276SMichael Jeanson	# make sure we are starting with a clean slate
2921a017276SMichael Jeanson	cleanup
2931a017276SMichael Jeanson
2941a017276SMichael Jeanson	#
2951a017276SMichael Jeanson	# create nodes as namespaces
2961a017276SMichael Jeanson	#
2971a017276SMichael Jeanson	for ns in h1 h2 r1 r2; do
2981a017276SMichael Jeanson		ip netns add $ns
2991a017276SMichael Jeanson		ip -netns $ns link set lo up
3001a017276SMichael Jeanson
3011a017276SMichael Jeanson		case "${ns}" in
3021a017276SMichael Jeanson		h[12]) ip netns exec $ns sysctl -q -w net.ipv6.conf.all.forwarding=0
3031a017276SMichael Jeanson		       ip netns exec $ns sysctl -q -w net.ipv6.conf.all.keep_addr_on_down=1
3041a017276SMichael Jeanson			;;
3051a017276SMichael Jeanson		r[12]) ip netns exec $ns sysctl -q -w net.ipv4.ip_forward=1
3061a017276SMichael Jeanson		       ip netns exec $ns sysctl -q -w net.ipv6.conf.all.forwarding=1
3071a017276SMichael Jeanson		esac
3081a017276SMichael Jeanson	done
3091a017276SMichael Jeanson
3101a017276SMichael Jeanson	#
3111a017276SMichael Jeanson	# create interconnects
3121a017276SMichael Jeanson	#
3131a017276SMichael Jeanson	ip -netns h1 link add eth0 type veth peer name r1h1
3141a017276SMichael Jeanson	ip -netns h1 link set r1h1 netns r1 name eth0 up
3151a017276SMichael Jeanson
3161a017276SMichael Jeanson	ip -netns h1 link add eth1 type veth peer name r2h1
3171a017276SMichael Jeanson	ip -netns h1 link set r2h1 netns r2 name eth0 up
3181a017276SMichael Jeanson
3191a017276SMichael Jeanson	ip -netns h2 link add eth0 type veth peer name r1h2
3201a017276SMichael Jeanson	ip -netns h2 link set r1h2 netns r1 name eth1 up
3211a017276SMichael Jeanson
3221a017276SMichael Jeanson	ip -netns h2 link add eth1 type veth peer name r2h2
3231a017276SMichael Jeanson	ip -netns h2 link set r2h2 netns r2 name eth1 up
3241a017276SMichael Jeanson
3251a017276SMichael Jeanson	#
3261a017276SMichael Jeanson	# h1
3271a017276SMichael Jeanson	#
3281a017276SMichael Jeanson	ip -netns h1 link add br0 type bridge
3291a017276SMichael Jeanson	ip -netns h1 link set br0 up
3301a017276SMichael Jeanson	ip -netns h1 addr add dev br0 ${H1_N1_IP}/24
3311a017276SMichael Jeanson	ip -netns h1 -6 addr add dev br0 ${H1_N1_IP6}/64 nodad
3321a017276SMichael Jeanson	ip -netns h1 link set eth0 master br0 up
3331a017276SMichael Jeanson	ip -netns h1 link set eth1 master br0 up
3341a017276SMichael Jeanson
3351a017276SMichael Jeanson	# h1 to h2 via r1
3361a017276SMichael Jeanson	ip -netns h1    route add ${H2_N2} via ${R1_N1_IP} dev br0
3371a017276SMichael Jeanson	ip -netns h1 -6 route add ${H2_N2_6} via "${R1_N1_IP6}" dev br0
3381a017276SMichael Jeanson
3391a017276SMichael Jeanson	#
3401a017276SMichael Jeanson	# h2
3411a017276SMichael Jeanson	#
3421a017276SMichael Jeanson	ip -netns h2 link add br0 type bridge
3431a017276SMichael Jeanson	ip -netns h2 link set br0 up
3441a017276SMichael Jeanson	ip -netns h2 addr add dev br0 ${H2_N2_IP}/24
3451a017276SMichael Jeanson	ip -netns h2 -6 addr add dev br0 ${H2_N2_IP6}/64 nodad
3461a017276SMichael Jeanson	ip -netns h2 link set eth0 master br0 up
3471a017276SMichael Jeanson	ip -netns h2 link set eth1 master br0 up
3481a017276SMichael Jeanson
3491a017276SMichael Jeanson	# h2 to h1 via r2
3501a017276SMichael Jeanson	ip -netns h2 route add default via ${R2_N2_IP} dev br0
3511a017276SMichael Jeanson	ip -netns h2 -6 route add default via ${R2_N2_IP6} dev br0
3521a017276SMichael Jeanson
3531a017276SMichael Jeanson	#
3541a017276SMichael Jeanson	# r1
3551a017276SMichael Jeanson	#
3561a017276SMichael Jeanson	setup_vrf r1
3571a017276SMichael Jeanson	create_vrf r1 blue 1101
3581a017276SMichael Jeanson	create_vrf r1 red 1102
3591a017276SMichael Jeanson	ip -netns r1 link set mtu 1400 dev eth1
3601a017276SMichael Jeanson	ip -netns r1 link set eth0 vrf blue up
3611a017276SMichael Jeanson	ip -netns r1 link set eth1 vrf red up
3621a017276SMichael Jeanson	ip -netns r1 addr add dev eth0 ${R1_N1_IP}/24
3631a017276SMichael Jeanson	ip -netns r1 -6 addr add dev eth0 ${R1_N1_IP6}/64 nodad
3641a017276SMichael Jeanson	ip -netns r1 addr add dev eth1 ${R1_N2_IP}/24
3651a017276SMichael Jeanson	ip -netns r1 -6 addr add dev eth1 ${R1_N2_IP6}/64 nodad
3661a017276SMichael Jeanson
3671a017276SMichael Jeanson	# Route leak from blue to red
3681a017276SMichael Jeanson	ip -netns r1 route add vrf blue ${H2_N2} dev red
3691a017276SMichael Jeanson	ip -netns r1 -6 route add vrf blue ${H2_N2_6} dev red
3701a017276SMichael Jeanson
3711a017276SMichael Jeanson	# No route leak from red to blue
3721a017276SMichael Jeanson
3731a017276SMichael Jeanson	#
3741a017276SMichael Jeanson	# r2
3751a017276SMichael Jeanson	#
3761a017276SMichael Jeanson	ip -netns r2 addr add dev eth0 ${R2_N1_IP}/24
3771a017276SMichael Jeanson	ip -netns r2 -6 addr add dev eth0 ${R2_N1_IP6}/64 nodad
3781a017276SMichael Jeanson	ip -netns r2 addr add dev eth1 ${R2_N2_IP}/24
3791a017276SMichael Jeanson	ip -netns r2 -6 addr add dev eth1 ${R2_N2_IP6}/64 nodad
3801a017276SMichael Jeanson
3811a017276SMichael Jeanson	# Wait for ip config to settle
3821a017276SMichael Jeanson	sleep 2
3831a017276SMichael Jeanson}
3841a017276SMichael Jeanson
3851a017276SMichael Jeansoncheck_connectivity()
3861a017276SMichael Jeanson{
3871a017276SMichael Jeanson	ip netns exec h1 ping -c1 -w1 ${H2_N2_IP} >/dev/null 2>&1
3881a017276SMichael Jeanson	log_test $? 0 "Basic IPv4 connectivity"
3891a017276SMichael Jeanson	return $?
3901a017276SMichael Jeanson}
3911a017276SMichael Jeanson
3921a017276SMichael Jeansoncheck_connectivity6()
3931a017276SMichael Jeanson{
3941a017276SMichael Jeanson	ip netns exec h1 "${ping6}" -c1 -w1 ${H2_N2_IP6} >/dev/null 2>&1
3951a017276SMichael Jeanson	log_test $? 0 "Basic IPv6 connectivity"
3961a017276SMichael Jeanson	return $?
3971a017276SMichael Jeanson}
3981a017276SMichael Jeanson
3991a017276SMichael Jeansoncheck_traceroute()
4001a017276SMichael Jeanson{
4011a017276SMichael Jeanson	if [ ! -x "$(command -v traceroute)" ]; then
4021a017276SMichael Jeanson		echo "SKIP: Could not run IPV4 test without traceroute"
4031a017276SMichael Jeanson		return 1
4041a017276SMichael Jeanson	fi
4051a017276SMichael Jeanson}
4061a017276SMichael Jeanson
4071a017276SMichael Jeansoncheck_traceroute6()
4081a017276SMichael Jeanson{
4091a017276SMichael Jeanson	if [ ! -x "$(command -v traceroute6)" ]; then
4101a017276SMichael Jeanson		echo "SKIP: Could not run IPV6 test without traceroute6"
4111a017276SMichael Jeanson		return 1
4121a017276SMichael Jeanson	fi
4131a017276SMichael Jeanson}
4141a017276SMichael Jeanson
4151a017276SMichael Jeansonipv4_traceroute()
4161a017276SMichael Jeanson{
4171a017276SMichael Jeanson	local ttype="$1"
4181a017276SMichael Jeanson
4191a017276SMichael Jeanson	[ "x$ttype" = "x" ] && ttype="$DEFAULT_TTYPE"
4201a017276SMichael Jeanson
4211a017276SMichael Jeanson	log_section "IPv4 ($ttype route): VRF ICMP error route lookup traceroute"
4221a017276SMichael Jeanson
4231a017276SMichael Jeanson	check_traceroute || return
4241a017276SMichael Jeanson
4251a017276SMichael Jeanson	setup_"$ttype"
4261a017276SMichael Jeanson
4271a017276SMichael Jeanson	check_connectivity || return
4281a017276SMichael Jeanson
4291a017276SMichael Jeanson	run_cmd_grep "${R1_N1_IP}" ip netns exec h1 traceroute ${H2_N2_IP}
4301a017276SMichael Jeanson	log_test $? 0 "Traceroute reports a hop on r1"
4311a017276SMichael Jeanson}
4321a017276SMichael Jeanson
4331a017276SMichael Jeansonipv4_traceroute_asym()
4341a017276SMichael Jeanson{
4351a017276SMichael Jeanson	ipv4_traceroute asym
4361a017276SMichael Jeanson}
4371a017276SMichael Jeanson
4381a017276SMichael Jeansonipv6_traceroute()
4391a017276SMichael Jeanson{
4401a017276SMichael Jeanson	local ttype="$1"
4411a017276SMichael Jeanson
4421a017276SMichael Jeanson	[ "x$ttype" = "x" ] && ttype="$DEFAULT_TTYPE"
4431a017276SMichael Jeanson
4441a017276SMichael Jeanson	log_section "IPv6 ($ttype route): VRF ICMP error route lookup traceroute"
4451a017276SMichael Jeanson
4461a017276SMichael Jeanson	check_traceroute6 || return
4471a017276SMichael Jeanson
4481a017276SMichael Jeanson	setup_"$ttype"
4491a017276SMichael Jeanson
4501a017276SMichael Jeanson	check_connectivity6 || return
4511a017276SMichael Jeanson
4521a017276SMichael Jeanson	run_cmd_grep "${R1_N1_IP6}" ip netns exec h1 traceroute6 ${H2_N2_IP6}
4531a017276SMichael Jeanson	log_test $? 0 "Traceroute6 reports a hop on r1"
4541a017276SMichael Jeanson}
4551a017276SMichael Jeanson
4561a017276SMichael Jeansonipv6_traceroute_asym()
4571a017276SMichael Jeanson{
4581a017276SMichael Jeanson	ipv6_traceroute asym
4591a017276SMichael Jeanson}
4601a017276SMichael Jeanson
4611a017276SMichael Jeansonipv4_ping_ttl()
4621a017276SMichael Jeanson{
4631a017276SMichael Jeanson	local ttype="$1"
4641a017276SMichael Jeanson
4651a017276SMichael Jeanson	[ "x$ttype" = "x" ] && ttype="$DEFAULT_TTYPE"
4661a017276SMichael Jeanson
4671a017276SMichael Jeanson	log_section "IPv4 ($ttype route): VRF ICMP ttl error route lookup ping"
4681a017276SMichael Jeanson
4691a017276SMichael Jeanson	setup_"$ttype"
4701a017276SMichael Jeanson
4711a017276SMichael Jeanson	check_connectivity || return
4721a017276SMichael Jeanson
4731a017276SMichael Jeanson	run_cmd_grep "Time to live exceeded" ip netns exec h1 ping -t1 -c1 -W2 ${H2_N2_IP}
4741a017276SMichael Jeanson	log_test $? 0 "Ping received ICMP ttl exceeded"
4751a017276SMichael Jeanson}
4761a017276SMichael Jeanson
4771a017276SMichael Jeansonipv4_ping_ttl_asym()
4781a017276SMichael Jeanson{
4791a017276SMichael Jeanson	ipv4_ping_ttl asym
4801a017276SMichael Jeanson}
4811a017276SMichael Jeanson
4821a017276SMichael Jeansonipv4_ping_frag()
4831a017276SMichael Jeanson{
4841a017276SMichael Jeanson	local ttype="$1"
4851a017276SMichael Jeanson
4861a017276SMichael Jeanson	[ "x$ttype" = "x" ] && ttype="$DEFAULT_TTYPE"
4871a017276SMichael Jeanson
4881a017276SMichael Jeanson	log_section "IPv4 ($ttype route): VRF ICMP fragmentation error route lookup ping"
4891a017276SMichael Jeanson
4901a017276SMichael Jeanson	setup_"$ttype"
4911a017276SMichael Jeanson
4921a017276SMichael Jeanson	check_connectivity || return
4931a017276SMichael Jeanson
4941a017276SMichael Jeanson	run_cmd_grep "Frag needed" ip netns exec h1 ping -s 1450 -Mdo -c1 -W2 ${H2_N2_IP}
4951a017276SMichael Jeanson	log_test $? 0 "Ping received ICMP Frag needed"
4961a017276SMichael Jeanson}
4971a017276SMichael Jeanson
4981a017276SMichael Jeansonipv4_ping_frag_asym()
4991a017276SMichael Jeanson{
5001a017276SMichael Jeanson	ipv4_ping_frag asym
5011a017276SMichael Jeanson}
5021a017276SMichael Jeanson
5031a017276SMichael Jeansonipv6_ping_ttl()
5041a017276SMichael Jeanson{
5051a017276SMichael Jeanson	local ttype="$1"
5061a017276SMichael Jeanson
5071a017276SMichael Jeanson	[ "x$ttype" = "x" ] && ttype="$DEFAULT_TTYPE"
5081a017276SMichael Jeanson
5091a017276SMichael Jeanson	log_section "IPv6 ($ttype route): VRF ICMP ttl error route lookup ping"
5101a017276SMichael Jeanson
5111a017276SMichael Jeanson	setup_"$ttype"
5121a017276SMichael Jeanson
5131a017276SMichael Jeanson	check_connectivity6 || return
5141a017276SMichael Jeanson
5151a017276SMichael Jeanson	run_cmd_grep "Time exceeded: Hop limit" ip netns exec h1 "${ping6}" -t1 -c1 -W2 ${H2_N2_IP6}
5161a017276SMichael Jeanson	log_test $? 0 "Ping received ICMP Hop limit"
5171a017276SMichael Jeanson}
5181a017276SMichael Jeanson
5191a017276SMichael Jeansonipv6_ping_ttl_asym()
5201a017276SMichael Jeanson{
5211a017276SMichael Jeanson	ipv6_ping_ttl asym
5221a017276SMichael Jeanson}
5231a017276SMichael Jeanson
5241a017276SMichael Jeansonipv6_ping_frag()
5251a017276SMichael Jeanson{
5261a017276SMichael Jeanson	local ttype="$1"
5271a017276SMichael Jeanson
5281a017276SMichael Jeanson	[ "x$ttype" = "x" ] && ttype="$DEFAULT_TTYPE"
5291a017276SMichael Jeanson
5301a017276SMichael Jeanson	log_section "IPv6 ($ttype route): VRF ICMP fragmentation error route lookup ping"
5311a017276SMichael Jeanson
5321a017276SMichael Jeanson	setup_"$ttype"
5331a017276SMichael Jeanson
5341a017276SMichael Jeanson	check_connectivity6 || return
5351a017276SMichael Jeanson
5361a017276SMichael Jeanson	run_cmd_grep "Packet too big" ip netns exec h1 "${ping6}" -s 1450 -Mdo -c1 -W2 ${H2_N2_IP6}
5371a017276SMichael Jeanson	log_test $? 0 "Ping received ICMP Packet too big"
5381a017276SMichael Jeanson}
5391a017276SMichael Jeanson
5401a017276SMichael Jeansonipv6_ping_frag_asym()
5411a017276SMichael Jeanson{
5421a017276SMichael Jeanson	ipv6_ping_frag asym
5431a017276SMichael Jeanson}
5441a017276SMichael Jeanson
5451a017276SMichael Jeanson################################################################################
5461a017276SMichael Jeanson# usage
5471a017276SMichael Jeanson
5481a017276SMichael Jeansonusage()
5491a017276SMichael Jeanson{
5501a017276SMichael Jeanson        cat <<EOF
5511a017276SMichael Jeansonusage: ${0##*/} OPTS
5521a017276SMichael Jeanson
5531a017276SMichael Jeanson	-4          Run IPv4 tests only
5541a017276SMichael Jeanson	-6          Run IPv6 tests only
5551a017276SMichael Jeanson        -t TEST     Run only TEST
5561a017276SMichael Jeanson	-p          Pause on fail
5571a017276SMichael Jeanson	-v          verbose mode (show commands and output)
5581a017276SMichael JeansonEOF
5591a017276SMichael Jeanson}
5601a017276SMichael Jeanson
5611a017276SMichael Jeanson################################################################################
5621a017276SMichael Jeanson# main
5631a017276SMichael Jeanson
5641a017276SMichael Jeanson# Some systems don't have a ping6 binary anymore
5651a017276SMichael Jeansoncommand -v ping6 > /dev/null 2>&1 && ping6=$(command -v ping6) || ping6=$(command -v ping)
5661a017276SMichael Jeanson
5671a017276SMichael JeansonTESTS_IPV4="ipv4_ping_ttl ipv4_traceroute ipv4_ping_frag ipv4_ping_ttl_asym ipv4_traceroute_asym"
568*c4cf2bc0SHangbin LiuTESTS_IPV6="ipv6_ping_ttl ipv6_traceroute ipv6_ping_ttl_asym ipv6_traceroute_asym"
5691a017276SMichael Jeanson
5701a017276SMichael Jeansonret=0
5711a017276SMichael Jeansonnsuccess=0
5721a017276SMichael Jeansonnfail=0
5731a017276SMichael Jeanson
5741a017276SMichael Jeansonwhile getopts :46t:pvh o
5751a017276SMichael Jeansondo
5761a017276SMichael Jeanson	case $o in
5771a017276SMichael Jeanson		4) TESTS=ipv4;;
5781a017276SMichael Jeanson		6) TESTS=ipv6;;
5791a017276SMichael Jeanson		t) TESTS=$OPTARG;;
5801a017276SMichael Jeanson		p) PAUSE_ON_FAIL=yes;;
5811a017276SMichael Jeanson		v) VERBOSE=1;;
5821a017276SMichael Jeanson		h) usage; exit 0;;
5831a017276SMichael Jeanson		*) usage; exit 1;;
5841a017276SMichael Jeanson	esac
5851a017276SMichael Jeansondone
5861a017276SMichael Jeanson
5871a017276SMichael Jeanson#
5881a017276SMichael Jeanson# show user test config
5891a017276SMichael Jeanson#
5901a017276SMichael Jeansonif [ -z "$TESTS" ]; then
5911a017276SMichael Jeanson        TESTS="$TESTS_IPV4 $TESTS_IPV6"
5921a017276SMichael Jeansonelif [ "$TESTS" = "ipv4" ]; then
5931a017276SMichael Jeanson        TESTS="$TESTS_IPV4"
5941a017276SMichael Jeansonelif [ "$TESTS" = "ipv6" ]; then
5951a017276SMichael Jeanson        TESTS="$TESTS_IPV6"
5961a017276SMichael Jeansonfi
5971a017276SMichael Jeanson
5981a017276SMichael Jeansonfor t in $TESTS
5991a017276SMichael Jeansondo
6001a017276SMichael Jeanson	case $t in
6011a017276SMichael Jeanson	ipv4_ping_ttl|ping)              ipv4_ping_ttl;;&
6021a017276SMichael Jeanson	ipv4_ping_ttl_asym|ping)         ipv4_ping_ttl_asym;;&
6031a017276SMichael Jeanson	ipv4_traceroute|traceroute)      ipv4_traceroute;;&
6041a017276SMichael Jeanson	ipv4_traceroute_asym|traceroute) ipv4_traceroute_asym;;&
6051a017276SMichael Jeanson	ipv4_ping_frag|ping)             ipv4_ping_frag;;&
6061a017276SMichael Jeanson
6071a017276SMichael Jeanson	ipv6_ping_ttl|ping)              ipv6_ping_ttl;;&
6081a017276SMichael Jeanson	ipv6_ping_ttl_asym|ping)         ipv6_ping_ttl_asym;;&
6091a017276SMichael Jeanson	ipv6_traceroute|traceroute)      ipv6_traceroute;;&
6101a017276SMichael Jeanson	ipv6_traceroute_asym|traceroute) ipv6_traceroute_asym;;&
6111a017276SMichael Jeanson	ipv6_ping_frag|ping)             ipv6_ping_frag;;&
6121a017276SMichael Jeanson
6131a017276SMichael Jeanson	# setup namespaces and config, but do not run any tests
6141a017276SMichael Jeanson	setup_sym|setup)                 setup_sym; exit 0;;
6151a017276SMichael Jeanson	setup_asym)                      setup_asym; exit 0;;
6161a017276SMichael Jeanson
6171a017276SMichael Jeanson	help)                       echo "Test names: $TESTS"; exit 0;;
6181a017276SMichael Jeanson	esac
6191a017276SMichael Jeansondone
6201a017276SMichael Jeanson
6211a017276SMichael Jeansoncleanup
6221a017276SMichael Jeanson
6231a017276SMichael Jeansonprintf "\nTests passed: %3d\n" ${nsuccess}
6241a017276SMichael Jeansonprintf "Tests failed: %3d\n"   ${nfail}
6251a017276SMichael Jeanson
6261a017276SMichael Jeansonexit $ret
627