1*c923c149SIdo Schimmel#!/bin/bash 2*c923c149SIdo Schimmel# SPDX-License-Identifier: GPL-2.0 3*c923c149SIdo Schimmel# 4*c923c149SIdo Schimmel# Test that the state of the route exception cache after an ICMP error is 5*c923c149SIdo Schimmel# processed does not depend on whether the quoted packet was matched to a 6*c923c149SIdo Schimmel# socket. Otherwise, an off-path attacker can probe the cache to discover the 7*c923c149SIdo Schimmel# ephemeral port used by a connected UDP socket. 8*c923c149SIdo Schimmel# 9*c923c149SIdo Schimmel# When the quoted packet is not matched to a socket, the same exception is 10*c923c149SIdo Schimmel# created as when it is matched, so that neither its presence nor its contents 11*c923c149SIdo Schimmel# reveal the result of socket matching. 12*c923c149SIdo Schimmel# 13*c923c149SIdo Schimmel# +----+ 14*c923c149SIdo Schimmel# +---------| r1 | 15*c923c149SIdo Schimmel# | +----+ 16*c923c149SIdo Schimmel# +----+ +--------+ | .1 17*c923c149SIdo Schimmel# | h1 |---| bridge | | 198.51.100.0/30 18*c923c149SIdo Schimmel# +----+ +--------+ | 2001:db8:2::/64 19*c923c149SIdo Schimmel# .1 | | .2 20*c923c149SIdo Schimmel# | +----+ +----+ 21*c923c149SIdo Schimmel# +---------| r2 |-----------| h2 | 22*c923c149SIdo Schimmel# .2 .3 +----+ .1 .2 +----+ 23*c923c149SIdo Schimmel# 203.0.113.0/24 24*c923c149SIdo Schimmel# 2001:db8:3::/64 25*c923c149SIdo Schimmel# 192.0.2.0/24 26*c923c149SIdo Schimmel# 2001:db8:1::/64 27*c923c149SIdo Schimmel# 28*c923c149SIdo Schimmel# Traffic from h1 to h2 is routed via r1, which reaches h2's network via r2 29*c923c149SIdo Schimmel# over the point-to-point link. The MTU of the r2 - h2 link is lowered so that 30*c923c149SIdo Schimmel# r2 emits ICMP errors towards h1. 31*c923c149SIdo Schimmel# 32*c923c149SIdo Schimmel# For the redirect tests r1's route to h2's network is replaced with one via r2 33*c923c149SIdo Schimmel# on the shared segment, so that r1 forwards the packet back to the segment it 34*c923c149SIdo Schimmel# arrived from and emits a redirect towards h1. 35*c923c149SIdo Schimmel# 36*c923c149SIdo Schimmel# The packets that provoke the ICMP errors are injected with a packet socket so 37*c923c149SIdo Schimmel# that no socket is ever associated with them. A socket is created separately, 38*c923c149SIdo Schimmel# with socat, when a test needs the ICMP error to be matched. 39*c923c149SIdo Schimmel 40*c923c149SIdo Schimmel# shellcheck disable=SC1091,SC2034,SC2154,SC2329 41*c923c149SIdo Schimmelsource lib.sh 42*c923c149SIdo Schimmel 43*c923c149SIdo Schimmelrequire_command jq 44*c923c149SIdo Schimmelrequire_command mausezahn 45*c923c149SIdo Schimmelrequire_command nstat 46*c923c149SIdo Schimmelrequire_command socat 47*c923c149SIdo Schimmel 48*c923c149SIdo SchimmelALL_TESTS=" 49*c923c149SIdo Schimmel pmtu_no_socket_ipv4 50*c923c149SIdo Schimmel pmtu_no_socket_ipv6 51*c923c149SIdo Schimmel pmtu_socket_ipv4 52*c923c149SIdo Schimmel pmtu_socket_ipv6 53*c923c149SIdo Schimmel pmtu_omit_ipv4 54*c923c149SIdo Schimmel pmtu_omit_ipv6 55*c923c149SIdo Schimmel redirect_no_socket_ipv4 56*c923c149SIdo Schimmel redirect_no_socket_ipv6 57*c923c149SIdo Schimmel redirect_socket_ipv4 58*c923c149SIdo Schimmel redirect_socket_ipv6 59*c923c149SIdo Schimmel" 60*c923c149SIdo Schimmel 61*c923c149SIdo Schimmel# Shared segment. 62*c923c149SIdo SchimmelH1_ADDR4=192.0.2.1 63*c923c149SIdo SchimmelR1_ADDR4=192.0.2.2 64*c923c149SIdo SchimmelR2_ADDR4=192.0.2.3 65*c923c149SIdo SchimmelH1_ADDR6=2001:db8:1::1 66*c923c149SIdo SchimmelR1_ADDR6=2001:db8:1::2 67*c923c149SIdo SchimmelR2_ADDR6=2001:db8:1::3 68*c923c149SIdo Schimmel 69*c923c149SIdo Schimmel# r1 - r2 link. 70*c923c149SIdo SchimmelR2_R1_ADDR4=198.51.100.2 71*c923c149SIdo SchimmelR2_R1_ADDR6=2001:db8:2::2 72*c923c149SIdo Schimmel 73*c923c149SIdo Schimmel# r2 - h2 link. 74*c923c149SIdo SchimmelH2_ADDR4=203.0.113.2 75*c923c149SIdo SchimmelH2_NET4=203.0.113.0/24 76*c923c149SIdo SchimmelH2_ADDR6=2001:db8:3::2 77*c923c149SIdo SchimmelH2_NET6=2001:db8:3::/64 78*c923c149SIdo Schimmel 79*c923c149SIdo SchimmelSPORT=12345 80*c923c149SIdo SchimmelDPORT=54321 81*c923c149SIdo Schimmel 82*c923c149SIdo Schimmel# The MTU of the shared segment and of the r1 - r2 link. Large enough for the 83*c923c149SIdo Schimmel# injected packets to reach r2 intact. 84*c923c149SIdo SchimmelSEGMENT_MTU=2000 85*c923c149SIdo Schimmel# Size of the injected packets. The PMTU tests need a size that exceeds every 86*c923c149SIdo Schimmel# MTU used for the r2 - h2 link, so that r2 responds with an ICMP error. The 87*c923c149SIdo Schimmel# redirect tests need a size that does not, otherwise r2 would respond with an 88*c923c149SIdo Schimmel# ICMP error in addition to the redirect emitted by r1. 89*c923c149SIdo SchimmelPMTU_PACKET_SIZE=1800 90*c923c149SIdo SchimmelREDIRECT_PACKET_SIZE=100 91*c923c149SIdo Schimmel 92*c923c149SIdo Schimmel# The MTUs used for the r2 - h2 link. All of them must be at least 93*c923c149SIdo Schimmel# IPV6_MIN_MTU, otherwise IPv6 silently ignores the error instead of creating 94*c923c149SIdo Schimmel# an exception. 95*c923c149SIdo SchimmelMTU_MID=1400 96*c923c149SIdo SchimmelMTU_LOW=1300 97*c923c149SIdo Schimmel 98*c923c149SIdo Schimmel# Values for the IP{,V6}_MTU_DISCOVER socket option. 99*c923c149SIdo SchimmelPMTUDISC_DONT=0 100*c923c149SIdo SchimmelPMTUDISC_OMIT=5 101*c923c149SIdo Schimmel 102*c923c149SIdo SchimmelSOCAT_PID= 103*c923c149SIdo Schimmel 104*c923c149SIdo Schimmellinklocal_get() 105*c923c149SIdo Schimmel{ 106*c923c149SIdo Schimmel local ns=$1; shift 107*c923c149SIdo Schimmel local dev=$1; shift 108*c923c149SIdo Schimmel 109*c923c149SIdo Schimmel ip -n "$ns" -j -6 addr show dev "$dev" | \ 110*c923c149SIdo Schimmel jq -r '.[]["addr_info"][] | select(.scope == "link") | .local' 111*c923c149SIdo Schimmel} 112*c923c149SIdo Schimmel 113*c923c149SIdo Schimmellinklocal_exists() 114*c923c149SIdo Schimmel{ 115*c923c149SIdo Schimmel local ns=$1; shift 116*c923c149SIdo Schimmel local dev=$1; shift 117*c923c149SIdo Schimmel 118*c923c149SIdo Schimmel [ -n "$(linklocal_get "$ns" "$dev")" ] 119*c923c149SIdo Schimmel} 120*c923c149SIdo Schimmel 121*c923c149SIdo Schimmelfamily_vars_set() 122*c923c149SIdo Schimmel{ 123*c923c149SIdo Schimmel local family=$1; shift 124*c923c149SIdo Schimmel 125*c923c149SIdo Schimmel FAMILY=$family 126*c923c149SIdo Schimmel 127*c923c149SIdo Schimmel if [ "$family" -eq 4 ]; then 128*c923c149SIdo Schimmel H1_ADDR=$H1_ADDR4 129*c923c149SIdo Schimmel H2_ADDR=$H2_ADDR4 130*c923c149SIdo Schimmel MZ_FAMILY_OPT=() 131*c923c149SIdo Schimmel # Without the Don't Fragment bit set r2 fragments the packet 132*c923c149SIdo Schimmel # instead of reporting the MTU of the next hop. 133*c923c149SIdo Schimmel MZ_IP_OPTS="df," 134*c923c149SIdo Schimmel SOCAT_DST="UDP4-CONNECT:$H2_ADDR4:$DPORT" 135*c923c149SIdo Schimmel SOCAT_BIND="bind=$H1_ADDR4:$SPORT" 136*c923c149SIdo Schimmel SOCAT_PMTUDISC="ip-mtu-discover" 137*c923c149SIdo Schimmel else 138*c923c149SIdo Schimmel H1_ADDR=$H1_ADDR6 139*c923c149SIdo Schimmel H2_ADDR=$H2_ADDR6 140*c923c149SIdo Schimmel MZ_FAMILY_OPT=(-6) 141*c923c149SIdo Schimmel MZ_IP_OPTS= 142*c923c149SIdo Schimmel SOCAT_DST="UDP6-CONNECT:[$H2_ADDR6]:$DPORT" 143*c923c149SIdo Schimmel SOCAT_BIND="bind=[$H1_ADDR6]:$SPORT" 144*c923c149SIdo Schimmel SOCAT_PMTUDISC="ipv6-mtu-discover" 145*c923c149SIdo Schimmel fi 146*c923c149SIdo Schimmel} 147*c923c149SIdo Schimmel 148*c923c149SIdo Schimmeltopology_setup() 149*c923c149SIdo Schimmel{ 150*c923c149SIdo Schimmel local ns 151*c923c149SIdo Schimmel 152*c923c149SIdo Schimmel setup_ns h1 r1 r2 h2 sw 153*c923c149SIdo Schimmel defer cleanup_all_ns 154*c923c149SIdo Schimmel 155*c923c149SIdo Schimmel # Link-local addresses are generated from the MAC address and read 156*c923c149SIdo Schimmel # back during setup, so request that generation mode explicitly and 157*c923c149SIdo Schimmel # make the addresses available as soon as the devices are brought up. 158*c923c149SIdo Schimmel for ns in "$h1" "$r1" "$r2" "$h2" "$sw"; do 159*c923c149SIdo Schimmel ip netns exec "$ns" sysctl -qw \ 160*c923c149SIdo Schimmel net.ipv6.conf.default.addr_gen_mode=0 \ 161*c923c149SIdo Schimmel net.ipv6.conf.default.accept_dad=0 \ 162*c923c149SIdo Schimmel net.ipv6.conf.all.accept_dad=0 163*c923c149SIdo Schimmel done 164*c923c149SIdo Schimmel 165*c923c149SIdo Schimmel ip -n "$sw" link add name br0 type bridge 166*c923c149SIdo Schimmel ip -n "$sw" link set dev br0 mtu "$SEGMENT_MTU" up 167*c923c149SIdo Schimmel 168*c923c149SIdo Schimmel ip -n "$h1" link add name eth0 mtu "$SEGMENT_MTU" type veth \ 169*c923c149SIdo Schimmel peer name swp1 mtu "$SEGMENT_MTU" netns "$sw" 170*c923c149SIdo Schimmel ip -n "$r1" link add name eth0 mtu "$SEGMENT_MTU" type veth \ 171*c923c149SIdo Schimmel peer name swp2 mtu "$SEGMENT_MTU" netns "$sw" 172*c923c149SIdo Schimmel ip -n "$r2" link add name eth0 mtu "$SEGMENT_MTU" type veth \ 173*c923c149SIdo Schimmel peer name swp3 mtu "$SEGMENT_MTU" netns "$sw" 174*c923c149SIdo Schimmel ip -n "$r1" link add name eth1 mtu "$SEGMENT_MTU" type veth \ 175*c923c149SIdo Schimmel peer name eth1 mtu "$SEGMENT_MTU" netns "$r2" 176*c923c149SIdo Schimmel ip -n "$r2" link add name eth2 type veth peer name eth0 netns "$h2" 177*c923c149SIdo Schimmel 178*c923c149SIdo Schimmel ip -n "$sw" link set dev swp1 master br0 up 179*c923c149SIdo Schimmel ip -n "$sw" link set dev swp2 master br0 up 180*c923c149SIdo Schimmel ip -n "$sw" link set dev swp3 master br0 up 181*c923c149SIdo Schimmel 182*c923c149SIdo Schimmel ip -n "$h1" link set dev eth0 up 183*c923c149SIdo Schimmel ip -n "$r1" link set dev eth0 up 184*c923c149SIdo Schimmel ip -n "$r1" link set dev eth1 up 185*c923c149SIdo Schimmel ip -n "$r2" link set dev eth0 up 186*c923c149SIdo Schimmel ip -n "$r2" link set dev eth1 up 187*c923c149SIdo Schimmel ip -n "$r2" link set dev eth2 up 188*c923c149SIdo Schimmel ip -n "$h2" link set dev eth0 up 189*c923c149SIdo Schimmel 190*c923c149SIdo Schimmel ip -n "$h1" address add "$H1_ADDR4/24" dev eth0 191*c923c149SIdo Schimmel ip -n "$r1" address add "$R1_ADDR4/24" dev eth0 192*c923c149SIdo Schimmel ip -n "$r2" address add "$R2_ADDR4/24" dev eth0 193*c923c149SIdo Schimmel ip -n "$r1" address add 198.51.100.1/30 dev eth1 194*c923c149SIdo Schimmel ip -n "$r2" address add "$R2_R1_ADDR4/30" dev eth1 195*c923c149SIdo Schimmel ip -n "$r2" address add 203.0.113.1/24 dev eth2 196*c923c149SIdo Schimmel ip -n "$h2" address add "$H2_ADDR4/24" dev eth0 197*c923c149SIdo Schimmel 198*c923c149SIdo Schimmel ip -n "$h1" -6 address add "$H1_ADDR6/64" dev eth0 nodad 199*c923c149SIdo Schimmel ip -n "$r1" -6 address add "$R1_ADDR6/64" dev eth0 nodad 200*c923c149SIdo Schimmel ip -n "$r2" -6 address add "$R2_ADDR6/64" dev eth0 nodad 201*c923c149SIdo Schimmel ip -n "$r1" -6 address add 2001:db8:2::1/64 dev eth1 nodad 202*c923c149SIdo Schimmel ip -n "$r2" -6 address add "$R2_R1_ADDR6/64" dev eth1 nodad 203*c923c149SIdo Schimmel ip -n "$r2" -6 address add 2001:db8:3::1/64 dev eth2 nodad 204*c923c149SIdo Schimmel ip -n "$h2" -6 address add "$H2_ADDR6/64" dev eth0 nodad 205*c923c149SIdo Schimmel 206*c923c149SIdo Schimmel ip netns exec "$r1" sysctl -qw net.ipv4.ip_forward=1 207*c923c149SIdo Schimmel ip netns exec "$r1" sysctl -qw net.ipv4.conf.all.send_redirects=1 208*c923c149SIdo Schimmel ip netns exec "$r1" sysctl -qw net.ipv6.conf.all.forwarding=1 209*c923c149SIdo Schimmel ip netns exec "$r2" sysctl -qw net.ipv4.ip_forward=1 210*c923c149SIdo Schimmel ip netns exec "$r2" sysctl -qw net.ipv6.conf.all.forwarding=1 211*c923c149SIdo Schimmel 212*c923c149SIdo Schimmel ip netns exec "$h1" sysctl -qw net.ipv4.conf.all.accept_redirects=1 213*c923c149SIdo Schimmel ip netns exec "$h1" sysctl -qw net.ipv4.conf.eth0.accept_redirects=1 214*c923c149SIdo Schimmel ip netns exec "$h1" sysctl -qw net.ipv6.conf.all.accept_redirects=1 215*c923c149SIdo Schimmel ip netns exec "$h1" sysctl -qw net.ipv6.conf.eth0.accept_redirects=1 216*c923c149SIdo Schimmel 217*c923c149SIdo Schimmel slowwait 5 linklocal_exists "$r1" eth0 218*c923c149SIdo Schimmel check_err $? "r1: link-local address was not generated" 219*c923c149SIdo Schimmel slowwait 5 linklocal_exists "$r2" eth0 220*c923c149SIdo Schimmel check_err $? "r2: link-local address was not generated" 221*c923c149SIdo Schimmel 222*c923c149SIdo Schimmel R1_LLADDR=$(linklocal_get "$r1" eth0) 223*c923c149SIdo Schimmel R2_LLADDR=$(linklocal_get "$r2" eth0) 224*c923c149SIdo Schimmel R1_MAC=$(ip -n "$r1" -j link show dev eth0 | jq -r '.[]["address"]') 225*c923c149SIdo Schimmel R2_MAC=$(ip -n "$r2" -j link show dev eth0 | jq -r '.[]["address"]') 226*c923c149SIdo Schimmel 227*c923c149SIdo Schimmel ip -n "$h1" route add "$H2_NET4" via "$R1_ADDR4" dev eth0 228*c923c149SIdo Schimmel ip -n "$h1" -6 route add "$H2_NET6" via "$R1_LLADDR" dev eth0 229*c923c149SIdo Schimmel ip -n "$r1" route add "$H2_NET4" via "$R2_R1_ADDR4" dev eth1 230*c923c149SIdo Schimmel ip -n "$r1" -6 route add "$H2_NET6" via "$R2_R1_ADDR6" dev eth1 231*c923c149SIdo Schimmel ip -n "$h2" route add default via 203.0.113.1 dev eth0 232*c923c149SIdo Schimmel ip -n "$h2" -6 route add default via 2001:db8:3::1 dev eth0 233*c923c149SIdo Schimmel 234*c923c149SIdo Schimmel far_mtu_set "$MTU_MID" 235*c923c149SIdo Schimmel} 236*c923c149SIdo Schimmel 237*c923c149SIdo Schimmel# Make r1 forward towards h2's network over the segment it receives the packet 238*c923c149SIdo Schimmel# from, so that it emits a redirect towards h1. 239*c923c149SIdo Schimmelredirect_route_set() 240*c923c149SIdo Schimmel{ 241*c923c149SIdo Schimmel ip -n "$r1" route replace "$H2_NET4" via "$R2_ADDR4" dev eth0 242*c923c149SIdo Schimmel ip -n "$r1" -6 route replace "$H2_NET6" via "$R2_LLADDR" dev eth0 243*c923c149SIdo Schimmel 244*c923c149SIdo Schimmel # __ip_do_redirect() only creates an exception if the new gateway is 245*c923c149SIdo Schimmel # already a valid neighbour. Otherwise it merely triggers address 246*c923c149SIdo Schimmel # resolution. IPv6 resolves the target itself, in rt6_do_redirect(). 247*c923c149SIdo Schimmel ip -n "$h1" neigh replace "$R2_ADDR4" lladdr "$R2_MAC" dev eth0 \ 248*c923c149SIdo Schimmel nud permanent 249*c923c149SIdo Schimmel} 250*c923c149SIdo Schimmel 251*c923c149SIdo Schimmelfar_mtu_set() 252*c923c149SIdo Schimmel{ 253*c923c149SIdo Schimmel local mtu=$1; shift 254*c923c149SIdo Schimmel 255*c923c149SIdo Schimmel ip -n "$r2" link set dev eth2 mtu "$mtu" 256*c923c149SIdo Schimmel ip -n "$h2" link set dev eth0 mtu "$mtu" 257*c923c149SIdo Schimmel} 258*c923c149SIdo Schimmel 259*c923c149SIdo Schimmelsocket_is_open() 260*c923c149SIdo Schimmel{ 261*c923c149SIdo Schimmel ip netns exec "$h1" ss -uHn "sport = :$SPORT" | grep -q . 262*c923c149SIdo Schimmel} 263*c923c149SIdo Schimmel 264*c923c149SIdo Schimmelsocket_start() 265*c923c149SIdo Schimmel{ 266*c923c149SIdo Schimmel # Disable PMTU discovery by default so that ICMP errors are not 267*c923c149SIdo Schimmel # reported to the socket. Otherwise socat would exit when the first one 268*c923c149SIdo Schimmel # arrives and later packets in the same test would not be matched to a 269*c923c149SIdo Schimmel # socket. The exception is still created, as ip{,6}_sk_accept_pmtu() 270*c923c149SIdo Schimmel # only rejects IP{,V6}_PMTUDISC_{INTERFACE,OMIT}. 271*c923c149SIdo Schimmel local pmtudisc=${1:-$PMTUDISC_DONT} 272*c923c149SIdo Schimmel 273*c923c149SIdo Schimmel # Send socat's diagnostics to /dev/null. It reports the ICMP errors 274*c923c149SIdo Schimmel # that reach the socket, which is exactly what the tests provoke. 275*c923c149SIdo Schimmel ip netns exec "$h1" socat -u -lf/dev/null \ 276*c923c149SIdo Schimmel "$SOCAT_DST,$SOCAT_BIND,$SOCAT_PMTUDISC=$pmtudisc" \ 277*c923c149SIdo Schimmel OPEN:/dev/null,wronly=1 & 278*c923c149SIdo Schimmel SOCAT_PID=$! 279*c923c149SIdo Schimmel defer socket_stop 280*c923c149SIdo Schimmel 281*c923c149SIdo Schimmel slowwait 5 socket_is_open 282*c923c149SIdo Schimmel check_err $? "socket did not open" 283*c923c149SIdo Schimmel} 284*c923c149SIdo Schimmel 285*c923c149SIdo Schimmelsocket_stop() 286*c923c149SIdo Schimmel{ 287*c923c149SIdo Schimmel [ -z "$SOCAT_PID" ] && return 0 288*c923c149SIdo Schimmel 289*c923c149SIdo Schimmel kill "$SOCAT_PID" &> /dev/null 290*c923c149SIdo Schimmel wait "$SOCAT_PID" 2> /dev/null 291*c923c149SIdo Schimmel SOCAT_PID= 292*c923c149SIdo Schimmel} 293*c923c149SIdo Schimmel 294*c923c149SIdo Schimmel# Inject a packet towards h2 with a packet socket. No socket is associated with 295*c923c149SIdo Schimmel# it, so an ICMP error quoting it is matched to a socket only if one was 296*c923c149SIdo Schimmel# created separately with the same source port. 297*c923c149SIdo Schimmelpacket_send() 298*c923c149SIdo Schimmel{ 299*c923c149SIdo Schimmel local size=$1; shift 300*c923c149SIdo Schimmel 301*c923c149SIdo Schimmel ip netns exec "$h1" mausezahn "${MZ_FAMILY_OPT[@]}" eth0 \ 302*c923c149SIdo Schimmel -a own -b "$R1_MAC" -A "$H1_ADDR" -B "$H2_ADDR" \ 303*c923c149SIdo Schimmel -t udp "${MZ_IP_OPTS}sp=$SPORT,dp=$DPORT" \ 304*c923c149SIdo Schimmel -p "$size" -c 1 -q 305*c923c149SIdo Schimmel} 306*c923c149SIdo Schimmel 307*c923c149SIdo Schimmelexception_show() 308*c923c149SIdo Schimmel{ 309*c923c149SIdo Schimmel if [ "$FAMILY" -eq 4 ]; then 310*c923c149SIdo Schimmel # IPv4 exceptions without a bound route are not dumped, but 311*c923c149SIdo Schimmel # "route get" reports the exception and binds a route to it. 312*c923c149SIdo Schimmel ip -n "$h1" route get "$H2_ADDR" 313*c923c149SIdo Schimmel else 314*c923c149SIdo Schimmel # IPv6 does not report a cache indication in "route get" 315*c923c149SIdo Schimmel # output, so dump the exceptions instead. 316*c923c149SIdo Schimmel ip -n "$h1" -6 route show cache | grep -F "$H2_ADDR" || true 317*c923c149SIdo Schimmel fi 318*c923c149SIdo Schimmel} 319*c923c149SIdo Schimmel 320*c923c149SIdo Schimmelexception_mtu_get() 321*c923c149SIdo Schimmel{ 322*c923c149SIdo Schimmel exception_show | grep -o "mtu [0-9]*" | cut -d ' ' -f 2 323*c923c149SIdo Schimmel} 324*c923c149SIdo Schimmel 325*c923c149SIdo Schimmelexception_gw_get() 326*c923c149SIdo Schimmel{ 327*c923c149SIdo Schimmel exception_show | grep -o "via [0-9a-f.:]*" | cut -d ' ' -f 2 328*c923c149SIdo Schimmel} 329*c923c149SIdo Schimmel 330*c923c149SIdo Schimmelexception_mtu_check() 331*c923c149SIdo Schimmel{ 332*c923c149SIdo Schimmel local expected=$1; shift 333*c923c149SIdo Schimmel 334*c923c149SIdo Schimmel [ "$(exception_mtu_get)" = "$expected" ] 335*c923c149SIdo Schimmel} 336*c923c149SIdo Schimmel 337*c923c149SIdo Schimmelicmp_errors_get() 338*c923c149SIdo Schimmel{ 339*c923c149SIdo Schimmel local ctr=IcmpInDestUnreachs 340*c923c149SIdo Schimmel 341*c923c149SIdo Schimmel [ "$FAMILY" -eq 6 ] && ctr=Icmp6InPktTooBigs 342*c923c149SIdo Schimmel 343*c923c149SIdo Schimmel ip netns exec "$h1" nstat -asz "$ctr" | \ 344*c923c149SIdo Schimmel awk -v ctr="$ctr" '$1 == ctr { print $2 }' 345*c923c149SIdo Schimmel} 346*c923c149SIdo Schimmel 347*c923c149SIdo Schimmelexception_pmtu_check() 348*c923c149SIdo Schimmel{ 349*c923c149SIdo Schimmel local mtu=$1; shift 350*c923c149SIdo Schimmel local desc=$1; shift 351*c923c149SIdo Schimmel 352*c923c149SIdo Schimmel busywait "$BUSYWAIT_TIMEOUT" exception_mtu_check "$mtu" 353*c923c149SIdo Schimmel check_err $? "$desc: exception does not carry an MTU of $mtu" 354*c923c149SIdo Schimmel} 355*c923c149SIdo Schimmel 356*c923c149SIdo Schimmelpmtu_no_socket() 357*c923c149SIdo Schimmel{ 358*c923c149SIdo Schimmel local family=$1; shift 359*c923c149SIdo Schimmel 360*c923c149SIdo Schimmel RET=0 361*c923c149SIdo Schimmel family_vars_set "$family" 362*c923c149SIdo Schimmel topology_setup 363*c923c149SIdo Schimmel 364*c923c149SIdo Schimmel packet_send "$PMTU_PACKET_SIZE" 365*c923c149SIdo Schimmel exception_pmtu_check "$MTU_MID" "No socket" 366*c923c149SIdo Schimmel 367*c923c149SIdo Schimmel log_test "IPv$family: PMTU: exception without a matching socket" 368*c923c149SIdo Schimmel} 369*c923c149SIdo Schimmel 370*c923c149SIdo Schimmelpmtu_no_socket_ipv4() 371*c923c149SIdo Schimmel{ 372*c923c149SIdo Schimmel pmtu_no_socket 4 373*c923c149SIdo Schimmel} 374*c923c149SIdo Schimmel 375*c923c149SIdo Schimmelpmtu_no_socket_ipv6() 376*c923c149SIdo Schimmel{ 377*c923c149SIdo Schimmel pmtu_no_socket 6 378*c923c149SIdo Schimmel} 379*c923c149SIdo Schimmel 380*c923c149SIdo Schimmelpmtu_socket() 381*c923c149SIdo Schimmel{ 382*c923c149SIdo Schimmel local family=$1; shift 383*c923c149SIdo Schimmel local t0 384*c923c149SIdo Schimmel 385*c923c149SIdo Schimmel RET=0 386*c923c149SIdo Schimmel family_vars_set "$family" 387*c923c149SIdo Schimmel topology_setup 388*c923c149SIdo Schimmel socket_start 389*c923c149SIdo Schimmel 390*c923c149SIdo Schimmel packet_send "$PMTU_PACKET_SIZE" 391*c923c149SIdo Schimmel exception_pmtu_check "$MTU_MID" "Matching socket" 392*c923c149SIdo Schimmel 393*c923c149SIdo Schimmel # A lower PMTU replaces the one currently stored in the exception. 394*c923c149SIdo Schimmel far_mtu_set "$MTU_LOW" 395*c923c149SIdo Schimmel packet_send "$PMTU_PACKET_SIZE" 396*c923c149SIdo Schimmel exception_pmtu_check "$MTU_LOW" "Lower PMTU" 397*c923c149SIdo Schimmel 398*c923c149SIdo Schimmel # A higher PMTU is ignored, so the exception is left as it is. Wait 399*c923c149SIdo Schimmel # for the error to be received, as otherwise the check below would 400*c923c149SIdo Schimmel # pass even if it never was. 401*c923c149SIdo Schimmel far_mtu_set "$MTU_MID" 402*c923c149SIdo Schimmel t0=$(icmp_errors_get) 403*c923c149SIdo Schimmel packet_send "$PMTU_PACKET_SIZE" 404*c923c149SIdo Schimmel busywait "$BUSYWAIT_TIMEOUT" until_counter_is ">= $((t0 + 1))" \ 405*c923c149SIdo Schimmel icmp_errors_get > /dev/null 406*c923c149SIdo Schimmel check_err $? "Higher PMTU: ICMP error was not received" 407*c923c149SIdo Schimmel 408*c923c149SIdo Schimmel exception_mtu_check "$MTU_LOW" 409*c923c149SIdo Schimmel check_err $? "Higher PMTU: exception does not carry an MTU of $MTU_LOW" 410*c923c149SIdo Schimmel 411*c923c149SIdo Schimmel log_test "IPv$family: PMTU: exception with a matching socket" 412*c923c149SIdo Schimmel} 413*c923c149SIdo Schimmel 414*c923c149SIdo Schimmelpmtu_socket_ipv4() 415*c923c149SIdo Schimmel{ 416*c923c149SIdo Schimmel pmtu_socket 4 417*c923c149SIdo Schimmel} 418*c923c149SIdo Schimmel 419*c923c149SIdo Schimmelpmtu_socket_ipv6() 420*c923c149SIdo Schimmel{ 421*c923c149SIdo Schimmel pmtu_socket 6 422*c923c149SIdo Schimmel} 423*c923c149SIdo Schimmel 424*c923c149SIdo Schimmelpmtu_omit() 425*c923c149SIdo Schimmel{ 426*c923c149SIdo Schimmel local family=$1; shift 427*c923c149SIdo Schimmel 428*c923c149SIdo Schimmel RET=0 429*c923c149SIdo Schimmel family_vars_set "$family" 430*c923c149SIdo Schimmel topology_setup 431*c923c149SIdo Schimmel socket_start "$PMTUDISC_OMIT" 432*c923c149SIdo Schimmel 433*c923c149SIdo Schimmel packet_send "$PMTU_PACKET_SIZE" 434*c923c149SIdo Schimmel exception_pmtu_check "$MTU_MID" "PMTU discovery disabled" 435*c923c149SIdo Schimmel 436*c923c149SIdo Schimmel log_test "IPv$family: PMTU: exception with a socket ignoring it" 437*c923c149SIdo Schimmel} 438*c923c149SIdo Schimmel 439*c923c149SIdo Schimmelpmtu_omit_ipv4() 440*c923c149SIdo Schimmel{ 441*c923c149SIdo Schimmel pmtu_omit 4 442*c923c149SIdo Schimmel} 443*c923c149SIdo Schimmel 444*c923c149SIdo Schimmelpmtu_omit_ipv6() 445*c923c149SIdo Schimmel{ 446*c923c149SIdo Schimmel pmtu_omit 6 447*c923c149SIdo Schimmel} 448*c923c149SIdo Schimmel 449*c923c149SIdo Schimmelexception_gw_check() 450*c923c149SIdo Schimmel{ 451*c923c149SIdo Schimmel local expected=$1; shift 452*c923c149SIdo Schimmel 453*c923c149SIdo Schimmel [ -n "$expected" ] && [ "$(exception_gw_get)" = "$expected" ] 454*c923c149SIdo Schimmel} 455*c923c149SIdo Schimmel 456*c923c149SIdo Schimmelredirect_gw_new() 457*c923c149SIdo Schimmel{ 458*c923c149SIdo Schimmel if [ "$FAMILY" -eq 4 ]; then 459*c923c149SIdo Schimmel echo "$R2_ADDR4" 460*c923c149SIdo Schimmel else 461*c923c149SIdo Schimmel echo "$R2_LLADDR" 462*c923c149SIdo Schimmel fi 463*c923c149SIdo Schimmel} 464*c923c149SIdo Schimmel 465*c923c149SIdo Schimmelredirect_no_socket() 466*c923c149SIdo Schimmel{ 467*c923c149SIdo Schimmel local family=$1; shift 468*c923c149SIdo Schimmel 469*c923c149SIdo Schimmel RET=0 470*c923c149SIdo Schimmel family_vars_set "$family" 471*c923c149SIdo Schimmel topology_setup 472*c923c149SIdo Schimmel redirect_route_set 473*c923c149SIdo Schimmel 474*c923c149SIdo Schimmel packet_send "$REDIRECT_PACKET_SIZE" 475*c923c149SIdo Schimmel busywait "$BUSYWAIT_TIMEOUT" exception_gw_check "$(redirect_gw_new)" 476*c923c149SIdo Schimmel check_err $? "No socket: exception does not carry the new gateway" 477*c923c149SIdo Schimmel 478*c923c149SIdo Schimmel log_test "IPv$family: Redirect: exception without a matching socket" 479*c923c149SIdo Schimmel} 480*c923c149SIdo Schimmel 481*c923c149SIdo Schimmelredirect_no_socket_ipv4() 482*c923c149SIdo Schimmel{ 483*c923c149SIdo Schimmel redirect_no_socket 4 484*c923c149SIdo Schimmel} 485*c923c149SIdo Schimmel 486*c923c149SIdo Schimmelredirect_no_socket_ipv6() 487*c923c149SIdo Schimmel{ 488*c923c149SIdo Schimmel redirect_no_socket 6 489*c923c149SIdo Schimmel} 490*c923c149SIdo Schimmel 491*c923c149SIdo Schimmelredirect_socket() 492*c923c149SIdo Schimmel{ 493*c923c149SIdo Schimmel local family=$1; shift 494*c923c149SIdo Schimmel 495*c923c149SIdo Schimmel RET=0 496*c923c149SIdo Schimmel family_vars_set "$family" 497*c923c149SIdo Schimmel topology_setup 498*c923c149SIdo Schimmel redirect_route_set 499*c923c149SIdo Schimmel socket_start 500*c923c149SIdo Schimmel 501*c923c149SIdo Schimmel packet_send "$REDIRECT_PACKET_SIZE" 502*c923c149SIdo Schimmel busywait "$BUSYWAIT_TIMEOUT" exception_gw_check "$(redirect_gw_new)" 503*c923c149SIdo Schimmel check_err $? "Matching socket: exception does not carry the new gateway" 504*c923c149SIdo Schimmel 505*c923c149SIdo Schimmel log_test "IPv$family: Redirect: exception with a matching socket" 506*c923c149SIdo Schimmel} 507*c923c149SIdo Schimmel 508*c923c149SIdo Schimmelredirect_socket_ipv4() 509*c923c149SIdo Schimmel{ 510*c923c149SIdo Schimmel redirect_socket 4 511*c923c149SIdo Schimmel} 512*c923c149SIdo Schimmel 513*c923c149SIdo Schimmelredirect_socket_ipv6() 514*c923c149SIdo Schimmel{ 515*c923c149SIdo Schimmel redirect_socket 6 516*c923c149SIdo Schimmel} 517*c923c149SIdo Schimmel 518*c923c149SIdo Schimmeltrap defer_scopes_cleanup EXIT 519*c923c149SIdo Schimmeltests_run 520*c923c149SIdo Schimmel 521*c923c149SIdo Schimmelexit "$EXIT_STATUS" 522