xref: /linux/tools/testing/selftests/net/forwarding/min_max_mtu.sh (revision a1ff5a7d78a036d6c2178ee5acd6ba4946243800)
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
25ALL_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
34NUM_NETIFS=2
35source lib.sh
36
37h1_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
43h1_destroy()
44{
45	vlan_destroy $h1 10 192.0.2.2/24 2001:db8:1::2/64
46	simple_if_fini $h1
47}
48
49switch_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
55switch_destroy()
56{
57	ip li set dev $swp1 down
58	vlan_destroy $swp1 10
59}
60
61setup_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
75cleanup()
76{
77	pre_cleanup
78
79	forwarding_restore
80
81	switch_destroy
82
83	h1_destroy
84
85	vrf_cleanup
86}
87
88ping_ipv4()
89{
90	ping_test $h1.10 192.0.2.1
91}
92
93ping_ipv6()
94{
95	ping6_test $h1.10 2001:db8:1::1
96}
97
98min_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
106ensure_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
122mtu_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
132mtu_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
143mtu_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
153mtu_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
166mtu_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
179max_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
202max_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
231min_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
254min_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
276trap cleanup EXIT
277
278setup_prepare
279setup_wait
280
281tests_run
282
283exit $EXIT_STATUS
284