Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 1 | #!/bin/sh |
| 2 | # SPDX-License-Identifier: GPL-2.0 |
| 3 | # |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 4 | # Check that route PMTU values match expectations, and that initial device MTU |
| 5 | # values are assigned correctly |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 6 | # |
| 7 | # Tests currently implemented: |
| 8 | # |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 9 | # - pmtu_vti6_exception |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 10 | # Set up vti6 tunnel on top of veth, with xfrm states and policies, in two |
| 11 | # namespaces with matching endpoints. Check that route exception is |
| 12 | # created by exceeding link layer MTU with ping to other endpoint. Then |
| 13 | # decrease and increase MTU of tunnel, checking that route exception PMTU |
| 14 | # changes accordingly |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 15 | # |
| 16 | # - pmtu_vti4_default_mtu |
| 17 | # Set up vti4 tunnel on top of veth, in two namespaces with matching |
| 18 | # endpoints. Check that MTU assigned to vti interface is the MTU of the |
| 19 | # lower layer (veth) minus additional lower layer headers (zero, for veth) |
| 20 | # minus IPv4 header length |
Stefano Brivio | 35b4942 | 2018-03-17 02:31:43 +0100 | [diff] [blame^] | 21 | # |
| 22 | # - pmtu_vti6_default_mtu |
| 23 | # Same as above, for IPv6 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 24 | |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 25 | tests=" |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 26 | pmtu_vti6_exception vti6: PMTU exceptions |
Stefano Brivio | 35b4942 | 2018-03-17 02:31:43 +0100 | [diff] [blame^] | 27 | pmtu_vti4_default_mtu vti4: default MTU assignment |
| 28 | pmtu_vti6_default_mtu vti6: default MTU assignment" |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 29 | |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 30 | NS_A="ns-$(mktemp -u XXXXXX)" |
| 31 | NS_B="ns-$(mktemp -u XXXXXX)" |
| 32 | ns_a="ip netns exec ${NS_A}" |
| 33 | ns_b="ip netns exec ${NS_B}" |
| 34 | |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 35 | veth4_a_addr="192.168.1.1" |
| 36 | veth4_b_addr="192.168.1.2" |
| 37 | veth4_mask="24" |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 38 | veth6_a_addr="fd00:1::a" |
| 39 | veth6_b_addr="fd00:1::b" |
| 40 | veth6_mask="64" |
| 41 | |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 42 | vti4_a_addr="192.168.2.1" |
| 43 | vti4_b_addr="192.168.2.2" |
| 44 | vti4_mask="24" |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 45 | vti6_a_addr="fd00:2::a" |
| 46 | vti6_b_addr="fd00:2::b" |
| 47 | vti6_mask="64" |
| 48 | |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 49 | cleanup_done=1 |
| 50 | err_buf= |
| 51 | |
| 52 | err() { |
| 53 | err_buf="${err_buf}${1} |
| 54 | " |
| 55 | } |
| 56 | |
| 57 | err_flush() { |
| 58 | echo -n "${err_buf}" |
| 59 | err_buf= |
| 60 | } |
| 61 | |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 62 | setup_namespaces() { |
Stefano Brivio | 380e29a | 2018-03-17 02:31:38 +0100 | [diff] [blame] | 63 | ip netns add ${NS_A} || return 1 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 64 | ip netns add ${NS_B} |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 65 | } |
| 66 | |
| 67 | setup_veth() { |
Stefano Brivio | 380e29a | 2018-03-17 02:31:38 +0100 | [diff] [blame] | 68 | ${ns_a} ip link add veth_a type veth peer name veth_b || return 1 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 69 | ${ns_a} ip link set veth_b netns ${NS_B} |
| 70 | |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 71 | ${ns_a} ip addr add ${veth4_a_addr}/${veth4_mask} dev veth_a |
| 72 | ${ns_b} ip addr add ${veth4_b_addr}/${veth4_mask} dev veth_b |
| 73 | |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 74 | ${ns_a} ip addr add ${veth6_a_addr}/${veth6_mask} dev veth_a |
| 75 | ${ns_b} ip addr add ${veth6_b_addr}/${veth6_mask} dev veth_b |
| 76 | |
| 77 | ${ns_a} ip link set veth_a up |
| 78 | ${ns_b} ip link set veth_b up |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 79 | } |
| 80 | |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 81 | setup_vti() { |
| 82 | proto=${1} |
| 83 | veth_a_addr="${2}" |
| 84 | veth_b_addr="${3}" |
| 85 | vti_a_addr="${4}" |
| 86 | vti_b_addr="${5}" |
| 87 | vti_mask=${6} |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 88 | |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 89 | [ ${proto} -eq 6 ] && vti_type="vti6" || vti_type="vti" |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 90 | |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 91 | ${ns_a} ip link add vti${proto}_a type ${vti_type} local ${veth_a_addr} remote ${veth_b_addr} key 10 || return 1 |
| 92 | ${ns_b} ip link add vti${proto}_b type ${vti_type} local ${veth_b_addr} remote ${veth_a_addr} key 10 |
| 93 | |
| 94 | ${ns_a} ip addr add ${vti_a_addr}/${vti_mask} dev vti${proto}_a |
| 95 | ${ns_b} ip addr add ${vti_b_addr}/${vti_mask} dev vti${proto}_b |
| 96 | |
| 97 | ${ns_a} ip link set vti${proto}_a up |
| 98 | ${ns_b} ip link set vti${proto}_b up |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 99 | |
| 100 | sleep 1 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 101 | } |
| 102 | |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 103 | setup_vti4() { |
| 104 | setup_vti 4 ${veth4_a_addr} ${veth4_b_addr} ${vti4_a_addr} ${vti4_b_addr} ${vti4_mask} |
| 105 | } |
| 106 | |
| 107 | setup_vti6() { |
| 108 | setup_vti 6 ${veth6_a_addr} ${veth6_b_addr} ${vti6_a_addr} ${vti6_b_addr} ${vti6_mask} |
| 109 | } |
| 110 | |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 111 | setup_xfrm() { |
Stefano Brivio | 380e29a | 2018-03-17 02:31:38 +0100 | [diff] [blame] | 112 | ${ns_a} ip -6 xfrm state add src ${veth6_a_addr} dst ${veth6_b_addr} spi 0x1000 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel || return 1 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 113 | ${ns_a} ip -6 xfrm state add src ${veth6_b_addr} dst ${veth6_a_addr} spi 0x1001 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel |
| 114 | ${ns_a} ip -6 xfrm policy add dir out mark 10 tmpl src ${veth6_a_addr} dst ${veth6_b_addr} proto esp mode tunnel |
| 115 | ${ns_a} ip -6 xfrm policy add dir in mark 10 tmpl src ${veth6_b_addr} dst ${veth6_a_addr} proto esp mode tunnel |
| 116 | |
| 117 | ${ns_b} ip -6 xfrm state add src ${veth6_a_addr} dst ${veth6_b_addr} spi 0x1000 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel |
| 118 | ${ns_b} ip -6 xfrm state add src ${veth6_b_addr} dst ${veth6_a_addr} spi 0x1001 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel |
| 119 | ${ns_b} ip -6 xfrm policy add dir out mark 10 tmpl src ${veth6_b_addr} dst ${veth6_a_addr} proto esp mode tunnel |
| 120 | ${ns_b} ip -6 xfrm policy add dir in mark 10 tmpl src ${veth6_a_addr} dst ${veth6_b_addr} proto esp mode tunnel |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 121 | } |
| 122 | |
| 123 | setup() { |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 124 | [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return 1 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 125 | |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 126 | cleanup_done=0 |
| 127 | for arg do |
| 128 | eval setup_${arg} || { echo " ${arg} not supported"; return 1; } |
| 129 | done |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 130 | } |
| 131 | |
| 132 | cleanup() { |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 133 | [ ${cleanup_done} -eq 1 ] && return |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 134 | ip netns del ${NS_A} 2 > /dev/null |
| 135 | ip netns del ${NS_B} 2 > /dev/null |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 136 | cleanup_done=1 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 137 | } |
| 138 | |
| 139 | mtu() { |
| 140 | ns_cmd="${1}" |
| 141 | dev="${2}" |
| 142 | mtu="${3}" |
| 143 | |
| 144 | ${ns_cmd} ip link set dev ${dev} mtu ${mtu} |
| 145 | } |
| 146 | |
Stefano Brivio | f2c929f | 2018-03-17 02:31:40 +0100 | [diff] [blame] | 147 | mtu_parse() { |
| 148 | input="${1}" |
| 149 | |
| 150 | next=0 |
| 151 | for i in ${input}; do |
| 152 | [ ${next} -eq 1 ] && echo "${i}" && return |
| 153 | [ "${i}" = "mtu" ] && next=1 |
| 154 | done |
| 155 | } |
| 156 | |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 157 | link_get() { |
| 158 | ns_cmd="${1}" |
| 159 | name="${2}" |
| 160 | |
| 161 | ${ns_cmd} ip link show dev "${name}" |
| 162 | } |
| 163 | |
| 164 | link_get_mtu() { |
| 165 | ns_cmd="${1}" |
| 166 | name="${2}" |
| 167 | |
| 168 | mtu_parse "$(link_get "${ns_cmd}" ${name})" |
| 169 | } |
| 170 | |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 171 | route_get_dst_exception() { |
Stefano Brivio | 822d2f8 | 2018-03-17 02:31:39 +0100 | [diff] [blame] | 172 | ns_cmd="${1}" |
| 173 | dst="${2}" |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 174 | |
Stefano Brivio | 822d2f8 | 2018-03-17 02:31:39 +0100 | [diff] [blame] | 175 | ${ns_cmd} ip route get "${dst}" |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 176 | } |
| 177 | |
| 178 | route_get_dst_pmtu_from_exception() { |
Stefano Brivio | 822d2f8 | 2018-03-17 02:31:39 +0100 | [diff] [blame] | 179 | ns_cmd="${1}" |
| 180 | dst="${2}" |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 181 | |
Stefano Brivio | f2c929f | 2018-03-17 02:31:40 +0100 | [diff] [blame] | 182 | mtu_parse "$(route_get_dst_exception "${ns_cmd}" ${dst})" |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 183 | } |
| 184 | |
| 185 | test_pmtu_vti6_exception() { |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 186 | setup namespaces veth vti6 xfrm || return 2 |
| 187 | fail=0 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 188 | |
| 189 | # Create route exception by exceeding link layer MTU |
| 190 | mtu "${ns_a}" veth_a 4000 |
| 191 | mtu "${ns_b}" veth_b 4000 |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 192 | mtu "${ns_a}" vti6_a 5000 |
| 193 | mtu "${ns_b}" vti6_b 5000 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 194 | ${ns_a} ping6 -q -i 0.1 -w 2 -s 60000 ${vti6_b_addr} > /dev/null |
| 195 | |
| 196 | # Check that exception was created |
Stefano Brivio | 822d2f8 | 2018-03-17 02:31:39 +0100 | [diff] [blame] | 197 | if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" = "" ]; then |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 198 | err " tunnel exceeding link layer MTU didn't create route exception" |
| 199 | return 1 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 200 | fi |
| 201 | |
| 202 | # Decrease tunnel MTU, check for PMTU decrease in route exception |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 203 | mtu "${ns_a}" vti6_a 3000 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 204 | |
Stefano Brivio | 822d2f8 | 2018-03-17 02:31:39 +0100 | [diff] [blame] | 205 | if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" -ne 3000 ]; then |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 206 | err " decreasing tunnel MTU didn't decrease route exception PMTU" |
| 207 | fail=1 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 208 | fi |
| 209 | |
| 210 | # Increase tunnel MTU, check for PMTU increase in route exception |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 211 | mtu "${ns_a}" vti6_a 9000 |
Stefano Brivio | 822d2f8 | 2018-03-17 02:31:39 +0100 | [diff] [blame] | 212 | if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" -ne 9000 ]; then |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 213 | err " increasing tunnel MTU didn't increase route exception PMTU" |
| 214 | fail=1 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 215 | fi |
| 216 | |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 217 | return ${fail} |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 218 | } |
| 219 | |
Stefano Brivio | a41c789 | 2018-03-17 02:31:42 +0100 | [diff] [blame] | 220 | test_pmtu_vti4_default_mtu() { |
| 221 | setup namespaces veth vti4 || return 2 |
| 222 | |
| 223 | # Check that MTU of vti device is MTU of veth minus IPv4 header length |
| 224 | veth_mtu="$(link_get_mtu "${ns_a}" veth_a)" |
| 225 | vti4_mtu="$(link_get_mtu "${ns_a}" vti4_a)" |
| 226 | if [ $((veth_mtu - vti4_mtu)) -ne 20 ]; then |
| 227 | err " vti MTU ${vti4_mtu} is not veth MTU ${veth_mtu} minus IPv4 header length" |
| 228 | return 1 |
| 229 | fi |
| 230 | } |
| 231 | |
Stefano Brivio | 35b4942 | 2018-03-17 02:31:43 +0100 | [diff] [blame^] | 232 | test_pmtu_vti6_default_mtu() { |
| 233 | setup namespaces veth vti6 || return 2 |
| 234 | |
| 235 | # Check that MTU of vti device is MTU of veth minus IPv6 header length |
| 236 | veth_mtu="$(link_get_mtu "${ns_a}" veth_a)" |
| 237 | vti6_mtu="$(link_get_mtu "${ns_a}" vti6_a)" |
| 238 | if [ $((veth_mtu - vti6_mtu)) -ne 40 ]; then |
| 239 | err " vti MTU ${vti6_mtu} is not veth MTU ${veth_mtu} minus IPv6 header length" |
| 240 | return 1 |
| 241 | fi |
| 242 | } |
| 243 | |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 244 | trap cleanup EXIT |
| 245 | |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 246 | exitcode=0 |
| 247 | desc=0 |
| 248 | IFS=" |
| 249 | " |
| 250 | for t in ${tests}; do |
| 251 | [ $desc -eq 0 ] && name="${t}" && desc=1 && continue || desc=0 |
Stefano Brivio | d1f1b9c | 2018-03-06 22:16:27 +0100 | [diff] [blame] | 252 | |
Stefano Brivio | 36455bd | 2018-03-17 02:31:41 +0100 | [diff] [blame] | 253 | ( |
| 254 | unset IFS |
| 255 | eval test_${name} |
| 256 | ret=$? |
| 257 | cleanup |
| 258 | |
| 259 | if [ $ret -eq 0 ]; then |
| 260 | printf "TEST: %-60s [ OK ]\n" "${t}" |
| 261 | elif [ $ret -eq 1 ]; then |
| 262 | printf "TEST: %-60s [FAIL]\n" "${t}" |
| 263 | err_flush |
| 264 | exit 1 |
| 265 | elif [ $ret -eq 2 ]; then |
| 266 | printf "TEST: %-60s [SKIP]\n" "${t}" |
| 267 | err_flush |
| 268 | fi |
| 269 | ) |
| 270 | [ $? -ne 0 ] && exitcode=1 |
| 271 | done |
| 272 | |
| 273 | exit ${exitcode} |