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