Commit 4be3dcc9 authored by Amit Cohen's avatar Amit Cohen Committed by Jakub Kicinski
Browse files

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: default avatarAmit Cohen <amcohen@nvidia.com>
Reviewed-by: default avatarPetr Machata <petrm@nvidia.com>
Signed-off-by: default avatarPetr Machata <petrm@nvidia.com>
Link: https://lore.kernel.org/r/89de8be8989db7a97f3b39e3c9da695673e78d2e.1718275854.git.petrm@nvidia.com


Signed-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent 3e785654
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ TEST_PROGS = bridge_fdb_learning_limit.sh \
	ipip_hier_gre.sh \
	lib_sh_test.sh \
	local_termination.sh \
	min_max_mtu.sh \
	mirror_gre_bound.sh \
	mirror_gre_bridge_1d.sh \
	mirror_gre_bridge_1d_vlan.sh \
+283 −0
Original line number Diff line number Diff line
#!/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