Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

selftests: forwarding: Add test for minimum and maximum MTU

Add cases to check minimum and maximum MTU which are exposed via
"ip -d link show". Test configuration and traffic. Use VLAN devices as
usually VLAN header (4 bytes) is not included in the MTU, and drivers
should configure hardware correctly to send maximum MTU payload size
in VLAN tagged packets.

$ ./min_max_mtu.sh
TEST: ping [ OK ]
TEST: ping6 [ OK ]
TEST: Test maximum MTU configuration [ OK ]
TEST: Test traffic, packet size is maximum MTU [ OK ]
TEST: Test minimum MTU configuration [ OK ]
TEST: Test traffic, packet size is minimum MTU [ OK ]

Signed-off-by: Amit Cohen <amcohen@nvidia.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Signed-off-by: Petr Machata <petrm@nvidia.com>
Link: https://lore.kernel.org/r/89de8be8989db7a97f3b39e3c9da695673e78d2e.1718275854.git.petrm@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Amit Cohen and committed by
Jakub Kicinski
4be3dcc9 3e785654

+284
+1
tools/testing/selftests/net/forwarding/Makefile
··· 39 39 ipip_hier_gre.sh \ 40 40 lib_sh_test.sh \ 41 41 local_termination.sh \ 42 + min_max_mtu.sh \ 42 43 mirror_gre_bound.sh \ 43 44 mirror_gre_bridge_1d.sh \ 44 45 mirror_gre_bridge_1d_vlan.sh \
+283
tools/testing/selftests/net/forwarding/min_max_mtu.sh
··· 1 + #!/bin/bash 2 + # SPDX-License-Identifier: GPL-2.0 3 + 4 + # +--------------------+ 5 + # | H1 | 6 + # | | 7 + # | $h1.10 + | 8 + # | 192.0.2.2/24 | | 9 + # | 2001:db8:1::2/64 | | 10 + # | | | 11 + # | $h1 + | 12 + # | | | 13 + # +------------------|-+ 14 + # | 15 + # +------------------|-+ 16 + # | SW | | 17 + # | $swp1 + | 18 + # | | | 19 + # | $swp1.10 + | 20 + # | 192.0.2.1/24 | 21 + # | 2001:db8:1::1/64 | 22 + # | | 23 + # +--------------------+ 24 + 25 + ALL_TESTS=" 26 + ping_ipv4 27 + ping_ipv6 28 + max_mtu_config_test 29 + max_mtu_traffic_test 30 + min_mtu_config_test 31 + min_mtu_traffic_test 32 + " 33 + 34 + NUM_NETIFS=2 35 + source lib.sh 36 + 37 + h1_create() 38 + { 39 + simple_if_init $h1 40 + vlan_create $h1 10 v$h1 192.0.2.2/24 2001:db8:1::2/64 41 + } 42 + 43 + h1_destroy() 44 + { 45 + vlan_destroy $h1 10 192.0.2.2/24 2001:db8:1::2/64 46 + simple_if_fini $h1 47 + } 48 + 49 + switch_create() 50 + { 51 + ip li set dev $swp1 up 52 + vlan_create $swp1 10 "" 192.0.2.1/24 2001:db8:1::1/64 53 + } 54 + 55 + switch_destroy() 56 + { 57 + ip li set dev $swp1 down 58 + vlan_destroy $swp1 10 59 + } 60 + 61 + setup_prepare() 62 + { 63 + h1=${NETIFS[p1]} 64 + swp1=${NETIFS[p2]} 65 + 66 + vrf_prepare 67 + 68 + h1_create 69 + 70 + switch_create 71 + 72 + forwarding_enable 73 + } 74 + 75 + cleanup() 76 + { 77 + pre_cleanup 78 + 79 + forwarding_restore 80 + 81 + switch_destroy 82 + 83 + h1_destroy 84 + 85 + vrf_cleanup 86 + } 87 + 88 + ping_ipv4() 89 + { 90 + ping_test $h1.10 192.0.2.1 91 + } 92 + 93 + ping_ipv6() 94 + { 95 + ping6_test $h1.10 2001:db8:1::1 96 + } 97 + 98 + min_max_mtu_get_if() 99 + { 100 + local dev=$1; shift 101 + local min_max=$1; shift 102 + 103 + ip -d -j link show $dev | jq ".[].$min_max" 104 + } 105 + 106 + ensure_compatible_min_max_mtu() 107 + { 108 + local min_max=$1; shift 109 + 110 + local mtu=$(min_max_mtu_get_if ${NETIFS[p1]} $min_max) 111 + local i 112 + 113 + for ((i = 2; i <= NUM_NETIFS; ++i)); do 114 + local current_mtu=$(min_max_mtu_get_if ${NETIFS[p$i]} $min_max) 115 + 116 + if [ $current_mtu -ne $mtu ]; then 117 + return 1 118 + fi 119 + done 120 + } 121 + 122 + mtu_set_if() 123 + { 124 + local dev=$1; shift 125 + local mtu=$1; shift 126 + local should_fail=${1:-0}; shift 127 + 128 + mtu_set $dev $mtu 2>/dev/null 129 + check_err_fail $should_fail $? "Set MTU $mtu for $dev" 130 + } 131 + 132 + mtu_set_all_if() 133 + { 134 + local mtu=$1; shift 135 + local i 136 + 137 + for ((i = 1; i <= NUM_NETIFS; ++i)); do 138 + mtu_set_if ${NETIFS[p$i]} $mtu 139 + mtu_set_if ${NETIFS[p$i]}.10 $mtu 140 + done 141 + } 142 + 143 + mtu_restore_all_if() 144 + { 145 + local i 146 + 147 + for ((i = 1; i <= NUM_NETIFS; ++i)); do 148 + mtu_restore ${NETIFS[p$i]}.10 149 + mtu_restore ${NETIFS[p$i]} 150 + done 151 + } 152 + 153 + mtu_test_ping4() 154 + { 155 + local mtu=$1; shift 156 + local should_fail=$1; shift 157 + 158 + # Ping adds 8 bytes for ICMP header and 20 bytes for IP header 159 + local ping_headers_len=$((20 + 8)) 160 + local pkt_size=$((mtu - ping_headers_len)) 161 + 162 + ping_do $h1.10 192.0.2.1 "-s $pkt_size -M do" 163 + check_err_fail $should_fail $? "Ping, packet size: $pkt_size" 164 + } 165 + 166 + mtu_test_ping6() 167 + { 168 + local mtu=$1; shift 169 + local should_fail=$1; shift 170 + 171 + # Ping adds 8 bytes for ICMP header and 40 bytes for IPv6 header 172 + local ping6_headers_len=$((40 + 8)) 173 + local pkt_size=$((mtu - ping6_headers_len)) 174 + 175 + ping6_do $h1.10 2001:db8:1::1 "-s $pkt_size -M do" 176 + check_err_fail $should_fail $? "Ping6, packet size: $pkt_size" 177 + } 178 + 179 + max_mtu_config_test() 180 + { 181 + local i 182 + 183 + RET=0 184 + 185 + for ((i = 1; i <= NUM_NETIFS; ++i)); do 186 + local dev=${NETIFS[p$i]} 187 + local max_mtu=$(min_max_mtu_get_if $dev "max_mtu") 188 + local should_fail 189 + 190 + should_fail=0 191 + mtu_set_if $dev $max_mtu $should_fail 192 + mtu_restore $dev 193 + 194 + should_fail=1 195 + mtu_set_if $dev $((max_mtu + 1)) $should_fail 196 + mtu_restore $dev 197 + done 198 + 199 + log_test "Test maximum MTU configuration" 200 + } 201 + 202 + max_mtu_traffic_test() 203 + { 204 + local should_fail 205 + local max_mtu 206 + 207 + RET=0 208 + 209 + if ! ensure_compatible_min_max_mtu "max_mtu"; then 210 + log_test_xfail "Topology has incompatible maximum MTU values" 211 + return 212 + fi 213 + 214 + max_mtu=$(min_max_mtu_get_if ${NETIFS[p1]} "max_mtu") 215 + 216 + should_fail=0 217 + mtu_set_all_if $max_mtu 218 + mtu_test_ping4 $max_mtu $should_fail 219 + mtu_test_ping6 $max_mtu $should_fail 220 + mtu_restore_all_if 221 + 222 + should_fail=1 223 + mtu_set_all_if $((max_mtu - 1)) 224 + mtu_test_ping4 $max_mtu $should_fail 225 + mtu_test_ping6 $max_mtu $should_fail 226 + mtu_restore_all_if 227 + 228 + log_test "Test traffic, packet size is maximum MTU" 229 + } 230 + 231 + min_mtu_config_test() 232 + { 233 + local i 234 + 235 + RET=0 236 + 237 + for ((i = 1; i <= NUM_NETIFS; ++i)); do 238 + local dev=${NETIFS[p$i]} 239 + local min_mtu=$(min_max_mtu_get_if $dev "min_mtu") 240 + local should_fail 241 + 242 + should_fail=0 243 + mtu_set_if $dev $min_mtu $should_fail 244 + mtu_restore $dev 245 + 246 + should_fail=1 247 + mtu_set_if $dev $((min_mtu - 1)) $should_fail 248 + mtu_restore $dev 249 + done 250 + 251 + log_test "Test minimum MTU configuration" 252 + } 253 + 254 + min_mtu_traffic_test() 255 + { 256 + local should_fail=0 257 + local min_mtu 258 + 259 + RET=0 260 + 261 + if ! ensure_compatible_min_max_mtu "min_mtu"; then 262 + log_test_xfail "Topology has incompatible minimum MTU values" 263 + return 264 + fi 265 + 266 + min_mtu=$(min_max_mtu_get_if ${NETIFS[p1]} "min_mtu") 267 + mtu_set_all_if $min_mtu 268 + mtu_test_ping4 $min_mtu $should_fail 269 + # Do not test minimum MTU with IPv6, as IPv6 requires higher MTU. 270 + 271 + mtu_restore_all_if 272 + 273 + log_test "Test traffic, packet size is minimum MTU" 274 + } 275 + 276 + trap cleanup EXIT 277 + 278 + setup_prepare 279 + setup_wait 280 + 281 + tests_run 282 + 283 + exit $EXIT_STATUS