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 2371ccd5833SGuillaume Nault 2381ccd5833SGuillaume Nault # The intermediate namespaces don't have routes for the reverse path, 2391ccd5833SGuillaume Nault # as it will be handled by tc. So we need to ensure that rp_filter is 2401ccd5833SGuillaume Nault # not going to block the traffic. 241*e8658023SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.ipv4.conf.all.rp_filter=0 242*e8658023SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.ipv4.conf.all.rp_filter=0 2431ccd5833SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.ipv4.conf.default.rp_filter=0 2441ccd5833SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.ipv4.conf.default.rp_filter=0 245bbbc7aa4SGuillaume Nault} 246bbbc7aa4SGuillaume Nault 247bbbc7aa4SGuillaume Naultsetup_overlay_ipv6() 248bbbc7aa4SGuillaume Nault{ 249bbbc7aa4SGuillaume Nault # Add the overlay IP addresses and route them through the veth devices 250bbbc7aa4SGuillaume Nault ip -netns "${NS0}" address add 2001:db8::100/128 dev lo 251bbbc7aa4SGuillaume Nault ip -netns "${NS3}" address add 2001:db8::103/128 dev lo 252bbbc7aa4SGuillaume Nault ip -netns "${NS0}" route add 2001:db8::103/128 src 2001:db8::100 via 2001:db8::11 253bbbc7aa4SGuillaume Nault ip -netns "${NS3}" route add 2001:db8::100/128 src 2001:db8::103 via 2001:db8::32 254bbbc7aa4SGuillaume Nault 255bbbc7aa4SGuillaume Nault # Route the overlay addresses in the intermediate namespaces 256bbbc7aa4SGuillaume Nault # (used after bareudp decapsulation) 257bbbc7aa4SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.ipv6.conf.all.forwarding=1 258bbbc7aa4SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.ipv6.conf.all.forwarding=1 259bbbc7aa4SGuillaume Nault ip -netns "${NS1}" route add 2001:db8::100/128 via 2001:db8::10 260bbbc7aa4SGuillaume Nault ip -netns "${NS2}" route add 2001:db8::103/128 via 2001:db8::33 261bbbc7aa4SGuillaume Nault} 262bbbc7aa4SGuillaume Nault 263bbbc7aa4SGuillaume Naultsetup_overlay_mpls() 264bbbc7aa4SGuillaume Nault{ 265bbbc7aa4SGuillaume Nault # Add specific overlay IP addresses, routed over MPLS 266bbbc7aa4SGuillaume Nault ip -netns "${NS0}" address add 2001:db8::200/128 dev lo 267bbbc7aa4SGuillaume Nault ip -netns "${NS3}" address add 2001:db8::203/128 dev lo 268bbbc7aa4SGuillaume Nault ip -netns "${NS0}" route add 2001:db8::203/128 src 2001:db8::200 encap mpls 203 via 2001:db8::11 269bbbc7aa4SGuillaume Nault ip -netns "${NS3}" route add 2001:db8::200/128 src 2001:db8::203 encap mpls 200 via 2001:db8::32 270bbbc7aa4SGuillaume Nault 271bbbc7aa4SGuillaume Nault # Route the MPLS packets in the intermediate namespaces 272bbbc7aa4SGuillaume Nault # (used after bareudp decapsulation) 273bbbc7aa4SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.mpls.platform_labels=256 274bbbc7aa4SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.mpls.platform_labels=256 275bbbc7aa4SGuillaume Nault ip -netns "${NS1}" -family mpls route add 200 via inet6 2001:db8::10 276bbbc7aa4SGuillaume Nault ip -netns "${NS2}" -family mpls route add 203 via inet6 2001:db8::33 277bbbc7aa4SGuillaume Nault} 278bbbc7aa4SGuillaume Nault 279bbbc7aa4SGuillaume Nault# Run "ping" from NS0 and print the result 280bbbc7aa4SGuillaume Nault# 281bbbc7aa4SGuillaume Nault# Parameters: 282bbbc7aa4SGuillaume Nault# 283bbbc7aa4SGuillaume Nault# * $1: the variant of ping to use (normally either "ping" or "ping6"), 284bbbc7aa4SGuillaume Nault# * $2: the IP address to ping, 285bbbc7aa4SGuillaume Nault# * $3: a human readable description of the purpose of the test. 286bbbc7aa4SGuillaume Nault# 287bbbc7aa4SGuillaume Nault# If the test fails and PAUSE_ON_FAIL is active, the user is given the 288bbbc7aa4SGuillaume Nault# possibility to continue with the next test or to quit immediately. 289bbbc7aa4SGuillaume Nault# 290bbbc7aa4SGuillaume Naultping_test_one() 291bbbc7aa4SGuillaume Nault{ 292bbbc7aa4SGuillaume Nault local PING="$1"; readonly PING 293bbbc7aa4SGuillaume Nault local IP="$2"; readonly IP 294bbbc7aa4SGuillaume Nault local MSG="$3"; readonly MSG 295bbbc7aa4SGuillaume Nault local RET 296bbbc7aa4SGuillaume Nault 297bbbc7aa4SGuillaume Nault printf "TEST: %-60s " "${MSG}" 298bbbc7aa4SGuillaume Nault 299bbbc7aa4SGuillaume Nault set +e 300bbbc7aa4SGuillaume Nault ip netns exec "${NS0}" "${PING}" -w 5 -c 1 "${IP}" > /dev/null 2>&1 301bbbc7aa4SGuillaume Nault RET=$? 302bbbc7aa4SGuillaume Nault set -e 303bbbc7aa4SGuillaume Nault 304bbbc7aa4SGuillaume Nault if [ "${RET}" -eq 0 ]; then 305bbbc7aa4SGuillaume Nault printf "[ OK ]\n" 306bbbc7aa4SGuillaume Nault else 307bbbc7aa4SGuillaume Nault ERR=1 308bbbc7aa4SGuillaume Nault printf "[FAIL]\n" 309bbbc7aa4SGuillaume Nault if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 310bbbc7aa4SGuillaume Nault printf "\nHit enter to continue, 'q' to quit\n" 311bbbc7aa4SGuillaume Nault read a 312bbbc7aa4SGuillaume Nault if [ "$a" = "q" ]; then 313bbbc7aa4SGuillaume Nault exit 1 314bbbc7aa4SGuillaume Nault fi 315bbbc7aa4SGuillaume Nault fi 316bbbc7aa4SGuillaume Nault fi 317bbbc7aa4SGuillaume Nault} 318bbbc7aa4SGuillaume Nault 319bbbc7aa4SGuillaume Nault# Run reachability tests 320bbbc7aa4SGuillaume Nault# 321bbbc7aa4SGuillaume Nault# Parameters: 322bbbc7aa4SGuillaume Nault# 323bbbc7aa4SGuillaume Nault# * $1: human readable string describing the underlay protocol. 324bbbc7aa4SGuillaume Nault# 325bbbc7aa4SGuillaume Nault# $IPV4, $IPV6, $MPLS_UC and $MULTIPROTO are inherited from the calling 326bbbc7aa4SGuillaume Nault# function. 327bbbc7aa4SGuillaume Nault# 328bbbc7aa4SGuillaume Naultping_test() 329bbbc7aa4SGuillaume Nault{ 330bbbc7aa4SGuillaume Nault local UNDERLAY="$1"; readonly UNDERLAY 331bbbc7aa4SGuillaume Nault local MODE 332bbbc7aa4SGuillaume Nault local MSG 333bbbc7aa4SGuillaume Nault 334bbbc7aa4SGuillaume Nault if [ "${MULTIPROTO}" = "multiproto" ]; then 335bbbc7aa4SGuillaume Nault MODE=" (multiproto mode)" 336bbbc7aa4SGuillaume Nault else 337bbbc7aa4SGuillaume Nault MODE="" 338bbbc7aa4SGuillaume Nault fi 339bbbc7aa4SGuillaume Nault 340bbbc7aa4SGuillaume Nault if [ $IPV4 ]; then 341bbbc7aa4SGuillaume Nault ping_test_one "ping" "192.0.2.103" "IPv4 packets over ${UNDERLAY}${MODE}" 342bbbc7aa4SGuillaume Nault fi 343bbbc7aa4SGuillaume Nault if [ $IPV6 ]; then 344bbbc7aa4SGuillaume Nault ping_test_one "${PING6}" "2001:db8::103" "IPv6 packets over ${UNDERLAY}${MODE}" 345bbbc7aa4SGuillaume Nault fi 346bbbc7aa4SGuillaume Nault if [ $MPLS_UC ]; then 347bbbc7aa4SGuillaume Nault ping_test_one "${PING6}" "2001:db8::203" "Unicast MPLS packets over ${UNDERLAY}${MODE}" 348bbbc7aa4SGuillaume Nault fi 349bbbc7aa4SGuillaume Nault} 350bbbc7aa4SGuillaume Nault 351bbbc7aa4SGuillaume Nault# Set up a bareudp overlay and run reachability tests over IPv4 and IPv6 352bbbc7aa4SGuillaume Nault# 353bbbc7aa4SGuillaume Nault# Parameters: 354bbbc7aa4SGuillaume Nault# 355bbbc7aa4SGuillaume Nault# * $1: the packet type (protocol) to be handled by bareudp, 356bbbc7aa4SGuillaume Nault# * $2: a flag to activate or deactivate bareudp's "multiproto" mode. 357bbbc7aa4SGuillaume Nault# 358bbbc7aa4SGuillaume Naulttest_overlay() 359bbbc7aa4SGuillaume Nault{ 360bbbc7aa4SGuillaume Nault local ETHERTYPE="$1"; readonly ETHERTYPE 361bbbc7aa4SGuillaume Nault local MULTIPROTO="$2"; readonly MULTIPROTO 362bbbc7aa4SGuillaume Nault local IPV4 363bbbc7aa4SGuillaume Nault local IPV6 364bbbc7aa4SGuillaume Nault local MPLS_UC 365bbbc7aa4SGuillaume Nault 366bbbc7aa4SGuillaume Nault case "${ETHERTYPE}" in 367bbbc7aa4SGuillaume Nault "ipv4") 368bbbc7aa4SGuillaume Nault IPV4="ipv4" 369bbbc7aa4SGuillaume Nault if [ "${MULTIPROTO}" = "multiproto" ]; then 370bbbc7aa4SGuillaume Nault IPV6="ipv6" 371bbbc7aa4SGuillaume Nault else 372bbbc7aa4SGuillaume Nault IPV6="" 373bbbc7aa4SGuillaume Nault fi 374bbbc7aa4SGuillaume Nault MPLS_UC="" 375bbbc7aa4SGuillaume Nault ;; 376bbbc7aa4SGuillaume Nault "ipv6") 377bbbc7aa4SGuillaume Nault IPV6="ipv6" 378bbbc7aa4SGuillaume Nault IPV4="" 379bbbc7aa4SGuillaume Nault MPLS_UC="" 380bbbc7aa4SGuillaume Nault ;; 381bbbc7aa4SGuillaume Nault "mpls_uc") 382bbbc7aa4SGuillaume Nault MPLS_UC="mpls_uc" 383bbbc7aa4SGuillaume Nault IPV4="" 384bbbc7aa4SGuillaume Nault IPV6="" 385bbbc7aa4SGuillaume Nault ;; 386bbbc7aa4SGuillaume Nault *) 387bbbc7aa4SGuillaume Nault exit 1 388bbbc7aa4SGuillaume Nault ;; 389bbbc7aa4SGuillaume Nault esac 390bbbc7aa4SGuillaume Nault readonly IPV4 391bbbc7aa4SGuillaume Nault readonly IPV6 392bbbc7aa4SGuillaume Nault readonly MPLS_UC 393bbbc7aa4SGuillaume Nault 394bbbc7aa4SGuillaume Nault # Create the bareudp devices in the intermediate namespaces 395bbbc7aa4SGuillaume Nault ip -netns "${NS1}" link add name bareudp_ns1 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}" 396bbbc7aa4SGuillaume Nault ip -netns "${NS2}" link add name bareudp_ns2 up type bareudp dstport 6635 ethertype "${ETHERTYPE}" "${MULTIPROTO}" 397bbbc7aa4SGuillaume Nault 398bbbc7aa4SGuillaume Nault # IPv4 over UDPv4 399bbbc7aa4SGuillaume Nault if [ $IPV4 ]; then 400bbbc7aa4SGuillaume Nault # Encapsulation instructions for bareudp over IPv4 401bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4 \ 402bbbc7aa4SGuillaume Nault flower dst_ip 192.0.2.103/32 \ 403bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \ 404bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 405bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4 \ 406bbbc7aa4SGuillaume Nault flower dst_ip 192.0.2.100/32 \ 407bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \ 408bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 409bbbc7aa4SGuillaume Nault fi 410bbbc7aa4SGuillaume Nault 411bbbc7aa4SGuillaume Nault # IPv6 over UDPv4 412bbbc7aa4SGuillaume Nault if [ $IPV6 ]; then 413bbbc7aa4SGuillaume Nault # Encapsulation instructions for bareudp over IPv4 414bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6 \ 415bbbc7aa4SGuillaume Nault flower dst_ip 2001:db8::103/128 \ 416bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \ 417bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 418bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6 \ 419bbbc7aa4SGuillaume Nault flower dst_ip 2001:db8::100/128 \ 420bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \ 421bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 422bbbc7aa4SGuillaume Nault fi 423bbbc7aa4SGuillaume Nault 424bbbc7aa4SGuillaume Nault # MPLS (unicast) over UDPv4 425bbbc7aa4SGuillaume Nault if [ $MPLS_UC ]; then 426bbbc7aa4SGuillaume Nault ip netns exec "${NS1}" sysctl -qw net.mpls.conf.bareudp_ns1.input=1 427bbbc7aa4SGuillaume Nault ip netns exec "${NS2}" sysctl -qw net.mpls.conf.bareudp_ns2.input=1 428bbbc7aa4SGuillaume Nault 429bbbc7aa4SGuillaume Nault # Encapsulation instructions for bareudp over IPv4 430bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc \ 431bbbc7aa4SGuillaume Nault flower mpls_label 203 \ 432bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.21 dst_ip 192.0.2.22 id 0 \ 433bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 434bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc \ 435bbbc7aa4SGuillaume Nault flower mpls_label 200 \ 436bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 192.0.2.22 dst_ip 192.0.2.21 id 0 \ 437bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 438bbbc7aa4SGuillaume Nault fi 439bbbc7aa4SGuillaume Nault 440bbbc7aa4SGuillaume Nault # Test IPv4 underlay 441bbbc7aa4SGuillaume Nault ping_test "UDPv4" 442bbbc7aa4SGuillaume Nault 443bbbc7aa4SGuillaume Nault # Cleanup bareudp encapsulation instructions, as they were specific to 444bbbc7aa4SGuillaume Nault # the IPv4 underlay, before setting up and testing the IPv6 underlay 445bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter delete dev veth10 ingress 446bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter delete dev veth23 ingress 447bbbc7aa4SGuillaume Nault 448bbbc7aa4SGuillaume Nault # IPv4 over UDPv6 449bbbc7aa4SGuillaume Nault if [ $IPV4 ]; then 450bbbc7aa4SGuillaume Nault # New encapsulation instructions for bareudp over IPv6 451bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv4 \ 452bbbc7aa4SGuillaume Nault flower dst_ip 192.0.2.103/32 \ 453bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \ 454bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 455bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv4 \ 456bbbc7aa4SGuillaume Nault flower dst_ip 192.0.2.100/32 \ 457bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \ 458bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 459bbbc7aa4SGuillaume Nault fi 460bbbc7aa4SGuillaume Nault 461bbbc7aa4SGuillaume Nault # IPv6 over UDPv6 462bbbc7aa4SGuillaume Nault if [ $IPV6 ]; then 463bbbc7aa4SGuillaume Nault # New encapsulation instructions for bareudp over IPv6 464bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol ipv6 \ 465bbbc7aa4SGuillaume Nault flower dst_ip 2001:db8::103/128 \ 466bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \ 467bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 468bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol ipv6 \ 469bbbc7aa4SGuillaume Nault flower dst_ip 2001:db8::100/128 \ 470bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \ 471bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 472bbbc7aa4SGuillaume Nault fi 473bbbc7aa4SGuillaume Nault 474bbbc7aa4SGuillaume Nault # MPLS (unicast) over UDPv6 475bbbc7aa4SGuillaume Nault if [ $MPLS_UC ]; then 476bbbc7aa4SGuillaume Nault # New encapsulation instructions for bareudp over IPv6 477bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter add dev veth10 ingress protocol mpls_uc \ 478bbbc7aa4SGuillaume Nault flower mpls_label 203 \ 479bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::21 dst_ip 2001:db8::22 id 0 \ 480bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns1 481bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter add dev veth23 ingress protocol mpls_uc \ 482bbbc7aa4SGuillaume Nault flower mpls_label 200 \ 483bbbc7aa4SGuillaume Nault action tunnel_key set src_ip 2001:db8::22 dst_ip 2001:db8::21 id 0 \ 484bbbc7aa4SGuillaume Nault action mirred egress redirect dev bareudp_ns2 485bbbc7aa4SGuillaume Nault fi 486bbbc7aa4SGuillaume Nault 487bbbc7aa4SGuillaume Nault # Test IPv6 underlay 488bbbc7aa4SGuillaume Nault ping_test "UDPv6" 489bbbc7aa4SGuillaume Nault 490bbbc7aa4SGuillaume Nault tc -netns "${NS1}" filter delete dev veth10 ingress 491bbbc7aa4SGuillaume Nault tc -netns "${NS2}" filter delete dev veth23 ingress 492bbbc7aa4SGuillaume Nault ip -netns "${NS1}" link delete bareudp_ns1 493bbbc7aa4SGuillaume Nault ip -netns "${NS2}" link delete bareudp_ns2 494bbbc7aa4SGuillaume Nault} 495bbbc7aa4SGuillaume Nault 496bbbc7aa4SGuillaume Naultcheck_features() 497bbbc7aa4SGuillaume Nault{ 498bbbc7aa4SGuillaume Nault ip link help 2>&1 | grep -q bareudp 499bbbc7aa4SGuillaume Nault if [ $? -ne 0 ]; then 500bbbc7aa4SGuillaume Nault echo "Missing bareudp support in iproute2" >&2 501bbbc7aa4SGuillaume Nault exit_cleanup 502bbbc7aa4SGuillaume Nault fi 503bbbc7aa4SGuillaume Nault 504bbbc7aa4SGuillaume Nault # Use ping6 on systems where ping doesn't handle IPv6 505bbbc7aa4SGuillaume Nault ping -w 1 -c 1 ::1 > /dev/null 2>&1 || PING6="ping6" 506bbbc7aa4SGuillaume Nault} 507bbbc7aa4SGuillaume Nault 508bbbc7aa4SGuillaume Naultusage() 509bbbc7aa4SGuillaume Nault{ 510bbbc7aa4SGuillaume Nault echo "Usage: $0 [-p]" 511bbbc7aa4SGuillaume Nault exit 1 512bbbc7aa4SGuillaume Nault} 513bbbc7aa4SGuillaume Nault 514bbbc7aa4SGuillaume Naultwhile getopts :p o 515bbbc7aa4SGuillaume Naultdo 516bbbc7aa4SGuillaume Nault case $o in 517bbbc7aa4SGuillaume Nault p) PAUSE_ON_FAIL="yes";; 518bbbc7aa4SGuillaume Nault *) usage;; 519bbbc7aa4SGuillaume Nault esac 520bbbc7aa4SGuillaume Naultdone 521bbbc7aa4SGuillaume Nault 522bbbc7aa4SGuillaume Naultcheck_features 523bbbc7aa4SGuillaume Nault 524bbbc7aa4SGuillaume Nault# Create namespaces before setting up the exit trap. 525bbbc7aa4SGuillaume Nault# Otherwise, exit_cleanup_all() could delete namespaces that were not created 526bbbc7aa4SGuillaume Nault# by this script. 527bbbc7aa4SGuillaume Naultcreate_namespaces 528bbbc7aa4SGuillaume Nault 529bbbc7aa4SGuillaume Naultset -e 530bbbc7aa4SGuillaume Naulttrap exit_cleanup_all EXIT 531bbbc7aa4SGuillaume Nault 532bbbc7aa4SGuillaume Naultsetup_underlay 533bbbc7aa4SGuillaume Naultsetup_overlay_ipv4 534bbbc7aa4SGuillaume Naultsetup_overlay_ipv6 535bbbc7aa4SGuillaume Naultsetup_overlay_mpls 536bbbc7aa4SGuillaume Nault 537bbbc7aa4SGuillaume Naulttest_overlay ipv4 nomultiproto 538bbbc7aa4SGuillaume Naulttest_overlay ipv6 nomultiproto 539bbbc7aa4SGuillaume Naulttest_overlay ipv4 multiproto 540bbbc7aa4SGuillaume Naulttest_overlay mpls_uc nomultiproto 541bbbc7aa4SGuillaume Nault 542bbbc7aa4SGuillaume Naultif [ "${ERR}" -eq 1 ]; then 543bbbc7aa4SGuillaume Nault echo "Some tests failed." >&2 544bbbc7aa4SGuillaume Naultelse 545bbbc7aa4SGuillaume Nault ERR=0 546bbbc7aa4SGuillaume Naultfi 547