| #!/bin/bash | |
| # SPDX-License-Identifier: GPL-2.0 | |
| # +--------------------+ | |
| # | H1 | | |
| # | | | |
| # | $h1.10 + | | |
| # | 192.0.2.2/24 | | | |
| # | 2001:db8:1::2/64 | | | |
| # | | | | |
| # | $h1 + | | |
| # | | | | |
| # +------------------|-+ | |
| # | | |
| # +------------------|-+ | |
| # | SW | | | |
| # | $swp1 + | | |
| # | | | | |
| # | $swp1.10 + | | |
| # | 192.0.2.1/24 | | |
| # | 2001:db8:1::1/64 | | |
| # | | | |
| # +--------------------+ | |
| ALL_TESTS=" | |
| ping_ipv4 | |
| ping_ipv6 | |
| max_mtu_config_test | |
| max_mtu_traffic_test | |
| min_mtu_config_test | |
| min_mtu_traffic_test | |
| " | |
| NUM_NETIFS=2 | |
| source lib.sh | |
| h1_create() | |
| { | |
| simple_if_init $h1 | |
| vlan_create $h1 10 v$h1 192.0.2.2/24 2001:db8:1::2/64 | |
| } | |
| h1_destroy() | |
| { | |
| vlan_destroy $h1 10 192.0.2.2/24 2001:db8:1::2/64 | |
| simple_if_fini $h1 | |
| } | |
| switch_create() | |
| { | |
| ip li set dev $swp1 up | |
| vlan_create $swp1 10 "" 192.0.2.1/24 2001:db8:1::1/64 | |
| } | |
| switch_destroy() | |
| { | |
| ip li set dev $swp1 down | |
| vlan_destroy $swp1 10 | |
| } | |
| setup_prepare() | |
| { | |
| h1=${NETIFS[p1]} | |
| swp1=${NETIFS[p2]} | |
| vrf_prepare | |
| h1_create | |
| switch_create | |
| forwarding_enable | |
| } | |
| cleanup() | |
| { | |
| pre_cleanup | |
| forwarding_restore | |
| switch_destroy | |
| h1_destroy | |
| vrf_cleanup | |
| } | |
| ping_ipv4() | |
| { | |
| ping_test $h1.10 192.0.2.1 | |
| } | |
| ping_ipv6() | |
| { | |
| ping6_test $h1.10 2001:db8:1::1 | |
| } | |
| min_max_mtu_get_if() | |
| { | |
| local dev=$1; shift | |
| local min_max=$1; shift | |
| ip -d -j link show $dev | jq ".[].$min_max" | |
| } | |
| ensure_compatible_min_max_mtu() | |
| { | |
| local min_max=$1; shift | |
| local mtu=$(min_max_mtu_get_if ${NETIFS[p1]} $min_max) | |
| local i | |
| for ((i = 2; i <= NUM_NETIFS; ++i)); do | |
| local current_mtu=$(min_max_mtu_get_if ${NETIFS[p$i]} $min_max) | |
| if [ $current_mtu -ne $mtu ]; then | |
| return 1 | |
| fi | |
| done | |
| } | |
| mtu_set_if() | |
| { | |
| local dev=$1; shift | |
| local mtu=$1; shift | |
| local should_fail=${1:-0}; shift | |
| mtu_set $dev $mtu 2>/dev/null | |
| check_err_fail $should_fail $? "Set MTU $mtu for $dev" | |
| } | |
| mtu_set_all_if() | |
| { | |
| local mtu=$1; shift | |
| local i | |
| for ((i = 1; i <= NUM_NETIFS; ++i)); do | |
| mtu_set_if ${NETIFS[p$i]} $mtu | |
| mtu_set_if ${NETIFS[p$i]}.10 $mtu | |
| done | |
| } | |
| mtu_restore_all_if() | |
| { | |
| local i | |
| for ((i = 1; i <= NUM_NETIFS; ++i)); do | |
| mtu_restore ${NETIFS[p$i]}.10 | |
| mtu_restore ${NETIFS[p$i]} | |
| done | |
| } | |
| mtu_test_ping4() | |
| { | |
| local mtu=$1; shift | |
| local should_fail=$1; shift | |
| # Ping adds 8 bytes for ICMP header and 20 bytes for IP header | |
| local ping_headers_len=$((20 + 8)) | |
| local pkt_size=$((mtu - ping_headers_len)) | |
| ping_do $h1.10 192.0.2.1 "-s $pkt_size -M do" | |
| check_err_fail $should_fail $? "Ping, packet size: $pkt_size" | |
| } | |
| mtu_test_ping6() | |
| { | |
| local mtu=$1; shift | |
| local should_fail=$1; shift | |
| # Ping adds 8 bytes for ICMP header and 40 bytes for IPv6 header | |
| local ping6_headers_len=$((40 + 8)) | |
| local pkt_size=$((mtu - ping6_headers_len)) | |
| ping6_do $h1.10 2001:db8:1::1 "-s $pkt_size -M do" | |
| check_err_fail $should_fail $? "Ping6, packet size: $pkt_size" | |
| } | |
| max_mtu_config_test() | |
| { | |
| local i | |
| RET=0 | |
| for ((i = 1; i <= NUM_NETIFS; ++i)); do | |
| local dev=${NETIFS[p$i]} | |
| local max_mtu=$(min_max_mtu_get_if $dev "max_mtu") | |
| local should_fail | |
| should_fail=0 | |
| mtu_set_if $dev $max_mtu $should_fail | |
| mtu_restore $dev | |
| should_fail=1 | |
| mtu_set_if $dev $((max_mtu + 1)) $should_fail | |
| mtu_restore $dev | |
| done | |
| log_test "Test maximum MTU configuration" | |
| } | |
| max_mtu_traffic_test() | |
| { | |
| local should_fail | |
| local max_mtu | |
| RET=0 | |
| if ! ensure_compatible_min_max_mtu "max_mtu"; then | |
| log_test_xfail "Topology has incompatible maximum MTU values" | |
| return | |
| fi | |
| max_mtu=$(min_max_mtu_get_if ${NETIFS[p1]} "max_mtu") | |
| should_fail=0 | |
| mtu_set_all_if $max_mtu | |
| mtu_test_ping4 $max_mtu $should_fail | |
| mtu_test_ping6 $max_mtu $should_fail | |
| mtu_restore_all_if | |
| should_fail=1 | |
| mtu_set_all_if $((max_mtu - 1)) | |
| mtu_test_ping4 $max_mtu $should_fail | |
| mtu_test_ping6 $max_mtu $should_fail | |
| mtu_restore_all_if | |
| log_test "Test traffic, packet size is maximum MTU" | |
| } | |
| min_mtu_config_test() | |
| { | |
| local i | |
| RET=0 | |
| for ((i = 1; i <= NUM_NETIFS; ++i)); do | |
| local dev=${NETIFS[p$i]} | |
| local min_mtu=$(min_max_mtu_get_if $dev "min_mtu") | |
| local should_fail | |
| should_fail=0 | |
| mtu_set_if $dev $min_mtu $should_fail | |
| mtu_restore $dev | |
| should_fail=1 | |
| mtu_set_if $dev $((min_mtu - 1)) $should_fail | |
| mtu_restore $dev | |
| done | |
| log_test "Test minimum MTU configuration" | |
| } | |
| min_mtu_traffic_test() | |
| { | |
| local should_fail=0 | |
| local min_mtu | |
| RET=0 | |
| if ! ensure_compatible_min_max_mtu "min_mtu"; then | |
| log_test_xfail "Topology has incompatible minimum MTU values" | |
| return | |
| fi | |
| min_mtu=$(min_max_mtu_get_if ${NETIFS[p1]} "min_mtu") | |
| mtu_set_all_if $min_mtu | |
| mtu_test_ping4 $min_mtu $should_fail | |
| # Do not test minimum MTU with IPv6, as IPv6 requires higher MTU. | |
| mtu_restore_all_if | |
| log_test "Test traffic, packet size is minimum MTU" | |
| } | |
| trap cleanup EXIT | |
| setup_prepare | |
| setup_wait | |
| tests_run | |
| exit $EXIT_STATUS |