1f08c3bdfSopenharmony_ci#!/bin/sh
2f08c3bdfSopenharmony_ci# SPDX-License-Identifier: GPL-2.0-or-later
3f08c3bdfSopenharmony_ci# Copyright (c) 2017-2022 Petr Vorel <pvorel@suse.cz>
4f08c3bdfSopenharmony_ci# Copyright (c) 2015-2017 Oracle and/or its affiliates. All Rights Reserved.
5f08c3bdfSopenharmony_ci# Copyright (c) International Business Machines  Corp., 2005
6f08c3bdfSopenharmony_ci# Author: Mitsuru Chinen <mitch@jp.ibm.com>
7f08c3bdfSopenharmony_ci
8f08c3bdfSopenharmony_ciIF_CMD='ifconfig'
9f08c3bdfSopenharmony_ciTST_SETUP="do_setup"
10f08c3bdfSopenharmony_ciTST_CLEANUP="do_cleanup"
11f08c3bdfSopenharmony_ci
12f08c3bdfSopenharmony_ci# The array of the value which MTU is changed into sequentially
13f08c3bdfSopenharmony_ci# 552 - net.ipv4.route.min_pmtu
14f08c3bdfSopenharmony_ciCHANGE_VALUES="784 1142 552 1500 552 1500 552 748 552 1142 1500"
15f08c3bdfSopenharmony_ciCHANGE6_VALUES="1280 1445 1335 1390 1500 1280 1500 1280 1335 1500"
16f08c3bdfSopenharmony_cisaved_mtu=
17f08c3bdfSopenharmony_ci
18f08c3bdfSopenharmony_ciMAX_PACKET_SIZE=65507
19f08c3bdfSopenharmony_ci
20f08c3bdfSopenharmony_cido_setup()
21f08c3bdfSopenharmony_ci{
22f08c3bdfSopenharmony_ci	# CHANGE_INTERVAL: The interval of the mtu change
23f08c3bdfSopenharmony_ci	if tst_net_use_netns; then
24f08c3bdfSopenharmony_ci		CHANGE_INTERVAL=${CHANGE_INTERVAL:-100ms}
25f08c3bdfSopenharmony_ci	else
26f08c3bdfSopenharmony_ci		CHANGE_INTERVAL=${CHANGE_INTERVAL:-5}
27f08c3bdfSopenharmony_ci	fi
28f08c3bdfSopenharmony_ci
29f08c3bdfSopenharmony_ci	local timeout=1
30f08c3bdfSopenharmony_ci	tst_is_int $CHANGE_INTERVAL && timeout=$CHANGE_INTERVAL
31f08c3bdfSopenharmony_ci	tst_set_timeout $(((timeout + 30) * MTU_CHANGE_TIMES))
32f08c3bdfSopenharmony_ci
33f08c3bdfSopenharmony_ci	[ "$TST_IPV6" ] && CHANGE_VALUES=$CHANGE6_VALUES
34f08c3bdfSopenharmony_ci
35f08c3bdfSopenharmony_ci	if_setup
36f08c3bdfSopenharmony_ci	saved_mtu="$(cat /sys/class/net/$(tst_iface)/mtu)"
37f08c3bdfSopenharmony_ci	[ "$TST_IPV6" ] || find_ipv4_max_packet_size
38f08c3bdfSopenharmony_ci}
39f08c3bdfSopenharmony_ci
40f08c3bdfSopenharmony_cido_cleanup()
41f08c3bdfSopenharmony_ci{
42f08c3bdfSopenharmony_ci	if_cleanup_restore
43f08c3bdfSopenharmony_ci
44f08c3bdfSopenharmony_ci	if [ "$saved_mtu" ]; then
45f08c3bdfSopenharmony_ci		ip link set $(tst_iface) mtu $saved_mtu
46f08c3bdfSopenharmony_ci		tst_rhost_run -c "ip link set $(tst_iface rhost) mtu $saved_mtu"
47f08c3bdfSopenharmony_ci	fi
48f08c3bdfSopenharmony_ci}
49f08c3bdfSopenharmony_ci
50f08c3bdfSopenharmony_ciset_mtu()
51f08c3bdfSopenharmony_ci{
52f08c3bdfSopenharmony_ci	local mtu="$1"
53f08c3bdfSopenharmony_ci	local cmd="$2"
54f08c3bdfSopenharmony_ci	local ret=0
55f08c3bdfSopenharmony_ci	local iface=$(tst_iface)
56f08c3bdfSopenharmony_ci	local iface_rmt=$(tst_iface rhost)
57f08c3bdfSopenharmony_ci
58f08c3bdfSopenharmony_ci	case $cmd in
59f08c3bdfSopenharmony_ci		ifconfig) ifconfig $iface mtu $mtu || ret=1
60f08c3bdfSopenharmony_ci			tst_rhost_run -c "ifconfig $iface_rmt mtu $mtu" || ret=1
61f08c3bdfSopenharmony_ci			;;
62f08c3bdfSopenharmony_ci		ip) ip link set $iface mtu $mtu || ret=1
63f08c3bdfSopenharmony_ci			tst_rhost_run -c "ip link set $iface_rmt mtu $mtu" || ret=1
64f08c3bdfSopenharmony_ci			;;
65f08c3bdfSopenharmony_ci		*) tst_brk TBROK "unknown cmd '$cmd'"
66f08c3bdfSopenharmony_ci			;;
67f08c3bdfSopenharmony_ci	esac
68f08c3bdfSopenharmony_ci
69f08c3bdfSopenharmony_ci	return $ret
70f08c3bdfSopenharmony_ci}
71f08c3bdfSopenharmony_ci
72f08c3bdfSopenharmony_cifind_ipv4_max_packet_size()
73f08c3bdfSopenharmony_ci{
74f08c3bdfSopenharmony_ci	local min_mtu=552
75f08c3bdfSopenharmony_ci	local size=$MAX_PACKET_SIZE
76f08c3bdfSopenharmony_ci
77f08c3bdfSopenharmony_ci	set_mtu $min_mtu $CMD || tst_brk TBROK "failed to set MTU to $mtu"
78f08c3bdfSopenharmony_ci	tst_res TINFO "checking max MTU"
79f08c3bdfSopenharmony_ci	while [ $size -gt 0 ]; do
80f08c3bdfSopenharmony_ci		if ping -I $(tst_iface) -c1 -w1 -s $size $(tst_ipaddr rhost) >/dev/null; then
81f08c3bdfSopenharmony_ci			tst_res TINFO "use max MTU $size"
82f08c3bdfSopenharmony_ci			MAX_PACKET_SIZE=$size
83f08c3bdfSopenharmony_ci			return
84f08c3bdfSopenharmony_ci		fi
85f08c3bdfSopenharmony_ci		size=$((size - 500))
86f08c3bdfSopenharmony_ci	done
87f08c3bdfSopenharmony_ci	tst_brk TBROK "failed to find max MTU"
88f08c3bdfSopenharmony_ci}
89f08c3bdfSopenharmony_ci
90f08c3bdfSopenharmony_citest_body()
91f08c3bdfSopenharmony_ci{
92f08c3bdfSopenharmony_ci	local cmd="$CMD"
93f08c3bdfSopenharmony_ci	local msg="'$cmd' changes MTU $MTU_CHANGE_TIMES times every $CHANGE_INTERVAL"
94f08c3bdfSopenharmony_ci
95f08c3bdfSopenharmony_ci	tst_is_int $CHANGE_INTERVAL && msg="$msg seconds"
96f08c3bdfSopenharmony_ci	tst_res TINFO "$msg"
97f08c3bdfSopenharmony_ci
98f08c3bdfSopenharmony_ci	mtu_array_len=$(echo $CHANGE_VALUES | wc -w)
99f08c3bdfSopenharmony_ci	local cnt=0
100f08c3bdfSopenharmony_ci	while [ $cnt -lt $MTU_CHANGE_TIMES ]; do
101f08c3bdfSopenharmony_ci		local nth=$(($cnt % $mtu_array_len))
102f08c3bdfSopenharmony_ci		field=$(($nth + 1))
103f08c3bdfSopenharmony_ci		cnt=$(($cnt + 1))
104f08c3bdfSopenharmony_ci		mtu=$(echo $CHANGE_VALUES | cut -d ' ' -f $field)
105f08c3bdfSopenharmony_ci		[ $cnt -eq $MTU_CHANGE_TIMES ] && mtu="$saved_mtu"
106f08c3bdfSopenharmony_ci
107f08c3bdfSopenharmony_ci		make_background_tcp_traffic
108f08c3bdfSopenharmony_ci
109f08c3bdfSopenharmony_ci		tst_res TINFO "set MTU to $mtu $cnt/$MTU_CHANGE_TIMES"
110f08c3bdfSopenharmony_ci		if ! set_mtu $mtu $cmd; then
111f08c3bdfSopenharmony_ci			tst_res TFAIL "failed to change MTU to $mtu at $cnt time"
112f08c3bdfSopenharmony_ci			return
113f08c3bdfSopenharmony_ci		fi
114f08c3bdfSopenharmony_ci
115f08c3bdfSopenharmony_ci		tst_sleep $CHANGE_INTERVAL
116f08c3bdfSopenharmony_ci
117f08c3bdfSopenharmony_ci		tst_ping -s "1 $((mtu / 2)) $mtu $MAX_PACKET_SIZE"
118f08c3bdfSopenharmony_ci	done
119f08c3bdfSopenharmony_ci}
120f08c3bdfSopenharmony_ci
121f08c3bdfSopenharmony_ci. if-lib.sh
122f08c3bdfSopenharmony_citst_run
123