1bbbc7aa4SGuillaume Nault#!/bin/sh 2bbbc7aa4SGuillaume Nault# SPDX-License-Identifier: GPL-2.0 3bbbc7aa4SGuillaume Nault 4bbbc7aa4SGuillaume Nault# Test various bareudp tunnel configurations. 5bbbc7aa4SGuillaume Nault# 6bbbc7aa4SGuillaume Nault# The bareudp module allows to tunnel network protocols like IP or MPLS over 7bbbc7aa4SGuillaume Nault# UDP, without adding any intermediate header. This scripts tests several 8bbbc7aa4SGuillaume Nault# configurations of bareudp (using IPv4 or IPv6 as underlay and transporting 9bbbc7aa4SGuillaume Nault# IPv4, IPv6 or MPLS packets on the overlay). 10bbbc7aa4SGuillaume Nault# 11bbbc7aa4SGuillaume Nault# Network topology: 12bbbc7aa4SGuillaume Nault# 13bbbc7aa4SGuillaume Nault# * A chain of 4 network namespaces, connected with veth pairs. Each veth 14bbbc7aa4SGuillaume Nault# is assigned an IPv4 and an IPv6 address. A host-route allows a veth to 15bbbc7aa4SGuillaume Nault# join its peer. 16bbbc7aa4SGuillaume Nault# 17bbbc7aa4SGuillaume Nault# * NS0 and NS3 are at the extremities of the chain. They have additional 18bbbc7aa4SGuillaume Nault# IPv4 and IPv6 addresses on their loopback device. Routes are added in NS0 19bbbc7aa4SGuillaume Nault# and NS3, so that they can communicate using these overlay IP addresses. 20bbbc7aa4SGuillaume Nault# For IPv4 and IPv6 reachability tests, the route simply sets the peer's 21bbbc7aa4SGuillaume Nault# veth address as gateway. For MPLS reachability tests, an MPLS header is 22bbbc7aa4SGuillaume Nault# also pushed before the IP header. 23bbbc7aa4SGuillaume Nault# 24bbbc7aa4SGuillaume Nault# * NS1 and NS2 are the intermediate namespaces. They use a bareudp device to 25bbbc7aa4SGuillaume Nault# encapsulate the traffic into UDP. 26bbbc7aa4SGuillaume Nault# 27bbbc7aa4SGuillaume Nault# +-----------------------------------------------------------------------+ 28bbbc7aa4SGuillaume Nault# | NS0 | 29bbbc7aa4SGuillaume Nault# | | 30bbbc7aa4SGuillaume Nault# | lo: | 31bbbc7aa4SGuillaume Nault# | * IPv4 address: 192.0.2.100/32 | 32bbbc7aa4SGuillaume Nault# | * IPv6 address: 2001:db8::100/128 | 33bbbc7aa4SGuillaume Nault# | * IPv6 address: 2001:db8::200/128 | 34bbbc7aa4SGuillaume Nault# | * IPv4 route: 192.0.2.103/32 reachable via 192.0.2.11 | 35bbbc7aa4SGuillaume Nault# | * IPv6 route: 2001:db8::103/128 reachable via 2001:db8::11 | 36bbbc7aa4SGuillaume Nault# | * IPv6 route: 2001:db8::203/128 reachable via 2001:db8::11 | 37bbbc7aa4SGuillaume Nault# | (encapsulated with MPLS label 203) | 38bbbc7aa4SGuillaume Nault# | | 39bbbc7aa4SGuillaume Nault# | veth01: | 40bbbc7aa4SGuillaume Nault# | ^ * IPv4 address: 192.0.2.10, peer 192.0.2.11/32 | 41bbbc7aa4SGuillaume Nault# | | * IPv6 address: 2001:db8::10, peer 2001:db8::11/128 | 42bbbc7aa4SGuillaume Nault# | | | 43bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+ 44bbbc7aa4SGuillaume Nault# | 45bbbc7aa4SGuillaume Nault# | Traffic type: IP or MPLS (depending on test) 46bbbc7aa4SGuillaume Nault# | 47bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+ 48bbbc7aa4SGuillaume Nault# | | NS1 | 49bbbc7aa4SGuillaume Nault# | | | 50bbbc7aa4SGuillaume Nault# | v | 51bbbc7aa4SGuillaume Nault# | veth10: | 52bbbc7aa4SGuillaume Nault# | * IPv4 address: 192.0.2.11, peer 192.0.2.10/32 | 53bbbc7aa4SGuillaume Nault# | * IPv6 address: 2001:db8::11, peer 2001:db8::10/128 | 54bbbc7aa4SGuillaume Nault# | | 55bbbc7aa4SGuillaume Nault# | bareudp_ns1: | 56bbbc7aa4SGuillaume Nault# | * Encapsulate IP or MPLS packets received on veth10 into UDP | 57bbbc7aa4SGuillaume Nault# | and send the resulting packets through veth12. | 58bbbc7aa4SGuillaume Nault# | * Decapsulate bareudp packets (either IP or MPLS, over UDP) | 59bbbc7aa4SGuillaume Nault# | received on veth12 and send the inner packets through veth10. | 60bbbc7aa4SGuillaume Nault# | | 61bbbc7aa4SGuillaume Nault# | veth12: | 62bbbc7aa4SGuillaume Nault# | ^ * IPv4 address: 192.0.2.21, peer 192.0.2.22/32 | 63bbbc7aa4SGuillaume Nault# | | * IPv6 address: 2001:db8::21, peer 2001:db8::22/128 | 64bbbc7aa4SGuillaume Nault# | | | 65bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+ 66bbbc7aa4SGuillaume Nault# | 67bbbc7aa4SGuillaume Nault# | Traffic type: IP or MPLS (depending on test), over UDP 68bbbc7aa4SGuillaume Nault# | 69bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+ 70bbbc7aa4SGuillaume Nault# | | NS2 | 71bbbc7aa4SGuillaume Nault# | | | 72bbbc7aa4SGuillaume Nault# | v | 73bbbc7aa4SGuillaume Nault# | veth21: | 74bbbc7aa4SGuillaume Nault# | * IPv4 address: 192.0.2.22, peer 192.0.2.21/32 | 75bbbc7aa4SGuillaume Nault# | * IPv6 address: 2001:db8::22, peer 2001:db8::21/128 | 76bbbc7aa4SGuillaume Nault# | | 77bbbc7aa4SGuillaume Nault# | bareudp_ns2: | 78bbbc7aa4SGuillaume Nault# | * Decapsulate bareudp packets (either IP or MPLS, over UDP) | 79bbbc7aa4SGuillaume Nault# | received on veth21 and send the inner packets through veth23. | 80bbbc7aa4SGuillaume Nault# | * Encapsulate IP or MPLS packets received on veth23 into UDP | 81bbbc7aa4SGuillaume Nault# | and send the resulting packets through veth21. | 82bbbc7aa4SGuillaume Nault# | | 83bbbc7aa4SGuillaume Nault# | veth23: | 84bbbc7aa4SGuillaume Nault# | ^ * IPv4 address: 192.0.2.32, peer 192.0.2.33/32 | 85bbbc7aa4SGuillaume Nault# | | * IPv6 address: 2001:db8::32, peer 2001:db8::33/128 | 86bbbc7aa4SGuillaume Nault# | | | 87bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+ 88bbbc7aa4SGuillaume Nault# | 89bbbc7aa4SGuillaume Nault# | Traffic type: IP or MPLS (depending on test) 90bbbc7aa4SGuillaume Nault# | 91bbbc7aa4SGuillaume Nault# +---+-------------------------------------------------------------------+ 92bbbc7aa4SGuillaume Nault# | | NS3 | 93bbbc7aa4SGuillaume Nault# | v | 94bbbc7aa4SGuillaume Nault# | veth32: | 95bbbc7aa4SGuillaume Nault# | * IPv4 address: 192.0.2.33, peer 192.0.2.32/32 | 96bbbc7aa4SGuillaume Nault# | * IPv6 address: 2001:db8::33, peer 2001:db8::32/128 | 97bbbc7aa4SGuillaume Nault# | | 98bbbc7aa4SGuillaume Nault# | lo: | 99bbbc7aa4SGuillaume Nault# | * IPv4 address: 192.0.2.103/32 | 100bbbc7aa4SGuillaume Nault# | * IPv6 address: 2001:db8::103/128 | 101bbbc7aa4SGuillaume Nault# | * IPv6 address: 2001:db8::203/128 | 102bbbc7aa4SGuillaume Nault# | * IPv4 route: 192.0.2.100/32 reachable via 192.0.2.32 | 103bbbc7aa4SGuillaume Nault# | * IPv6 route: 2001:db8::100/128 reachable via 2001:db8::32 | 104bbbc7aa4SGuillaume Nault# | * IPv6 route: 2001:db8::200/128 reachable via 2001:db8::32 | 105bbbc7aa4SGuillaume Nault# | (encapsulated with MPLS label 200) | 106bbbc7aa4SGuillaume Nault# | | 107bbbc7aa4SGuillaume Nault# +-----------------------------------------------------------------------+ 108bbbc7aa4SGuillaume Nault 109bbbc7aa4SGuillaume NaultERR=4 # Return 4 by default, which is the SKIP code for kselftest 110bbbc7aa4SGuillaume NaultPING6="ping" 111bbbc7aa4SGuillaume NaultPAUSE_ON_FAIL="no" 112bbbc7aa4SGuillaume Nault 113bbbc7aa4SGuillaume Naultreadonly NS0=$(mktemp -u ns0-XXXXXXXX) 114bbbc7aa4SGuillaume Naultreadonly NS1=$(mktemp -u ns1-XXXXXXXX) 115bbbc7aa4SGuillaume Naultreadonly NS2=$(mktemp -u ns2-XXXXXXXX) 116bbbc7aa4SGuillaume Naultreadonly NS3=$(mktemp -u ns3-XXXXXXXX) 117bbbc7aa4SGuillaume Nault 118bbbc7aa4SGuillaume Nault# Exit the script after having removed the network namespaces it created 119bbbc7aa4SGuillaume Nault# 120bbbc7aa4SGuillaume Nault# Parameters: 121bbbc7aa4SGuillaume Nault# 122bbbc7aa4SGuillaume Nault# * The list of network namespaces to delete before exiting. 123bbbc7aa4SGuillaume Nault# 124bbbc7aa4SGuillaume Naultexit_cleanup() 125bbbc7aa4SGuillaume Nault{ 126bbbc7aa4SGuillaume Nault for ns in "$@"; do 127bbbc7aa4SGuillaume Nault ip netns delete "${ns}" 2>/dev/null || true 128bbbc7aa4SGuillaume Nault done 129bbbc7aa4SGuillaume Nault 130bbbc7aa4SGuillaume Nault if [ "${ERR}" -eq 4 ]; then 131bbbc7aa4SGuillaume Nault echo "Error: Setting up the testing environment failed." >&2 132bbbc7aa4SGuillaume Nault fi 133bbbc7aa4SGuillaume Nault 134bbbc7aa4SGuillaume Nault exit "${ERR}" 135bbbc7aa4SGuillaume Nault} 136bbbc7aa4SGuillaume Nault 137bbbc7aa4SGuillaume Nault# Create the four network namespaces used by the script (NS0, NS1, NS2 and NS3) 138bbbc7aa4SGuillaume Nault# 139bbbc7aa4SGuillaume Nault# New namespaces are cleaned up manually in case of error, to ensure that only 140bbbc7aa4SGuillaume Nault# namespaces created by this script are deleted. 141bbbc7aa4SGuillaume Naultcreate_namespaces() 142bbbc7aa4SGuillaume Nault{ 143bbbc7aa4SGuillaume Nault ip netns add "${NS0}" || exit_cleanup 144bbbc7aa4SGuillaume Nault ip netns add "${NS1}" || exit_cleanup "${NS0}" 145bbbc7aa4SGuillaume Nault ip netns add "${NS2}" || exit_cleanup "${NS0}" "${NS1}" 146bbbc7aa4SGuillaume Nault ip netns add "${NS3}" || exit_cleanup "${NS0}" "${NS1}" "${NS2}" 147bbbc7aa4SGuillaume Nault} 148bbbc7aa4SGuillaume Nault 149bbbc7aa4SGuillaume Nault# The trap function handler 150bbbc7aa4SGuillaume Nault# 151bbbc7aa4SGuillaume Naultexit_cleanup_all() 152bbbc7aa4SGuillaume Nault{ 153bbbc7aa4SGuillaume Nault exit_cleanup "${NS0}" "${NS1}" "${NS2}" "${NS3}" 154bbbc7aa4SGuillaume Nault} 155bbbc7aa4SGuillaume Nault 156bbbc7aa4SGuillaume Nault# Configure a network interface using a host route 157bbbc7aa4SGuillaume Nault# 158bbbc7aa4SGuillaume Nault# Parameters 159bbbc7aa4SGuillaume Nault# 160bbbc7aa4SGuillaume Nault# * $1: the netns the network interface resides in, 161bbbc7aa4SGuillaume Nault# * $2: the network interface name, 162bbbc7aa4SGuillaume Nault# * $3: the local IPv4 address to assign to this interface, 163bbbc7aa4SGuillaume Nault# * $4: the IPv4 address of the remote network interface, 164bbbc7aa4SGuillaume Nault# * $5: the local IPv6 address to assign to this interface, 165bbbc7aa4SGuillaume Nault# * $6: the IPv6 address of the remote network interface. 166bbbc7aa4SGuillaume Nault# 167bbbc7aa4SGuillaume Naultiface_config() 168bbbc7aa4SGuillaume Nault{ 169bbbc7aa4SGuillaume Nault local NS="${1}"; readonly NS 170bbbc7aa4SGuillaume Nault local DEV="${2}"; readonly DEV 171bbbc7aa4SGuillaume Nault local LOCAL_IP4="${3}"; readonly LOCAL_IP4 172bbbc7aa4SGuillaume Nault local PEER_IP4="${4}"; readonly PEER_IP4 173bbbc7aa4SGuillaume Nault local LOCAL_IP6="${5}"; readonly LOCAL_IP6 174bbbc7aa4SGuillaume Nault local PEER_IP6="${6}"; readonly PEER_IP6 175bbbc7aa4SGuillaume Nault 176bbbc7aa4SGuillaume Nault ip -netns "${NS}" link set dev "${DEV}" up 177bbbc7aa4SGuillaume Nault ip -netns "${NS}" address add dev "${DEV}" "${LOCAL_IP4}" peer "${PEER_IP4}" 178bbbc7aa4SGuillaume Nault ip -netns "${NS}" address add dev "${DEV}" "${LOCAL_IP6}" peer "${PEER_IP6}" nodad 179bbbc7aa4SGuillaume Nault} 180bbbc7aa4SGuillaume Nault 181bbbc7aa4SGuillaume Nault# Create base networking topology: 182bbbc7aa4SGuillaume Nault# 183bbbc7aa4SGuillaume Nault# * set up the loopback device in all network namespaces (NS0..NS3), 184bbbc7aa4SGuillaume Nault# * set up a veth pair to connect each netns in sequence (NS0 with NS1, 185bbbc7aa4SGuillaume Nault# NS1 with NS2, etc.), 186bbbc7aa4SGuillaume Nault# * add and IPv4 and an IPv6 address on each veth interface, 187bbbc7aa4SGuillaume Nault# * prepare the ingress qdiscs in the intermediate namespaces. 188bbbc7aa4SGuillaume Nault# 189bbbc7aa4SGuillaume Naultsetup_underlay() 190bbbc7aa4SGuillaume Nault{ 191bbbc7aa4SGuillaume Nault for ns in "${NS0}" "${NS1}" "${NS2}" "${NS3}"; do 192bbbc7aa4SGuillaume Nault ip -netns "${ns}" link set dev lo up 193bbbc7aa4SGuillaume Nault done; 194bbbc7aa4SGuillaume Nault 195bbbc7aa4SGuillaume Nault ip link add name veth01 netns "${NS0}" type veth peer name veth10 netns "${NS1}" 196bbbc7aa4SGuillaume Nault ip link add name veth12 netns "${NS1}" type veth peer name veth21 netns "${NS2}" 197bbbc7aa4SGuillaume Nault ip link add name veth23 netns "${NS2}" type veth peer name veth32 netns "${NS3}" 198bbbc7aa4SGuillaume Nault iface_config "${NS0}" veth01 192.0.2.10 192.0.2.11/32 2001:db8::10 2001:db8::11/128 199bbbc7aa4SGuillaume Nault iface_config "${NS1}" veth10 192.0.2.11 192.0.2.10/32 2001:db8::11 2001:db8::10/128 200bbbc7aa4SGuillaume Nault iface_config "${NS1}" veth12 192.0.2.21 192.0.2.22/32 2001:db8::21 2001:db8::22/128 201bbbc7aa4SGuillaume Nault iface_config "${NS2}" veth21 192.0.2.22 192.0.2.21/32 2001:db8::22 2001:db8::21/128 202bbbc7aa4SGuillaume Nault iface_config "${NS2}" veth23 192.0.2.32 192.0.2.33/32 2001:db8::32 2001:db8::33/128 203bbbc7aa4SGuillaume Nault iface_config "${NS3}" veth32 192.0.2.33 192.0.2.32/32 2001:db8::33 2001:db8::32/128 204bbbc7aa4SGuillaume Nault 205bbbc7aa4SGuillaume Nault tc -netns "${NS1}" qdisc add dev veth10 ingress 206bbbc7aa4SGuillaume Nault tc -netns "${NS2}" qdisc add dev veth23 ingress 207bbbc7aa4SGuillaume Nault} 208bbbc7aa4SGuillaume Nault 209bbbc7aa4SGuillaume Nault# Set up the IPv4, IPv6 and MPLS overlays. 210bbbc7aa4SGuillaume Nault# 211bbbc7aa4SGuillaume Nault# Configuration is similar for all protocols: 212bbbc7aa4SGuillaume Nault# 213bbbc7aa4SGuillaume Nault# * add an overlay IP address on the loopback interface of each edge 214bbbc7aa4SGuillaume Nault# namespace, 215bbbc7aa4SGuillaume Nault# * route these IP addresses via the intermediate namespaces (for the MPLS 216bbbc7aa4SGuillaume Nault# tests, this is also where MPLS encapsulation is done), 217bbbc7aa4SGuillaume Nault# * add routes for these IP addresses (or MPLS labels) in the intermediate 218bbbc7aa4SGuillaume Nault# namespaces. 219bbbc7aa4SGuillaume Nault# 220bbbc7aa4SGuillaume Nault# The bareudp encapsulation isn't configured in setup_overlay_*(). That will be 221bbbc7aa4SGuillaume Nault# done just before running the reachability tests. 222bbbc7aa4SGuillaume Nault 223bbbc7aa4SGuillaume Naultsetup_overlay_ipv4() 224bbbc7aa4SGuillaume Nault{ 225bbbc7aa4SGuillaume Nault # Add the overlay IP addresses and route them through the veth devices 226bbbc7aa4SGuillaume Nault ip -netns "${NS0}" address add 192.0.2.100/32 dev lo 227bbbc7aa4SGuillaume Nault ip -netns "${NS3}" address add 192.0.2.103/32 dev lo 228bbbc7aa4SGuillaume Nault ip -netns "${NS0}" route add 192.0.2.103/32 src 192.0.2.100 via 192.0.2.11 229bbbc7aa4SGuillaume Nault ip -netns "${NS3}" route add 192.0.2.100/32 src 192.0.2.103 via 192.0.2.32 230bbbc7aa4SGuillaume Nault 231bbbc7aa4SGuillaume Nault # Route the overlay addresses in the intermediate namespaces 232bbbc7aa4SGuillaume Nault # (used after bareudp decapsulation) 233bbbc7aa4SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.ipv4.ip_forward=1 234bbbc7aa4SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.ipv4.ip_forward=1 235bbbc7aa4SGuillaume Nault ip -netns "${NS1}" route add 192.0.2.100/32 via 192.0.2.10 236bbbc7aa4SGuillaume Nault ip -netns "${NS2}" route add 192.0.2.103/32 via 192.0.2.33 237*1ccd5833SGuillaume Nault 238*1ccd5833SGuillaume Nault # The intermediate namespaces don't have routes for the reverse path, 239*1ccd5833SGuillaume Nault # as it will be handled by tc. So we need to ensure that rp_filter is 240*1ccd5833SGuillaume Nault # not going to block the traffic. 241*1ccd5833SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.ipv4.conf.default.rp_filter=0 242*1ccd5833SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.ipv4.conf.default.rp_filter=0 243bbbc7aa4SGuillaume Nault} 244bbbc7aa4SGuillaume Nault 245bbbc7aa4SGuillaume Naultsetup_overlay_ipv6() 246bbbc7aa4SGuillaume Nault{ 247bbbc7aa4SGuillaume Nault # Add the overlay IP addresses and route them through the veth devices 248bbbc7aa4SGuillaume Nault ip -netns "${NS0}" address add 2001:db8::100/128 dev lo 249bbbc7aa4SGuillaume Nault ip -netns "${NS3}" address add 2001:db8::103/128 dev lo 250bbbc7aa4SGuillaume Nault ip -netns "${NS0}" route add 2001:db8::103/128 src 2001:db8::100 via 2001:db8::11 251bbbc7aa4SGuillaume Nault ip -netns "${NS3}" route add 2001:db8::100/128 src 2001:db8::103 via 2001:db8::32 252bbbc7aa4SGuillaume Nault 253bbbc7aa4SGuillaume Nault # Route the overlay addresses in the intermediate namespaces 254bbbc7aa4SGuillaume Nault # (used after bareudp decapsulation) 255bbbc7aa4SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.ipv6.conf.all.forwarding=1 256bbbc7aa4SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.ipv6.conf.all.forwarding=1 257bbbc7aa4SGuillaume Nault ip -netns "${NS1}" route add 2001:db8::100/128 via 2001:db8::10 258bbbc7aa4SGuillaume Nault ip -netns "${NS2}" route add 2001:db8::103/128 via 2001:db8::33 259bbbc7aa4SGuillaume Nault} 260bbbc7aa4SGuillaume Nault 261bbbc7aa4SGuillaume Naultsetup_overlay_mpls() 262bbbc7aa4SGuillaume Nault{ 263bbbc7aa4SGuillaume Nault # Add specific overlay IP addresses, routed over MPLS 264bbbc7aa4SGuillaume Nault ip -netns "${NS0}" address add 2001:db8::200/128 dev lo 265bbbc7aa4SGuillaume Nault ip -netns "${NS3}" address add 2001:db8::203/128 dev lo 266bbbc7aa4SGuillaume Nault ip -netns "${NS0}" route add 2001:db8::203/128 src 2001:db8::200 encap mpls 203 via 2001:db8::11 267bbbc7aa4SGuillaume Nault ip -netns "${NS3}" route add 2001:db8::200/128 src 2001:db8::203 encap mpls 200 via 2001:db8::32 268bbbc7aa4SGuillaume Nault 269bbbc7aa4SGuillaume Nault # Route the MPLS packets in the intermediate namespaces 270bbbc7aa4SGuillaume Nault # (used after bareudp decapsulation) 271bbbc7aa4SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.mpls.platform_labels=256 272bbbc7aa4SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.mpls.platform_labels=256 273bbbc7aa4SGuillaume Nault ip -netns "${NS1}" -family mpls route add 200 via inet6 2001:db8::10 274bbbc7aa4SGuillaume Nault ip -netns "${NS2}" -family mpls route add 203 via inet6 2001:db8::33 275bbbc7aa4SGuillaume Nault} 276bbbc7aa4SGuillaume Nault 277bbbc7aa4SGuillaume Nault# Run "ping" from NS0 and print the result 278bbbc7aa4SGuillaume Nault# 279bbbc7aa4SGuillaume Nault# Parameters: 280bbbc7aa4SGuillaume Nault# 281bbbc7aa4SGuillaume Nault# * $1: the variant of ping to use (normally either "ping" or "ping6"), 282bbbc7aa4SGuillaume Nault# * $2: the IP address to ping, 283bbbc7aa4SGuillaume Nault# * $3: a human readable description of the purpose of the test. 284bbbc7aa4SGuillaume Nault# 285bbbc7aa4SGuillaume Nault# If the test fails and PAUSE_ON_FAIL is active, the user is given the 286bbbc7aa4SGuillaume Nault# possibility to continue with the next test or to quit immediately. 287bbbc7aa4SGuillaume Nault# 288bbbc7aa4SGuillaume Naultping_test_one() 289bbbc7aa4SGuillaume Nault{ 290bbbc7aa4SGuillaume Nault local PING="$1"; readonly PING 291bbbc7aa4SGuillaume Nault local IP="$2"; readonly IP 292bbbc7aa4SGuillaume Nault local MSG="$3"; readonly MSG 293bbbc7aa4SGuillaume Nault local RET 294bbbc7aa4SGuillaume Nault 295bbbc7aa4SGuillaume Nault printf "TEST: %-60s " "${MSG}" 296bbbc7aa4SGuillaume Nault 297bbbc7aa4SGuillaume Nault set +e 298bbbc7aa4SGuillaume Nault ip netns exec "${NS0}" "${PING}" -w 5 -c 1 "${IP}" > /dev/null 2>&1 299bbbc7aa4SGuillaume Nault RET=$? 300bbbc7aa4SGuillaume Nault set -e 301bbbc7aa4SGuillaume Nault 302bbbc7aa4SGuillaume Nault if [ "${RET}" -eq 0 ]; then 303bbbc7aa4SGuillaume Nault printf "[ OK ]\n" 304bbbc7aa4SGuillaume Nault else 305bbbc7aa4SGuillaume Nault ERR=1 306bbbc7aa4SGuillaume Nault printf "[FAIL]\n" 307bbbc7aa4SGuillaume Nault if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 308bbbc7aa4SGuillaume Nault printf "\nHit enter to continue, 'q' to quit\n" 309bbbc7aa4SGuillaume Nault read a 310bbbc7aa4SGuillaume Nault if [ "$a" = "q" ]; then 311bbbc7aa4SGuillaume Nault exit 1 312bbbc7aa4SGuillaume Nault fi 313bbbc7aa4SGuillaume Nault fi 314bbbc7aa4SGuillaume Nault fi 315bbbc7aa4SGuillaume Nault} 316bbbc7aa4SGuillaume Nault 317bbbc7aa4SGuillaume Nault# Run reachability tests 318bbbc7aa4SGuillaume Nault# 319bbbc7aa4SGuillaume Nault# Parameters: 320bbbc7aa4SGuillaume Nault# 321bbbc7aa4SGuillaume Nault# * $1: human readable string describing the underlay protocol. 322bbbc7aa4SGuillaume Nault# 323bbbc7aa4SGuillaume Nault# $IPV4, $IPV6, $MPLS_UC and $MULTIPROTO are inherited from the calling 324bbbc7aa4SGuillaume Nault# function. 325bbbc7aa4SGuillaume Nault# 326bbbc7aa4SGuillaume Naultping_test() 327bbbc7aa4SGuillaume Nault{ 328bbbc7aa4SGuillaume Nault local UNDERLAY="$1"; readonly UNDERLAY 329bbbc7aa4SGuillaume Nault local MODE 330bbbc7aa4SGuillaume Nault local MSG 331bbbc7aa4SGuillaume Nault 332bbbc7aa4SGuillaume Nault if [ "${MULTIPROTO}" = "multiproto" ]; then 333bbbc7aa4SGuillaume Nault MODE=" (multiproto mode)" 334bbbc7aa4SGuillaume Nault else 335bbbc7aa4SGuillaume Nault MODE="" 336bbbc7aa4SGuillaume Nault fi 337bbbc7aa4SGuillaume Nault 338bbbc7aa4SGuillaume Nault if [ $IPV4 ]; then 339bbbc7aa4SGuillaume Nault ping_test_one "ping" "192.0.2.103" "IPv4 packets over ${UNDERLAY}${MODE}" 340bbbc7aa4SGuillaume Nault fi 341bbbc7aa4SGuillaume Nault if [ $IPV6 ]; then 342bbbc7aa4SGuillaume Nault ping_test_one "${PING6}" "2001:db8::103" "IPv6 packets over ${UNDERLAY}${MODE}" 343bbbc7aa4SGuillaume Nault fi 344bbbc7aa4SGuillaume Nault if [ $MPLS_UC ]; then 345bbbc7aa4SGuillaume Nault ping_test_one "${PING6}" "2001:db8::203" "Unicast MPLS packets over ${UNDERLAY}${MODE}" 346bbbc7aa4SGuillaume Nault fi 347bbbc7aa4SGuillaume Nault} 348bbbc7aa4SGuillaume Nault 349bbbc7aa4SGuillaume Nault# Set up a bareudp overlay and run reachability tests over IPv4 and IPv6 350bbbc7aa4SGuillaume Nault# 351bbbc7aa4SGuillaume Nault# Parameters: 352bbbc7aa4SGuillaume Nault# 353bbbc7aa4SGuillaume Nault# * $1: the packet type (protocol) to be handled by bareudp, 354bbbc7aa4SGuillaume Nault# * $2: a flag to activate or deactivate bareudp's "multiproto" mode. 355bbbc7aa4SGuillaume Nault# 356bbbc7aa4SGuillaume Naulttest_overlay() 357bbbc7aa4SGuillaume Nault{ 358bbbc7aa4SGuillaume Nault local ETHERTYPE="$1"; readonly ETHERTYPE 359bbbc7aa4SGuillaume Nault local MULTIPROTO="$2"; readonly MULTIPROTO 360bbbc7aa4SGuillaume Nault local IPV4 361bbbc7aa4SGuillaume Nault local IPV6 362bbbc7aa4SGuillaume Nault local MPLS_UC 363bbbc7aa4SGuillaume Nault 364bbbc7aa4SGuillaume Nault case "${ETHERTYPE}" in 365bbbc7aa4SGuillaume Nault "ipv4") 366bbbc7aa4SGuillaume Nault IPV4="ipv4" 367bbbc7aa4SGuillaume Nault if [ "${MULTIPROTO}" = "multiproto" ]; then 368bbbc7aa4SGuillaume Nault IPV6="ipv6" 369bbbc7aa4SGuillaume Nault else 370bbbc7aa4SGuillaume Nault IPV6="" 371bbbc7aa4SGuillaume Nault fi 372bbbc7aa4SGuillaume Nault MPLS_UC="" 373bbbc7aa4SGuillaume Nault ;; 374bbbc7aa4SGuillaume Nault "ipv6") 375bbbc7aa4SGuillaume Nault IPV6="ipv6" 376bbbc7aa4SGuillaume Nault IPV4="" 377bbbc7aa4SGuillaume Nault MPLS_UC="" 378bbbc7aa4SGuillaume Nault ;; 379bbbc7aa4SGuillaume Nault "mpls_uc") 380bbbc7aa4SGuillaume Nault MPLS_UC="mpls_uc" 381bbbc7aa4SGuillaume Nault IPV4="" 382bbbc7aa4SGuillaume Nault IPV6="" 383bbbc7aa4SGuillaume Nault ;; 384bbbc7aa4SGuillaume Nault *) 385bbbc7aa4SGuillaume Nault exit 1 386bbbc7aa4SGuillaume Nault ;; 387bbbc7aa4SGuillaume Nault esac 388bbbc7aa4SGuillaume Nault readonly IPV4 389bbbc7aa4SGuillaume Nault readonly IPV6 390bbbc7aa4SGuillaume Nault readonly MPLS_UC 391bbbc7aa4SGuillaume Nault 392bbbc7aa4SGuillaume Nault # Create the bareudp devices in the intermediate namespaces 393bbbc7aa4SGuillaume Nault ip -netns "${NS1}" link add name bareudp_ns1 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}" 394bbbc7aa4SGuillaume Nault ip -netns "${NS2}" link add name bareudp_ns2 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}" 395bbbc7aa4SGuillaume Nault 396bbbc7aa4SGuillaume Nault # IPv4 over UDPv4 397bbbc7aa4SGuillaume Nault if [ $IPV4 ]; then 398bbbc7aa4SGuillaume Nault # Encapsulation instructions for bareudp over IPv4 399bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4 \ 400bbbc7aa4SGuillaume Nault flower dst_ip 192.0.2.103/32 \ 401bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \ 402bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 403bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4 \ 404bbbc7aa4SGuillaume Nault flower dst_ip 192.0.2.100/32 \ 405bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \ 406bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 407bbbc7aa4SGuillaume Nault fi 408bbbc7aa4SGuillaume Nault 409bbbc7aa4SGuillaume Nault # IPv6 over UDPv4 410bbbc7aa4SGuillaume Nault if [ $IPV6 ]; then 411bbbc7aa4SGuillaume Nault # Encapsulation instructions for bareudp over IPv4 412bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6 \ 413bbbc7aa4SGuillaume Nault flower dst_ip 2001:db8::103/128 \ 414bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \ 415bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 416bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6 \ 417bbbc7aa4SGuillaume Nault flower dst_ip 2001:db8::100/128 \ 418bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \ 419bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 420bbbc7aa4SGuillaume Nault fi 421bbbc7aa4SGuillaume Nault 422bbbc7aa4SGuillaume Nault # MPLS (unicast) over UDPv4 423bbbc7aa4SGuillaume Nault if [ $MPLS_UC ]; then 424bbbc7aa4SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.mpls.conf.bareudp_ns1.input=1 425bbbc7aa4SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.mpls.conf.bareudp_ns2.input=1 426bbbc7aa4SGuillaume Nault 427bbbc7aa4SGuillaume Nault # Encapsulation instructions for bareudp over IPv4 428bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc \ 429bbbc7aa4SGuillaume Nault flower mpls_label 203 \ 430bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \ 431bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 432bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc \ 433bbbc7aa4SGuillaume Nault flower mpls_label 200 \ 434bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \ 435bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 436bbbc7aa4SGuillaume Nault fi 437bbbc7aa4SGuillaume Nault 438bbbc7aa4SGuillaume Nault # Test IPv4 underlay 439bbbc7aa4SGuillaume Nault ping_test "UDPv4" 440bbbc7aa4SGuillaume Nault 441bbbc7aa4SGuillaume Nault # Cleanup bareudp encapsulation instructions, as they were specific to 442bbbc7aa4SGuillaume Nault # the IPv4 underlay, before setting up and testing the IPv6 underlay 443bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter delete dev veth10 ingress 444bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter delete dev veth23 ingress 445bbbc7aa4SGuillaume Nault 446bbbc7aa4SGuillaume Nault # IPv4 over UDPv6 447bbbc7aa4SGuillaume Nault if [ $IPV4 ]; then 448bbbc7aa4SGuillaume Nault # New encapsulation instructions for bareudp over IPv6 449bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4 \ 450bbbc7aa4SGuillaume Nault flower dst_ip 192.0.2.103/32 \ 451bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \ 452bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 453bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4 \ 454bbbc7aa4SGuillaume Nault flower dst_ip 192.0.2.100/32 \ 455bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \ 456bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 457bbbc7aa4SGuillaume Nault fi 458bbbc7aa4SGuillaume Nault 459bbbc7aa4SGuillaume Nault # IPv6 over UDPv6 460bbbc7aa4SGuillaume Nault if [ $IPV6 ]; then 461bbbc7aa4SGuillaume Nault # New encapsulation instructions for bareudp over IPv6 462bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6 \ 463bbbc7aa4SGuillaume Nault flower dst_ip 2001:db8::103/128 \ 464bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \ 465bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 466bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6 \ 467bbbc7aa4SGuillaume Nault flower dst_ip 2001:db8::100/128 \ 468bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \ 469bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 470bbbc7aa4SGuillaume Nault fi 471bbbc7aa4SGuillaume Nault 472bbbc7aa4SGuillaume Nault # MPLS (unicast) over UDPv6 473bbbc7aa4SGuillaume Nault if [ $MPLS_UC ]; then 474bbbc7aa4SGuillaume Nault # New encapsulation instructions for bareudp over IPv6 475bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc \ 476bbbc7aa4SGuillaume Nault flower mpls_label 203 \ 477bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \ 478bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 479bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc \ 480bbbc7aa4SGuillaume Nault flower mpls_label 200 \ 481bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \ 482bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 483bbbc7aa4SGuillaume Nault fi 484bbbc7aa4SGuillaume Nault 485bbbc7aa4SGuillaume Nault # Test IPv6 underlay 486bbbc7aa4SGuillaume Nault ping_test "UDPv6" 487bbbc7aa4SGuillaume Nault 488bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter delete dev veth10 ingress 489bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter delete dev veth23 ingress 490bbbc7aa4SGuillaume Nault ip -netns "${NS1}" link delete bareudp_ns1 491bbbc7aa4SGuillaume Nault ip -netns "${NS2}" link delete bareudp_ns2 492bbbc7aa4SGuillaume Nault} 493bbbc7aa4SGuillaume Nault 494bbbc7aa4SGuillaume Naultcheck_features() 495bbbc7aa4SGuillaume Nault{ 496bbbc7aa4SGuillaume Nault ip link help 2>&1 | grep -q bareudp 497bbbc7aa4SGuillaume Nault if [ $? -ne 0 ]; then 498bbbc7aa4SGuillaume Nault echo "Missing bareudp support in iproute2" >&2 499bbbc7aa4SGuillaume Nault exit_cleanup 500bbbc7aa4SGuillaume Nault fi 501bbbc7aa4SGuillaume Nault 502bbbc7aa4SGuillaume Nault # Use ping6 on systems where ping doesn't handle IPv6 503bbbc7aa4SGuillaume Nault ping -w 1 -c 1 ::1 > /dev/null 2>&1 || PING6="ping6" 504bbbc7aa4SGuillaume Nault} 505bbbc7aa4SGuillaume Nault 506bbbc7aa4SGuillaume Naultusage() 507bbbc7aa4SGuillaume Nault{ 508bbbc7aa4SGuillaume Nault echo "Usage: $0 [-p]" 509bbbc7aa4SGuillaume Nault exit 1 510bbbc7aa4SGuillaume Nault} 511bbbc7aa4SGuillaume Nault 512bbbc7aa4SGuillaume Naultwhile getopts :p o 513bbbc7aa4SGuillaume Naultdo 514bbbc7aa4SGuillaume Nault case $o in 515bbbc7aa4SGuillaume Nault p) PAUSE_ON_FAIL="yes";; 516bbbc7aa4SGuillaume Nault *) usage;; 517bbbc7aa4SGuillaume Nault esac 518bbbc7aa4SGuillaume Naultdone 519bbbc7aa4SGuillaume Nault 520bbbc7aa4SGuillaume Naultcheck_features 521bbbc7aa4SGuillaume Nault 522bbbc7aa4SGuillaume Nault# Create namespaces before setting up the exit trap. 523bbbc7aa4SGuillaume Nault# Otherwise, exit_cleanup_all() could delete namespaces that were not created 524bbbc7aa4SGuillaume Nault# by this script. 525bbbc7aa4SGuillaume Naultcreate_namespaces 526bbbc7aa4SGuillaume Nault 527bbbc7aa4SGuillaume Naultset -e 528bbbc7aa4SGuillaume Naulttrap exit_cleanup_all EXIT 529bbbc7aa4SGuillaume Nault 530bbbc7aa4SGuillaume Naultsetup_underlay 531bbbc7aa4SGuillaume Naultsetup_overlay_ipv4 532bbbc7aa4SGuillaume Naultsetup_overlay_ipv6 533bbbc7aa4SGuillaume Naultsetup_overlay_mpls 534bbbc7aa4SGuillaume Nault 535bbbc7aa4SGuillaume Naulttest_overlay ipv4 nomultiproto 536bbbc7aa4SGuillaume Naulttest_overlay ipv6 nomultiproto 537bbbc7aa4SGuillaume Naulttest_overlay ipv4 multiproto 538bbbc7aa4SGuillaume Naulttest_overlay mpls_uc nomultiproto 539bbbc7aa4SGuillaume Nault 540bbbc7aa4SGuillaume Naultif [ "${ERR}" -eq 1 ]; then 541bbbc7aa4SGuillaume Nault echo "Some tests failed." >&2 542bbbc7aa4SGuillaume Naultelse 543bbbc7aa4SGuillaume Nault ERR=0 544bbbc7aa4SGuillaume Naultfi 545