1*4882a593Smuzhiyun#!/bin/sh 2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0 3*4882a593Smuzhiyun# 4*4882a593Smuzhiyun# Check that route PMTU values match expectations, and that initial device MTU 5*4882a593Smuzhiyun# values are assigned correctly 6*4882a593Smuzhiyun# 7*4882a593Smuzhiyun# Tests currently implemented: 8*4882a593Smuzhiyun# 9*4882a593Smuzhiyun# - pmtu_ipv4 10*4882a593Smuzhiyun# Set up two namespaces, A and B, with two paths between them over routers 11*4882a593Smuzhiyun# R1 and R2 (also implemented with namespaces), with different MTUs: 12*4882a593Smuzhiyun# 13*4882a593Smuzhiyun# segment a_r1 segment b_r1 a_r1: 2000 14*4882a593Smuzhiyun# .--------------R1--------------. b_r1: 1400 15*4882a593Smuzhiyun# A B a_r2: 2000 16*4882a593Smuzhiyun# '--------------R2--------------' b_r2: 1500 17*4882a593Smuzhiyun# segment a_r2 segment b_r2 18*4882a593Smuzhiyun# 19*4882a593Smuzhiyun# Check that PMTU exceptions with the correct PMTU are created. Then 20*4882a593Smuzhiyun# decrease and increase the MTU of the local link for one of the paths, 21*4882a593Smuzhiyun# A to R1, checking that route exception PMTU changes accordingly over 22*4882a593Smuzhiyun# this path. Also check that locked exceptions are created when an ICMP 23*4882a593Smuzhiyun# message advertising a PMTU smaller than net.ipv4.route.min_pmtu is 24*4882a593Smuzhiyun# received 25*4882a593Smuzhiyun# 26*4882a593Smuzhiyun# - pmtu_ipv6 27*4882a593Smuzhiyun# Same as pmtu_ipv4, except for locked PMTU tests, using IPv6 28*4882a593Smuzhiyun# 29*4882a593Smuzhiyun# - pmtu_ipv4_vxlan4_exception 30*4882a593Smuzhiyun# Set up the same network topology as pmtu_ipv4, create a VXLAN tunnel 31*4882a593Smuzhiyun# over IPv4 between A and B, routed via R1. On the link between R1 and B, 32*4882a593Smuzhiyun# set a MTU lower than the VXLAN MTU and the MTU on the link between A and 33*4882a593Smuzhiyun# R1. Send IPv4 packets, exceeding the MTU between R1 and B, over VXLAN 34*4882a593Smuzhiyun# from A to B and check that the PMTU exception is created with the right 35*4882a593Smuzhiyun# value on A 36*4882a593Smuzhiyun# 37*4882a593Smuzhiyun# - pmtu_ipv6_vxlan4_exception 38*4882a593Smuzhiyun# Same as pmtu_ipv4_vxlan4_exception, but send IPv6 packets from A to B 39*4882a593Smuzhiyun# 40*4882a593Smuzhiyun# - pmtu_ipv4_vxlan6_exception 41*4882a593Smuzhiyun# Same as pmtu_ipv4_vxlan4_exception, but use IPv6 transport from A to B 42*4882a593Smuzhiyun# 43*4882a593Smuzhiyun# - pmtu_ipv6_vxlan6_exception 44*4882a593Smuzhiyun# Same as pmtu_ipv4_vxlan6_exception, but send IPv6 packets from A to B 45*4882a593Smuzhiyun# 46*4882a593Smuzhiyun# - pmtu_ipv4_geneve4_exception 47*4882a593Smuzhiyun# Same as pmtu_ipv4_vxlan4_exception, but using a GENEVE tunnel instead of 48*4882a593Smuzhiyun# VXLAN 49*4882a593Smuzhiyun# 50*4882a593Smuzhiyun# - pmtu_ipv6_geneve4_exception 51*4882a593Smuzhiyun# Same as pmtu_ipv6_vxlan4_exception, but using a GENEVE tunnel instead of 52*4882a593Smuzhiyun# VXLAN 53*4882a593Smuzhiyun# 54*4882a593Smuzhiyun# - pmtu_ipv4_geneve6_exception 55*4882a593Smuzhiyun# Same as pmtu_ipv4_vxlan6_exception, but using a GENEVE tunnel instead of 56*4882a593Smuzhiyun# VXLAN 57*4882a593Smuzhiyun# 58*4882a593Smuzhiyun# - pmtu_ipv6_geneve6_exception 59*4882a593Smuzhiyun# Same as pmtu_ipv6_vxlan6_exception, but using a GENEVE tunnel instead of 60*4882a593Smuzhiyun# VXLAN 61*4882a593Smuzhiyun# 62*4882a593Smuzhiyun# - pmtu_ipv{4,6}_br_vxlan{4,6}_exception 63*4882a593Smuzhiyun# Set up three namespaces, A, B, and C, with routing between A and B over 64*4882a593Smuzhiyun# R1. R2 is unused in these tests. A has a veth connection to C, and is 65*4882a593Smuzhiyun# connected to B via a VXLAN endpoint, which is directly bridged to C. 66*4882a593Smuzhiyun# MTU on the B-R1 link is lower than other MTUs. 67*4882a593Smuzhiyun# 68*4882a593Smuzhiyun# Check that both C and A are able to communicate with B over the VXLAN 69*4882a593Smuzhiyun# tunnel, and that PMTU exceptions with the correct values are created. 70*4882a593Smuzhiyun# 71*4882a593Smuzhiyun# segment a_r1 segment b_r1 b_r1: 4000 72*4882a593Smuzhiyun# .--------------R1--------------. everything 73*4882a593Smuzhiyun# C---veth A B else: 5000 74*4882a593Smuzhiyun# ' bridge | 75*4882a593Smuzhiyun# '---- - - - - - VXLAN - - - - - - - ' 76*4882a593Smuzhiyun# 77*4882a593Smuzhiyun# - pmtu_ipv{4,6}_br_geneve{4,6}_exception 78*4882a593Smuzhiyun# Same as pmtu_ipv{4,6}_br_vxlan{4,6}_exception, with a GENEVE tunnel 79*4882a593Smuzhiyun# instead. 80*4882a593Smuzhiyun# 81*4882a593Smuzhiyun# - pmtu_ipv{4,6}_ovs_vxlan{4,6}_exception 82*4882a593Smuzhiyun# Set up two namespaces, B, and C, with routing between the init namespace 83*4882a593Smuzhiyun# and B over R1. A and R2 are unused in these tests. The init namespace 84*4882a593Smuzhiyun# has a veth connection to C, and is connected to B via a VXLAN endpoint, 85*4882a593Smuzhiyun# which is handled by Open vSwitch and bridged to C. MTU on the B-R1 link 86*4882a593Smuzhiyun# is lower than other MTUs. 87*4882a593Smuzhiyun# 88*4882a593Smuzhiyun# Check that C is able to communicate with B over the VXLAN tunnel, and 89*4882a593Smuzhiyun# that PMTU exceptions with the correct values are created. 90*4882a593Smuzhiyun# 91*4882a593Smuzhiyun# segment a_r1 segment b_r1 b_r1: 4000 92*4882a593Smuzhiyun# .--------------R1--------------. everything 93*4882a593Smuzhiyun# C---veth init B else: 5000 94*4882a593Smuzhiyun# '- ovs | 95*4882a593Smuzhiyun# '---- - - - - - VXLAN - - - - - - - ' 96*4882a593Smuzhiyun# 97*4882a593Smuzhiyun# - pmtu_ipv{4,6}_ovs_geneve{4,6}_exception 98*4882a593Smuzhiyun# Same as pmtu_ipv{4,6}_ovs_vxlan{4,6}_exception, with a GENEVE tunnel 99*4882a593Smuzhiyun# instead. 100*4882a593Smuzhiyun# 101*4882a593Smuzhiyun# - pmtu_ipv{4,6}_fou{4,6}_exception 102*4882a593Smuzhiyun# Same as pmtu_ipv4_vxlan4, but using a direct IPv4/IPv6 encapsulation 103*4882a593Smuzhiyun# (FoU) over IPv4/IPv6, instead of VXLAN 104*4882a593Smuzhiyun# 105*4882a593Smuzhiyun# - pmtu_ipv{4,6}_fou{4,6}_exception 106*4882a593Smuzhiyun# Same as pmtu_ipv4_vxlan4, but using a generic UDP IPv4/IPv6 107*4882a593Smuzhiyun# encapsulation (GUE) over IPv4/IPv6, instead of VXLAN 108*4882a593Smuzhiyun# 109*4882a593Smuzhiyun# - pmtu_ipv{4,6}_ipv{4,6}_exception 110*4882a593Smuzhiyun# Same as pmtu_ipv4_vxlan4, but using a IPv4/IPv6 tunnel over IPv4/IPv6, 111*4882a593Smuzhiyun# instead of VXLAN 112*4882a593Smuzhiyun# 113*4882a593Smuzhiyun# - pmtu_vti4_exception 114*4882a593Smuzhiyun# Set up vti tunnel on top of veth, with xfrm states and policies, in two 115*4882a593Smuzhiyun# namespaces with matching endpoints. Check that route exception is not 116*4882a593Smuzhiyun# created if link layer MTU is not exceeded, then exceed it and check that 117*4882a593Smuzhiyun# exception is created with the expected PMTU. The approach described 118*4882a593Smuzhiyun# below for IPv6 doesn't apply here, because, on IPv4, administrative MTU 119*4882a593Smuzhiyun# changes alone won't affect PMTU 120*4882a593Smuzhiyun# 121*4882a593Smuzhiyun# - pmtu_vti6_exception 122*4882a593Smuzhiyun# Set up vti6 tunnel on top of veth, with xfrm states and policies, in two 123*4882a593Smuzhiyun# namespaces with matching endpoints. Check that route exception is 124*4882a593Smuzhiyun# created by exceeding link layer MTU with ping to other endpoint. Then 125*4882a593Smuzhiyun# decrease and increase MTU of tunnel, checking that route exception PMTU 126*4882a593Smuzhiyun# changes accordingly 127*4882a593Smuzhiyun# 128*4882a593Smuzhiyun# - pmtu_vti4_default_mtu 129*4882a593Smuzhiyun# Set up vti4 tunnel on top of veth, in two namespaces with matching 130*4882a593Smuzhiyun# endpoints. Check that MTU assigned to vti interface is the MTU of the 131*4882a593Smuzhiyun# lower layer (veth) minus additional lower layer headers (zero, for veth) 132*4882a593Smuzhiyun# minus IPv4 header length 133*4882a593Smuzhiyun# 134*4882a593Smuzhiyun# - pmtu_vti6_default_mtu 135*4882a593Smuzhiyun# Same as above, for IPv6 136*4882a593Smuzhiyun# 137*4882a593Smuzhiyun# - pmtu_vti4_link_add_mtu 138*4882a593Smuzhiyun# Set up vti4 interface passing MTU value at link creation, check MTU is 139*4882a593Smuzhiyun# configured, and that link is not created with invalid MTU values 140*4882a593Smuzhiyun# 141*4882a593Smuzhiyun# - pmtu_vti6_link_add_mtu 142*4882a593Smuzhiyun# Same as above, for IPv6 143*4882a593Smuzhiyun# 144*4882a593Smuzhiyun# - pmtu_vti6_link_change_mtu 145*4882a593Smuzhiyun# Set up two dummy interfaces with different MTUs, create a vti6 tunnel 146*4882a593Smuzhiyun# and check that configured MTU is used on link creation and changes, and 147*4882a593Smuzhiyun# that MTU is properly calculated instead when MTU is not configured from 148*4882a593Smuzhiyun# userspace 149*4882a593Smuzhiyun# 150*4882a593Smuzhiyun# - cleanup_ipv4_exception 151*4882a593Smuzhiyun# Similar to pmtu_ipv4_vxlan4_exception, but explicitly generate PMTU 152*4882a593Smuzhiyun# exceptions on multiple CPUs and check that the veth device tear-down 153*4882a593Smuzhiyun# happens in a timely manner 154*4882a593Smuzhiyun# 155*4882a593Smuzhiyun# - cleanup_ipv6_exception 156*4882a593Smuzhiyun# Same as above, but use IPv6 transport from A to B 157*4882a593Smuzhiyun# 158*4882a593Smuzhiyun# - list_flush_ipv4_exception 159*4882a593Smuzhiyun# Using the same topology as in pmtu_ipv4, create exceptions, and check 160*4882a593Smuzhiyun# they are shown when listing exception caches, gone after flushing them 161*4882a593Smuzhiyun# 162*4882a593Smuzhiyun# - list_flush_ipv6_exception 163*4882a593Smuzhiyun# Using the same topology as in pmtu_ipv6, create exceptions, and check 164*4882a593Smuzhiyun# they are shown when listing exception caches, gone after flushing them 165*4882a593Smuzhiyun# 166*4882a593Smuzhiyun# - pmtu_ipv4_route_change 167*4882a593Smuzhiyun# Use the same topology as in pmtu_ipv4, but issue a route replacement 168*4882a593Smuzhiyun# command and delete the corresponding device afterward. This tests for 169*4882a593Smuzhiyun# proper cleanup of the PMTU exceptions by the route replacement path. 170*4882a593Smuzhiyun# Device unregistration should complete successfully 171*4882a593Smuzhiyun# 172*4882a593Smuzhiyun# - pmtu_ipv6_route_change 173*4882a593Smuzhiyun# Same as above but with IPv6 174*4882a593Smuzhiyun 175*4882a593Smuzhiyun# Kselftest framework requirement - SKIP code is 4. 176*4882a593Smuzhiyunksft_skip=4 177*4882a593Smuzhiyun 178*4882a593SmuzhiyunPAUSE_ON_FAIL=no 179*4882a593SmuzhiyunVERBOSE=0 180*4882a593SmuzhiyunTRACING=0 181*4882a593Smuzhiyun 182*4882a593Smuzhiyun# Some systems don't have a ping6 binary anymore 183*4882a593Smuzhiyunwhich ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping) 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun# Name Description re-run with nh 186*4882a593Smuzhiyuntests=" 187*4882a593Smuzhiyun pmtu_ipv4_exception ipv4: PMTU exceptions 1 188*4882a593Smuzhiyun pmtu_ipv6_exception ipv6: PMTU exceptions 1 189*4882a593Smuzhiyun pmtu_ipv4_vxlan4_exception IPv4 over vxlan4: PMTU exceptions 1 190*4882a593Smuzhiyun pmtu_ipv6_vxlan4_exception IPv6 over vxlan4: PMTU exceptions 1 191*4882a593Smuzhiyun pmtu_ipv4_vxlan6_exception IPv4 over vxlan6: PMTU exceptions 1 192*4882a593Smuzhiyun pmtu_ipv6_vxlan6_exception IPv6 over vxlan6: PMTU exceptions 1 193*4882a593Smuzhiyun pmtu_ipv4_geneve4_exception IPv4 over geneve4: PMTU exceptions 1 194*4882a593Smuzhiyun pmtu_ipv6_geneve4_exception IPv6 over geneve4: PMTU exceptions 1 195*4882a593Smuzhiyun pmtu_ipv4_geneve6_exception IPv4 over geneve6: PMTU exceptions 1 196*4882a593Smuzhiyun pmtu_ipv6_geneve6_exception IPv6 over geneve6: PMTU exceptions 1 197*4882a593Smuzhiyun pmtu_ipv4_br_vxlan4_exception IPv4, bridged vxlan4: PMTU exceptions 1 198*4882a593Smuzhiyun pmtu_ipv6_br_vxlan4_exception IPv6, bridged vxlan4: PMTU exceptions 1 199*4882a593Smuzhiyun pmtu_ipv4_br_vxlan6_exception IPv4, bridged vxlan6: PMTU exceptions 1 200*4882a593Smuzhiyun pmtu_ipv6_br_vxlan6_exception IPv6, bridged vxlan6: PMTU exceptions 1 201*4882a593Smuzhiyun pmtu_ipv4_br_geneve4_exception IPv4, bridged geneve4: PMTU exceptions 1 202*4882a593Smuzhiyun pmtu_ipv6_br_geneve4_exception IPv6, bridged geneve4: PMTU exceptions 1 203*4882a593Smuzhiyun pmtu_ipv4_br_geneve6_exception IPv4, bridged geneve6: PMTU exceptions 1 204*4882a593Smuzhiyun pmtu_ipv6_br_geneve6_exception IPv6, bridged geneve6: PMTU exceptions 1 205*4882a593Smuzhiyun pmtu_ipv4_ovs_vxlan4_exception IPv4, OVS vxlan4: PMTU exceptions 1 206*4882a593Smuzhiyun pmtu_ipv6_ovs_vxlan4_exception IPv6, OVS vxlan4: PMTU exceptions 1 207*4882a593Smuzhiyun pmtu_ipv4_ovs_vxlan6_exception IPv4, OVS vxlan6: PMTU exceptions 1 208*4882a593Smuzhiyun pmtu_ipv6_ovs_vxlan6_exception IPv6, OVS vxlan6: PMTU exceptions 1 209*4882a593Smuzhiyun pmtu_ipv4_ovs_geneve4_exception IPv4, OVS geneve4: PMTU exceptions 1 210*4882a593Smuzhiyun pmtu_ipv6_ovs_geneve4_exception IPv6, OVS geneve4: PMTU exceptions 1 211*4882a593Smuzhiyun pmtu_ipv4_ovs_geneve6_exception IPv4, OVS geneve6: PMTU exceptions 1 212*4882a593Smuzhiyun pmtu_ipv6_ovs_geneve6_exception IPv6, OVS geneve6: PMTU exceptions 1 213*4882a593Smuzhiyun pmtu_ipv4_fou4_exception IPv4 over fou4: PMTU exceptions 1 214*4882a593Smuzhiyun pmtu_ipv6_fou4_exception IPv6 over fou4: PMTU exceptions 1 215*4882a593Smuzhiyun pmtu_ipv4_fou6_exception IPv4 over fou6: PMTU exceptions 1 216*4882a593Smuzhiyun pmtu_ipv6_fou6_exception IPv6 over fou6: PMTU exceptions 1 217*4882a593Smuzhiyun pmtu_ipv4_gue4_exception IPv4 over gue4: PMTU exceptions 1 218*4882a593Smuzhiyun pmtu_ipv6_gue4_exception IPv6 over gue4: PMTU exceptions 1 219*4882a593Smuzhiyun pmtu_ipv4_gue6_exception IPv4 over gue6: PMTU exceptions 1 220*4882a593Smuzhiyun pmtu_ipv6_gue6_exception IPv6 over gue6: PMTU exceptions 1 221*4882a593Smuzhiyun pmtu_ipv4_ipv4_exception IPv4 over IPv4: PMTU exceptions 1 222*4882a593Smuzhiyun pmtu_ipv6_ipv4_exception IPv6 over IPv4: PMTU exceptions 1 223*4882a593Smuzhiyun pmtu_ipv4_ipv6_exception IPv4 over IPv6: PMTU exceptions 1 224*4882a593Smuzhiyun pmtu_ipv6_ipv6_exception IPv6 over IPv6: PMTU exceptions 1 225*4882a593Smuzhiyun pmtu_vti6_exception vti6: PMTU exceptions 0 226*4882a593Smuzhiyun pmtu_vti4_exception vti4: PMTU exceptions 0 227*4882a593Smuzhiyun pmtu_vti4_default_mtu vti4: default MTU assignment 0 228*4882a593Smuzhiyun pmtu_vti6_default_mtu vti6: default MTU assignment 0 229*4882a593Smuzhiyun pmtu_vti4_link_add_mtu vti4: MTU setting on link creation 0 230*4882a593Smuzhiyun pmtu_vti6_link_add_mtu vti6: MTU setting on link creation 0 231*4882a593Smuzhiyun pmtu_vti6_link_change_mtu vti6: MTU changes on link changes 0 232*4882a593Smuzhiyun cleanup_ipv4_exception ipv4: cleanup of cached exceptions 1 233*4882a593Smuzhiyun cleanup_ipv6_exception ipv6: cleanup of cached exceptions 1 234*4882a593Smuzhiyun list_flush_ipv4_exception ipv4: list and flush cached exceptions 1 235*4882a593Smuzhiyun list_flush_ipv6_exception ipv6: list and flush cached exceptions 1 236*4882a593Smuzhiyun pmtu_ipv4_route_change ipv4: PMTU exception w/route replace 1 237*4882a593Smuzhiyun pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1" 238*4882a593Smuzhiyun 239*4882a593SmuzhiyunNS_A="ns-A" 240*4882a593SmuzhiyunNS_B="ns-B" 241*4882a593SmuzhiyunNS_C="ns-C" 242*4882a593SmuzhiyunNS_R1="ns-R1" 243*4882a593SmuzhiyunNS_R2="ns-R2" 244*4882a593Smuzhiyunns_a="ip netns exec ${NS_A}" 245*4882a593Smuzhiyunns_b="ip netns exec ${NS_B}" 246*4882a593Smuzhiyunns_c="ip netns exec ${NS_C}" 247*4882a593Smuzhiyunns_r1="ip netns exec ${NS_R1}" 248*4882a593Smuzhiyunns_r2="ip netns exec ${NS_R2}" 249*4882a593Smuzhiyun 250*4882a593Smuzhiyun# Addressing and routing for tests with routers: four network segments, with 251*4882a593Smuzhiyun# index SEGMENT between 1 and 4, a common prefix (PREFIX4 or PREFIX6) and an 252*4882a593Smuzhiyun# identifier ID, which is 1 for hosts (A and B), 2 for routers (R1 and R2). 253*4882a593Smuzhiyun# Addresses are: 254*4882a593Smuzhiyun# - IPv4: PREFIX4.SEGMENT.ID (/24) 255*4882a593Smuzhiyun# - IPv6: PREFIX6:SEGMENT::ID (/64) 256*4882a593Smuzhiyunprefix4="10.0" 257*4882a593Smuzhiyunprefix6="fc00" 258*4882a593Smuzhiyuna_r1=1 259*4882a593Smuzhiyuna_r2=2 260*4882a593Smuzhiyunb_r1=3 261*4882a593Smuzhiyunb_r2=4 262*4882a593Smuzhiyun# ns peer segment 263*4882a593Smuzhiyunrouting_addrs=" 264*4882a593Smuzhiyun A R1 ${a_r1} 265*4882a593Smuzhiyun A R2 ${a_r2} 266*4882a593Smuzhiyun B R1 ${b_r1} 267*4882a593Smuzhiyun B R2 ${b_r2} 268*4882a593Smuzhiyun" 269*4882a593Smuzhiyun# Traffic from A to B goes through R1 by default, and through R2, if destined to 270*4882a593Smuzhiyun# B's address on the b_r2 segment. 271*4882a593Smuzhiyun# Traffic from B to A goes through R1. 272*4882a593Smuzhiyun# ns destination gateway 273*4882a593Smuzhiyunroutes=" 274*4882a593Smuzhiyun A default ${prefix4}.${a_r1}.2 275*4882a593Smuzhiyun A ${prefix4}.${b_r2}.1 ${prefix4}.${a_r2}.2 276*4882a593Smuzhiyun B default ${prefix4}.${b_r1}.2 277*4882a593Smuzhiyun 278*4882a593Smuzhiyun A default ${prefix6}:${a_r1}::2 279*4882a593Smuzhiyun A ${prefix6}:${b_r2}::1 ${prefix6}:${a_r2}::2 280*4882a593Smuzhiyun B default ${prefix6}:${b_r1}::2 281*4882a593Smuzhiyun" 282*4882a593Smuzhiyun 283*4882a593SmuzhiyunUSE_NH="no" 284*4882a593Smuzhiyun# ns family nh id destination gateway 285*4882a593Smuzhiyunnexthops=" 286*4882a593Smuzhiyun A 4 41 ${prefix4}.${a_r1}.2 veth_A-R1 287*4882a593Smuzhiyun A 4 42 ${prefix4}.${a_r2}.2 veth_A-R2 288*4882a593Smuzhiyun B 4 41 ${prefix4}.${b_r1}.2 veth_B-R1 289*4882a593Smuzhiyun 290*4882a593Smuzhiyun A 6 61 ${prefix6}:${a_r1}::2 veth_A-R1 291*4882a593Smuzhiyun A 6 62 ${prefix6}:${a_r2}::2 veth_A-R2 292*4882a593Smuzhiyun B 6 61 ${prefix6}:${b_r1}::2 veth_B-R1 293*4882a593Smuzhiyun" 294*4882a593Smuzhiyun 295*4882a593Smuzhiyun# nexthop id correlates to id in nexthops config above 296*4882a593Smuzhiyun# ns family prefix nh id 297*4882a593Smuzhiyunroutes_nh=" 298*4882a593Smuzhiyun A 4 default 41 299*4882a593Smuzhiyun A 4 ${prefix4}.${b_r2}.1 42 300*4882a593Smuzhiyun B 4 default 41 301*4882a593Smuzhiyun 302*4882a593Smuzhiyun A 6 default 61 303*4882a593Smuzhiyun A 6 ${prefix6}:${b_r2}::1 62 304*4882a593Smuzhiyun B 6 default 61 305*4882a593Smuzhiyun" 306*4882a593Smuzhiyun 307*4882a593Smuzhiyunveth4_a_addr="192.168.1.1" 308*4882a593Smuzhiyunveth4_b_addr="192.168.1.2" 309*4882a593Smuzhiyunveth4_c_addr="192.168.2.10" 310*4882a593Smuzhiyunveth4_mask="24" 311*4882a593Smuzhiyunveth6_a_addr="fd00:1::a" 312*4882a593Smuzhiyunveth6_b_addr="fd00:1::b" 313*4882a593Smuzhiyunveth6_c_addr="fd00:2::c" 314*4882a593Smuzhiyunveth6_mask="64" 315*4882a593Smuzhiyun 316*4882a593Smuzhiyuntunnel4_a_addr="192.168.2.1" 317*4882a593Smuzhiyuntunnel4_b_addr="192.168.2.2" 318*4882a593Smuzhiyuntunnel4_mask="24" 319*4882a593Smuzhiyuntunnel6_a_addr="fd00:2::a" 320*4882a593Smuzhiyuntunnel6_b_addr="fd00:2::b" 321*4882a593Smuzhiyuntunnel6_mask="64" 322*4882a593Smuzhiyun 323*4882a593Smuzhiyundummy6_0_prefix="fc00:1000::" 324*4882a593Smuzhiyundummy6_1_prefix="fc00:1001::" 325*4882a593Smuzhiyundummy6_mask="64" 326*4882a593Smuzhiyun 327*4882a593Smuzhiyunerr_buf= 328*4882a593Smuzhiyuntcpdump_pids= 329*4882a593Smuzhiyun 330*4882a593Smuzhiyunerr() { 331*4882a593Smuzhiyun err_buf="${err_buf}${1} 332*4882a593Smuzhiyun" 333*4882a593Smuzhiyun} 334*4882a593Smuzhiyun 335*4882a593Smuzhiyunerr_flush() { 336*4882a593Smuzhiyun echo -n "${err_buf}" 337*4882a593Smuzhiyun err_buf= 338*4882a593Smuzhiyun} 339*4882a593Smuzhiyun 340*4882a593Smuzhiyunrun_cmd() { 341*4882a593Smuzhiyun cmd="$*" 342*4882a593Smuzhiyun 343*4882a593Smuzhiyun if [ "$VERBOSE" = "1" ]; then 344*4882a593Smuzhiyun printf " COMMAND: $cmd\n" 345*4882a593Smuzhiyun fi 346*4882a593Smuzhiyun 347*4882a593Smuzhiyun out="$($cmd 2>&1)" 348*4882a593Smuzhiyun rc=$? 349*4882a593Smuzhiyun if [ "$VERBOSE" = "1" -a -n "$out" ]; then 350*4882a593Smuzhiyun echo " $out" 351*4882a593Smuzhiyun echo 352*4882a593Smuzhiyun fi 353*4882a593Smuzhiyun 354*4882a593Smuzhiyun return $rc 355*4882a593Smuzhiyun} 356*4882a593Smuzhiyun 357*4882a593Smuzhiyun# Find the auto-generated name for this namespace 358*4882a593Smuzhiyunnsname() { 359*4882a593Smuzhiyun eval echo \$NS_$1 360*4882a593Smuzhiyun} 361*4882a593Smuzhiyun 362*4882a593Smuzhiyunsetup_fou_or_gue() { 363*4882a593Smuzhiyun outer="${1}" 364*4882a593Smuzhiyun inner="${2}" 365*4882a593Smuzhiyun encap="${3}" 366*4882a593Smuzhiyun 367*4882a593Smuzhiyun if [ "${outer}" = "4" ]; then 368*4882a593Smuzhiyun modprobe fou || return 2 369*4882a593Smuzhiyun a_addr="${prefix4}.${a_r1}.1" 370*4882a593Smuzhiyun b_addr="${prefix4}.${b_r1}.1" 371*4882a593Smuzhiyun if [ "${inner}" = "4" ]; then 372*4882a593Smuzhiyun type="ipip" 373*4882a593Smuzhiyun ipproto="4" 374*4882a593Smuzhiyun else 375*4882a593Smuzhiyun type="sit" 376*4882a593Smuzhiyun ipproto="41" 377*4882a593Smuzhiyun fi 378*4882a593Smuzhiyun else 379*4882a593Smuzhiyun modprobe fou6 || return 2 380*4882a593Smuzhiyun a_addr="${prefix6}:${a_r1}::1" 381*4882a593Smuzhiyun b_addr="${prefix6}:${b_r1}::1" 382*4882a593Smuzhiyun if [ "${inner}" = "4" ]; then 383*4882a593Smuzhiyun type="ip6tnl" 384*4882a593Smuzhiyun mode="mode ipip6" 385*4882a593Smuzhiyun ipproto="4 -6" 386*4882a593Smuzhiyun else 387*4882a593Smuzhiyun type="ip6tnl" 388*4882a593Smuzhiyun mode="mode ip6ip6" 389*4882a593Smuzhiyun ipproto="41 -6" 390*4882a593Smuzhiyun fi 391*4882a593Smuzhiyun fi 392*4882a593Smuzhiyun 393*4882a593Smuzhiyun run_cmd ${ns_a} ip fou add port 5555 ipproto ${ipproto} || return 2 394*4882a593Smuzhiyun run_cmd ${ns_a} ip link add ${encap}_a type ${type} ${mode} local ${a_addr} remote ${b_addr} encap ${encap} encap-sport auto encap-dport 5556 || return 2 395*4882a593Smuzhiyun 396*4882a593Smuzhiyun run_cmd ${ns_b} ip fou add port 5556 ipproto ${ipproto} 397*4882a593Smuzhiyun run_cmd ${ns_b} ip link add ${encap}_b type ${type} ${mode} local ${b_addr} remote ${a_addr} encap ${encap} encap-sport auto encap-dport 5555 398*4882a593Smuzhiyun 399*4882a593Smuzhiyun if [ "${inner}" = "4" ]; then 400*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${tunnel4_a_addr}/${tunnel4_mask} dev ${encap}_a 401*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${encap}_b 402*4882a593Smuzhiyun else 403*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${tunnel6_a_addr}/${tunnel6_mask} dev ${encap}_a 404*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${encap}_b 405*4882a593Smuzhiyun fi 406*4882a593Smuzhiyun 407*4882a593Smuzhiyun run_cmd ${ns_a} ip link set ${encap}_a up 408*4882a593Smuzhiyun run_cmd ${ns_b} ip link set ${encap}_b up 409*4882a593Smuzhiyun} 410*4882a593Smuzhiyun 411*4882a593Smuzhiyunsetup_fou44() { 412*4882a593Smuzhiyun setup_fou_or_gue 4 4 fou 413*4882a593Smuzhiyun} 414*4882a593Smuzhiyun 415*4882a593Smuzhiyunsetup_fou46() { 416*4882a593Smuzhiyun setup_fou_or_gue 4 6 fou 417*4882a593Smuzhiyun} 418*4882a593Smuzhiyun 419*4882a593Smuzhiyunsetup_fou64() { 420*4882a593Smuzhiyun setup_fou_or_gue 6 4 fou 421*4882a593Smuzhiyun} 422*4882a593Smuzhiyun 423*4882a593Smuzhiyunsetup_fou66() { 424*4882a593Smuzhiyun setup_fou_or_gue 6 6 fou 425*4882a593Smuzhiyun} 426*4882a593Smuzhiyun 427*4882a593Smuzhiyunsetup_gue44() { 428*4882a593Smuzhiyun setup_fou_or_gue 4 4 gue 429*4882a593Smuzhiyun} 430*4882a593Smuzhiyun 431*4882a593Smuzhiyunsetup_gue46() { 432*4882a593Smuzhiyun setup_fou_or_gue 4 6 gue 433*4882a593Smuzhiyun} 434*4882a593Smuzhiyun 435*4882a593Smuzhiyunsetup_gue64() { 436*4882a593Smuzhiyun setup_fou_or_gue 6 4 gue 437*4882a593Smuzhiyun} 438*4882a593Smuzhiyun 439*4882a593Smuzhiyunsetup_gue66() { 440*4882a593Smuzhiyun setup_fou_or_gue 6 6 gue 441*4882a593Smuzhiyun} 442*4882a593Smuzhiyun 443*4882a593Smuzhiyunsetup_ipvX_over_ipvY() { 444*4882a593Smuzhiyun inner=${1} 445*4882a593Smuzhiyun outer=${2} 446*4882a593Smuzhiyun 447*4882a593Smuzhiyun if [ "${outer}" -eq 4 ]; then 448*4882a593Smuzhiyun a_addr="${prefix4}.${a_r1}.1" 449*4882a593Smuzhiyun b_addr="${prefix4}.${b_r1}.1" 450*4882a593Smuzhiyun if [ "${inner}" -eq 4 ]; then 451*4882a593Smuzhiyun type="ipip" 452*4882a593Smuzhiyun mode="ipip" 453*4882a593Smuzhiyun else 454*4882a593Smuzhiyun type="sit" 455*4882a593Smuzhiyun mode="ip6ip" 456*4882a593Smuzhiyun fi 457*4882a593Smuzhiyun else 458*4882a593Smuzhiyun a_addr="${prefix6}:${a_r1}::1" 459*4882a593Smuzhiyun b_addr="${prefix6}:${b_r1}::1" 460*4882a593Smuzhiyun type="ip6tnl" 461*4882a593Smuzhiyun if [ "${inner}" -eq 4 ]; then 462*4882a593Smuzhiyun mode="ipip6" 463*4882a593Smuzhiyun else 464*4882a593Smuzhiyun mode="ip6ip6" 465*4882a593Smuzhiyun fi 466*4882a593Smuzhiyun fi 467*4882a593Smuzhiyun 468*4882a593Smuzhiyun run_cmd ${ns_a} ip link add ip_a type ${type} local ${a_addr} remote ${b_addr} mode ${mode} || return 2 469*4882a593Smuzhiyun run_cmd ${ns_b} ip link add ip_b type ${type} local ${b_addr} remote ${a_addr} mode ${mode} 470*4882a593Smuzhiyun 471*4882a593Smuzhiyun run_cmd ${ns_a} ip link set ip_a up 472*4882a593Smuzhiyun run_cmd ${ns_b} ip link set ip_b up 473*4882a593Smuzhiyun 474*4882a593Smuzhiyun if [ "${inner}" = "4" ]; then 475*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${tunnel4_a_addr}/${tunnel4_mask} dev ip_a 476*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ip_b 477*4882a593Smuzhiyun else 478*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${tunnel6_a_addr}/${tunnel6_mask} dev ip_a 479*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ip_b 480*4882a593Smuzhiyun fi 481*4882a593Smuzhiyun} 482*4882a593Smuzhiyun 483*4882a593Smuzhiyunsetup_ip4ip4() { 484*4882a593Smuzhiyun setup_ipvX_over_ipvY 4 4 485*4882a593Smuzhiyun} 486*4882a593Smuzhiyun 487*4882a593Smuzhiyunsetup_ip6ip4() { 488*4882a593Smuzhiyun setup_ipvX_over_ipvY 6 4 489*4882a593Smuzhiyun} 490*4882a593Smuzhiyun 491*4882a593Smuzhiyunsetup_ip4ip6() { 492*4882a593Smuzhiyun setup_ipvX_over_ipvY 4 6 493*4882a593Smuzhiyun} 494*4882a593Smuzhiyun 495*4882a593Smuzhiyunsetup_ip6ip6() { 496*4882a593Smuzhiyun setup_ipvX_over_ipvY 6 6 497*4882a593Smuzhiyun} 498*4882a593Smuzhiyun 499*4882a593Smuzhiyunsetup_namespaces() { 500*4882a593Smuzhiyun for n in ${NS_A} ${NS_B} ${NS_C} ${NS_R1} ${NS_R2}; do 501*4882a593Smuzhiyun ip netns add ${n} || return 1 502*4882a593Smuzhiyun 503*4882a593Smuzhiyun # Disable DAD, so that we don't have to wait to use the 504*4882a593Smuzhiyun # configured IPv6 addresses 505*4882a593Smuzhiyun ip netns exec ${n} sysctl -q net/ipv6/conf/default/accept_dad=0 506*4882a593Smuzhiyun done 507*4882a593Smuzhiyun} 508*4882a593Smuzhiyun 509*4882a593Smuzhiyunsetup_veth() { 510*4882a593Smuzhiyun run_cmd ${ns_a} ip link add veth_a type veth peer name veth_b || return 1 511*4882a593Smuzhiyun run_cmd ${ns_a} ip link set veth_b netns ${NS_B} 512*4882a593Smuzhiyun 513*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${veth4_a_addr}/${veth4_mask} dev veth_a 514*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${veth4_b_addr}/${veth4_mask} dev veth_b 515*4882a593Smuzhiyun 516*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${veth6_a_addr}/${veth6_mask} dev veth_a 517*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${veth6_b_addr}/${veth6_mask} dev veth_b 518*4882a593Smuzhiyun 519*4882a593Smuzhiyun run_cmd ${ns_a} ip link set veth_a up 520*4882a593Smuzhiyun run_cmd ${ns_b} ip link set veth_b up 521*4882a593Smuzhiyun} 522*4882a593Smuzhiyun 523*4882a593Smuzhiyunsetup_vti() { 524*4882a593Smuzhiyun proto=${1} 525*4882a593Smuzhiyun veth_a_addr="${2}" 526*4882a593Smuzhiyun veth_b_addr="${3}" 527*4882a593Smuzhiyun vti_a_addr="${4}" 528*4882a593Smuzhiyun vti_b_addr="${5}" 529*4882a593Smuzhiyun vti_mask=${6} 530*4882a593Smuzhiyun 531*4882a593Smuzhiyun [ ${proto} -eq 6 ] && vti_type="vti6" || vti_type="vti" 532*4882a593Smuzhiyun 533*4882a593Smuzhiyun run_cmd ${ns_a} ip link add vti${proto}_a type ${vti_type} local ${veth_a_addr} remote ${veth_b_addr} key 10 || return 1 534*4882a593Smuzhiyun run_cmd ${ns_b} ip link add vti${proto}_b type ${vti_type} local ${veth_b_addr} remote ${veth_a_addr} key 10 535*4882a593Smuzhiyun 536*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${vti_a_addr}/${vti_mask} dev vti${proto}_a 537*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${vti_b_addr}/${vti_mask} dev vti${proto}_b 538*4882a593Smuzhiyun 539*4882a593Smuzhiyun run_cmd ${ns_a} ip link set vti${proto}_a up 540*4882a593Smuzhiyun run_cmd ${ns_b} ip link set vti${proto}_b up 541*4882a593Smuzhiyun} 542*4882a593Smuzhiyun 543*4882a593Smuzhiyunsetup_vti4() { 544*4882a593Smuzhiyun setup_vti 4 ${veth4_a_addr} ${veth4_b_addr} ${tunnel4_a_addr} ${tunnel4_b_addr} ${tunnel4_mask} 545*4882a593Smuzhiyun} 546*4882a593Smuzhiyun 547*4882a593Smuzhiyunsetup_vti6() { 548*4882a593Smuzhiyun setup_vti 6 ${veth6_a_addr} ${veth6_b_addr} ${tunnel6_a_addr} ${tunnel6_b_addr} ${tunnel6_mask} 549*4882a593Smuzhiyun} 550*4882a593Smuzhiyun 551*4882a593Smuzhiyunsetup_vxlan_or_geneve() { 552*4882a593Smuzhiyun type="${1}" 553*4882a593Smuzhiyun a_addr="${2}" 554*4882a593Smuzhiyun b_addr="${3}" 555*4882a593Smuzhiyun opts="${4}" 556*4882a593Smuzhiyun br_if_a="${5}" 557*4882a593Smuzhiyun 558*4882a593Smuzhiyun if [ "${type}" = "vxlan" ]; then 559*4882a593Smuzhiyun opts="${opts} ttl 64 dstport 4789" 560*4882a593Smuzhiyun opts_a="local ${a_addr}" 561*4882a593Smuzhiyun opts_b="local ${b_addr}" 562*4882a593Smuzhiyun else 563*4882a593Smuzhiyun opts_a="" 564*4882a593Smuzhiyun opts_b="" 565*4882a593Smuzhiyun fi 566*4882a593Smuzhiyun 567*4882a593Smuzhiyun run_cmd ${ns_a} ip link add ${type}_a type ${type} id 1 ${opts_a} remote ${b_addr} ${opts} || return 1 568*4882a593Smuzhiyun run_cmd ${ns_b} ip link add ${type}_b type ${type} id 1 ${opts_b} remote ${a_addr} ${opts} 569*4882a593Smuzhiyun 570*4882a593Smuzhiyun if [ -n "${br_if_a}" ]; then 571*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${tunnel4_a_addr}/${tunnel4_mask} dev ${br_if_a} 572*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${tunnel6_a_addr}/${tunnel6_mask} dev ${br_if_a} 573*4882a593Smuzhiyun run_cmd ${ns_a} ip link set ${type}_a master ${br_if_a} 574*4882a593Smuzhiyun else 575*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${tunnel4_a_addr}/${tunnel4_mask} dev ${type}_a 576*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${tunnel6_a_addr}/${tunnel6_mask} dev ${type}_a 577*4882a593Smuzhiyun fi 578*4882a593Smuzhiyun 579*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${type}_b 580*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${type}_b 581*4882a593Smuzhiyun 582*4882a593Smuzhiyun run_cmd ${ns_a} ip link set ${type}_a up 583*4882a593Smuzhiyun run_cmd ${ns_b} ip link set ${type}_b up 584*4882a593Smuzhiyun} 585*4882a593Smuzhiyun 586*4882a593Smuzhiyunsetup_geneve4() { 587*4882a593Smuzhiyun setup_vxlan_or_geneve geneve ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "df set" 588*4882a593Smuzhiyun} 589*4882a593Smuzhiyun 590*4882a593Smuzhiyunsetup_vxlan4() { 591*4882a593Smuzhiyun setup_vxlan_or_geneve vxlan ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "df set" 592*4882a593Smuzhiyun} 593*4882a593Smuzhiyun 594*4882a593Smuzhiyunsetup_geneve6() { 595*4882a593Smuzhiyun setup_vxlan_or_geneve geneve ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "" 596*4882a593Smuzhiyun} 597*4882a593Smuzhiyun 598*4882a593Smuzhiyunsetup_vxlan6() { 599*4882a593Smuzhiyun setup_vxlan_or_geneve vxlan ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "" 600*4882a593Smuzhiyun} 601*4882a593Smuzhiyun 602*4882a593Smuzhiyunsetup_bridged_geneve4() { 603*4882a593Smuzhiyun setup_vxlan_or_geneve geneve ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "df set" "br0" 604*4882a593Smuzhiyun} 605*4882a593Smuzhiyun 606*4882a593Smuzhiyunsetup_bridged_vxlan4() { 607*4882a593Smuzhiyun setup_vxlan_or_geneve vxlan ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "df set" "br0" 608*4882a593Smuzhiyun} 609*4882a593Smuzhiyun 610*4882a593Smuzhiyunsetup_bridged_geneve6() { 611*4882a593Smuzhiyun setup_vxlan_or_geneve geneve ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "" "br0" 612*4882a593Smuzhiyun} 613*4882a593Smuzhiyun 614*4882a593Smuzhiyunsetup_bridged_vxlan6() { 615*4882a593Smuzhiyun setup_vxlan_or_geneve vxlan ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "" "br0" 616*4882a593Smuzhiyun} 617*4882a593Smuzhiyun 618*4882a593Smuzhiyunsetup_xfrm() { 619*4882a593Smuzhiyun proto=${1} 620*4882a593Smuzhiyun veth_a_addr="${2}" 621*4882a593Smuzhiyun veth_b_addr="${3}" 622*4882a593Smuzhiyun 623*4882a593Smuzhiyun run_cmd ${ns_a} ip -${proto} xfrm state add src ${veth_a_addr} dst ${veth_b_addr} spi 0x1000 proto esp aead 'rfc4106(gcm(aes))' 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel || return 1 624*4882a593Smuzhiyun run_cmd ${ns_a} ip -${proto} xfrm state add src ${veth_b_addr} dst ${veth_a_addr} spi 0x1001 proto esp aead 'rfc4106(gcm(aes))' 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel 625*4882a593Smuzhiyun run_cmd ${ns_a} ip -${proto} xfrm policy add dir out mark 10 tmpl src ${veth_a_addr} dst ${veth_b_addr} proto esp mode tunnel 626*4882a593Smuzhiyun run_cmd ${ns_a} ip -${proto} xfrm policy add dir in mark 10 tmpl src ${veth_b_addr} dst ${veth_a_addr} proto esp mode tunnel 627*4882a593Smuzhiyun 628*4882a593Smuzhiyun run_cmd ${ns_b} ip -${proto} xfrm state add src ${veth_a_addr} dst ${veth_b_addr} spi 0x1000 proto esp aead 'rfc4106(gcm(aes))' 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel 629*4882a593Smuzhiyun run_cmd ${ns_b} ip -${proto} xfrm state add src ${veth_b_addr} dst ${veth_a_addr} spi 0x1001 proto esp aead 'rfc4106(gcm(aes))' 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel 630*4882a593Smuzhiyun run_cmd ${ns_b} ip -${proto} xfrm policy add dir out mark 10 tmpl src ${veth_b_addr} dst ${veth_a_addr} proto esp mode tunnel 631*4882a593Smuzhiyun run_cmd ${ns_b} ip -${proto} xfrm policy add dir in mark 10 tmpl src ${veth_a_addr} dst ${veth_b_addr} proto esp mode tunnel 632*4882a593Smuzhiyun} 633*4882a593Smuzhiyun 634*4882a593Smuzhiyunsetup_xfrm4() { 635*4882a593Smuzhiyun setup_xfrm 4 ${veth4_a_addr} ${veth4_b_addr} 636*4882a593Smuzhiyun} 637*4882a593Smuzhiyun 638*4882a593Smuzhiyunsetup_xfrm6() { 639*4882a593Smuzhiyun setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr} 640*4882a593Smuzhiyun} 641*4882a593Smuzhiyun 642*4882a593Smuzhiyunsetup_routing_old() { 643*4882a593Smuzhiyun for i in ${routes}; do 644*4882a593Smuzhiyun [ "${ns}" = "" ] && ns="${i}" && continue 645*4882a593Smuzhiyun [ "${addr}" = "" ] && addr="${i}" && continue 646*4882a593Smuzhiyun [ "${gw}" = "" ] && gw="${i}" 647*4882a593Smuzhiyun 648*4882a593Smuzhiyun ns_name="$(nsname ${ns})" 649*4882a593Smuzhiyun 650*4882a593Smuzhiyun ip -n ${ns_name} route add ${addr} via ${gw} 651*4882a593Smuzhiyun 652*4882a593Smuzhiyun ns=""; addr=""; gw="" 653*4882a593Smuzhiyun done 654*4882a593Smuzhiyun} 655*4882a593Smuzhiyun 656*4882a593Smuzhiyunsetup_routing_new() { 657*4882a593Smuzhiyun for i in ${nexthops}; do 658*4882a593Smuzhiyun [ "${ns}" = "" ] && ns="${i}" && continue 659*4882a593Smuzhiyun [ "${fam}" = "" ] && fam="${i}" && continue 660*4882a593Smuzhiyun [ "${nhid}" = "" ] && nhid="${i}" && continue 661*4882a593Smuzhiyun [ "${gw}" = "" ] && gw="${i}" && continue 662*4882a593Smuzhiyun [ "${dev}" = "" ] && dev="${i}" 663*4882a593Smuzhiyun 664*4882a593Smuzhiyun ns_name="$(nsname ${ns})" 665*4882a593Smuzhiyun 666*4882a593Smuzhiyun ip -n ${ns_name} -${fam} nexthop add id ${nhid} via ${gw} dev ${dev} 667*4882a593Smuzhiyun 668*4882a593Smuzhiyun ns=""; fam=""; nhid=""; gw=""; dev="" 669*4882a593Smuzhiyun 670*4882a593Smuzhiyun done 671*4882a593Smuzhiyun 672*4882a593Smuzhiyun for i in ${routes_nh}; do 673*4882a593Smuzhiyun [ "${ns}" = "" ] && ns="${i}" && continue 674*4882a593Smuzhiyun [ "${fam}" = "" ] && fam="${i}" && continue 675*4882a593Smuzhiyun [ "${addr}" = "" ] && addr="${i}" && continue 676*4882a593Smuzhiyun [ "${nhid}" = "" ] && nhid="${i}" 677*4882a593Smuzhiyun 678*4882a593Smuzhiyun ns_name="$(nsname ${ns})" 679*4882a593Smuzhiyun 680*4882a593Smuzhiyun ip -n ${ns_name} -${fam} route add ${addr} nhid ${nhid} 681*4882a593Smuzhiyun 682*4882a593Smuzhiyun ns=""; fam=""; addr=""; nhid="" 683*4882a593Smuzhiyun done 684*4882a593Smuzhiyun} 685*4882a593Smuzhiyun 686*4882a593Smuzhiyunsetup_routing() { 687*4882a593Smuzhiyun for i in ${NS_R1} ${NS_R2}; do 688*4882a593Smuzhiyun ip netns exec ${i} sysctl -q net/ipv4/ip_forward=1 689*4882a593Smuzhiyun ip netns exec ${i} sysctl -q net/ipv6/conf/all/forwarding=1 690*4882a593Smuzhiyun done 691*4882a593Smuzhiyun 692*4882a593Smuzhiyun for i in ${routing_addrs}; do 693*4882a593Smuzhiyun [ "${ns}" = "" ] && ns="${i}" && continue 694*4882a593Smuzhiyun [ "${peer}" = "" ] && peer="${i}" && continue 695*4882a593Smuzhiyun [ "${segment}" = "" ] && segment="${i}" 696*4882a593Smuzhiyun 697*4882a593Smuzhiyun ns_name="$(nsname ${ns})" 698*4882a593Smuzhiyun peer_name="$(nsname ${peer})" 699*4882a593Smuzhiyun if="veth_${ns}-${peer}" 700*4882a593Smuzhiyun ifpeer="veth_${peer}-${ns}" 701*4882a593Smuzhiyun 702*4882a593Smuzhiyun # Create veth links 703*4882a593Smuzhiyun ip link add ${if} up netns ${ns_name} type veth peer name ${ifpeer} netns ${peer_name} || return 1 704*4882a593Smuzhiyun ip -n ${peer_name} link set dev ${ifpeer} up 705*4882a593Smuzhiyun 706*4882a593Smuzhiyun # Add addresses 707*4882a593Smuzhiyun ip -n ${ns_name} addr add ${prefix4}.${segment}.1/24 dev ${if} 708*4882a593Smuzhiyun ip -n ${ns_name} addr add ${prefix6}:${segment}::1/64 dev ${if} 709*4882a593Smuzhiyun 710*4882a593Smuzhiyun ip -n ${peer_name} addr add ${prefix4}.${segment}.2/24 dev ${ifpeer} 711*4882a593Smuzhiyun ip -n ${peer_name} addr add ${prefix6}:${segment}::2/64 dev ${ifpeer} 712*4882a593Smuzhiyun 713*4882a593Smuzhiyun ns=""; peer=""; segment="" 714*4882a593Smuzhiyun done 715*4882a593Smuzhiyun 716*4882a593Smuzhiyun if [ "$USE_NH" = "yes" ]; then 717*4882a593Smuzhiyun setup_routing_new 718*4882a593Smuzhiyun else 719*4882a593Smuzhiyun setup_routing_old 720*4882a593Smuzhiyun fi 721*4882a593Smuzhiyun 722*4882a593Smuzhiyun return 0 723*4882a593Smuzhiyun} 724*4882a593Smuzhiyun 725*4882a593Smuzhiyunsetup_bridge() { 726*4882a593Smuzhiyun run_cmd ${ns_a} ip link add br0 type bridge || return 2 727*4882a593Smuzhiyun run_cmd ${ns_a} ip link set br0 up 728*4882a593Smuzhiyun 729*4882a593Smuzhiyun run_cmd ${ns_c} ip link add veth_C-A type veth peer name veth_A-C 730*4882a593Smuzhiyun run_cmd ${ns_c} ip link set veth_A-C netns ns-A 731*4882a593Smuzhiyun 732*4882a593Smuzhiyun run_cmd ${ns_a} ip link set veth_A-C up 733*4882a593Smuzhiyun run_cmd ${ns_c} ip link set veth_C-A up 734*4882a593Smuzhiyun run_cmd ${ns_c} ip addr add ${veth4_c_addr}/${veth4_mask} dev veth_C-A 735*4882a593Smuzhiyun run_cmd ${ns_c} ip addr add ${veth6_c_addr}/${veth6_mask} dev veth_C-A 736*4882a593Smuzhiyun run_cmd ${ns_a} ip link set veth_A-C master br0 737*4882a593Smuzhiyun} 738*4882a593Smuzhiyun 739*4882a593Smuzhiyunsetup_ovs_vxlan_or_geneve() { 740*4882a593Smuzhiyun type="${1}" 741*4882a593Smuzhiyun a_addr="${2}" 742*4882a593Smuzhiyun b_addr="${3}" 743*4882a593Smuzhiyun 744*4882a593Smuzhiyun if [ "${type}" = "vxlan" ]; then 745*4882a593Smuzhiyun opts="${opts} ttl 64 dstport 4789" 746*4882a593Smuzhiyun opts_b="local ${b_addr}" 747*4882a593Smuzhiyun fi 748*4882a593Smuzhiyun 749*4882a593Smuzhiyun run_cmd ovs-vsctl add-port ovs_br0 ${type}_a -- \ 750*4882a593Smuzhiyun set interface ${type}_a type=${type} \ 751*4882a593Smuzhiyun options:remote_ip=${b_addr} options:key=1 options:csum=true || return 1 752*4882a593Smuzhiyun 753*4882a593Smuzhiyun run_cmd ${ns_b} ip link add ${type}_b type ${type} id 1 ${opts_b} remote ${a_addr} ${opts} || return 1 754*4882a593Smuzhiyun 755*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${type}_b 756*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${type}_b 757*4882a593Smuzhiyun 758*4882a593Smuzhiyun run_cmd ${ns_b} ip link set ${type}_b up 759*4882a593Smuzhiyun} 760*4882a593Smuzhiyun 761*4882a593Smuzhiyunsetup_ovs_geneve4() { 762*4882a593Smuzhiyun setup_ovs_vxlan_or_geneve geneve ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 763*4882a593Smuzhiyun} 764*4882a593Smuzhiyun 765*4882a593Smuzhiyunsetup_ovs_vxlan4() { 766*4882a593Smuzhiyun setup_ovs_vxlan_or_geneve vxlan ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 767*4882a593Smuzhiyun} 768*4882a593Smuzhiyun 769*4882a593Smuzhiyunsetup_ovs_geneve6() { 770*4882a593Smuzhiyun setup_ovs_vxlan_or_geneve geneve ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 771*4882a593Smuzhiyun} 772*4882a593Smuzhiyun 773*4882a593Smuzhiyunsetup_ovs_vxlan6() { 774*4882a593Smuzhiyun setup_ovs_vxlan_or_geneve vxlan ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 775*4882a593Smuzhiyun} 776*4882a593Smuzhiyun 777*4882a593Smuzhiyunsetup_ovs_bridge() { 778*4882a593Smuzhiyun run_cmd ovs-vsctl add-br ovs_br0 || return 2 779*4882a593Smuzhiyun run_cmd ip link set ovs_br0 up 780*4882a593Smuzhiyun 781*4882a593Smuzhiyun run_cmd ${ns_c} ip link add veth_C-A type veth peer name veth_A-C 782*4882a593Smuzhiyun run_cmd ${ns_c} ip link set veth_A-C netns 1 783*4882a593Smuzhiyun 784*4882a593Smuzhiyun run_cmd ip link set veth_A-C up 785*4882a593Smuzhiyun run_cmd ${ns_c} ip link set veth_C-A up 786*4882a593Smuzhiyun run_cmd ${ns_c} ip addr add ${veth4_c_addr}/${veth4_mask} dev veth_C-A 787*4882a593Smuzhiyun run_cmd ${ns_c} ip addr add ${veth6_c_addr}/${veth6_mask} dev veth_C-A 788*4882a593Smuzhiyun run_cmd ovs-vsctl add-port ovs_br0 veth_A-C 789*4882a593Smuzhiyun 790*4882a593Smuzhiyun # Move veth_A-R1 to init 791*4882a593Smuzhiyun run_cmd ${ns_a} ip link set veth_A-R1 netns 1 792*4882a593Smuzhiyun run_cmd ip addr add ${prefix4}.${a_r1}.1/${veth4_mask} dev veth_A-R1 793*4882a593Smuzhiyun run_cmd ip addr add ${prefix6}:${a_r1}::1/${veth6_mask} dev veth_A-R1 794*4882a593Smuzhiyun run_cmd ip link set veth_A-R1 up 795*4882a593Smuzhiyun run_cmd ip route add ${prefix4}.${b_r1}.1 via ${prefix4}.${a_r1}.2 796*4882a593Smuzhiyun run_cmd ip route add ${prefix6}:${b_r1}::1 via ${prefix6}:${a_r1}::2 797*4882a593Smuzhiyun} 798*4882a593Smuzhiyun 799*4882a593Smuzhiyunsetup() { 800*4882a593Smuzhiyun [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return $ksft_skip 801*4882a593Smuzhiyun 802*4882a593Smuzhiyun for arg do 803*4882a593Smuzhiyun eval setup_${arg} || { echo " ${arg} not supported"; return 1; } 804*4882a593Smuzhiyun done 805*4882a593Smuzhiyun} 806*4882a593Smuzhiyun 807*4882a593Smuzhiyuntrace() { 808*4882a593Smuzhiyun [ $TRACING -eq 0 ] && return 809*4882a593Smuzhiyun 810*4882a593Smuzhiyun for arg do 811*4882a593Smuzhiyun [ "${ns_cmd}" = "" ] && ns_cmd="${arg}" && continue 812*4882a593Smuzhiyun ${ns_cmd} tcpdump --immediate-mode -s 0 -i "${arg}" -w "${name}_${arg}.pcap" 2> /dev/null & 813*4882a593Smuzhiyun tcpdump_pids="${tcpdump_pids} $!" 814*4882a593Smuzhiyun ns_cmd= 815*4882a593Smuzhiyun done 816*4882a593Smuzhiyun sleep 1 817*4882a593Smuzhiyun} 818*4882a593Smuzhiyun 819*4882a593Smuzhiyuncleanup() { 820*4882a593Smuzhiyun for pid in ${tcpdump_pids}; do 821*4882a593Smuzhiyun kill ${pid} 822*4882a593Smuzhiyun done 823*4882a593Smuzhiyun tcpdump_pids= 824*4882a593Smuzhiyun 825*4882a593Smuzhiyun for n in ${NS_A} ${NS_B} ${NS_C} ${NS_R1} ${NS_R2}; do 826*4882a593Smuzhiyun ip netns del ${n} 2> /dev/null 827*4882a593Smuzhiyun done 828*4882a593Smuzhiyun 829*4882a593Smuzhiyun ip link del veth_A-C 2>/dev/null 830*4882a593Smuzhiyun ip link del veth_A-R1 2>/dev/null 831*4882a593Smuzhiyun ovs-vsctl --if-exists del-port vxlan_a 2>/dev/null 832*4882a593Smuzhiyun ovs-vsctl --if-exists del-br ovs_br0 2>/dev/null 833*4882a593Smuzhiyun} 834*4882a593Smuzhiyun 835*4882a593Smuzhiyunmtu() { 836*4882a593Smuzhiyun ns_cmd="${1}" 837*4882a593Smuzhiyun dev="${2}" 838*4882a593Smuzhiyun mtu="${3}" 839*4882a593Smuzhiyun 840*4882a593Smuzhiyun ${ns_cmd} ip link set dev ${dev} mtu ${mtu} 841*4882a593Smuzhiyun} 842*4882a593Smuzhiyun 843*4882a593Smuzhiyunmtu_parse() { 844*4882a593Smuzhiyun input="${1}" 845*4882a593Smuzhiyun 846*4882a593Smuzhiyun next=0 847*4882a593Smuzhiyun for i in ${input}; do 848*4882a593Smuzhiyun [ ${next} -eq 1 -a "${i}" = "lock" ] && next=2 && continue 849*4882a593Smuzhiyun [ ${next} -eq 1 ] && echo "${i}" && return 850*4882a593Smuzhiyun [ ${next} -eq 2 ] && echo "lock ${i}" && return 851*4882a593Smuzhiyun [ "${i}" = "mtu" ] && next=1 852*4882a593Smuzhiyun done 853*4882a593Smuzhiyun} 854*4882a593Smuzhiyun 855*4882a593Smuzhiyunlink_get() { 856*4882a593Smuzhiyun ns_cmd="${1}" 857*4882a593Smuzhiyun name="${2}" 858*4882a593Smuzhiyun 859*4882a593Smuzhiyun ${ns_cmd} ip link show dev "${name}" 860*4882a593Smuzhiyun} 861*4882a593Smuzhiyun 862*4882a593Smuzhiyunlink_get_mtu() { 863*4882a593Smuzhiyun ns_cmd="${1}" 864*4882a593Smuzhiyun name="${2}" 865*4882a593Smuzhiyun 866*4882a593Smuzhiyun mtu_parse "$(link_get "${ns_cmd}" ${name})" 867*4882a593Smuzhiyun} 868*4882a593Smuzhiyun 869*4882a593Smuzhiyunroute_get_dst_exception() { 870*4882a593Smuzhiyun ns_cmd="${1}" 871*4882a593Smuzhiyun dst="${2}" 872*4882a593Smuzhiyun 873*4882a593Smuzhiyun ${ns_cmd} ip route get "${dst}" 874*4882a593Smuzhiyun} 875*4882a593Smuzhiyun 876*4882a593Smuzhiyunroute_get_dst_pmtu_from_exception() { 877*4882a593Smuzhiyun ns_cmd="${1}" 878*4882a593Smuzhiyun dst="${2}" 879*4882a593Smuzhiyun 880*4882a593Smuzhiyun mtu_parse "$(route_get_dst_exception "${ns_cmd}" ${dst})" 881*4882a593Smuzhiyun} 882*4882a593Smuzhiyun 883*4882a593Smuzhiyuncheck_pmtu_value() { 884*4882a593Smuzhiyun expected="${1}" 885*4882a593Smuzhiyun value="${2}" 886*4882a593Smuzhiyun event="${3}" 887*4882a593Smuzhiyun 888*4882a593Smuzhiyun [ "${expected}" = "any" ] && [ -n "${value}" ] && return 0 889*4882a593Smuzhiyun [ "${value}" = "${expected}" ] && return 0 890*4882a593Smuzhiyun [ -z "${value}" ] && err " PMTU exception wasn't created after ${event}" && return 1 891*4882a593Smuzhiyun [ -z "${expected}" ] && err " PMTU exception shouldn't exist after ${event}" && return 1 892*4882a593Smuzhiyun err " found PMTU exception with incorrect MTU ${value}, expected ${expected}, after ${event}" 893*4882a593Smuzhiyun return 1 894*4882a593Smuzhiyun} 895*4882a593Smuzhiyun 896*4882a593Smuzhiyuntest_pmtu_ipvX() { 897*4882a593Smuzhiyun family=${1} 898*4882a593Smuzhiyun 899*4882a593Smuzhiyun setup namespaces routing || return 2 900*4882a593Smuzhiyun trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ 901*4882a593Smuzhiyun "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ 902*4882a593Smuzhiyun "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ 903*4882a593Smuzhiyun "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 904*4882a593Smuzhiyun 905*4882a593Smuzhiyun if [ ${family} -eq 4 ]; then 906*4882a593Smuzhiyun ping=ping 907*4882a593Smuzhiyun dst1="${prefix4}.${b_r1}.1" 908*4882a593Smuzhiyun dst2="${prefix4}.${b_r2}.1" 909*4882a593Smuzhiyun else 910*4882a593Smuzhiyun ping=${ping6} 911*4882a593Smuzhiyun dst1="${prefix6}:${b_r1}::1" 912*4882a593Smuzhiyun dst2="${prefix6}:${b_r2}::1" 913*4882a593Smuzhiyun fi 914*4882a593Smuzhiyun 915*4882a593Smuzhiyun # Set up initial MTU values 916*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 2000 917*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A 2000 918*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B 1400 919*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 1400 920*4882a593Smuzhiyun 921*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R2 2000 922*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-A 2000 923*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-B 1500 924*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R2 1500 925*4882a593Smuzhiyun 926*4882a593Smuzhiyun # Create route exceptions 927*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst1} 928*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst2} 929*4882a593Smuzhiyun 930*4882a593Smuzhiyun # Check that exceptions have been created with the correct PMTU 931*4882a593Smuzhiyun pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})" 932*4882a593Smuzhiyun check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1 933*4882a593Smuzhiyun pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" 934*4882a593Smuzhiyun check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1 935*4882a593Smuzhiyun 936*4882a593Smuzhiyun # Decrease local MTU below PMTU, check for PMTU decrease in route exception 937*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 1300 938*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A 1300 939*4882a593Smuzhiyun pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})" 940*4882a593Smuzhiyun check_pmtu_value "1300" "${pmtu_1}" "decreasing local MTU" || return 1 941*4882a593Smuzhiyun # Second exception shouldn't be modified 942*4882a593Smuzhiyun pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" 943*4882a593Smuzhiyun check_pmtu_value "1500" "${pmtu_2}" "changing local MTU on a link not on this path" || return 1 944*4882a593Smuzhiyun 945*4882a593Smuzhiyun # Increase MTU, check for PMTU increase in route exception 946*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 1700 947*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A 1700 948*4882a593Smuzhiyun pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})" 949*4882a593Smuzhiyun check_pmtu_value "1700" "${pmtu_1}" "increasing local MTU" || return 1 950*4882a593Smuzhiyun # Second exception shouldn't be modified 951*4882a593Smuzhiyun pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" 952*4882a593Smuzhiyun check_pmtu_value "1500" "${pmtu_2}" "changing local MTU on a link not on this path" || return 1 953*4882a593Smuzhiyun 954*4882a593Smuzhiyun # Skip PMTU locking tests for IPv6 955*4882a593Smuzhiyun [ $family -eq 6 ] && return 0 956*4882a593Smuzhiyun 957*4882a593Smuzhiyun # Decrease remote MTU on path via R2, get new exception 958*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-B 400 959*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R2 400 960*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1400 ${dst2} 961*4882a593Smuzhiyun pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" 962*4882a593Smuzhiyun check_pmtu_value "lock 552" "${pmtu_2}" "exceeding MTU, with MTU < min_pmtu" || return 1 963*4882a593Smuzhiyun 964*4882a593Smuzhiyun # Decrease local MTU below PMTU 965*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R2 500 966*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-A 500 967*4882a593Smuzhiyun pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" 968*4882a593Smuzhiyun check_pmtu_value "500" "${pmtu_2}" "decreasing local MTU" || return 1 969*4882a593Smuzhiyun 970*4882a593Smuzhiyun # Increase local MTU 971*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R2 1500 972*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-A 1500 973*4882a593Smuzhiyun pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" 974*4882a593Smuzhiyun check_pmtu_value "1500" "${pmtu_2}" "increasing local MTU" || return 1 975*4882a593Smuzhiyun 976*4882a593Smuzhiyun # Get new exception 977*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1400 ${dst2} 978*4882a593Smuzhiyun pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" 979*4882a593Smuzhiyun check_pmtu_value "lock 552" "${pmtu_2}" "exceeding MTU, with MTU < min_pmtu" || return 1 980*4882a593Smuzhiyun} 981*4882a593Smuzhiyun 982*4882a593Smuzhiyuntest_pmtu_ipv4_exception() { 983*4882a593Smuzhiyun test_pmtu_ipvX 4 984*4882a593Smuzhiyun} 985*4882a593Smuzhiyun 986*4882a593Smuzhiyuntest_pmtu_ipv6_exception() { 987*4882a593Smuzhiyun test_pmtu_ipvX 6 988*4882a593Smuzhiyun} 989*4882a593Smuzhiyun 990*4882a593Smuzhiyuntest_pmtu_ipvX_over_vxlanY_or_geneveY_exception() { 991*4882a593Smuzhiyun type=${1} 992*4882a593Smuzhiyun family=${2} 993*4882a593Smuzhiyun outer_family=${3} 994*4882a593Smuzhiyun ll_mtu=4000 995*4882a593Smuzhiyun 996*4882a593Smuzhiyun if [ ${outer_family} -eq 4 ]; then 997*4882a593Smuzhiyun setup namespaces routing ${type}4 || return 2 998*4882a593Smuzhiyun # IPv4 header UDP header VXLAN/GENEVE header Ethernet header 999*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 20 - 8 - 8 - 14)) 1000*4882a593Smuzhiyun else 1001*4882a593Smuzhiyun setup namespaces routing ${type}6 || return 2 1002*4882a593Smuzhiyun # IPv6 header UDP header VXLAN/GENEVE header Ethernet header 1003*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - 14)) 1004*4882a593Smuzhiyun fi 1005*4882a593Smuzhiyun 1006*4882a593Smuzhiyun trace "${ns_a}" ${type}_a "${ns_b}" ${type}_b \ 1007*4882a593Smuzhiyun "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ 1008*4882a593Smuzhiyun "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B 1009*4882a593Smuzhiyun 1010*4882a593Smuzhiyun if [ ${family} -eq 4 ]; then 1011*4882a593Smuzhiyun ping=ping 1012*4882a593Smuzhiyun dst=${tunnel4_b_addr} 1013*4882a593Smuzhiyun else 1014*4882a593Smuzhiyun ping=${ping6} 1015*4882a593Smuzhiyun dst=${tunnel6_b_addr} 1016*4882a593Smuzhiyun fi 1017*4882a593Smuzhiyun 1018*4882a593Smuzhiyun # Create route exception by exceeding link layer MTU 1019*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000)) 1020*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000)) 1021*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 ${ll_mtu} 1022*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B ${ll_mtu} 1023*4882a593Smuzhiyun 1024*4882a593Smuzhiyun mtu "${ns_a}" ${type}_a $((${ll_mtu} + 1000)) 1025*4882a593Smuzhiyun mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000)) 1026*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst} 1027*4882a593Smuzhiyun 1028*4882a593Smuzhiyun # Check that exception was created 1029*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})" 1030*4882a593Smuzhiyun check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on ${type} interface" 1031*4882a593Smuzhiyun} 1032*4882a593Smuzhiyun 1033*4882a593Smuzhiyuntest_pmtu_ipv4_vxlan4_exception() { 1034*4882a593Smuzhiyun test_pmtu_ipvX_over_vxlanY_or_geneveY_exception vxlan 4 4 1035*4882a593Smuzhiyun} 1036*4882a593Smuzhiyun 1037*4882a593Smuzhiyuntest_pmtu_ipv6_vxlan4_exception() { 1038*4882a593Smuzhiyun test_pmtu_ipvX_over_vxlanY_or_geneveY_exception vxlan 6 4 1039*4882a593Smuzhiyun} 1040*4882a593Smuzhiyun 1041*4882a593Smuzhiyuntest_pmtu_ipv4_geneve4_exception() { 1042*4882a593Smuzhiyun test_pmtu_ipvX_over_vxlanY_or_geneveY_exception geneve 4 4 1043*4882a593Smuzhiyun} 1044*4882a593Smuzhiyun 1045*4882a593Smuzhiyuntest_pmtu_ipv6_geneve4_exception() { 1046*4882a593Smuzhiyun test_pmtu_ipvX_over_vxlanY_or_geneveY_exception geneve 6 4 1047*4882a593Smuzhiyun} 1048*4882a593Smuzhiyun 1049*4882a593Smuzhiyuntest_pmtu_ipv4_vxlan6_exception() { 1050*4882a593Smuzhiyun test_pmtu_ipvX_over_vxlanY_or_geneveY_exception vxlan 4 6 1051*4882a593Smuzhiyun} 1052*4882a593Smuzhiyun 1053*4882a593Smuzhiyuntest_pmtu_ipv6_vxlan6_exception() { 1054*4882a593Smuzhiyun test_pmtu_ipvX_over_vxlanY_or_geneveY_exception vxlan 6 6 1055*4882a593Smuzhiyun} 1056*4882a593Smuzhiyun 1057*4882a593Smuzhiyuntest_pmtu_ipv4_geneve6_exception() { 1058*4882a593Smuzhiyun test_pmtu_ipvX_over_vxlanY_or_geneveY_exception geneve 4 6 1059*4882a593Smuzhiyun} 1060*4882a593Smuzhiyun 1061*4882a593Smuzhiyuntest_pmtu_ipv6_geneve6_exception() { 1062*4882a593Smuzhiyun test_pmtu_ipvX_over_vxlanY_or_geneveY_exception geneve 6 6 1063*4882a593Smuzhiyun} 1064*4882a593Smuzhiyun 1065*4882a593Smuzhiyuntest_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception() { 1066*4882a593Smuzhiyun type=${1} 1067*4882a593Smuzhiyun family=${2} 1068*4882a593Smuzhiyun outer_family=${3} 1069*4882a593Smuzhiyun ll_mtu=4000 1070*4882a593Smuzhiyun 1071*4882a593Smuzhiyun if [ ${outer_family} -eq 4 ]; then 1072*4882a593Smuzhiyun setup namespaces routing bridge bridged_${type}4 || return 2 1073*4882a593Smuzhiyun # IPv4 header UDP header VXLAN/GENEVE header Ethernet header 1074*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 20 - 8 - 8 - 14)) 1075*4882a593Smuzhiyun else 1076*4882a593Smuzhiyun setup namespaces routing bridge bridged_${type}6 || return 2 1077*4882a593Smuzhiyun # IPv6 header UDP header VXLAN/GENEVE header Ethernet header 1078*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - 14)) 1079*4882a593Smuzhiyun fi 1080*4882a593Smuzhiyun 1081*4882a593Smuzhiyun trace "${ns_a}" ${type}_a "${ns_b}" ${type}_b \ 1082*4882a593Smuzhiyun "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ 1083*4882a593Smuzhiyun "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \ 1084*4882a593Smuzhiyun "${ns_a}" br0 "${ns_a}" veth-A-C \ 1085*4882a593Smuzhiyun "${ns_c}" veth_C-A 1086*4882a593Smuzhiyun 1087*4882a593Smuzhiyun if [ ${family} -eq 4 ]; then 1088*4882a593Smuzhiyun ping=ping 1089*4882a593Smuzhiyun dst=${tunnel4_b_addr} 1090*4882a593Smuzhiyun else 1091*4882a593Smuzhiyun ping=${ping6} 1092*4882a593Smuzhiyun dst=${tunnel6_b_addr} 1093*4882a593Smuzhiyun fi 1094*4882a593Smuzhiyun 1095*4882a593Smuzhiyun # Create route exception by exceeding link layer MTU 1096*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000)) 1097*4882a593Smuzhiyun mtu "${ns_a}" br0 $((${ll_mtu} + 1000)) 1098*4882a593Smuzhiyun mtu "${ns_a}" veth_A-C $((${ll_mtu} + 1000)) 1099*4882a593Smuzhiyun mtu "${ns_c}" veth_C-A $((${ll_mtu} + 1000)) 1100*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000)) 1101*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 ${ll_mtu} 1102*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B ${ll_mtu} 1103*4882a593Smuzhiyun 1104*4882a593Smuzhiyun mtu "${ns_a}" ${type}_a $((${ll_mtu} + 1000)) 1105*4882a593Smuzhiyun mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000)) 1106*4882a593Smuzhiyun 1107*4882a593Smuzhiyun run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 10 -s $((${ll_mtu} + 500)) ${dst} || return 1 1108*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst} || return 1 1109*4882a593Smuzhiyun 1110*4882a593Smuzhiyun # Check that exceptions were created 1111*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_c}" ${dst})" 1112*4882a593Smuzhiyun check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on bridged ${type} interface" 1113*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})" 1114*4882a593Smuzhiyun check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on locally bridged ${type} interface" 1115*4882a593Smuzhiyun} 1116*4882a593Smuzhiyun 1117*4882a593Smuzhiyuntest_pmtu_ipv4_br_vxlan4_exception() { 1118*4882a593Smuzhiyun test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception vxlan 4 4 1119*4882a593Smuzhiyun} 1120*4882a593Smuzhiyun 1121*4882a593Smuzhiyuntest_pmtu_ipv6_br_vxlan4_exception() { 1122*4882a593Smuzhiyun test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception vxlan 6 4 1123*4882a593Smuzhiyun} 1124*4882a593Smuzhiyun 1125*4882a593Smuzhiyuntest_pmtu_ipv4_br_geneve4_exception() { 1126*4882a593Smuzhiyun test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception geneve 4 4 1127*4882a593Smuzhiyun} 1128*4882a593Smuzhiyun 1129*4882a593Smuzhiyuntest_pmtu_ipv6_br_geneve4_exception() { 1130*4882a593Smuzhiyun test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception geneve 6 4 1131*4882a593Smuzhiyun} 1132*4882a593Smuzhiyun 1133*4882a593Smuzhiyuntest_pmtu_ipv4_br_vxlan6_exception() { 1134*4882a593Smuzhiyun test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception vxlan 4 6 1135*4882a593Smuzhiyun} 1136*4882a593Smuzhiyun 1137*4882a593Smuzhiyuntest_pmtu_ipv6_br_vxlan6_exception() { 1138*4882a593Smuzhiyun test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception vxlan 6 6 1139*4882a593Smuzhiyun} 1140*4882a593Smuzhiyun 1141*4882a593Smuzhiyuntest_pmtu_ipv4_br_geneve6_exception() { 1142*4882a593Smuzhiyun test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception geneve 4 6 1143*4882a593Smuzhiyun} 1144*4882a593Smuzhiyun 1145*4882a593Smuzhiyuntest_pmtu_ipv6_br_geneve6_exception() { 1146*4882a593Smuzhiyun test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception geneve 6 6 1147*4882a593Smuzhiyun} 1148*4882a593Smuzhiyun 1149*4882a593Smuzhiyuntest_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception() { 1150*4882a593Smuzhiyun type=${1} 1151*4882a593Smuzhiyun family=${2} 1152*4882a593Smuzhiyun outer_family=${3} 1153*4882a593Smuzhiyun ll_mtu=4000 1154*4882a593Smuzhiyun 1155*4882a593Smuzhiyun if [ ${outer_family} -eq 4 ]; then 1156*4882a593Smuzhiyun setup namespaces routing ovs_bridge ovs_${type}4 || return 2 1157*4882a593Smuzhiyun # IPv4 header UDP header VXLAN/GENEVE header Ethernet header 1158*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 20 - 8 - 8 - 14)) 1159*4882a593Smuzhiyun else 1160*4882a593Smuzhiyun setup namespaces routing ovs_bridge ovs_${type}6 || return 2 1161*4882a593Smuzhiyun # IPv6 header UDP header VXLAN/GENEVE header Ethernet header 1162*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - 14)) 1163*4882a593Smuzhiyun fi 1164*4882a593Smuzhiyun 1165*4882a593Smuzhiyun if [ "${type}" = "vxlan" ]; then 1166*4882a593Smuzhiyun tun_a="vxlan_sys_4789" 1167*4882a593Smuzhiyun elif [ "${type}" = "geneve" ]; then 1168*4882a593Smuzhiyun tun_a="genev_sys_6081" 1169*4882a593Smuzhiyun fi 1170*4882a593Smuzhiyun 1171*4882a593Smuzhiyun trace "" "${tun_a}" "${ns_b}" ${type}_b \ 1172*4882a593Smuzhiyun "" veth_A-R1 "${ns_r1}" veth_R1-A \ 1173*4882a593Smuzhiyun "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \ 1174*4882a593Smuzhiyun "" ovs_br0 "" veth-A-C \ 1175*4882a593Smuzhiyun "${ns_c}" veth_C-A 1176*4882a593Smuzhiyun 1177*4882a593Smuzhiyun if [ ${family} -eq 4 ]; then 1178*4882a593Smuzhiyun ping=ping 1179*4882a593Smuzhiyun dst=${tunnel4_b_addr} 1180*4882a593Smuzhiyun else 1181*4882a593Smuzhiyun ping=${ping6} 1182*4882a593Smuzhiyun dst=${tunnel6_b_addr} 1183*4882a593Smuzhiyun fi 1184*4882a593Smuzhiyun 1185*4882a593Smuzhiyun # Create route exception by exceeding link layer MTU 1186*4882a593Smuzhiyun mtu "" veth_A-R1 $((${ll_mtu} + 1000)) 1187*4882a593Smuzhiyun mtu "" ovs_br0 $((${ll_mtu} + 1000)) 1188*4882a593Smuzhiyun mtu "" veth_A-C $((${ll_mtu} + 1000)) 1189*4882a593Smuzhiyun mtu "${ns_c}" veth_C-A $((${ll_mtu} + 1000)) 1190*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000)) 1191*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 ${ll_mtu} 1192*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B ${ll_mtu} 1193*4882a593Smuzhiyun 1194*4882a593Smuzhiyun mtu "" ${tun_a} $((${ll_mtu} + 1000)) 1195*4882a593Smuzhiyun mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000)) 1196*4882a593Smuzhiyun 1197*4882a593Smuzhiyun run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 20 -s $((${ll_mtu} + 500)) ${dst} || return 1 1198*4882a593Smuzhiyun 1199*4882a593Smuzhiyun # Check that exceptions were created 1200*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_c}" ${dst})" 1201*4882a593Smuzhiyun check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on Open vSwitch ${type} interface" 1202*4882a593Smuzhiyun} 1203*4882a593Smuzhiyun 1204*4882a593Smuzhiyuntest_pmtu_ipv4_ovs_vxlan4_exception() { 1205*4882a593Smuzhiyun test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan 4 4 1206*4882a593Smuzhiyun} 1207*4882a593Smuzhiyun 1208*4882a593Smuzhiyuntest_pmtu_ipv6_ovs_vxlan4_exception() { 1209*4882a593Smuzhiyun test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan 6 4 1210*4882a593Smuzhiyun} 1211*4882a593Smuzhiyun 1212*4882a593Smuzhiyuntest_pmtu_ipv4_ovs_geneve4_exception() { 1213*4882a593Smuzhiyun test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 4 4 1214*4882a593Smuzhiyun} 1215*4882a593Smuzhiyun 1216*4882a593Smuzhiyuntest_pmtu_ipv6_ovs_geneve4_exception() { 1217*4882a593Smuzhiyun test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 6 4 1218*4882a593Smuzhiyun} 1219*4882a593Smuzhiyun 1220*4882a593Smuzhiyuntest_pmtu_ipv4_ovs_vxlan6_exception() { 1221*4882a593Smuzhiyun test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan 4 6 1222*4882a593Smuzhiyun} 1223*4882a593Smuzhiyun 1224*4882a593Smuzhiyuntest_pmtu_ipv6_ovs_vxlan6_exception() { 1225*4882a593Smuzhiyun test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan 6 6 1226*4882a593Smuzhiyun} 1227*4882a593Smuzhiyun 1228*4882a593Smuzhiyuntest_pmtu_ipv4_ovs_geneve6_exception() { 1229*4882a593Smuzhiyun test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 4 6 1230*4882a593Smuzhiyun} 1231*4882a593Smuzhiyun 1232*4882a593Smuzhiyuntest_pmtu_ipv6_ovs_geneve6_exception() { 1233*4882a593Smuzhiyun test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 6 6 1234*4882a593Smuzhiyun} 1235*4882a593Smuzhiyun 1236*4882a593Smuzhiyuntest_pmtu_ipvX_over_fouY_or_gueY() { 1237*4882a593Smuzhiyun inner_family=${1} 1238*4882a593Smuzhiyun outer_family=${2} 1239*4882a593Smuzhiyun encap=${3} 1240*4882a593Smuzhiyun ll_mtu=4000 1241*4882a593Smuzhiyun 1242*4882a593Smuzhiyun setup namespaces routing ${encap}${outer_family}${inner_family} || return 2 1243*4882a593Smuzhiyun trace "${ns_a}" ${encap}_a "${ns_b}" ${encap}_b \ 1244*4882a593Smuzhiyun "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ 1245*4882a593Smuzhiyun "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B 1246*4882a593Smuzhiyun 1247*4882a593Smuzhiyun if [ ${inner_family} -eq 4 ]; then 1248*4882a593Smuzhiyun ping=ping 1249*4882a593Smuzhiyun dst=${tunnel4_b_addr} 1250*4882a593Smuzhiyun else 1251*4882a593Smuzhiyun ping=${ping6} 1252*4882a593Smuzhiyun dst=${tunnel6_b_addr} 1253*4882a593Smuzhiyun fi 1254*4882a593Smuzhiyun 1255*4882a593Smuzhiyun if [ "${encap}" = "gue" ]; then 1256*4882a593Smuzhiyun encap_overhead=4 1257*4882a593Smuzhiyun else 1258*4882a593Smuzhiyun encap_overhead=0 1259*4882a593Smuzhiyun fi 1260*4882a593Smuzhiyun 1261*4882a593Smuzhiyun if [ ${outer_family} -eq 4 ]; then 1262*4882a593Smuzhiyun # IPv4 header UDP header 1263*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 20 - 8 - ${encap_overhead})) 1264*4882a593Smuzhiyun else 1265*4882a593Smuzhiyun # IPv6 header Option 4 UDP header 1266*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - ${encap_overhead})) 1267*4882a593Smuzhiyun fi 1268*4882a593Smuzhiyun 1269*4882a593Smuzhiyun # Create route exception by exceeding link layer MTU 1270*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000)) 1271*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000)) 1272*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 ${ll_mtu} 1273*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B ${ll_mtu} 1274*4882a593Smuzhiyun 1275*4882a593Smuzhiyun mtu "${ns_a}" ${encap}_a $((${ll_mtu} + 1000)) 1276*4882a593Smuzhiyun mtu "${ns_b}" ${encap}_b $((${ll_mtu} + 1000)) 1277*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst} 1278*4882a593Smuzhiyun 1279*4882a593Smuzhiyun # Check that exception was created 1280*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})" 1281*4882a593Smuzhiyun check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on ${encap} interface" 1282*4882a593Smuzhiyun} 1283*4882a593Smuzhiyun 1284*4882a593Smuzhiyuntest_pmtu_ipv4_fou4_exception() { 1285*4882a593Smuzhiyun test_pmtu_ipvX_over_fouY_or_gueY 4 4 fou 1286*4882a593Smuzhiyun} 1287*4882a593Smuzhiyun 1288*4882a593Smuzhiyuntest_pmtu_ipv6_fou4_exception() { 1289*4882a593Smuzhiyun test_pmtu_ipvX_over_fouY_or_gueY 6 4 fou 1290*4882a593Smuzhiyun} 1291*4882a593Smuzhiyun 1292*4882a593Smuzhiyuntest_pmtu_ipv4_fou6_exception() { 1293*4882a593Smuzhiyun test_pmtu_ipvX_over_fouY_or_gueY 4 6 fou 1294*4882a593Smuzhiyun} 1295*4882a593Smuzhiyun 1296*4882a593Smuzhiyuntest_pmtu_ipv6_fou6_exception() { 1297*4882a593Smuzhiyun test_pmtu_ipvX_over_fouY_or_gueY 6 6 fou 1298*4882a593Smuzhiyun} 1299*4882a593Smuzhiyun 1300*4882a593Smuzhiyuntest_pmtu_ipv4_gue4_exception() { 1301*4882a593Smuzhiyun test_pmtu_ipvX_over_fouY_or_gueY 4 4 gue 1302*4882a593Smuzhiyun} 1303*4882a593Smuzhiyun 1304*4882a593Smuzhiyuntest_pmtu_ipv6_gue4_exception() { 1305*4882a593Smuzhiyun test_pmtu_ipvX_over_fouY_or_gueY 6 4 gue 1306*4882a593Smuzhiyun} 1307*4882a593Smuzhiyun 1308*4882a593Smuzhiyuntest_pmtu_ipv4_gue6_exception() { 1309*4882a593Smuzhiyun test_pmtu_ipvX_over_fouY_or_gueY 4 6 gue 1310*4882a593Smuzhiyun} 1311*4882a593Smuzhiyun 1312*4882a593Smuzhiyuntest_pmtu_ipv6_gue6_exception() { 1313*4882a593Smuzhiyun test_pmtu_ipvX_over_fouY_or_gueY 6 6 gue 1314*4882a593Smuzhiyun} 1315*4882a593Smuzhiyun 1316*4882a593Smuzhiyuntest_pmtu_ipvX_over_ipvY_exception() { 1317*4882a593Smuzhiyun inner=${1} 1318*4882a593Smuzhiyun outer=${2} 1319*4882a593Smuzhiyun ll_mtu=4000 1320*4882a593Smuzhiyun 1321*4882a593Smuzhiyun setup namespaces routing ip${inner}ip${outer} || return 2 1322*4882a593Smuzhiyun 1323*4882a593Smuzhiyun trace "${ns_a}" ip_a "${ns_b}" ip_b \ 1324*4882a593Smuzhiyun "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ 1325*4882a593Smuzhiyun "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B 1326*4882a593Smuzhiyun 1327*4882a593Smuzhiyun if [ ${inner} -eq 4 ]; then 1328*4882a593Smuzhiyun ping=ping 1329*4882a593Smuzhiyun dst=${tunnel4_b_addr} 1330*4882a593Smuzhiyun else 1331*4882a593Smuzhiyun ping=${ping6} 1332*4882a593Smuzhiyun dst=${tunnel6_b_addr} 1333*4882a593Smuzhiyun fi 1334*4882a593Smuzhiyun 1335*4882a593Smuzhiyun if [ ${outer} -eq 4 ]; then 1336*4882a593Smuzhiyun # IPv4 header 1337*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 20)) 1338*4882a593Smuzhiyun else 1339*4882a593Smuzhiyun # IPv6 header Option 4 1340*4882a593Smuzhiyun exp_mtu=$((${ll_mtu} - 40 - 8)) 1341*4882a593Smuzhiyun fi 1342*4882a593Smuzhiyun 1343*4882a593Smuzhiyun # Create route exception by exceeding link layer MTU 1344*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000)) 1345*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000)) 1346*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 ${ll_mtu} 1347*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B ${ll_mtu} 1348*4882a593Smuzhiyun 1349*4882a593Smuzhiyun mtu "${ns_a}" ip_a $((${ll_mtu} + 1000)) || return 1350*4882a593Smuzhiyun mtu "${ns_b}" ip_b $((${ll_mtu} + 1000)) || return 1351*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst} 1352*4882a593Smuzhiyun 1353*4882a593Smuzhiyun # Check that exception was created 1354*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})" 1355*4882a593Smuzhiyun check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on ip${inner}ip${outer} interface" 1356*4882a593Smuzhiyun} 1357*4882a593Smuzhiyun 1358*4882a593Smuzhiyuntest_pmtu_ipv4_ipv4_exception() { 1359*4882a593Smuzhiyun test_pmtu_ipvX_over_ipvY_exception 4 4 1360*4882a593Smuzhiyun} 1361*4882a593Smuzhiyun 1362*4882a593Smuzhiyuntest_pmtu_ipv6_ipv4_exception() { 1363*4882a593Smuzhiyun test_pmtu_ipvX_over_ipvY_exception 6 4 1364*4882a593Smuzhiyun} 1365*4882a593Smuzhiyun 1366*4882a593Smuzhiyuntest_pmtu_ipv4_ipv6_exception() { 1367*4882a593Smuzhiyun test_pmtu_ipvX_over_ipvY_exception 4 6 1368*4882a593Smuzhiyun} 1369*4882a593Smuzhiyun 1370*4882a593Smuzhiyuntest_pmtu_ipv6_ipv6_exception() { 1371*4882a593Smuzhiyun test_pmtu_ipvX_over_ipvY_exception 6 6 1372*4882a593Smuzhiyun} 1373*4882a593Smuzhiyun 1374*4882a593Smuzhiyuntest_pmtu_vti4_exception() { 1375*4882a593Smuzhiyun setup namespaces veth vti4 xfrm4 || return 2 1376*4882a593Smuzhiyun trace "${ns_a}" veth_a "${ns_b}" veth_b \ 1377*4882a593Smuzhiyun "${ns_a}" vti4_a "${ns_b}" vti4_b 1378*4882a593Smuzhiyun 1379*4882a593Smuzhiyun veth_mtu=1500 1380*4882a593Smuzhiyun vti_mtu=$((veth_mtu - 20)) 1381*4882a593Smuzhiyun 1382*4882a593Smuzhiyun # SPI SN IV ICV pad length next header 1383*4882a593Smuzhiyun esp_payload_rfc4106=$((vti_mtu - 4 - 4 - 8 - 16 - 1 - 1)) 1384*4882a593Smuzhiyun ping_payload=$((esp_payload_rfc4106 - 28)) 1385*4882a593Smuzhiyun 1386*4882a593Smuzhiyun mtu "${ns_a}" veth_a ${veth_mtu} 1387*4882a593Smuzhiyun mtu "${ns_b}" veth_b ${veth_mtu} 1388*4882a593Smuzhiyun mtu "${ns_a}" vti4_a ${vti_mtu} 1389*4882a593Smuzhiyun mtu "${ns_b}" vti4_b ${vti_mtu} 1390*4882a593Smuzhiyun 1391*4882a593Smuzhiyun # Send DF packet without exceeding link layer MTU, check that no 1392*4882a593Smuzhiyun # exception is created 1393*4882a593Smuzhiyun run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s ${ping_payload} ${tunnel4_b_addr} 1394*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel4_b_addr})" 1395*4882a593Smuzhiyun check_pmtu_value "" "${pmtu}" "sending packet smaller than PMTU (IP payload length ${esp_payload_rfc4106})" || return 1 1396*4882a593Smuzhiyun 1397*4882a593Smuzhiyun # Now exceed link layer MTU by one byte, check that exception is created 1398*4882a593Smuzhiyun # with the right PMTU value 1399*4882a593Smuzhiyun run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s $((ping_payload + 1)) ${tunnel4_b_addr} 1400*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel4_b_addr})" 1401*4882a593Smuzhiyun check_pmtu_value "${esp_payload_rfc4106}" "${pmtu}" "exceeding PMTU (IP payload length $((esp_payload_rfc4106 + 1)))" 1402*4882a593Smuzhiyun} 1403*4882a593Smuzhiyun 1404*4882a593Smuzhiyuntest_pmtu_vti6_exception() { 1405*4882a593Smuzhiyun setup namespaces veth vti6 xfrm6 || return 2 1406*4882a593Smuzhiyun trace "${ns_a}" veth_a "${ns_b}" veth_b \ 1407*4882a593Smuzhiyun "${ns_a}" vti6_a "${ns_b}" vti6_b 1408*4882a593Smuzhiyun fail=0 1409*4882a593Smuzhiyun 1410*4882a593Smuzhiyun # Create route exception by exceeding link layer MTU 1411*4882a593Smuzhiyun mtu "${ns_a}" veth_a 4000 1412*4882a593Smuzhiyun mtu "${ns_b}" veth_b 4000 1413*4882a593Smuzhiyun mtu "${ns_a}" vti6_a 5000 1414*4882a593Smuzhiyun mtu "${ns_b}" vti6_b 5000 1415*4882a593Smuzhiyun run_cmd ${ns_a} ${ping6} -q -i 0.1 -w 1 -s 60000 ${tunnel6_b_addr} 1416*4882a593Smuzhiyun 1417*4882a593Smuzhiyun # Check that exception was created 1418*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel6_b_addr})" 1419*4882a593Smuzhiyun check_pmtu_value any "${pmtu}" "creating tunnel exceeding link layer MTU" || return 1 1420*4882a593Smuzhiyun 1421*4882a593Smuzhiyun # Decrease tunnel MTU, check for PMTU decrease in route exception 1422*4882a593Smuzhiyun mtu "${ns_a}" vti6_a 3000 1423*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel6_b_addr})" 1424*4882a593Smuzhiyun check_pmtu_value "3000" "${pmtu}" "decreasing tunnel MTU" || fail=1 1425*4882a593Smuzhiyun 1426*4882a593Smuzhiyun # Increase tunnel MTU, check for PMTU increase in route exception 1427*4882a593Smuzhiyun mtu "${ns_a}" vti6_a 9000 1428*4882a593Smuzhiyun pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel6_b_addr})" 1429*4882a593Smuzhiyun check_pmtu_value "9000" "${pmtu}" "increasing tunnel MTU" || fail=1 1430*4882a593Smuzhiyun 1431*4882a593Smuzhiyun return ${fail} 1432*4882a593Smuzhiyun} 1433*4882a593Smuzhiyun 1434*4882a593Smuzhiyuntest_pmtu_vti4_default_mtu() { 1435*4882a593Smuzhiyun setup namespaces veth vti4 || return 2 1436*4882a593Smuzhiyun 1437*4882a593Smuzhiyun # Check that MTU of vti device is MTU of veth minus IPv4 header length 1438*4882a593Smuzhiyun veth_mtu="$(link_get_mtu "${ns_a}" veth_a)" 1439*4882a593Smuzhiyun vti4_mtu="$(link_get_mtu "${ns_a}" vti4_a)" 1440*4882a593Smuzhiyun if [ $((veth_mtu - vti4_mtu)) -ne 20 ]; then 1441*4882a593Smuzhiyun err " vti MTU ${vti4_mtu} is not veth MTU ${veth_mtu} minus IPv4 header length" 1442*4882a593Smuzhiyun return 1 1443*4882a593Smuzhiyun fi 1444*4882a593Smuzhiyun} 1445*4882a593Smuzhiyun 1446*4882a593Smuzhiyuntest_pmtu_vti6_default_mtu() { 1447*4882a593Smuzhiyun setup namespaces veth vti6 || return 2 1448*4882a593Smuzhiyun 1449*4882a593Smuzhiyun # Check that MTU of vti device is MTU of veth minus IPv6 header length 1450*4882a593Smuzhiyun veth_mtu="$(link_get_mtu "${ns_a}" veth_a)" 1451*4882a593Smuzhiyun vti6_mtu="$(link_get_mtu "${ns_a}" vti6_a)" 1452*4882a593Smuzhiyun if [ $((veth_mtu - vti6_mtu)) -ne 40 ]; then 1453*4882a593Smuzhiyun err " vti MTU ${vti6_mtu} is not veth MTU ${veth_mtu} minus IPv6 header length" 1454*4882a593Smuzhiyun return 1 1455*4882a593Smuzhiyun fi 1456*4882a593Smuzhiyun} 1457*4882a593Smuzhiyun 1458*4882a593Smuzhiyuntest_pmtu_vti4_link_add_mtu() { 1459*4882a593Smuzhiyun setup namespaces || return 2 1460*4882a593Smuzhiyun 1461*4882a593Smuzhiyun run_cmd ${ns_a} ip link add vti4_a type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10 1462*4882a593Smuzhiyun [ $? -ne 0 ] && err " vti not supported" && return 2 1463*4882a593Smuzhiyun run_cmd ${ns_a} ip link del vti4_a 1464*4882a593Smuzhiyun 1465*4882a593Smuzhiyun fail=0 1466*4882a593Smuzhiyun 1467*4882a593Smuzhiyun min=68 1468*4882a593Smuzhiyun max=$((65535 - 20)) 1469*4882a593Smuzhiyun # Check invalid values first 1470*4882a593Smuzhiyun for v in $((min - 1)) $((max + 1)); do 1471*4882a593Smuzhiyun run_cmd ${ns_a} ip link add vti4_a mtu ${v} type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10 1472*4882a593Smuzhiyun # This can fail, or MTU can be adjusted to a proper value 1473*4882a593Smuzhiyun [ $? -ne 0 ] && continue 1474*4882a593Smuzhiyun mtu="$(link_get_mtu "${ns_a}" vti4_a)" 1475*4882a593Smuzhiyun if [ ${mtu} -lt ${min} -o ${mtu} -gt ${max} ]; then 1476*4882a593Smuzhiyun err " vti tunnel created with invalid MTU ${mtu}" 1477*4882a593Smuzhiyun fail=1 1478*4882a593Smuzhiyun fi 1479*4882a593Smuzhiyun run_cmd ${ns_a} ip link del vti4_a 1480*4882a593Smuzhiyun done 1481*4882a593Smuzhiyun 1482*4882a593Smuzhiyun # Now check valid values 1483*4882a593Smuzhiyun for v in ${min} 1300 ${max}; do 1484*4882a593Smuzhiyun run_cmd ${ns_a} ip link add vti4_a mtu ${v} type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10 1485*4882a593Smuzhiyun mtu="$(link_get_mtu "${ns_a}" vti4_a)" 1486*4882a593Smuzhiyun run_cmd ${ns_a} ip link del vti4_a 1487*4882a593Smuzhiyun if [ "${mtu}" != "${v}" ]; then 1488*4882a593Smuzhiyun err " vti MTU ${mtu} doesn't match configured value ${v}" 1489*4882a593Smuzhiyun fail=1 1490*4882a593Smuzhiyun fi 1491*4882a593Smuzhiyun done 1492*4882a593Smuzhiyun 1493*4882a593Smuzhiyun return ${fail} 1494*4882a593Smuzhiyun} 1495*4882a593Smuzhiyun 1496*4882a593Smuzhiyuntest_pmtu_vti6_link_add_mtu() { 1497*4882a593Smuzhiyun setup namespaces || return 2 1498*4882a593Smuzhiyun 1499*4882a593Smuzhiyun run_cmd ${ns_a} ip link add vti6_a type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10 1500*4882a593Smuzhiyun [ $? -ne 0 ] && err " vti6 not supported" && return 2 1501*4882a593Smuzhiyun run_cmd ${ns_a} ip link del vti6_a 1502*4882a593Smuzhiyun 1503*4882a593Smuzhiyun fail=0 1504*4882a593Smuzhiyun 1505*4882a593Smuzhiyun min=68 # vti6 can carry IPv4 packets too 1506*4882a593Smuzhiyun max=$((65535 - 40)) 1507*4882a593Smuzhiyun # Check invalid values first 1508*4882a593Smuzhiyun for v in $((min - 1)) $((max + 1)); do 1509*4882a593Smuzhiyun run_cmd ${ns_a} ip link add vti6_a mtu ${v} type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10 1510*4882a593Smuzhiyun # This can fail, or MTU can be adjusted to a proper value 1511*4882a593Smuzhiyun [ $? -ne 0 ] && continue 1512*4882a593Smuzhiyun mtu="$(link_get_mtu "${ns_a}" vti6_a)" 1513*4882a593Smuzhiyun if [ ${mtu} -lt ${min} -o ${mtu} -gt ${max} ]; then 1514*4882a593Smuzhiyun err " vti6 tunnel created with invalid MTU ${v}" 1515*4882a593Smuzhiyun fail=1 1516*4882a593Smuzhiyun fi 1517*4882a593Smuzhiyun run_cmd ${ns_a} ip link del vti6_a 1518*4882a593Smuzhiyun done 1519*4882a593Smuzhiyun 1520*4882a593Smuzhiyun # Now check valid values 1521*4882a593Smuzhiyun for v in 68 1280 1300 $((65535 - 40)); do 1522*4882a593Smuzhiyun run_cmd ${ns_a} ip link add vti6_a mtu ${v} type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10 1523*4882a593Smuzhiyun mtu="$(link_get_mtu "${ns_a}" vti6_a)" 1524*4882a593Smuzhiyun run_cmd ${ns_a} ip link del vti6_a 1525*4882a593Smuzhiyun if [ "${mtu}" != "${v}" ]; then 1526*4882a593Smuzhiyun err " vti6 MTU ${mtu} doesn't match configured value ${v}" 1527*4882a593Smuzhiyun fail=1 1528*4882a593Smuzhiyun fi 1529*4882a593Smuzhiyun done 1530*4882a593Smuzhiyun 1531*4882a593Smuzhiyun return ${fail} 1532*4882a593Smuzhiyun} 1533*4882a593Smuzhiyun 1534*4882a593Smuzhiyuntest_pmtu_vti6_link_change_mtu() { 1535*4882a593Smuzhiyun setup namespaces || return 2 1536*4882a593Smuzhiyun 1537*4882a593Smuzhiyun run_cmd ${ns_a} ip link add dummy0 mtu 1500 type dummy 1538*4882a593Smuzhiyun [ $? -ne 0 ] && err " dummy not supported" && return 2 1539*4882a593Smuzhiyun run_cmd ${ns_a} ip link add dummy1 mtu 3000 type dummy 1540*4882a593Smuzhiyun run_cmd ${ns_a} ip link set dummy0 up 1541*4882a593Smuzhiyun run_cmd ${ns_a} ip link set dummy1 up 1542*4882a593Smuzhiyun 1543*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${dummy6_0_prefix}1/${dummy6_mask} dev dummy0 1544*4882a593Smuzhiyun run_cmd ${ns_a} ip addr add ${dummy6_1_prefix}1/${dummy6_mask} dev dummy1 1545*4882a593Smuzhiyun 1546*4882a593Smuzhiyun fail=0 1547*4882a593Smuzhiyun 1548*4882a593Smuzhiyun # Create vti6 interface bound to device, passing MTU, check it 1549*4882a593Smuzhiyun run_cmd ${ns_a} ip link add vti6_a mtu 1300 type vti6 remote ${dummy6_0_prefix}2 local ${dummy6_0_prefix}1 1550*4882a593Smuzhiyun mtu="$(link_get_mtu "${ns_a}" vti6_a)" 1551*4882a593Smuzhiyun if [ ${mtu} -ne 1300 ]; then 1552*4882a593Smuzhiyun err " vti6 MTU ${mtu} doesn't match configured value 1300" 1553*4882a593Smuzhiyun fail=1 1554*4882a593Smuzhiyun fi 1555*4882a593Smuzhiyun 1556*4882a593Smuzhiyun # Move to another device with different MTU, without passing MTU, check 1557*4882a593Smuzhiyun # MTU is adjusted 1558*4882a593Smuzhiyun run_cmd ${ns_a} ip link set vti6_a type vti6 remote ${dummy6_1_prefix}2 local ${dummy6_1_prefix}1 1559*4882a593Smuzhiyun mtu="$(link_get_mtu "${ns_a}" vti6_a)" 1560*4882a593Smuzhiyun if [ ${mtu} -ne $((3000 - 40)) ]; then 1561*4882a593Smuzhiyun err " vti MTU ${mtu} is not dummy MTU 3000 minus IPv6 header length" 1562*4882a593Smuzhiyun fail=1 1563*4882a593Smuzhiyun fi 1564*4882a593Smuzhiyun 1565*4882a593Smuzhiyun # Move it back, passing MTU, check MTU is not overridden 1566*4882a593Smuzhiyun run_cmd ${ns_a} ip link set vti6_a mtu 1280 type vti6 remote ${dummy6_0_prefix}2 local ${dummy6_0_prefix}1 1567*4882a593Smuzhiyun mtu="$(link_get_mtu "${ns_a}" vti6_a)" 1568*4882a593Smuzhiyun if [ ${mtu} -ne 1280 ]; then 1569*4882a593Smuzhiyun err " vti6 MTU ${mtu} doesn't match configured value 1280" 1570*4882a593Smuzhiyun fail=1 1571*4882a593Smuzhiyun fi 1572*4882a593Smuzhiyun 1573*4882a593Smuzhiyun return ${fail} 1574*4882a593Smuzhiyun} 1575*4882a593Smuzhiyun 1576*4882a593Smuzhiyuncheck_command() { 1577*4882a593Smuzhiyun cmd=${1} 1578*4882a593Smuzhiyun 1579*4882a593Smuzhiyun if ! which ${cmd} > /dev/null 2>&1; then 1580*4882a593Smuzhiyun err " missing required command: '${cmd}'" 1581*4882a593Smuzhiyun return 1 1582*4882a593Smuzhiyun fi 1583*4882a593Smuzhiyun return 0 1584*4882a593Smuzhiyun} 1585*4882a593Smuzhiyun 1586*4882a593Smuzhiyuntest_cleanup_vxlanX_exception() { 1587*4882a593Smuzhiyun outer="${1}" 1588*4882a593Smuzhiyun encap="vxlan" 1589*4882a593Smuzhiyun ll_mtu=4000 1590*4882a593Smuzhiyun 1591*4882a593Smuzhiyun check_command taskset || return 2 1592*4882a593Smuzhiyun cpu_list=$(grep -m 2 processor /proc/cpuinfo | cut -d ' ' -f 2) 1593*4882a593Smuzhiyun 1594*4882a593Smuzhiyun setup namespaces routing ${encap}${outer} || return 2 1595*4882a593Smuzhiyun trace "${ns_a}" ${encap}_a "${ns_b}" ${encap}_b \ 1596*4882a593Smuzhiyun "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ 1597*4882a593Smuzhiyun "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B 1598*4882a593Smuzhiyun 1599*4882a593Smuzhiyun # Create route exception by exceeding link layer MTU 1600*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000)) 1601*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000)) 1602*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 ${ll_mtu} 1603*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B ${ll_mtu} 1604*4882a593Smuzhiyun 1605*4882a593Smuzhiyun mtu "${ns_a}" ${encap}_a $((${ll_mtu} + 1000)) 1606*4882a593Smuzhiyun mtu "${ns_b}" ${encap}_b $((${ll_mtu} + 1000)) 1607*4882a593Smuzhiyun 1608*4882a593Smuzhiyun # Fill exception cache for multiple CPUs (2) 1609*4882a593Smuzhiyun # we can always use inner IPv4 for that 1610*4882a593Smuzhiyun for cpu in ${cpu_list}; do 1611*4882a593Smuzhiyun run_cmd taskset --cpu-list ${cpu} ${ns_a} ping -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${tunnel4_b_addr} 1612*4882a593Smuzhiyun done 1613*4882a593Smuzhiyun 1614*4882a593Smuzhiyun ${ns_a} ip link del dev veth_A-R1 & 1615*4882a593Smuzhiyun iplink_pid=$! 1616*4882a593Smuzhiyun sleep 1 1617*4882a593Smuzhiyun if [ "$(cat /proc/${iplink_pid}/cmdline 2>/dev/null | tr -d '\0')" = "iplinkdeldevveth_A-R1" ]; then 1618*4882a593Smuzhiyun err " can't delete veth device in a timely manner, PMTU dst likely leaked" 1619*4882a593Smuzhiyun return 1 1620*4882a593Smuzhiyun fi 1621*4882a593Smuzhiyun} 1622*4882a593Smuzhiyun 1623*4882a593Smuzhiyuntest_cleanup_ipv6_exception() { 1624*4882a593Smuzhiyun test_cleanup_vxlanX_exception 6 1625*4882a593Smuzhiyun} 1626*4882a593Smuzhiyun 1627*4882a593Smuzhiyuntest_cleanup_ipv4_exception() { 1628*4882a593Smuzhiyun test_cleanup_vxlanX_exception 4 1629*4882a593Smuzhiyun} 1630*4882a593Smuzhiyun 1631*4882a593Smuzhiyunrun_test() { 1632*4882a593Smuzhiyun ( 1633*4882a593Smuzhiyun tname="$1" 1634*4882a593Smuzhiyun tdesc="$2" 1635*4882a593Smuzhiyun 1636*4882a593Smuzhiyun unset IFS 1637*4882a593Smuzhiyun 1638*4882a593Smuzhiyun # Since cleanup() relies on variables modified by this subshell, it 1639*4882a593Smuzhiyun # has to run in this context. 1640*4882a593Smuzhiyun trap cleanup EXIT 1641*4882a593Smuzhiyun 1642*4882a593Smuzhiyun if [ "$VERBOSE" = "1" ]; then 1643*4882a593Smuzhiyun printf "\n##########################################################################\n\n" 1644*4882a593Smuzhiyun fi 1645*4882a593Smuzhiyun 1646*4882a593Smuzhiyun eval test_${tname} 1647*4882a593Smuzhiyun ret=$? 1648*4882a593Smuzhiyun 1649*4882a593Smuzhiyun if [ $ret -eq 0 ]; then 1650*4882a593Smuzhiyun printf "TEST: %-60s [ OK ]\n" "${tdesc}" 1651*4882a593Smuzhiyun elif [ $ret -eq 1 ]; then 1652*4882a593Smuzhiyun printf "TEST: %-60s [FAIL]\n" "${tdesc}" 1653*4882a593Smuzhiyun if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 1654*4882a593Smuzhiyun echo 1655*4882a593Smuzhiyun echo "Pausing. Hit enter to continue" 1656*4882a593Smuzhiyun read a 1657*4882a593Smuzhiyun fi 1658*4882a593Smuzhiyun err_flush 1659*4882a593Smuzhiyun exit 1 1660*4882a593Smuzhiyun elif [ $ret -eq 2 ]; then 1661*4882a593Smuzhiyun printf "TEST: %-60s [SKIP]\n" "${tdesc}" 1662*4882a593Smuzhiyun err_flush 1663*4882a593Smuzhiyun fi 1664*4882a593Smuzhiyun 1665*4882a593Smuzhiyun return $ret 1666*4882a593Smuzhiyun ) 1667*4882a593Smuzhiyun ret=$? 1668*4882a593Smuzhiyun [ $ret -ne 0 ] && exitcode=1 1669*4882a593Smuzhiyun 1670*4882a593Smuzhiyun return $ret 1671*4882a593Smuzhiyun} 1672*4882a593Smuzhiyun 1673*4882a593Smuzhiyunrun_test_nh() { 1674*4882a593Smuzhiyun tname="$1" 1675*4882a593Smuzhiyun tdesc="$2" 1676*4882a593Smuzhiyun 1677*4882a593Smuzhiyun USE_NH=yes 1678*4882a593Smuzhiyun run_test "${tname}" "${tdesc} - nexthop objects" 1679*4882a593Smuzhiyun USE_NH=no 1680*4882a593Smuzhiyun} 1681*4882a593Smuzhiyun 1682*4882a593Smuzhiyuntest_list_flush_ipv4_exception() { 1683*4882a593Smuzhiyun setup namespaces routing || return 2 1684*4882a593Smuzhiyun trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ 1685*4882a593Smuzhiyun "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ 1686*4882a593Smuzhiyun "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ 1687*4882a593Smuzhiyun "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 1688*4882a593Smuzhiyun 1689*4882a593Smuzhiyun dst_prefix1="${prefix4}.${b_r1}." 1690*4882a593Smuzhiyun dst2="${prefix4}.${b_r2}.1" 1691*4882a593Smuzhiyun 1692*4882a593Smuzhiyun # Set up initial MTU values 1693*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 2000 1694*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A 2000 1695*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B 1500 1696*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 1500 1697*4882a593Smuzhiyun 1698*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R2 2000 1699*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-A 2000 1700*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-B 1500 1701*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R2 1500 1702*4882a593Smuzhiyun 1703*4882a593Smuzhiyun fail=0 1704*4882a593Smuzhiyun 1705*4882a593Smuzhiyun # Add 100 addresses for veth endpoint on B reached by default A route 1706*4882a593Smuzhiyun for i in $(seq 100 199); do 1707*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add "${dst_prefix1}${i}" dev veth_B-R1 1708*4882a593Smuzhiyun done 1709*4882a593Smuzhiyun 1710*4882a593Smuzhiyun # Create 100 cached route exceptions for path via R1, one via R2. Note 1711*4882a593Smuzhiyun # that with IPv4 we need to actually cause a route lookup that matches 1712*4882a593Smuzhiyun # the exception caused by ICMP, in order to actually have a cached 1713*4882a593Smuzhiyun # route, so we need to ping each destination twice 1714*4882a593Smuzhiyun for i in $(seq 100 199); do 1715*4882a593Smuzhiyun run_cmd ${ns_a} ping -q -M want -i 0.1 -c 2 -s 1800 "${dst_prefix1}${i}" 1716*4882a593Smuzhiyun done 1717*4882a593Smuzhiyun run_cmd ${ns_a} ping -q -M want -i 0.1 -c 2 -s 1800 "${dst2}" 1718*4882a593Smuzhiyun 1719*4882a593Smuzhiyun if [ "$(${ns_a} ip -oneline route list cache | wc -l)" -ne 101 ]; then 1720*4882a593Smuzhiyun err " can't list cached exceptions" 1721*4882a593Smuzhiyun fail=1 1722*4882a593Smuzhiyun fi 1723*4882a593Smuzhiyun 1724*4882a593Smuzhiyun run_cmd ${ns_a} ip route flush cache 1725*4882a593Smuzhiyun pmtu1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst_prefix}1)" 1726*4882a593Smuzhiyun pmtu2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst_prefix}2)" 1727*4882a593Smuzhiyun if [ -n "${pmtu1}" ] || [ -n "${pmtu2}" ] || \ 1728*4882a593Smuzhiyun [ -n "$(${ns_a} ip route list cache)" ]; then 1729*4882a593Smuzhiyun err " can't flush cached exceptions" 1730*4882a593Smuzhiyun fail=1 1731*4882a593Smuzhiyun fi 1732*4882a593Smuzhiyun 1733*4882a593Smuzhiyun return ${fail} 1734*4882a593Smuzhiyun} 1735*4882a593Smuzhiyun 1736*4882a593Smuzhiyuntest_list_flush_ipv6_exception() { 1737*4882a593Smuzhiyun setup namespaces routing || return 2 1738*4882a593Smuzhiyun trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ 1739*4882a593Smuzhiyun "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ 1740*4882a593Smuzhiyun "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ 1741*4882a593Smuzhiyun "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 1742*4882a593Smuzhiyun 1743*4882a593Smuzhiyun dst_prefix1="${prefix6}:${b_r1}::" 1744*4882a593Smuzhiyun dst2="${prefix6}:${b_r2}::1" 1745*4882a593Smuzhiyun 1746*4882a593Smuzhiyun # Set up initial MTU values 1747*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 2000 1748*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A 2000 1749*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B 1500 1750*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 1500 1751*4882a593Smuzhiyun 1752*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R2 2000 1753*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-A 2000 1754*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-B 1500 1755*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R2 1500 1756*4882a593Smuzhiyun 1757*4882a593Smuzhiyun fail=0 1758*4882a593Smuzhiyun 1759*4882a593Smuzhiyun # Add 100 addresses for veth endpoint on B reached by default A route 1760*4882a593Smuzhiyun for i in $(seq 100 199); do 1761*4882a593Smuzhiyun run_cmd ${ns_b} ip addr add "${dst_prefix1}${i}" dev veth_B-R1 1762*4882a593Smuzhiyun done 1763*4882a593Smuzhiyun 1764*4882a593Smuzhiyun # Create 100 cached route exceptions for path via R1, one via R2 1765*4882a593Smuzhiyun for i in $(seq 100 199); do 1766*4882a593Smuzhiyun run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s 1800 "${dst_prefix1}${i}" 1767*4882a593Smuzhiyun done 1768*4882a593Smuzhiyun run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s 1800 "${dst2}" 1769*4882a593Smuzhiyun if [ "$(${ns_a} ip -oneline -6 route list cache | wc -l)" -ne 101 ]; then 1770*4882a593Smuzhiyun err " can't list cached exceptions" 1771*4882a593Smuzhiyun fail=1 1772*4882a593Smuzhiyun fi 1773*4882a593Smuzhiyun 1774*4882a593Smuzhiyun run_cmd ${ns_a} ip -6 route flush cache 1775*4882a593Smuzhiyun pmtu1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst_prefix1}100")" 1776*4882a593Smuzhiyun pmtu2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" 1777*4882a593Smuzhiyun if [ -n "${pmtu1}" ] || [ -n "${pmtu2}" ] || \ 1778*4882a593Smuzhiyun [ -n "$(${ns_a} ip -6 route list cache)" ]; then 1779*4882a593Smuzhiyun err " can't flush cached exceptions" 1780*4882a593Smuzhiyun fail=1 1781*4882a593Smuzhiyun fi 1782*4882a593Smuzhiyun 1783*4882a593Smuzhiyun return ${fail} 1784*4882a593Smuzhiyun} 1785*4882a593Smuzhiyun 1786*4882a593Smuzhiyuntest_pmtu_ipvX_route_change() { 1787*4882a593Smuzhiyun family=${1} 1788*4882a593Smuzhiyun 1789*4882a593Smuzhiyun setup namespaces routing || return 2 1790*4882a593Smuzhiyun trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \ 1791*4882a593Smuzhiyun "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \ 1792*4882a593Smuzhiyun "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \ 1793*4882a593Smuzhiyun "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2 1794*4882a593Smuzhiyun 1795*4882a593Smuzhiyun if [ ${family} -eq 4 ]; then 1796*4882a593Smuzhiyun ping=ping 1797*4882a593Smuzhiyun dst1="${prefix4}.${b_r1}.1" 1798*4882a593Smuzhiyun dst2="${prefix4}.${b_r2}.1" 1799*4882a593Smuzhiyun gw="${prefix4}.${a_r1}.2" 1800*4882a593Smuzhiyun else 1801*4882a593Smuzhiyun ping=${ping6} 1802*4882a593Smuzhiyun dst1="${prefix6}:${b_r1}::1" 1803*4882a593Smuzhiyun dst2="${prefix6}:${b_r2}::1" 1804*4882a593Smuzhiyun gw="${prefix6}:${a_r1}::2" 1805*4882a593Smuzhiyun fi 1806*4882a593Smuzhiyun 1807*4882a593Smuzhiyun # Set up initial MTU values 1808*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R1 2000 1809*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-A 2000 1810*4882a593Smuzhiyun mtu "${ns_r1}" veth_R1-B 1400 1811*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R1 1400 1812*4882a593Smuzhiyun 1813*4882a593Smuzhiyun mtu "${ns_a}" veth_A-R2 2000 1814*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-A 2000 1815*4882a593Smuzhiyun mtu "${ns_r2}" veth_R2-B 1500 1816*4882a593Smuzhiyun mtu "${ns_b}" veth_B-R2 1500 1817*4882a593Smuzhiyun 1818*4882a593Smuzhiyun # Create route exceptions 1819*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst1} 1820*4882a593Smuzhiyun run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst2} 1821*4882a593Smuzhiyun 1822*4882a593Smuzhiyun # Check that exceptions have been created with the correct PMTU 1823*4882a593Smuzhiyun pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})" 1824*4882a593Smuzhiyun check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1 1825*4882a593Smuzhiyun pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})" 1826*4882a593Smuzhiyun check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1 1827*4882a593Smuzhiyun 1828*4882a593Smuzhiyun # Replace the route from A to R1 1829*4882a593Smuzhiyun run_cmd ${ns_a} ip route change default via ${gw} 1830*4882a593Smuzhiyun 1831*4882a593Smuzhiyun # Delete the device in A 1832*4882a593Smuzhiyun run_cmd ${ns_a} ip link del "veth_A-R1" 1833*4882a593Smuzhiyun} 1834*4882a593Smuzhiyun 1835*4882a593Smuzhiyuntest_pmtu_ipv4_route_change() { 1836*4882a593Smuzhiyun test_pmtu_ipvX_route_change 4 1837*4882a593Smuzhiyun} 1838*4882a593Smuzhiyun 1839*4882a593Smuzhiyuntest_pmtu_ipv6_route_change() { 1840*4882a593Smuzhiyun test_pmtu_ipvX_route_change 6 1841*4882a593Smuzhiyun} 1842*4882a593Smuzhiyun 1843*4882a593Smuzhiyunusage() { 1844*4882a593Smuzhiyun echo 1845*4882a593Smuzhiyun echo "$0 [OPTIONS] [TEST]..." 1846*4882a593Smuzhiyun echo "If no TEST argument is given, all tests will be run." 1847*4882a593Smuzhiyun echo 1848*4882a593Smuzhiyun echo "Options" 1849*4882a593Smuzhiyun echo " --trace: capture traffic to TEST_INTERFACE.pcap" 1850*4882a593Smuzhiyun echo 1851*4882a593Smuzhiyun echo "Available tests${tests}" 1852*4882a593Smuzhiyun exit 1 1853*4882a593Smuzhiyun} 1854*4882a593Smuzhiyun 1855*4882a593Smuzhiyun################################################################################ 1856*4882a593Smuzhiyun# 1857*4882a593Smuzhiyunexitcode=0 1858*4882a593Smuzhiyundesc=0 1859*4882a593Smuzhiyun 1860*4882a593Smuzhiyunwhile getopts :ptv o 1861*4882a593Smuzhiyundo 1862*4882a593Smuzhiyun case $o in 1863*4882a593Smuzhiyun p) PAUSE_ON_FAIL=yes;; 1864*4882a593Smuzhiyun v) VERBOSE=1;; 1865*4882a593Smuzhiyun t) if which tcpdump > /dev/null 2>&1; then 1866*4882a593Smuzhiyun TRACING=1 1867*4882a593Smuzhiyun else 1868*4882a593Smuzhiyun echo "=== tcpdump not available, tracing disabled" 1869*4882a593Smuzhiyun fi 1870*4882a593Smuzhiyun ;; 1871*4882a593Smuzhiyun *) usage;; 1872*4882a593Smuzhiyun esac 1873*4882a593Smuzhiyundone 1874*4882a593Smuzhiyunshift $(($OPTIND-1)) 1875*4882a593Smuzhiyun 1876*4882a593SmuzhiyunIFS=" 1877*4882a593Smuzhiyun" 1878*4882a593Smuzhiyun 1879*4882a593Smuzhiyunfor arg do 1880*4882a593Smuzhiyun # Check first that all requested tests are available before running any 1881*4882a593Smuzhiyun command -v > /dev/null "test_${arg}" || { echo "=== Test ${arg} not found"; usage; } 1882*4882a593Smuzhiyundone 1883*4882a593Smuzhiyun 1884*4882a593Smuzhiyuntrap cleanup EXIT 1885*4882a593Smuzhiyun 1886*4882a593Smuzhiyun# start clean 1887*4882a593Smuzhiyuncleanup 1888*4882a593Smuzhiyun 1889*4882a593SmuzhiyunHAVE_NH=no 1890*4882a593Smuzhiyunip nexthop ls >/dev/null 2>&1 1891*4882a593Smuzhiyun[ $? -eq 0 ] && HAVE_NH=yes 1892*4882a593Smuzhiyun 1893*4882a593Smuzhiyunname="" 1894*4882a593Smuzhiyundesc="" 1895*4882a593Smuzhiyunrerun_nh=0 1896*4882a593Smuzhiyunfor t in ${tests}; do 1897*4882a593Smuzhiyun [ "${name}" = "" ] && name="${t}" && continue 1898*4882a593Smuzhiyun [ "${desc}" = "" ] && desc="${t}" && continue 1899*4882a593Smuzhiyun 1900*4882a593Smuzhiyun if [ "${HAVE_NH}" = "yes" ]; then 1901*4882a593Smuzhiyun rerun_nh="${t}" 1902*4882a593Smuzhiyun fi 1903*4882a593Smuzhiyun 1904*4882a593Smuzhiyun run_this=1 1905*4882a593Smuzhiyun for arg do 1906*4882a593Smuzhiyun [ "${arg}" != "${arg#--*}" ] && continue 1907*4882a593Smuzhiyun [ "${arg}" = "${name}" ] && run_this=1 && break 1908*4882a593Smuzhiyun run_this=0 1909*4882a593Smuzhiyun done 1910*4882a593Smuzhiyun if [ $run_this -eq 1 ]; then 1911*4882a593Smuzhiyun run_test "${name}" "${desc}" 1912*4882a593Smuzhiyun # if test was skipped no need to retry with nexthop objects 1913*4882a593Smuzhiyun [ $? -eq 2 ] && rerun_nh=0 1914*4882a593Smuzhiyun 1915*4882a593Smuzhiyun if [ "${rerun_nh}" = "1" ]; then 1916*4882a593Smuzhiyun run_test_nh "${name}" "${desc}" 1917*4882a593Smuzhiyun fi 1918*4882a593Smuzhiyun fi 1919*4882a593Smuzhiyun name="" 1920*4882a593Smuzhiyun desc="" 1921*4882a593Smuzhiyun rerun_nh=0 1922*4882a593Smuzhiyundone 1923*4882a593Smuzhiyun 1924*4882a593Smuzhiyunexit ${exitcode} 1925