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