hc
2023-12-09 b22da3d8526a935aa31e086e63f60ff3246cb61c
kernel/tools/testing/selftests/net/pmtu.sh
....@@ -6,6 +6,110 @@
66 #
77 # Tests currently implemented:
88 #
9
+# - pmtu_ipv4
10
+# Set up two namespaces, A and B, with two paths between them over routers
11
+# R1 and R2 (also implemented with namespaces), with different MTUs:
12
+#
13
+# segment a_r1 segment b_r1 a_r1: 2000
14
+# .--------------R1--------------. b_r1: 1400
15
+# A B a_r2: 2000
16
+# '--------------R2--------------' b_r2: 1500
17
+# segment a_r2 segment b_r2
18
+#
19
+# Check that PMTU exceptions with the correct PMTU are created. Then
20
+# decrease and increase the MTU of the local link for one of the paths,
21
+# A to R1, checking that route exception PMTU changes accordingly over
22
+# this path. Also check that locked exceptions are created when an ICMP
23
+# message advertising a PMTU smaller than net.ipv4.route.min_pmtu is
24
+# received
25
+#
26
+# - pmtu_ipv6
27
+# Same as pmtu_ipv4, except for locked PMTU tests, using IPv6
28
+#
29
+# - pmtu_ipv4_vxlan4_exception
30
+# Set up the same network topology as pmtu_ipv4, create a VXLAN tunnel
31
+# over IPv4 between A and B, routed via R1. On the link between R1 and B,
32
+# set a MTU lower than the VXLAN MTU and the MTU on the link between A and
33
+# R1. Send IPv4 packets, exceeding the MTU between R1 and B, over VXLAN
34
+# from A to B and check that the PMTU exception is created with the right
35
+# value on A
36
+#
37
+# - pmtu_ipv6_vxlan4_exception
38
+# Same as pmtu_ipv4_vxlan4_exception, but send IPv6 packets from A to B
39
+#
40
+# - pmtu_ipv4_vxlan6_exception
41
+# Same as pmtu_ipv4_vxlan4_exception, but use IPv6 transport from A to B
42
+#
43
+# - pmtu_ipv6_vxlan6_exception
44
+# Same as pmtu_ipv4_vxlan6_exception, but send IPv6 packets from A to B
45
+#
46
+# - pmtu_ipv4_geneve4_exception
47
+# Same as pmtu_ipv4_vxlan4_exception, but using a GENEVE tunnel instead of
48
+# VXLAN
49
+#
50
+# - pmtu_ipv6_geneve4_exception
51
+# Same as pmtu_ipv6_vxlan4_exception, but using a GENEVE tunnel instead of
52
+# VXLAN
53
+#
54
+# - pmtu_ipv4_geneve6_exception
55
+# Same as pmtu_ipv4_vxlan6_exception, but using a GENEVE tunnel instead of
56
+# VXLAN
57
+#
58
+# - pmtu_ipv6_geneve6_exception
59
+# Same as pmtu_ipv6_vxlan6_exception, but using a GENEVE tunnel instead of
60
+# VXLAN
61
+#
62
+# - pmtu_ipv{4,6}_br_vxlan{4,6}_exception
63
+# Set up three namespaces, A, B, and C, with routing between A and B over
64
+# R1. R2 is unused in these tests. A has a veth connection to C, and is
65
+# connected to B via a VXLAN endpoint, which is directly bridged to C.
66
+# MTU on the B-R1 link is lower than other MTUs.
67
+#
68
+# Check that both C and A are able to communicate with B over the VXLAN
69
+# tunnel, and that PMTU exceptions with the correct values are created.
70
+#
71
+# segment a_r1 segment b_r1 b_r1: 4000
72
+# .--------------R1--------------. everything
73
+# C---veth A B else: 5000
74
+# ' bridge |
75
+# '---- - - - - - VXLAN - - - - - - - '
76
+#
77
+# - pmtu_ipv{4,6}_br_geneve{4,6}_exception
78
+# Same as pmtu_ipv{4,6}_br_vxlan{4,6}_exception, with a GENEVE tunnel
79
+# instead.
80
+#
81
+# - pmtu_ipv{4,6}_ovs_vxlan{4,6}_exception
82
+# Set up two namespaces, B, and C, with routing between the init namespace
83
+# and B over R1. A and R2 are unused in these tests. The init namespace
84
+# has a veth connection to C, and is connected to B via a VXLAN endpoint,
85
+# which is handled by Open vSwitch and bridged to C. MTU on the B-R1 link
86
+# is lower than other MTUs.
87
+#
88
+# Check that C is able to communicate with B over the VXLAN tunnel, and
89
+# that PMTU exceptions with the correct values are created.
90
+#
91
+# segment a_r1 segment b_r1 b_r1: 4000
92
+# .--------------R1--------------. everything
93
+# C---veth init B else: 5000
94
+# '- ovs |
95
+# '---- - - - - - VXLAN - - - - - - - '
96
+#
97
+# - pmtu_ipv{4,6}_ovs_geneve{4,6}_exception
98
+# Same as pmtu_ipv{4,6}_ovs_vxlan{4,6}_exception, with a GENEVE tunnel
99
+# instead.
100
+#
101
+# - pmtu_ipv{4,6}_fou{4,6}_exception
102
+# Same as pmtu_ipv4_vxlan4, but using a direct IPv4/IPv6 encapsulation
103
+# (FoU) over IPv4/IPv6, instead of VXLAN
104
+#
105
+# - pmtu_ipv{4,6}_fou{4,6}_exception
106
+# Same as pmtu_ipv4_vxlan4, but using a generic UDP IPv4/IPv6
107
+# encapsulation (GUE) over IPv4/IPv6, instead of VXLAN
108
+#
109
+# - pmtu_ipv{4,6}_ipv{4,6}_exception
110
+# Same as pmtu_ipv4_vxlan4, but using a IPv4/IPv6 tunnel over IPv4/IPv6,
111
+# instead of VXLAN
112
+#
9113 # - pmtu_vti4_exception
10114 # Set up vti tunnel on top of veth, with xfrm states and policies, in two
11115 # namespaces with matching endpoints. Check that route exception is not
....@@ -42,47 +146,186 @@
42146 # and check that configured MTU is used on link creation and changes, and
43147 # that MTU is properly calculated instead when MTU is not configured from
44148 # userspace
149
+#
150
+# - cleanup_ipv4_exception
151
+# Similar to pmtu_ipv4_vxlan4_exception, but explicitly generate PMTU
152
+# exceptions on multiple CPUs and check that the veth device tear-down
153
+# happens in a timely manner
154
+#
155
+# - cleanup_ipv6_exception
156
+# Same as above, but use IPv6 transport from A to B
157
+#
158
+# - list_flush_ipv4_exception
159
+# Using the same topology as in pmtu_ipv4, create exceptions, and check
160
+# they are shown when listing exception caches, gone after flushing them
161
+#
162
+# - list_flush_ipv6_exception
163
+# Using the same topology as in pmtu_ipv6, create exceptions, and check
164
+# they are shown when listing exception caches, gone after flushing them
165
+#
166
+# - pmtu_ipv4_route_change
167
+# Use the same topology as in pmtu_ipv4, but issue a route replacement
168
+# command and delete the corresponding device afterward. This tests for
169
+# proper cleanup of the PMTU exceptions by the route replacement path.
170
+# Device unregistration should complete successfully
171
+#
172
+# - pmtu_ipv6_route_change
173
+# Same as above but with IPv6
45174
46175 # Kselftest framework requirement - SKIP code is 4.
47176 ksft_skip=4
48177
178
+PAUSE_ON_FAIL=no
179
+VERBOSE=0
180
+TRACING=0
181
+
49182 # Some systems don't have a ping6 binary anymore
50183 which ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping)
51184
185
+# Name Description re-run with nh
52186 tests="
53
- pmtu_vti6_exception vti6: PMTU exceptions
54
- pmtu_vti4_exception vti4: PMTU exceptions
55
- pmtu_vti4_default_mtu vti4: default MTU assignment
56
- pmtu_vti6_default_mtu vti6: default MTU assignment
57
- pmtu_vti4_link_add_mtu vti4: MTU setting on link creation
58
- pmtu_vti6_link_add_mtu vti6: MTU setting on link creation
59
- pmtu_vti6_link_change_mtu vti6: MTU changes on link changes"
187
+ pmtu_ipv4_exception ipv4: PMTU exceptions 1
188
+ pmtu_ipv6_exception ipv6: PMTU exceptions 1
189
+ pmtu_ipv4_vxlan4_exception IPv4 over vxlan4: PMTU exceptions 1
190
+ pmtu_ipv6_vxlan4_exception IPv6 over vxlan4: PMTU exceptions 1
191
+ pmtu_ipv4_vxlan6_exception IPv4 over vxlan6: PMTU exceptions 1
192
+ pmtu_ipv6_vxlan6_exception IPv6 over vxlan6: PMTU exceptions 1
193
+ pmtu_ipv4_geneve4_exception IPv4 over geneve4: PMTU exceptions 1
194
+ pmtu_ipv6_geneve4_exception IPv6 over geneve4: PMTU exceptions 1
195
+ pmtu_ipv4_geneve6_exception IPv4 over geneve6: PMTU exceptions 1
196
+ pmtu_ipv6_geneve6_exception IPv6 over geneve6: PMTU exceptions 1
197
+ pmtu_ipv4_br_vxlan4_exception IPv4, bridged vxlan4: PMTU exceptions 1
198
+ pmtu_ipv6_br_vxlan4_exception IPv6, bridged vxlan4: PMTU exceptions 1
199
+ pmtu_ipv4_br_vxlan6_exception IPv4, bridged vxlan6: PMTU exceptions 1
200
+ pmtu_ipv6_br_vxlan6_exception IPv6, bridged vxlan6: PMTU exceptions 1
201
+ pmtu_ipv4_br_geneve4_exception IPv4, bridged geneve4: PMTU exceptions 1
202
+ pmtu_ipv6_br_geneve4_exception IPv6, bridged geneve4: PMTU exceptions 1
203
+ pmtu_ipv4_br_geneve6_exception IPv4, bridged geneve6: PMTU exceptions 1
204
+ pmtu_ipv6_br_geneve6_exception IPv6, bridged geneve6: PMTU exceptions 1
205
+ pmtu_ipv4_ovs_vxlan4_exception IPv4, OVS vxlan4: PMTU exceptions 1
206
+ pmtu_ipv6_ovs_vxlan4_exception IPv6, OVS vxlan4: PMTU exceptions 1
207
+ pmtu_ipv4_ovs_vxlan6_exception IPv4, OVS vxlan6: PMTU exceptions 1
208
+ pmtu_ipv6_ovs_vxlan6_exception IPv6, OVS vxlan6: PMTU exceptions 1
209
+ pmtu_ipv4_ovs_geneve4_exception IPv4, OVS geneve4: PMTU exceptions 1
210
+ pmtu_ipv6_ovs_geneve4_exception IPv6, OVS geneve4: PMTU exceptions 1
211
+ pmtu_ipv4_ovs_geneve6_exception IPv4, OVS geneve6: PMTU exceptions 1
212
+ pmtu_ipv6_ovs_geneve6_exception IPv6, OVS geneve6: PMTU exceptions 1
213
+ pmtu_ipv4_fou4_exception IPv4 over fou4: PMTU exceptions 1
214
+ pmtu_ipv6_fou4_exception IPv6 over fou4: PMTU exceptions 1
215
+ pmtu_ipv4_fou6_exception IPv4 over fou6: PMTU exceptions 1
216
+ pmtu_ipv6_fou6_exception IPv6 over fou6: PMTU exceptions 1
217
+ pmtu_ipv4_gue4_exception IPv4 over gue4: PMTU exceptions 1
218
+ pmtu_ipv6_gue4_exception IPv6 over gue4: PMTU exceptions 1
219
+ pmtu_ipv4_gue6_exception IPv4 over gue6: PMTU exceptions 1
220
+ pmtu_ipv6_gue6_exception IPv6 over gue6: PMTU exceptions 1
221
+ pmtu_ipv4_ipv4_exception IPv4 over IPv4: PMTU exceptions 1
222
+ pmtu_ipv6_ipv4_exception IPv6 over IPv4: PMTU exceptions 1
223
+ pmtu_ipv4_ipv6_exception IPv4 over IPv6: PMTU exceptions 1
224
+ pmtu_ipv6_ipv6_exception IPv6 over IPv6: PMTU exceptions 1
225
+ pmtu_vti6_exception vti6: PMTU exceptions 0
226
+ pmtu_vti4_exception vti4: PMTU exceptions 0
227
+ pmtu_vti4_default_mtu vti4: default MTU assignment 0
228
+ pmtu_vti6_default_mtu vti6: default MTU assignment 0
229
+ pmtu_vti4_link_add_mtu vti4: MTU setting on link creation 0
230
+ pmtu_vti6_link_add_mtu vti6: MTU setting on link creation 0
231
+ pmtu_vti6_link_change_mtu vti6: MTU changes on link changes 0
232
+ cleanup_ipv4_exception ipv4: cleanup of cached exceptions 1
233
+ cleanup_ipv6_exception ipv6: cleanup of cached exceptions 1
234
+ list_flush_ipv4_exception ipv4: list and flush cached exceptions 1
235
+ list_flush_ipv6_exception ipv6: list and flush cached exceptions 1
236
+ pmtu_ipv4_route_change ipv4: PMTU exception w/route replace 1
237
+ pmtu_ipv6_route_change ipv6: PMTU exception w/route replace 1"
60238
61
-NS_A="ns-$(mktemp -u XXXXXX)"
62
-NS_B="ns-$(mktemp -u XXXXXX)"
239
+NS_A="ns-A"
240
+NS_B="ns-B"
241
+NS_C="ns-C"
242
+NS_R1="ns-R1"
243
+NS_R2="ns-R2"
63244 ns_a="ip netns exec ${NS_A}"
64245 ns_b="ip netns exec ${NS_B}"
246
+ns_c="ip netns exec ${NS_C}"
247
+ns_r1="ip netns exec ${NS_R1}"
248
+ns_r2="ip netns exec ${NS_R2}"
249
+
250
+# Addressing and routing for tests with routers: four network segments, with
251
+# index SEGMENT between 1 and 4, a common prefix (PREFIX4 or PREFIX6) and an
252
+# identifier ID, which is 1 for hosts (A and B), 2 for routers (R1 and R2).
253
+# Addresses are:
254
+# - IPv4: PREFIX4.SEGMENT.ID (/24)
255
+# - IPv6: PREFIX6:SEGMENT::ID (/64)
256
+prefix4="10.0"
257
+prefix6="fc00"
258
+a_r1=1
259
+a_r2=2
260
+b_r1=3
261
+b_r2=4
262
+# ns peer segment
263
+routing_addrs="
264
+ A R1 ${a_r1}
265
+ A R2 ${a_r2}
266
+ B R1 ${b_r1}
267
+ B R2 ${b_r2}
268
+"
269
+# Traffic from A to B goes through R1 by default, and through R2, if destined to
270
+# B's address on the b_r2 segment.
271
+# Traffic from B to A goes through R1.
272
+# ns destination gateway
273
+routes="
274
+ A default ${prefix4}.${a_r1}.2
275
+ A ${prefix4}.${b_r2}.1 ${prefix4}.${a_r2}.2
276
+ B default ${prefix4}.${b_r1}.2
277
+
278
+ A default ${prefix6}:${a_r1}::2
279
+ A ${prefix6}:${b_r2}::1 ${prefix6}:${a_r2}::2
280
+ B default ${prefix6}:${b_r1}::2
281
+"
282
+
283
+USE_NH="no"
284
+# ns family nh id destination gateway
285
+nexthops="
286
+ A 4 41 ${prefix4}.${a_r1}.2 veth_A-R1
287
+ A 4 42 ${prefix4}.${a_r2}.2 veth_A-R2
288
+ B 4 41 ${prefix4}.${b_r1}.2 veth_B-R1
289
+
290
+ A 6 61 ${prefix6}:${a_r1}::2 veth_A-R1
291
+ A 6 62 ${prefix6}:${a_r2}::2 veth_A-R2
292
+ B 6 61 ${prefix6}:${b_r1}::2 veth_B-R1
293
+"
294
+
295
+# nexthop id correlates to id in nexthops config above
296
+# ns family prefix nh id
297
+routes_nh="
298
+ A 4 default 41
299
+ A 4 ${prefix4}.${b_r2}.1 42
300
+ B 4 default 41
301
+
302
+ A 6 default 61
303
+ A 6 ${prefix6}:${b_r2}::1 62
304
+ B 6 default 61
305
+"
65306
66307 veth4_a_addr="192.168.1.1"
67308 veth4_b_addr="192.168.1.2"
309
+veth4_c_addr="192.168.2.10"
68310 veth4_mask="24"
69311 veth6_a_addr="fd00:1::a"
70312 veth6_b_addr="fd00:1::b"
313
+veth6_c_addr="fd00:2::c"
71314 veth6_mask="64"
72315
73
-vti4_a_addr="192.168.2.1"
74
-vti4_b_addr="192.168.2.2"
75
-vti4_mask="24"
76
-vti6_a_addr="fd00:2::a"
77
-vti6_b_addr="fd00:2::b"
78
-vti6_mask="64"
316
+tunnel4_a_addr="192.168.2.1"
317
+tunnel4_b_addr="192.168.2.2"
318
+tunnel4_mask="24"
319
+tunnel6_a_addr="fd00:2::a"
320
+tunnel6_b_addr="fd00:2::b"
321
+tunnel6_mask="64"
79322
80
-dummy6_0_addr="fc00:1000::0"
81
-dummy6_1_addr="fc00:1001::0"
323
+dummy6_0_prefix="fc00:1000::"
324
+dummy6_1_prefix="fc00:1001::"
82325 dummy6_mask="64"
83326
84
-cleanup_done=1
85327 err_buf=
328
+tcpdump_pids=
86329
87330 err() {
88331 err_buf="${err_buf}${1}
....@@ -94,23 +337,187 @@
94337 err_buf=
95338 }
96339
340
+run_cmd() {
341
+ cmd="$*"
342
+
343
+ if [ "$VERBOSE" = "1" ]; then
344
+ printf " COMMAND: $cmd\n"
345
+ fi
346
+
347
+ out="$($cmd 2>&1)"
348
+ rc=$?
349
+ if [ "$VERBOSE" = "1" -a -n "$out" ]; then
350
+ echo " $out"
351
+ echo
352
+ fi
353
+
354
+ return $rc
355
+}
356
+
357
+# Find the auto-generated name for this namespace
358
+nsname() {
359
+ eval echo \$NS_$1
360
+}
361
+
362
+setup_fou_or_gue() {
363
+ outer="${1}"
364
+ inner="${2}"
365
+ encap="${3}"
366
+
367
+ if [ "${outer}" = "4" ]; then
368
+ modprobe fou || return 2
369
+ a_addr="${prefix4}.${a_r1}.1"
370
+ b_addr="${prefix4}.${b_r1}.1"
371
+ if [ "${inner}" = "4" ]; then
372
+ type="ipip"
373
+ ipproto="4"
374
+ else
375
+ type="sit"
376
+ ipproto="41"
377
+ fi
378
+ else
379
+ modprobe fou6 || return 2
380
+ a_addr="${prefix6}:${a_r1}::1"
381
+ b_addr="${prefix6}:${b_r1}::1"
382
+ if [ "${inner}" = "4" ]; then
383
+ type="ip6tnl"
384
+ mode="mode ipip6"
385
+ ipproto="4 -6"
386
+ else
387
+ type="ip6tnl"
388
+ mode="mode ip6ip6"
389
+ ipproto="41 -6"
390
+ fi
391
+ fi
392
+
393
+ run_cmd ${ns_a} ip fou add port 5555 ipproto ${ipproto} || return 2
394
+ run_cmd ${ns_a} ip link add ${encap}_a type ${type} ${mode} local ${a_addr} remote ${b_addr} encap ${encap} encap-sport auto encap-dport 5556 || return 2
395
+
396
+ run_cmd ${ns_b} ip fou add port 5556 ipproto ${ipproto}
397
+ run_cmd ${ns_b} ip link add ${encap}_b type ${type} ${mode} local ${b_addr} remote ${a_addr} encap ${encap} encap-sport auto encap-dport 5555
398
+
399
+ if [ "${inner}" = "4" ]; then
400
+ run_cmd ${ns_a} ip addr add ${tunnel4_a_addr}/${tunnel4_mask} dev ${encap}_a
401
+ run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${encap}_b
402
+ else
403
+ run_cmd ${ns_a} ip addr add ${tunnel6_a_addr}/${tunnel6_mask} dev ${encap}_a
404
+ run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${encap}_b
405
+ fi
406
+
407
+ run_cmd ${ns_a} ip link set ${encap}_a up
408
+ run_cmd ${ns_b} ip link set ${encap}_b up
409
+}
410
+
411
+setup_fou44() {
412
+ setup_fou_or_gue 4 4 fou
413
+}
414
+
415
+setup_fou46() {
416
+ setup_fou_or_gue 4 6 fou
417
+}
418
+
419
+setup_fou64() {
420
+ setup_fou_or_gue 6 4 fou
421
+}
422
+
423
+setup_fou66() {
424
+ setup_fou_or_gue 6 6 fou
425
+}
426
+
427
+setup_gue44() {
428
+ setup_fou_or_gue 4 4 gue
429
+}
430
+
431
+setup_gue46() {
432
+ setup_fou_or_gue 4 6 gue
433
+}
434
+
435
+setup_gue64() {
436
+ setup_fou_or_gue 6 4 gue
437
+}
438
+
439
+setup_gue66() {
440
+ setup_fou_or_gue 6 6 gue
441
+}
442
+
443
+setup_ipvX_over_ipvY() {
444
+ inner=${1}
445
+ outer=${2}
446
+
447
+ if [ "${outer}" -eq 4 ]; then
448
+ a_addr="${prefix4}.${a_r1}.1"
449
+ b_addr="${prefix4}.${b_r1}.1"
450
+ if [ "${inner}" -eq 4 ]; then
451
+ type="ipip"
452
+ mode="ipip"
453
+ else
454
+ type="sit"
455
+ mode="ip6ip"
456
+ fi
457
+ else
458
+ a_addr="${prefix6}:${a_r1}::1"
459
+ b_addr="${prefix6}:${b_r1}::1"
460
+ type="ip6tnl"
461
+ if [ "${inner}" -eq 4 ]; then
462
+ mode="ipip6"
463
+ else
464
+ mode="ip6ip6"
465
+ fi
466
+ fi
467
+
468
+ run_cmd ${ns_a} ip link add ip_a type ${type} local ${a_addr} remote ${b_addr} mode ${mode} || return 2
469
+ run_cmd ${ns_b} ip link add ip_b type ${type} local ${b_addr} remote ${a_addr} mode ${mode}
470
+
471
+ run_cmd ${ns_a} ip link set ip_a up
472
+ run_cmd ${ns_b} ip link set ip_b up
473
+
474
+ if [ "${inner}" = "4" ]; then
475
+ run_cmd ${ns_a} ip addr add ${tunnel4_a_addr}/${tunnel4_mask} dev ip_a
476
+ run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ip_b
477
+ else
478
+ run_cmd ${ns_a} ip addr add ${tunnel6_a_addr}/${tunnel6_mask} dev ip_a
479
+ run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ip_b
480
+ fi
481
+}
482
+
483
+setup_ip4ip4() {
484
+ setup_ipvX_over_ipvY 4 4
485
+}
486
+
487
+setup_ip6ip4() {
488
+ setup_ipvX_over_ipvY 6 4
489
+}
490
+
491
+setup_ip4ip6() {
492
+ setup_ipvX_over_ipvY 4 6
493
+}
494
+
495
+setup_ip6ip6() {
496
+ setup_ipvX_over_ipvY 6 6
497
+}
498
+
97499 setup_namespaces() {
98
- ip netns add ${NS_A} || return 1
99
- ip netns add ${NS_B}
500
+ for n in ${NS_A} ${NS_B} ${NS_C} ${NS_R1} ${NS_R2}; do
501
+ ip netns add ${n} || return 1
502
+
503
+ # Disable DAD, so that we don't have to wait to use the
504
+ # configured IPv6 addresses
505
+ ip netns exec ${n} sysctl -q net/ipv6/conf/default/accept_dad=0
506
+ done
100507 }
101508
102509 setup_veth() {
103
- ${ns_a} ip link add veth_a type veth peer name veth_b || return 1
104
- ${ns_a} ip link set veth_b netns ${NS_B}
510
+ run_cmd ${ns_a} ip link add veth_a type veth peer name veth_b || return 1
511
+ run_cmd ${ns_a} ip link set veth_b netns ${NS_B}
105512
106
- ${ns_a} ip addr add ${veth4_a_addr}/${veth4_mask} dev veth_a
107
- ${ns_b} ip addr add ${veth4_b_addr}/${veth4_mask} dev veth_b
513
+ run_cmd ${ns_a} ip addr add ${veth4_a_addr}/${veth4_mask} dev veth_a
514
+ run_cmd ${ns_b} ip addr add ${veth4_b_addr}/${veth4_mask} dev veth_b
108515
109
- ${ns_a} ip addr add ${veth6_a_addr}/${veth6_mask} dev veth_a
110
- ${ns_b} ip addr add ${veth6_b_addr}/${veth6_mask} dev veth_b
516
+ run_cmd ${ns_a} ip addr add ${veth6_a_addr}/${veth6_mask} dev veth_a
517
+ run_cmd ${ns_b} ip addr add ${veth6_b_addr}/${veth6_mask} dev veth_b
111518
112
- ${ns_a} ip link set veth_a up
113
- ${ns_b} ip link set veth_b up
519
+ run_cmd ${ns_a} ip link set veth_a up
520
+ run_cmd ${ns_b} ip link set veth_b up
114521 }
115522
116523 setup_vti() {
....@@ -123,24 +530,89 @@
123530
124531 [ ${proto} -eq 6 ] && vti_type="vti6" || vti_type="vti"
125532
126
- ${ns_a} ip link add vti${proto}_a type ${vti_type} local ${veth_a_addr} remote ${veth_b_addr} key 10 || return 1
127
- ${ns_b} ip link add vti${proto}_b type ${vti_type} local ${veth_b_addr} remote ${veth_a_addr} key 10
533
+ run_cmd ${ns_a} ip link add vti${proto}_a type ${vti_type} local ${veth_a_addr} remote ${veth_b_addr} key 10 || return 1
534
+ run_cmd ${ns_b} ip link add vti${proto}_b type ${vti_type} local ${veth_b_addr} remote ${veth_a_addr} key 10
128535
129
- ${ns_a} ip addr add ${vti_a_addr}/${vti_mask} dev vti${proto}_a
130
- ${ns_b} ip addr add ${vti_b_addr}/${vti_mask} dev vti${proto}_b
536
+ run_cmd ${ns_a} ip addr add ${vti_a_addr}/${vti_mask} dev vti${proto}_a
537
+ run_cmd ${ns_b} ip addr add ${vti_b_addr}/${vti_mask} dev vti${proto}_b
131538
132
- ${ns_a} ip link set vti${proto}_a up
133
- ${ns_b} ip link set vti${proto}_b up
134
-
135
- sleep 1
539
+ run_cmd ${ns_a} ip link set vti${proto}_a up
540
+ run_cmd ${ns_b} ip link set vti${proto}_b up
136541 }
137542
138543 setup_vti4() {
139
- setup_vti 4 ${veth4_a_addr} ${veth4_b_addr} ${vti4_a_addr} ${vti4_b_addr} ${vti4_mask}
544
+ setup_vti 4 ${veth4_a_addr} ${veth4_b_addr} ${tunnel4_a_addr} ${tunnel4_b_addr} ${tunnel4_mask}
140545 }
141546
142547 setup_vti6() {
143
- setup_vti 6 ${veth6_a_addr} ${veth6_b_addr} ${vti6_a_addr} ${vti6_b_addr} ${vti6_mask}
548
+ setup_vti 6 ${veth6_a_addr} ${veth6_b_addr} ${tunnel6_a_addr} ${tunnel6_b_addr} ${tunnel6_mask}
549
+}
550
+
551
+setup_vxlan_or_geneve() {
552
+ type="${1}"
553
+ a_addr="${2}"
554
+ b_addr="${3}"
555
+ opts="${4}"
556
+ br_if_a="${5}"
557
+
558
+ if [ "${type}" = "vxlan" ]; then
559
+ opts="${opts} ttl 64 dstport 4789"
560
+ opts_a="local ${a_addr}"
561
+ opts_b="local ${b_addr}"
562
+ else
563
+ opts_a=""
564
+ opts_b=""
565
+ fi
566
+
567
+ run_cmd ${ns_a} ip link add ${type}_a type ${type} id 1 ${opts_a} remote ${b_addr} ${opts} || return 1
568
+ run_cmd ${ns_b} ip link add ${type}_b type ${type} id 1 ${opts_b} remote ${a_addr} ${opts}
569
+
570
+ if [ -n "${br_if_a}" ]; then
571
+ run_cmd ${ns_a} ip addr add ${tunnel4_a_addr}/${tunnel4_mask} dev ${br_if_a}
572
+ run_cmd ${ns_a} ip addr add ${tunnel6_a_addr}/${tunnel6_mask} dev ${br_if_a}
573
+ run_cmd ${ns_a} ip link set ${type}_a master ${br_if_a}
574
+ else
575
+ run_cmd ${ns_a} ip addr add ${tunnel4_a_addr}/${tunnel4_mask} dev ${type}_a
576
+ run_cmd ${ns_a} ip addr add ${tunnel6_a_addr}/${tunnel6_mask} dev ${type}_a
577
+ fi
578
+
579
+ run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${type}_b
580
+ run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${type}_b
581
+
582
+ run_cmd ${ns_a} ip link set ${type}_a up
583
+ run_cmd ${ns_b} ip link set ${type}_b up
584
+}
585
+
586
+setup_geneve4() {
587
+ setup_vxlan_or_geneve geneve ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "df set"
588
+}
589
+
590
+setup_vxlan4() {
591
+ setup_vxlan_or_geneve vxlan ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "df set"
592
+}
593
+
594
+setup_geneve6() {
595
+ setup_vxlan_or_geneve geneve ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 ""
596
+}
597
+
598
+setup_vxlan6() {
599
+ setup_vxlan_or_geneve vxlan ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 ""
600
+}
601
+
602
+setup_bridged_geneve4() {
603
+ setup_vxlan_or_geneve geneve ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "df set" "br0"
604
+}
605
+
606
+setup_bridged_vxlan4() {
607
+ setup_vxlan_or_geneve vxlan ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1 "df set" "br0"
608
+}
609
+
610
+setup_bridged_geneve6() {
611
+ setup_vxlan_or_geneve geneve ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "" "br0"
612
+}
613
+
614
+setup_bridged_vxlan6() {
615
+ setup_vxlan_or_geneve vxlan ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1 "" "br0"
144616 }
145617
146618 setup_xfrm() {
....@@ -148,15 +620,15 @@
148620 veth_a_addr="${2}"
149621 veth_b_addr="${3}"
150622
151
- ${ns_a} ip -${proto} xfrm state add src ${veth_a_addr} dst ${veth_b_addr} spi 0x1000 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel || return 1
152
- ${ns_a} ip -${proto} xfrm state add src ${veth_b_addr} dst ${veth_a_addr} spi 0x1001 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
153
- ${ns_a} ip -${proto} xfrm policy add dir out mark 10 tmpl src ${veth_a_addr} dst ${veth_b_addr} proto esp mode tunnel
154
- ${ns_a} ip -${proto} xfrm policy add dir in mark 10 tmpl src ${veth_b_addr} dst ${veth_a_addr} proto esp mode tunnel
623
+ run_cmd ${ns_a} ip -${proto} xfrm state add src ${veth_a_addr} dst ${veth_b_addr} spi 0x1000 proto esp aead 'rfc4106(gcm(aes))' 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel || return 1
624
+ run_cmd ${ns_a} ip -${proto} xfrm state add src ${veth_b_addr} dst ${veth_a_addr} spi 0x1001 proto esp aead 'rfc4106(gcm(aes))' 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
625
+ run_cmd ${ns_a} ip -${proto} xfrm policy add dir out mark 10 tmpl src ${veth_a_addr} dst ${veth_b_addr} proto esp mode tunnel
626
+ run_cmd ${ns_a} ip -${proto} xfrm policy add dir in mark 10 tmpl src ${veth_b_addr} dst ${veth_a_addr} proto esp mode tunnel
155627
156
- ${ns_b} ip -${proto} xfrm state add src ${veth_a_addr} dst ${veth_b_addr} spi 0x1000 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
157
- ${ns_b} ip -${proto} xfrm state add src ${veth_b_addr} dst ${veth_a_addr} spi 0x1001 proto esp aead "rfc4106(gcm(aes))" 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
158
- ${ns_b} ip -${proto} xfrm policy add dir out mark 10 tmpl src ${veth_b_addr} dst ${veth_a_addr} proto esp mode tunnel
159
- ${ns_b} ip -${proto} xfrm policy add dir in mark 10 tmpl src ${veth_a_addr} dst ${veth_b_addr} proto esp mode tunnel
628
+ run_cmd ${ns_b} ip -${proto} xfrm state add src ${veth_a_addr} dst ${veth_b_addr} spi 0x1000 proto esp aead 'rfc4106(gcm(aes))' 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
629
+ run_cmd ${ns_b} ip -${proto} xfrm state add src ${veth_b_addr} dst ${veth_a_addr} spi 0x1001 proto esp aead 'rfc4106(gcm(aes))' 0x0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f 128 mode tunnel
630
+ run_cmd ${ns_b} ip -${proto} xfrm policy add dir out mark 10 tmpl src ${veth_b_addr} dst ${veth_a_addr} proto esp mode tunnel
631
+ run_cmd ${ns_b} ip -${proto} xfrm policy add dir in mark 10 tmpl src ${veth_a_addr} dst ${veth_b_addr} proto esp mode tunnel
160632 }
161633
162634 setup_xfrm4() {
....@@ -167,20 +639,197 @@
167639 setup_xfrm 6 ${veth6_a_addr} ${veth6_b_addr}
168640 }
169641
642
+setup_routing_old() {
643
+ for i in ${routes}; do
644
+ [ "${ns}" = "" ] && ns="${i}" && continue
645
+ [ "${addr}" = "" ] && addr="${i}" && continue
646
+ [ "${gw}" = "" ] && gw="${i}"
647
+
648
+ ns_name="$(nsname ${ns})"
649
+
650
+ ip -n ${ns_name} route add ${addr} via ${gw}
651
+
652
+ ns=""; addr=""; gw=""
653
+ done
654
+}
655
+
656
+setup_routing_new() {
657
+ for i in ${nexthops}; do
658
+ [ "${ns}" = "" ] && ns="${i}" && continue
659
+ [ "${fam}" = "" ] && fam="${i}" && continue
660
+ [ "${nhid}" = "" ] && nhid="${i}" && continue
661
+ [ "${gw}" = "" ] && gw="${i}" && continue
662
+ [ "${dev}" = "" ] && dev="${i}"
663
+
664
+ ns_name="$(nsname ${ns})"
665
+
666
+ ip -n ${ns_name} -${fam} nexthop add id ${nhid} via ${gw} dev ${dev}
667
+
668
+ ns=""; fam=""; nhid=""; gw=""; dev=""
669
+
670
+ done
671
+
672
+ for i in ${routes_nh}; do
673
+ [ "${ns}" = "" ] && ns="${i}" && continue
674
+ [ "${fam}" = "" ] && fam="${i}" && continue
675
+ [ "${addr}" = "" ] && addr="${i}" && continue
676
+ [ "${nhid}" = "" ] && nhid="${i}"
677
+
678
+ ns_name="$(nsname ${ns})"
679
+
680
+ ip -n ${ns_name} -${fam} route add ${addr} nhid ${nhid}
681
+
682
+ ns=""; fam=""; addr=""; nhid=""
683
+ done
684
+}
685
+
686
+setup_routing() {
687
+ for i in ${NS_R1} ${NS_R2}; do
688
+ ip netns exec ${i} sysctl -q net/ipv4/ip_forward=1
689
+ ip netns exec ${i} sysctl -q net/ipv6/conf/all/forwarding=1
690
+ done
691
+
692
+ for i in ${routing_addrs}; do
693
+ [ "${ns}" = "" ] && ns="${i}" && continue
694
+ [ "${peer}" = "" ] && peer="${i}" && continue
695
+ [ "${segment}" = "" ] && segment="${i}"
696
+
697
+ ns_name="$(nsname ${ns})"
698
+ peer_name="$(nsname ${peer})"
699
+ if="veth_${ns}-${peer}"
700
+ ifpeer="veth_${peer}-${ns}"
701
+
702
+ # Create veth links
703
+ ip link add ${if} up netns ${ns_name} type veth peer name ${ifpeer} netns ${peer_name} || return 1
704
+ ip -n ${peer_name} link set dev ${ifpeer} up
705
+
706
+ # Add addresses
707
+ ip -n ${ns_name} addr add ${prefix4}.${segment}.1/24 dev ${if}
708
+ ip -n ${ns_name} addr add ${prefix6}:${segment}::1/64 dev ${if}
709
+
710
+ ip -n ${peer_name} addr add ${prefix4}.${segment}.2/24 dev ${ifpeer}
711
+ ip -n ${peer_name} addr add ${prefix6}:${segment}::2/64 dev ${ifpeer}
712
+
713
+ ns=""; peer=""; segment=""
714
+ done
715
+
716
+ if [ "$USE_NH" = "yes" ]; then
717
+ setup_routing_new
718
+ else
719
+ setup_routing_old
720
+ fi
721
+
722
+ return 0
723
+}
724
+
725
+setup_bridge() {
726
+ run_cmd ${ns_a} ip link add br0 type bridge || return 2
727
+ run_cmd ${ns_a} ip link set br0 up
728
+
729
+ run_cmd ${ns_c} ip link add veth_C-A type veth peer name veth_A-C
730
+ run_cmd ${ns_c} ip link set veth_A-C netns ns-A
731
+
732
+ run_cmd ${ns_a} ip link set veth_A-C up
733
+ run_cmd ${ns_c} ip link set veth_C-A up
734
+ run_cmd ${ns_c} ip addr add ${veth4_c_addr}/${veth4_mask} dev veth_C-A
735
+ run_cmd ${ns_c} ip addr add ${veth6_c_addr}/${veth6_mask} dev veth_C-A
736
+ run_cmd ${ns_a} ip link set veth_A-C master br0
737
+}
738
+
739
+setup_ovs_vxlan_or_geneve() {
740
+ type="${1}"
741
+ a_addr="${2}"
742
+ b_addr="${3}"
743
+
744
+ if [ "${type}" = "vxlan" ]; then
745
+ opts="${opts} ttl 64 dstport 4789"
746
+ opts_b="local ${b_addr}"
747
+ fi
748
+
749
+ run_cmd ovs-vsctl add-port ovs_br0 ${type}_a -- \
750
+ set interface ${type}_a type=${type} \
751
+ options:remote_ip=${b_addr} options:key=1 options:csum=true || return 1
752
+
753
+ run_cmd ${ns_b} ip link add ${type}_b type ${type} id 1 ${opts_b} remote ${a_addr} ${opts} || return 1
754
+
755
+ run_cmd ${ns_b} ip addr add ${tunnel4_b_addr}/${tunnel4_mask} dev ${type}_b
756
+ run_cmd ${ns_b} ip addr add ${tunnel6_b_addr}/${tunnel6_mask} dev ${type}_b
757
+
758
+ run_cmd ${ns_b} ip link set ${type}_b up
759
+}
760
+
761
+setup_ovs_geneve4() {
762
+ setup_ovs_vxlan_or_geneve geneve ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1
763
+}
764
+
765
+setup_ovs_vxlan4() {
766
+ setup_ovs_vxlan_or_geneve vxlan ${prefix4}.${a_r1}.1 ${prefix4}.${b_r1}.1
767
+}
768
+
769
+setup_ovs_geneve6() {
770
+ setup_ovs_vxlan_or_geneve geneve ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1
771
+}
772
+
773
+setup_ovs_vxlan6() {
774
+ setup_ovs_vxlan_or_geneve vxlan ${prefix6}:${a_r1}::1 ${prefix6}:${b_r1}::1
775
+}
776
+
777
+setup_ovs_bridge() {
778
+ run_cmd ovs-vsctl add-br ovs_br0 || return 2
779
+ run_cmd ip link set ovs_br0 up
780
+
781
+ run_cmd ${ns_c} ip link add veth_C-A type veth peer name veth_A-C
782
+ run_cmd ${ns_c} ip link set veth_A-C netns 1
783
+
784
+ run_cmd ip link set veth_A-C up
785
+ run_cmd ${ns_c} ip link set veth_C-A up
786
+ run_cmd ${ns_c} ip addr add ${veth4_c_addr}/${veth4_mask} dev veth_C-A
787
+ run_cmd ${ns_c} ip addr add ${veth6_c_addr}/${veth6_mask} dev veth_C-A
788
+ run_cmd ovs-vsctl add-port ovs_br0 veth_A-C
789
+
790
+ # Move veth_A-R1 to init
791
+ run_cmd ${ns_a} ip link set veth_A-R1 netns 1
792
+ run_cmd ip addr add ${prefix4}.${a_r1}.1/${veth4_mask} dev veth_A-R1
793
+ run_cmd ip addr add ${prefix6}:${a_r1}::1/${veth6_mask} dev veth_A-R1
794
+ run_cmd ip link set veth_A-R1 up
795
+ run_cmd ip route add ${prefix4}.${b_r1}.1 via ${prefix4}.${a_r1}.2
796
+ run_cmd ip route add ${prefix6}:${b_r1}::1 via ${prefix6}:${a_r1}::2
797
+}
798
+
170799 setup() {
171800 [ "$(id -u)" -ne 0 ] && echo " need to run as root" && return $ksft_skip
172801
173
- cleanup_done=0
174802 for arg do
175803 eval setup_${arg} || { echo " ${arg} not supported"; return 1; }
176804 done
177805 }
178806
807
+trace() {
808
+ [ $TRACING -eq 0 ] && return
809
+
810
+ for arg do
811
+ [ "${ns_cmd}" = "" ] && ns_cmd="${arg}" && continue
812
+ ${ns_cmd} tcpdump --immediate-mode -s 0 -i "${arg}" -w "${name}_${arg}.pcap" 2> /dev/null &
813
+ tcpdump_pids="${tcpdump_pids} $!"
814
+ ns_cmd=
815
+ done
816
+ sleep 1
817
+}
818
+
179819 cleanup() {
180
- [ ${cleanup_done} -eq 1 ] && return
181
- ip netns del ${NS_A} 2> /dev/null
182
- ip netns del ${NS_B} 2> /dev/null
183
- cleanup_done=1
820
+ for pid in ${tcpdump_pids}; do
821
+ kill ${pid}
822
+ done
823
+ tcpdump_pids=
824
+
825
+ for n in ${NS_A} ${NS_B} ${NS_C} ${NS_R1} ${NS_R2}; do
826
+ ip netns del ${n} 2> /dev/null
827
+ done
828
+
829
+ ip link del veth_A-C 2>/dev/null
830
+ ip link del veth_A-R1 2>/dev/null
831
+ ovs-vsctl --if-exists del-port vxlan_a 2>/dev/null
832
+ ovs-vsctl --if-exists del-br ovs_br0 2>/dev/null
184833 }
185834
186835 mtu() {
....@@ -196,7 +845,9 @@
196845
197846 next=0
198847 for i in ${input}; do
848
+ [ ${next} -eq 1 -a "${i}" = "lock" ] && next=2 && continue
199849 [ ${next} -eq 1 ] && echo "${i}" && return
850
+ [ ${next} -eq 2 ] && echo "lock ${i}" && return
200851 [ "${i}" = "mtu" ] && next=1
201852 done
202853 }
....@@ -229,8 +880,501 @@
229880 mtu_parse "$(route_get_dst_exception "${ns_cmd}" ${dst})"
230881 }
231882
883
+check_pmtu_value() {
884
+ expected="${1}"
885
+ value="${2}"
886
+ event="${3}"
887
+
888
+ [ "${expected}" = "any" ] && [ -n "${value}" ] && return 0
889
+ [ "${value}" = "${expected}" ] && return 0
890
+ [ -z "${value}" ] && err " PMTU exception wasn't created after ${event}" && return 1
891
+ [ -z "${expected}" ] && err " PMTU exception shouldn't exist after ${event}" && return 1
892
+ err " found PMTU exception with incorrect MTU ${value}, expected ${expected}, after ${event}"
893
+ return 1
894
+}
895
+
896
+test_pmtu_ipvX() {
897
+ family=${1}
898
+
899
+ setup namespaces routing || return 2
900
+ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
901
+ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \
902
+ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \
903
+ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2
904
+
905
+ if [ ${family} -eq 4 ]; then
906
+ ping=ping
907
+ dst1="${prefix4}.${b_r1}.1"
908
+ dst2="${prefix4}.${b_r2}.1"
909
+ else
910
+ ping=${ping6}
911
+ dst1="${prefix6}:${b_r1}::1"
912
+ dst2="${prefix6}:${b_r2}::1"
913
+ fi
914
+
915
+ # Set up initial MTU values
916
+ mtu "${ns_a}" veth_A-R1 2000
917
+ mtu "${ns_r1}" veth_R1-A 2000
918
+ mtu "${ns_r1}" veth_R1-B 1400
919
+ mtu "${ns_b}" veth_B-R1 1400
920
+
921
+ mtu "${ns_a}" veth_A-R2 2000
922
+ mtu "${ns_r2}" veth_R2-A 2000
923
+ mtu "${ns_r2}" veth_R2-B 1500
924
+ mtu "${ns_b}" veth_B-R2 1500
925
+
926
+ # Create route exceptions
927
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst1}
928
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst2}
929
+
930
+ # Check that exceptions have been created with the correct PMTU
931
+ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})"
932
+ check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1
933
+ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})"
934
+ check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1
935
+
936
+ # Decrease local MTU below PMTU, check for PMTU decrease in route exception
937
+ mtu "${ns_a}" veth_A-R1 1300
938
+ mtu "${ns_r1}" veth_R1-A 1300
939
+ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})"
940
+ check_pmtu_value "1300" "${pmtu_1}" "decreasing local MTU" || return 1
941
+ # Second exception shouldn't be modified
942
+ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})"
943
+ check_pmtu_value "1500" "${pmtu_2}" "changing local MTU on a link not on this path" || return 1
944
+
945
+ # Increase MTU, check for PMTU increase in route exception
946
+ mtu "${ns_a}" veth_A-R1 1700
947
+ mtu "${ns_r1}" veth_R1-A 1700
948
+ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})"
949
+ check_pmtu_value "1700" "${pmtu_1}" "increasing local MTU" || return 1
950
+ # Second exception shouldn't be modified
951
+ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})"
952
+ check_pmtu_value "1500" "${pmtu_2}" "changing local MTU on a link not on this path" || return 1
953
+
954
+ # Skip PMTU locking tests for IPv6
955
+ [ $family -eq 6 ] && return 0
956
+
957
+ # Decrease remote MTU on path via R2, get new exception
958
+ mtu "${ns_r2}" veth_R2-B 400
959
+ mtu "${ns_b}" veth_B-R2 400
960
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1400 ${dst2}
961
+ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})"
962
+ check_pmtu_value "lock 552" "${pmtu_2}" "exceeding MTU, with MTU < min_pmtu" || return 1
963
+
964
+ # Decrease local MTU below PMTU
965
+ mtu "${ns_a}" veth_A-R2 500
966
+ mtu "${ns_r2}" veth_R2-A 500
967
+ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})"
968
+ check_pmtu_value "500" "${pmtu_2}" "decreasing local MTU" || return 1
969
+
970
+ # Increase local MTU
971
+ mtu "${ns_a}" veth_A-R2 1500
972
+ mtu "${ns_r2}" veth_R2-A 1500
973
+ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})"
974
+ check_pmtu_value "1500" "${pmtu_2}" "increasing local MTU" || return 1
975
+
976
+ # Get new exception
977
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1400 ${dst2}
978
+ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})"
979
+ check_pmtu_value "lock 552" "${pmtu_2}" "exceeding MTU, with MTU < min_pmtu" || return 1
980
+}
981
+
982
+test_pmtu_ipv4_exception() {
983
+ test_pmtu_ipvX 4
984
+}
985
+
986
+test_pmtu_ipv6_exception() {
987
+ test_pmtu_ipvX 6
988
+}
989
+
990
+test_pmtu_ipvX_over_vxlanY_or_geneveY_exception() {
991
+ type=${1}
992
+ family=${2}
993
+ outer_family=${3}
994
+ ll_mtu=4000
995
+
996
+ if [ ${outer_family} -eq 4 ]; then
997
+ setup namespaces routing ${type}4 || return 2
998
+ # IPv4 header UDP header VXLAN/GENEVE header Ethernet header
999
+ exp_mtu=$((${ll_mtu} - 20 - 8 - 8 - 14))
1000
+ else
1001
+ setup namespaces routing ${type}6 || return 2
1002
+ # IPv6 header UDP header VXLAN/GENEVE header Ethernet header
1003
+ exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - 14))
1004
+ fi
1005
+
1006
+ trace "${ns_a}" ${type}_a "${ns_b}" ${type}_b \
1007
+ "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
1008
+ "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B
1009
+
1010
+ if [ ${family} -eq 4 ]; then
1011
+ ping=ping
1012
+ dst=${tunnel4_b_addr}
1013
+ else
1014
+ ping=${ping6}
1015
+ dst=${tunnel6_b_addr}
1016
+ fi
1017
+
1018
+ # Create route exception by exceeding link layer MTU
1019
+ mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000))
1020
+ mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000))
1021
+ mtu "${ns_b}" veth_B-R1 ${ll_mtu}
1022
+ mtu "${ns_r1}" veth_R1-B ${ll_mtu}
1023
+
1024
+ mtu "${ns_a}" ${type}_a $((${ll_mtu} + 1000))
1025
+ mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
1026
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst}
1027
+
1028
+ # Check that exception was created
1029
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})"
1030
+ check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on ${type} interface"
1031
+}
1032
+
1033
+test_pmtu_ipv4_vxlan4_exception() {
1034
+ test_pmtu_ipvX_over_vxlanY_or_geneveY_exception vxlan 4 4
1035
+}
1036
+
1037
+test_pmtu_ipv6_vxlan4_exception() {
1038
+ test_pmtu_ipvX_over_vxlanY_or_geneveY_exception vxlan 6 4
1039
+}
1040
+
1041
+test_pmtu_ipv4_geneve4_exception() {
1042
+ test_pmtu_ipvX_over_vxlanY_or_geneveY_exception geneve 4 4
1043
+}
1044
+
1045
+test_pmtu_ipv6_geneve4_exception() {
1046
+ test_pmtu_ipvX_over_vxlanY_or_geneveY_exception geneve 6 4
1047
+}
1048
+
1049
+test_pmtu_ipv4_vxlan6_exception() {
1050
+ test_pmtu_ipvX_over_vxlanY_or_geneveY_exception vxlan 4 6
1051
+}
1052
+
1053
+test_pmtu_ipv6_vxlan6_exception() {
1054
+ test_pmtu_ipvX_over_vxlanY_or_geneveY_exception vxlan 6 6
1055
+}
1056
+
1057
+test_pmtu_ipv4_geneve6_exception() {
1058
+ test_pmtu_ipvX_over_vxlanY_or_geneveY_exception geneve 4 6
1059
+}
1060
+
1061
+test_pmtu_ipv6_geneve6_exception() {
1062
+ test_pmtu_ipvX_over_vxlanY_or_geneveY_exception geneve 6 6
1063
+}
1064
+
1065
+test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception() {
1066
+ type=${1}
1067
+ family=${2}
1068
+ outer_family=${3}
1069
+ ll_mtu=4000
1070
+
1071
+ if [ ${outer_family} -eq 4 ]; then
1072
+ setup namespaces routing bridge bridged_${type}4 || return 2
1073
+ # IPv4 header UDP header VXLAN/GENEVE header Ethernet header
1074
+ exp_mtu=$((${ll_mtu} - 20 - 8 - 8 - 14))
1075
+ else
1076
+ setup namespaces routing bridge bridged_${type}6 || return 2
1077
+ # IPv6 header UDP header VXLAN/GENEVE header Ethernet header
1078
+ exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - 14))
1079
+ fi
1080
+
1081
+ trace "${ns_a}" ${type}_a "${ns_b}" ${type}_b \
1082
+ "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
1083
+ "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \
1084
+ "${ns_a}" br0 "${ns_a}" veth-A-C \
1085
+ "${ns_c}" veth_C-A
1086
+
1087
+ if [ ${family} -eq 4 ]; then
1088
+ ping=ping
1089
+ dst=${tunnel4_b_addr}
1090
+ else
1091
+ ping=${ping6}
1092
+ dst=${tunnel6_b_addr}
1093
+ fi
1094
+
1095
+ # Create route exception by exceeding link layer MTU
1096
+ mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000))
1097
+ mtu "${ns_a}" br0 $((${ll_mtu} + 1000))
1098
+ mtu "${ns_a}" veth_A-C $((${ll_mtu} + 1000))
1099
+ mtu "${ns_c}" veth_C-A $((${ll_mtu} + 1000))
1100
+ mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000))
1101
+ mtu "${ns_b}" veth_B-R1 ${ll_mtu}
1102
+ mtu "${ns_r1}" veth_R1-B ${ll_mtu}
1103
+
1104
+ mtu "${ns_a}" ${type}_a $((${ll_mtu} + 1000))
1105
+ mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
1106
+
1107
+ run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 10 -s $((${ll_mtu} + 500)) ${dst} || return 1
1108
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst} || return 1
1109
+
1110
+ # Check that exceptions were created
1111
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_c}" ${dst})"
1112
+ check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on bridged ${type} interface"
1113
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})"
1114
+ check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on locally bridged ${type} interface"
1115
+}
1116
+
1117
+test_pmtu_ipv4_br_vxlan4_exception() {
1118
+ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception vxlan 4 4
1119
+}
1120
+
1121
+test_pmtu_ipv6_br_vxlan4_exception() {
1122
+ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception vxlan 6 4
1123
+}
1124
+
1125
+test_pmtu_ipv4_br_geneve4_exception() {
1126
+ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception geneve 4 4
1127
+}
1128
+
1129
+test_pmtu_ipv6_br_geneve4_exception() {
1130
+ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception geneve 6 4
1131
+}
1132
+
1133
+test_pmtu_ipv4_br_vxlan6_exception() {
1134
+ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception vxlan 4 6
1135
+}
1136
+
1137
+test_pmtu_ipv6_br_vxlan6_exception() {
1138
+ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception vxlan 6 6
1139
+}
1140
+
1141
+test_pmtu_ipv4_br_geneve6_exception() {
1142
+ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception geneve 4 6
1143
+}
1144
+
1145
+test_pmtu_ipv6_br_geneve6_exception() {
1146
+ test_pmtu_ipvX_over_bridged_vxlanY_or_geneveY_exception geneve 6 6
1147
+}
1148
+
1149
+test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception() {
1150
+ type=${1}
1151
+ family=${2}
1152
+ outer_family=${3}
1153
+ ll_mtu=4000
1154
+
1155
+ if [ ${outer_family} -eq 4 ]; then
1156
+ setup namespaces routing ovs_bridge ovs_${type}4 || return 2
1157
+ # IPv4 header UDP header VXLAN/GENEVE header Ethernet header
1158
+ exp_mtu=$((${ll_mtu} - 20 - 8 - 8 - 14))
1159
+ else
1160
+ setup namespaces routing ovs_bridge ovs_${type}6 || return 2
1161
+ # IPv6 header UDP header VXLAN/GENEVE header Ethernet header
1162
+ exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - 14))
1163
+ fi
1164
+
1165
+ if [ "${type}" = "vxlan" ]; then
1166
+ tun_a="vxlan_sys_4789"
1167
+ elif [ "${type}" = "geneve" ]; then
1168
+ tun_a="genev_sys_6081"
1169
+ fi
1170
+
1171
+ trace "" "${tun_a}" "${ns_b}" ${type}_b \
1172
+ "" veth_A-R1 "${ns_r1}" veth_R1-A \
1173
+ "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B \
1174
+ "" ovs_br0 "" veth-A-C \
1175
+ "${ns_c}" veth_C-A
1176
+
1177
+ if [ ${family} -eq 4 ]; then
1178
+ ping=ping
1179
+ dst=${tunnel4_b_addr}
1180
+ else
1181
+ ping=${ping6}
1182
+ dst=${tunnel6_b_addr}
1183
+ fi
1184
+
1185
+ # Create route exception by exceeding link layer MTU
1186
+ mtu "" veth_A-R1 $((${ll_mtu} + 1000))
1187
+ mtu "" ovs_br0 $((${ll_mtu} + 1000))
1188
+ mtu "" veth_A-C $((${ll_mtu} + 1000))
1189
+ mtu "${ns_c}" veth_C-A $((${ll_mtu} + 1000))
1190
+ mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000))
1191
+ mtu "${ns_b}" veth_B-R1 ${ll_mtu}
1192
+ mtu "${ns_r1}" veth_R1-B ${ll_mtu}
1193
+
1194
+ mtu "" ${tun_a} $((${ll_mtu} + 1000))
1195
+ mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
1196
+
1197
+ run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 20 -s $((${ll_mtu} + 500)) ${dst} || return 1
1198
+
1199
+ # Check that exceptions were created
1200
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_c}" ${dst})"
1201
+ check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on Open vSwitch ${type} interface"
1202
+}
1203
+
1204
+test_pmtu_ipv4_ovs_vxlan4_exception() {
1205
+ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan 4 4
1206
+}
1207
+
1208
+test_pmtu_ipv6_ovs_vxlan4_exception() {
1209
+ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan 6 4
1210
+}
1211
+
1212
+test_pmtu_ipv4_ovs_geneve4_exception() {
1213
+ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 4 4
1214
+}
1215
+
1216
+test_pmtu_ipv6_ovs_geneve4_exception() {
1217
+ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 6 4
1218
+}
1219
+
1220
+test_pmtu_ipv4_ovs_vxlan6_exception() {
1221
+ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan 4 6
1222
+}
1223
+
1224
+test_pmtu_ipv6_ovs_vxlan6_exception() {
1225
+ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception vxlan 6 6
1226
+}
1227
+
1228
+test_pmtu_ipv4_ovs_geneve6_exception() {
1229
+ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 4 6
1230
+}
1231
+
1232
+test_pmtu_ipv6_ovs_geneve6_exception() {
1233
+ test_pmtu_ipvX_over_ovs_vxlanY_or_geneveY_exception geneve 6 6
1234
+}
1235
+
1236
+test_pmtu_ipvX_over_fouY_or_gueY() {
1237
+ inner_family=${1}
1238
+ outer_family=${2}
1239
+ encap=${3}
1240
+ ll_mtu=4000
1241
+
1242
+ setup namespaces routing ${encap}${outer_family}${inner_family} || return 2
1243
+ trace "${ns_a}" ${encap}_a "${ns_b}" ${encap}_b \
1244
+ "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
1245
+ "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B
1246
+
1247
+ if [ ${inner_family} -eq 4 ]; then
1248
+ ping=ping
1249
+ dst=${tunnel4_b_addr}
1250
+ else
1251
+ ping=${ping6}
1252
+ dst=${tunnel6_b_addr}
1253
+ fi
1254
+
1255
+ if [ "${encap}" = "gue" ]; then
1256
+ encap_overhead=4
1257
+ else
1258
+ encap_overhead=0
1259
+ fi
1260
+
1261
+ if [ ${outer_family} -eq 4 ]; then
1262
+ # IPv4 header UDP header
1263
+ exp_mtu=$((${ll_mtu} - 20 - 8 - ${encap_overhead}))
1264
+ else
1265
+ # IPv6 header Option 4 UDP header
1266
+ exp_mtu=$((${ll_mtu} - 40 - 8 - 8 - ${encap_overhead}))
1267
+ fi
1268
+
1269
+ # Create route exception by exceeding link layer MTU
1270
+ mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000))
1271
+ mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000))
1272
+ mtu "${ns_b}" veth_B-R1 ${ll_mtu}
1273
+ mtu "${ns_r1}" veth_R1-B ${ll_mtu}
1274
+
1275
+ mtu "${ns_a}" ${encap}_a $((${ll_mtu} + 1000))
1276
+ mtu "${ns_b}" ${encap}_b $((${ll_mtu} + 1000))
1277
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst}
1278
+
1279
+ # Check that exception was created
1280
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})"
1281
+ check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on ${encap} interface"
1282
+}
1283
+
1284
+test_pmtu_ipv4_fou4_exception() {
1285
+ test_pmtu_ipvX_over_fouY_or_gueY 4 4 fou
1286
+}
1287
+
1288
+test_pmtu_ipv6_fou4_exception() {
1289
+ test_pmtu_ipvX_over_fouY_or_gueY 6 4 fou
1290
+}
1291
+
1292
+test_pmtu_ipv4_fou6_exception() {
1293
+ test_pmtu_ipvX_over_fouY_or_gueY 4 6 fou
1294
+}
1295
+
1296
+test_pmtu_ipv6_fou6_exception() {
1297
+ test_pmtu_ipvX_over_fouY_or_gueY 6 6 fou
1298
+}
1299
+
1300
+test_pmtu_ipv4_gue4_exception() {
1301
+ test_pmtu_ipvX_over_fouY_or_gueY 4 4 gue
1302
+}
1303
+
1304
+test_pmtu_ipv6_gue4_exception() {
1305
+ test_pmtu_ipvX_over_fouY_or_gueY 6 4 gue
1306
+}
1307
+
1308
+test_pmtu_ipv4_gue6_exception() {
1309
+ test_pmtu_ipvX_over_fouY_or_gueY 4 6 gue
1310
+}
1311
+
1312
+test_pmtu_ipv6_gue6_exception() {
1313
+ test_pmtu_ipvX_over_fouY_or_gueY 6 6 gue
1314
+}
1315
+
1316
+test_pmtu_ipvX_over_ipvY_exception() {
1317
+ inner=${1}
1318
+ outer=${2}
1319
+ ll_mtu=4000
1320
+
1321
+ setup namespaces routing ip${inner}ip${outer} || return 2
1322
+
1323
+ trace "${ns_a}" ip_a "${ns_b}" ip_b \
1324
+ "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
1325
+ "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B
1326
+
1327
+ if [ ${inner} -eq 4 ]; then
1328
+ ping=ping
1329
+ dst=${tunnel4_b_addr}
1330
+ else
1331
+ ping=${ping6}
1332
+ dst=${tunnel6_b_addr}
1333
+ fi
1334
+
1335
+ if [ ${outer} -eq 4 ]; then
1336
+ # IPv4 header
1337
+ exp_mtu=$((${ll_mtu} - 20))
1338
+ else
1339
+ # IPv6 header Option 4
1340
+ exp_mtu=$((${ll_mtu} - 40 - 8))
1341
+ fi
1342
+
1343
+ # Create route exception by exceeding link layer MTU
1344
+ mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000))
1345
+ mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000))
1346
+ mtu "${ns_b}" veth_B-R1 ${ll_mtu}
1347
+ mtu "${ns_r1}" veth_R1-B ${ll_mtu}
1348
+
1349
+ mtu "${ns_a}" ip_a $((${ll_mtu} + 1000)) || return
1350
+ mtu "${ns_b}" ip_b $((${ll_mtu} + 1000)) || return
1351
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst}
1352
+
1353
+ # Check that exception was created
1354
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst})"
1355
+ check_pmtu_value ${exp_mtu} "${pmtu}" "exceeding link layer MTU on ip${inner}ip${outer} interface"
1356
+}
1357
+
1358
+test_pmtu_ipv4_ipv4_exception() {
1359
+ test_pmtu_ipvX_over_ipvY_exception 4 4
1360
+}
1361
+
1362
+test_pmtu_ipv6_ipv4_exception() {
1363
+ test_pmtu_ipvX_over_ipvY_exception 6 4
1364
+}
1365
+
1366
+test_pmtu_ipv4_ipv6_exception() {
1367
+ test_pmtu_ipvX_over_ipvY_exception 4 6
1368
+}
1369
+
1370
+test_pmtu_ipv6_ipv6_exception() {
1371
+ test_pmtu_ipvX_over_ipvY_exception 6 6
1372
+}
1373
+
2321374 test_pmtu_vti4_exception() {
2331375 setup namespaces veth vti4 xfrm4 || return 2
1376
+ trace "${ns_a}" veth_a "${ns_b}" veth_b \
1377
+ "${ns_a}" vti4_a "${ns_b}" vti4_b
2341378
2351379 veth_mtu=1500
2361380 vti_mtu=$((veth_mtu - 20))
....@@ -246,30 +1390,21 @@
2461390
2471391 # Send DF packet without exceeding link layer MTU, check that no
2481392 # exception is created
249
- ${ns_a} ping -q -M want -i 0.1 -w 2 -s ${ping_payload} ${vti4_b_addr} > /dev/null
250
- pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti4_b_addr})"
251
- if [ "${pmtu}" != "" ]; then
252
- err " unexpected exception created with PMTU ${pmtu} for IP payload length ${esp_payload_rfc4106}"
253
- return 1
254
- fi
1393
+ run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s ${ping_payload} ${tunnel4_b_addr}
1394
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel4_b_addr})"
1395
+ check_pmtu_value "" "${pmtu}" "sending packet smaller than PMTU (IP payload length ${esp_payload_rfc4106})" || return 1
2551396
2561397 # Now exceed link layer MTU by one byte, check that exception is created
257
- ${ns_a} ping -q -M want -i 0.1 -w 2 -s $((ping_payload + 1)) ${vti4_b_addr} > /dev/null
258
- pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti4_b_addr})"
259
- if [ "${pmtu}" = "" ]; then
260
- err " exception not created for IP payload length $((esp_payload_rfc4106 + 1))"
261
- return 1
262
- fi
263
-
264
- # ...with the right PMTU value
265
- if [ ${pmtu} -ne ${esp_payload_rfc4106} ]; then
266
- err " wrong PMTU ${pmtu} in exception, expected: ${esp_payload_rfc4106}"
267
- return 1
268
- fi
1398
+ # with the right PMTU value
1399
+ run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s $((ping_payload + 1)) ${tunnel4_b_addr}
1400
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel4_b_addr})"
1401
+ check_pmtu_value "${esp_payload_rfc4106}" "${pmtu}" "exceeding PMTU (IP payload length $((esp_payload_rfc4106 + 1)))"
2691402 }
2701403
2711404 test_pmtu_vti6_exception() {
2721405 setup namespaces veth vti6 xfrm6 || return 2
1406
+ trace "${ns_a}" veth_a "${ns_b}" veth_b \
1407
+ "${ns_a}" vti6_a "${ns_b}" vti6_b
2731408 fail=0
2741409
2751410 # Create route exception by exceeding link layer MTU
....@@ -277,28 +1412,21 @@
2771412 mtu "${ns_b}" veth_b 4000
2781413 mtu "${ns_a}" vti6_a 5000
2791414 mtu "${ns_b}" vti6_b 5000
280
- ${ns_a} ${ping6} -q -i 0.1 -w 2 -s 60000 ${vti6_b_addr} > /dev/null
1415
+ run_cmd ${ns_a} ${ping6} -q -i 0.1 -w 1 -s 60000 ${tunnel6_b_addr}
2811416
2821417 # Check that exception was created
283
- if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" = "" ]; then
284
- err " tunnel exceeding link layer MTU didn't create route exception"
285
- return 1
286
- fi
1418
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel6_b_addr})"
1419
+ check_pmtu_value any "${pmtu}" "creating tunnel exceeding link layer MTU" || return 1
2871420
2881421 # Decrease tunnel MTU, check for PMTU decrease in route exception
2891422 mtu "${ns_a}" vti6_a 3000
290
-
291
- if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" -ne 3000 ]; then
292
- err " decreasing tunnel MTU didn't decrease route exception PMTU"
293
- fail=1
294
- fi
1423
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel6_b_addr})"
1424
+ check_pmtu_value "3000" "${pmtu}" "decreasing tunnel MTU" || fail=1
2951425
2961426 # Increase tunnel MTU, check for PMTU increase in route exception
2971427 mtu "${ns_a}" vti6_a 9000
298
- if [ "$(route_get_dst_pmtu_from_exception "${ns_a}" ${vti6_b_addr})" -ne 9000 ]; then
299
- err " increasing tunnel MTU didn't increase route exception PMTU"
300
- fail=1
301
- fi
1428
+ pmtu="$(route_get_dst_pmtu_from_exception "${ns_a}" ${tunnel6_b_addr})"
1429
+ check_pmtu_value "9000" "${pmtu}" "increasing tunnel MTU" || fail=1
3021430
3031431 return ${fail}
3041432 }
....@@ -330,9 +1458,9 @@
3301458 test_pmtu_vti4_link_add_mtu() {
3311459 setup namespaces || return 2
3321460
333
- ${ns_a} ip link add vti4_a type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10
1461
+ run_cmd ${ns_a} ip link add vti4_a type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10
3341462 [ $? -ne 0 ] && err " vti not supported" && return 2
335
- ${ns_a} ip link del vti4_a
1463
+ run_cmd ${ns_a} ip link del vti4_a
3361464
3371465 fail=0
3381466
....@@ -340,7 +1468,7 @@
3401468 max=$((65535 - 20))
3411469 # Check invalid values first
3421470 for v in $((min - 1)) $((max + 1)); do
343
- ${ns_a} ip link add vti4_a mtu ${v} type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10 2>/dev/null
1471
+ run_cmd ${ns_a} ip link add vti4_a mtu ${v} type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10
3441472 # This can fail, or MTU can be adjusted to a proper value
3451473 [ $? -ne 0 ] && continue
3461474 mtu="$(link_get_mtu "${ns_a}" vti4_a)"
....@@ -348,14 +1476,14 @@
3481476 err " vti tunnel created with invalid MTU ${mtu}"
3491477 fail=1
3501478 fi
351
- ${ns_a} ip link del vti4_a
1479
+ run_cmd ${ns_a} ip link del vti4_a
3521480 done
3531481
3541482 # Now check valid values
3551483 for v in ${min} 1300 ${max}; do
356
- ${ns_a} ip link add vti4_a mtu ${v} type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10
1484
+ run_cmd ${ns_a} ip link add vti4_a mtu ${v} type vti local ${veth4_a_addr} remote ${veth4_b_addr} key 10
3571485 mtu="$(link_get_mtu "${ns_a}" vti4_a)"
358
- ${ns_a} ip link del vti4_a
1486
+ run_cmd ${ns_a} ip link del vti4_a
3591487 if [ "${mtu}" != "${v}" ]; then
3601488 err " vti MTU ${mtu} doesn't match configured value ${v}"
3611489 fail=1
....@@ -368,9 +1496,9 @@
3681496 test_pmtu_vti6_link_add_mtu() {
3691497 setup namespaces || return 2
3701498
371
- ${ns_a} ip link add vti6_a type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10
1499
+ run_cmd ${ns_a} ip link add vti6_a type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10
3721500 [ $? -ne 0 ] && err " vti6 not supported" && return 2
373
- ${ns_a} ip link del vti6_a
1501
+ run_cmd ${ns_a} ip link del vti6_a
3741502
3751503 fail=0
3761504
....@@ -378,7 +1506,7 @@
3781506 max=$((65535 - 40))
3791507 # Check invalid values first
3801508 for v in $((min - 1)) $((max + 1)); do
381
- ${ns_a} ip link add vti6_a mtu ${v} type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10 2>/dev/null
1509
+ run_cmd ${ns_a} ip link add vti6_a mtu ${v} type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10
3821510 # This can fail, or MTU can be adjusted to a proper value
3831511 [ $? -ne 0 ] && continue
3841512 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
....@@ -386,14 +1514,14 @@
3861514 err " vti6 tunnel created with invalid MTU ${v}"
3871515 fail=1
3881516 fi
389
- ${ns_a} ip link del vti6_a
1517
+ run_cmd ${ns_a} ip link del vti6_a
3901518 done
3911519
3921520 # Now check valid values
3931521 for v in 68 1280 1300 $((65535 - 40)); do
394
- ${ns_a} ip link add vti6_a mtu ${v} type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10
1522
+ run_cmd ${ns_a} ip link add vti6_a mtu ${v} type vti6 local ${veth6_a_addr} remote ${veth6_b_addr} key 10
3951523 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
396
- ${ns_a} ip link del vti6_a
1524
+ run_cmd ${ns_a} ip link del vti6_a
3971525 if [ "${mtu}" != "${v}" ]; then
3981526 err " vti6 MTU ${mtu} doesn't match configured value ${v}"
3991527 fail=1
....@@ -406,19 +1534,19 @@
4061534 test_pmtu_vti6_link_change_mtu() {
4071535 setup namespaces || return 2
4081536
409
- ${ns_a} ip link add dummy0 mtu 1500 type dummy
1537
+ run_cmd ${ns_a} ip link add dummy0 mtu 1500 type dummy
4101538 [ $? -ne 0 ] && err " dummy not supported" && return 2
411
- ${ns_a} ip link add dummy1 mtu 3000 type dummy
412
- ${ns_a} ip link set dummy0 up
413
- ${ns_a} ip link set dummy1 up
1539
+ run_cmd ${ns_a} ip link add dummy1 mtu 3000 type dummy
1540
+ run_cmd ${ns_a} ip link set dummy0 up
1541
+ run_cmd ${ns_a} ip link set dummy1 up
4141542
415
- ${ns_a} ip addr add ${dummy6_0_addr}/${dummy6_mask} dev dummy0
416
- ${ns_a} ip addr add ${dummy6_1_addr}/${dummy6_mask} dev dummy1
1543
+ run_cmd ${ns_a} ip addr add ${dummy6_0_prefix}1/${dummy6_mask} dev dummy0
1544
+ run_cmd ${ns_a} ip addr add ${dummy6_1_prefix}1/${dummy6_mask} dev dummy1
4171545
4181546 fail=0
4191547
4201548 # Create vti6 interface bound to device, passing MTU, check it
421
- ${ns_a} ip link add vti6_a mtu 1300 type vti6 remote ${dummy6_0_addr} local ${dummy6_0_addr}
1549
+ run_cmd ${ns_a} ip link add vti6_a mtu 1300 type vti6 remote ${dummy6_0_prefix}2 local ${dummy6_0_prefix}1
4221550 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
4231551 if [ ${mtu} -ne 1300 ]; then
4241552 err " vti6 MTU ${mtu} doesn't match configured value 1300"
....@@ -427,7 +1555,7 @@
4271555
4281556 # Move to another device with different MTU, without passing MTU, check
4291557 # MTU is adjusted
430
- ${ns_a} ip link set vti6_a type vti6 remote ${dummy6_1_addr} local ${dummy6_1_addr}
1558
+ run_cmd ${ns_a} ip link set vti6_a type vti6 remote ${dummy6_1_prefix}2 local ${dummy6_1_prefix}1
4311559 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
4321560 if [ ${mtu} -ne $((3000 - 40)) ]; then
4331561 err " vti MTU ${mtu} is not dummy MTU 3000 minus IPv6 header length"
....@@ -435,7 +1563,7 @@
4351563 fi
4361564
4371565 # Move it back, passing MTU, check MTU is not overridden
438
- ${ns_a} ip link set vti6_a mtu 1280 type vti6 remote ${dummy6_0_addr} local ${dummy6_0_addr}
1566
+ run_cmd ${ns_a} ip link set vti6_a mtu 1280 type vti6 remote ${dummy6_0_prefix}2 local ${dummy6_0_prefix}1
4391567 mtu="$(link_get_mtu "${ns_a}" vti6_a)"
4401568 if [ ${mtu} -ne 1280 ]; then
4411569 err " vti6 MTU ${mtu} doesn't match configured value 1280"
....@@ -445,33 +1573,352 @@
4451573 return ${fail}
4461574 }
4471575
448
-trap cleanup EXIT
1576
+check_command() {
1577
+ cmd=${1}
4491578
1579
+ if ! which ${cmd} > /dev/null 2>&1; then
1580
+ err " missing required command: '${cmd}'"
1581
+ return 1
1582
+ fi
1583
+ return 0
1584
+}
1585
+
1586
+test_cleanup_vxlanX_exception() {
1587
+ outer="${1}"
1588
+ encap="vxlan"
1589
+ ll_mtu=4000
1590
+
1591
+ check_command taskset || return 2
1592
+ cpu_list=$(grep -m 2 processor /proc/cpuinfo | cut -d ' ' -f 2)
1593
+
1594
+ setup namespaces routing ${encap}${outer} || return 2
1595
+ trace "${ns_a}" ${encap}_a "${ns_b}" ${encap}_b \
1596
+ "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
1597
+ "${ns_b}" veth_B-R1 "${ns_r1}" veth_R1-B
1598
+
1599
+ # Create route exception by exceeding link layer MTU
1600
+ mtu "${ns_a}" veth_A-R1 $((${ll_mtu} + 1000))
1601
+ mtu "${ns_r1}" veth_R1-A $((${ll_mtu} + 1000))
1602
+ mtu "${ns_b}" veth_B-R1 ${ll_mtu}
1603
+ mtu "${ns_r1}" veth_R1-B ${ll_mtu}
1604
+
1605
+ mtu "${ns_a}" ${encap}_a $((${ll_mtu} + 1000))
1606
+ mtu "${ns_b}" ${encap}_b $((${ll_mtu} + 1000))
1607
+
1608
+ # Fill exception cache for multiple CPUs (2)
1609
+ # we can always use inner IPv4 for that
1610
+ for cpu in ${cpu_list}; do
1611
+ run_cmd taskset --cpu-list ${cpu} ${ns_a} ping -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${tunnel4_b_addr}
1612
+ done
1613
+
1614
+ ${ns_a} ip link del dev veth_A-R1 &
1615
+ iplink_pid=$!
1616
+ sleep 1
1617
+ if [ "$(cat /proc/${iplink_pid}/cmdline 2>/dev/null | tr -d '\0')" = "iplinkdeldevveth_A-R1" ]; then
1618
+ err " can't delete veth device in a timely manner, PMTU dst likely leaked"
1619
+ return 1
1620
+ fi
1621
+}
1622
+
1623
+test_cleanup_ipv6_exception() {
1624
+ test_cleanup_vxlanX_exception 6
1625
+}
1626
+
1627
+test_cleanup_ipv4_exception() {
1628
+ test_cleanup_vxlanX_exception 4
1629
+}
1630
+
1631
+run_test() {
1632
+ (
1633
+ tname="$1"
1634
+ tdesc="$2"
1635
+
1636
+ unset IFS
1637
+
1638
+ # Since cleanup() relies on variables modified by this subshell, it
1639
+ # has to run in this context.
1640
+ trap cleanup EXIT
1641
+
1642
+ if [ "$VERBOSE" = "1" ]; then
1643
+ printf "\n##########################################################################\n\n"
1644
+ fi
1645
+
1646
+ eval test_${tname}
1647
+ ret=$?
1648
+
1649
+ if [ $ret -eq 0 ]; then
1650
+ printf "TEST: %-60s [ OK ]\n" "${tdesc}"
1651
+ elif [ $ret -eq 1 ]; then
1652
+ printf "TEST: %-60s [FAIL]\n" "${tdesc}"
1653
+ if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
1654
+ echo
1655
+ echo "Pausing. Hit enter to continue"
1656
+ read a
1657
+ fi
1658
+ err_flush
1659
+ exit 1
1660
+ elif [ $ret -eq 2 ]; then
1661
+ printf "TEST: %-60s [SKIP]\n" "${tdesc}"
1662
+ err_flush
1663
+ fi
1664
+
1665
+ return $ret
1666
+ )
1667
+ ret=$?
1668
+ [ $ret -ne 0 ] && exitcode=1
1669
+
1670
+ return $ret
1671
+}
1672
+
1673
+run_test_nh() {
1674
+ tname="$1"
1675
+ tdesc="$2"
1676
+
1677
+ USE_NH=yes
1678
+ run_test "${tname}" "${tdesc} - nexthop objects"
1679
+ USE_NH=no
1680
+}
1681
+
1682
+test_list_flush_ipv4_exception() {
1683
+ setup namespaces routing || return 2
1684
+ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
1685
+ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \
1686
+ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \
1687
+ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2
1688
+
1689
+ dst_prefix1="${prefix4}.${b_r1}."
1690
+ dst2="${prefix4}.${b_r2}.1"
1691
+
1692
+ # Set up initial MTU values
1693
+ mtu "${ns_a}" veth_A-R1 2000
1694
+ mtu "${ns_r1}" veth_R1-A 2000
1695
+ mtu "${ns_r1}" veth_R1-B 1500
1696
+ mtu "${ns_b}" veth_B-R1 1500
1697
+
1698
+ mtu "${ns_a}" veth_A-R2 2000
1699
+ mtu "${ns_r2}" veth_R2-A 2000
1700
+ mtu "${ns_r2}" veth_R2-B 1500
1701
+ mtu "${ns_b}" veth_B-R2 1500
1702
+
1703
+ fail=0
1704
+
1705
+ # Add 100 addresses for veth endpoint on B reached by default A route
1706
+ for i in $(seq 100 199); do
1707
+ run_cmd ${ns_b} ip addr add "${dst_prefix1}${i}" dev veth_B-R1
1708
+ done
1709
+
1710
+ # Create 100 cached route exceptions for path via R1, one via R2. Note
1711
+ # that with IPv4 we need to actually cause a route lookup that matches
1712
+ # the exception caused by ICMP, in order to actually have a cached
1713
+ # route, so we need to ping each destination twice
1714
+ for i in $(seq 100 199); do
1715
+ run_cmd ${ns_a} ping -q -M want -i 0.1 -c 2 -s 1800 "${dst_prefix1}${i}"
1716
+ done
1717
+ run_cmd ${ns_a} ping -q -M want -i 0.1 -c 2 -s 1800 "${dst2}"
1718
+
1719
+ if [ "$(${ns_a} ip -oneline route list cache | wc -l)" -ne 101 ]; then
1720
+ err " can't list cached exceptions"
1721
+ fail=1
1722
+ fi
1723
+
1724
+ run_cmd ${ns_a} ip route flush cache
1725
+ pmtu1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst_prefix}1)"
1726
+ pmtu2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst_prefix}2)"
1727
+ if [ -n "${pmtu1}" ] || [ -n "${pmtu2}" ] || \
1728
+ [ -n "$(${ns_a} ip route list cache)" ]; then
1729
+ err " can't flush cached exceptions"
1730
+ fail=1
1731
+ fi
1732
+
1733
+ return ${fail}
1734
+}
1735
+
1736
+test_list_flush_ipv6_exception() {
1737
+ setup namespaces routing || return 2
1738
+ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
1739
+ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \
1740
+ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \
1741
+ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2
1742
+
1743
+ dst_prefix1="${prefix6}:${b_r1}::"
1744
+ dst2="${prefix6}:${b_r2}::1"
1745
+
1746
+ # Set up initial MTU values
1747
+ mtu "${ns_a}" veth_A-R1 2000
1748
+ mtu "${ns_r1}" veth_R1-A 2000
1749
+ mtu "${ns_r1}" veth_R1-B 1500
1750
+ mtu "${ns_b}" veth_B-R1 1500
1751
+
1752
+ mtu "${ns_a}" veth_A-R2 2000
1753
+ mtu "${ns_r2}" veth_R2-A 2000
1754
+ mtu "${ns_r2}" veth_R2-B 1500
1755
+ mtu "${ns_b}" veth_B-R2 1500
1756
+
1757
+ fail=0
1758
+
1759
+ # Add 100 addresses for veth endpoint on B reached by default A route
1760
+ for i in $(seq 100 199); do
1761
+ run_cmd ${ns_b} ip addr add "${dst_prefix1}${i}" dev veth_B-R1
1762
+ done
1763
+
1764
+ # Create 100 cached route exceptions for path via R1, one via R2
1765
+ for i in $(seq 100 199); do
1766
+ run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s 1800 "${dst_prefix1}${i}"
1767
+ done
1768
+ run_cmd ${ns_a} ping -q -M want -i 0.1 -w 1 -s 1800 "${dst2}"
1769
+ if [ "$(${ns_a} ip -oneline -6 route list cache | wc -l)" -ne 101 ]; then
1770
+ err " can't list cached exceptions"
1771
+ fail=1
1772
+ fi
1773
+
1774
+ run_cmd ${ns_a} ip -6 route flush cache
1775
+ pmtu1="$(route_get_dst_pmtu_from_exception "${ns_a}" "${dst_prefix1}100")"
1776
+ pmtu2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})"
1777
+ if [ -n "${pmtu1}" ] || [ -n "${pmtu2}" ] || \
1778
+ [ -n "$(${ns_a} ip -6 route list cache)" ]; then
1779
+ err " can't flush cached exceptions"
1780
+ fail=1
1781
+ fi
1782
+
1783
+ return ${fail}
1784
+}
1785
+
1786
+test_pmtu_ipvX_route_change() {
1787
+ family=${1}
1788
+
1789
+ setup namespaces routing || return 2
1790
+ trace "${ns_a}" veth_A-R1 "${ns_r1}" veth_R1-A \
1791
+ "${ns_r1}" veth_R1-B "${ns_b}" veth_B-R1 \
1792
+ "${ns_a}" veth_A-R2 "${ns_r2}" veth_R2-A \
1793
+ "${ns_r2}" veth_R2-B "${ns_b}" veth_B-R2
1794
+
1795
+ if [ ${family} -eq 4 ]; then
1796
+ ping=ping
1797
+ dst1="${prefix4}.${b_r1}.1"
1798
+ dst2="${prefix4}.${b_r2}.1"
1799
+ gw="${prefix4}.${a_r1}.2"
1800
+ else
1801
+ ping=${ping6}
1802
+ dst1="${prefix6}:${b_r1}::1"
1803
+ dst2="${prefix6}:${b_r2}::1"
1804
+ gw="${prefix6}:${a_r1}::2"
1805
+ fi
1806
+
1807
+ # Set up initial MTU values
1808
+ mtu "${ns_a}" veth_A-R1 2000
1809
+ mtu "${ns_r1}" veth_R1-A 2000
1810
+ mtu "${ns_r1}" veth_R1-B 1400
1811
+ mtu "${ns_b}" veth_B-R1 1400
1812
+
1813
+ mtu "${ns_a}" veth_A-R2 2000
1814
+ mtu "${ns_r2}" veth_R2-A 2000
1815
+ mtu "${ns_r2}" veth_R2-B 1500
1816
+ mtu "${ns_b}" veth_B-R2 1500
1817
+
1818
+ # Create route exceptions
1819
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst1}
1820
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s 1800 ${dst2}
1821
+
1822
+ # Check that exceptions have been created with the correct PMTU
1823
+ pmtu_1="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst1})"
1824
+ check_pmtu_value "1400" "${pmtu_1}" "exceeding MTU" || return 1
1825
+ pmtu_2="$(route_get_dst_pmtu_from_exception "${ns_a}" ${dst2})"
1826
+ check_pmtu_value "1500" "${pmtu_2}" "exceeding MTU" || return 1
1827
+
1828
+ # Replace the route from A to R1
1829
+ run_cmd ${ns_a} ip route change default via ${gw}
1830
+
1831
+ # Delete the device in A
1832
+ run_cmd ${ns_a} ip link del "veth_A-R1"
1833
+}
1834
+
1835
+test_pmtu_ipv4_route_change() {
1836
+ test_pmtu_ipvX_route_change 4
1837
+}
1838
+
1839
+test_pmtu_ipv6_route_change() {
1840
+ test_pmtu_ipvX_route_change 6
1841
+}
1842
+
1843
+usage() {
1844
+ echo
1845
+ echo "$0 [OPTIONS] [TEST]..."
1846
+ echo "If no TEST argument is given, all tests will be run."
1847
+ echo
1848
+ echo "Options"
1849
+ echo " --trace: capture traffic to TEST_INTERFACE.pcap"
1850
+ echo
1851
+ echo "Available tests${tests}"
1852
+ exit 1
1853
+}
1854
+
1855
+################################################################################
1856
+#
4501857 exitcode=0
4511858 desc=0
1859
+
1860
+while getopts :ptv o
1861
+do
1862
+ case $o in
1863
+ p) PAUSE_ON_FAIL=yes;;
1864
+ v) VERBOSE=1;;
1865
+ t) if which tcpdump > /dev/null 2>&1; then
1866
+ TRACING=1
1867
+ else
1868
+ echo "=== tcpdump not available, tracing disabled"
1869
+ fi
1870
+ ;;
1871
+ *) usage;;
1872
+ esac
1873
+done
1874
+shift $(($OPTIND-1))
1875
+
4521876 IFS="
4531877 "
1878
+
1879
+for arg do
1880
+ # Check first that all requested tests are available before running any
1881
+ command -v > /dev/null "test_${arg}" || { echo "=== Test ${arg} not found"; usage; }
1882
+done
1883
+
1884
+trap cleanup EXIT
1885
+
1886
+# start clean
1887
+cleanup
1888
+
1889
+HAVE_NH=no
1890
+ip nexthop ls >/dev/null 2>&1
1891
+[ $? -eq 0 ] && HAVE_NH=yes
1892
+
1893
+name=""
1894
+desc=""
1895
+rerun_nh=0
4541896 for t in ${tests}; do
455
- [ $desc -eq 0 ] && name="${t}" && desc=1 && continue || desc=0
1897
+ [ "${name}" = "" ] && name="${t}" && continue
1898
+ [ "${desc}" = "" ] && desc="${t}" && continue
4561899
457
- (
458
- unset IFS
459
- eval test_${name}
460
- ret=$?
461
- cleanup
1900
+ if [ "${HAVE_NH}" = "yes" ]; then
1901
+ rerun_nh="${t}"
1902
+ fi
4621903
463
- if [ $ret -eq 0 ]; then
464
- printf "TEST: %-60s [ OK ]\n" "${t}"
465
- elif [ $ret -eq 1 ]; then
466
- printf "TEST: %-60s [FAIL]\n" "${t}"
467
- err_flush
468
- exit 1
469
- elif [ $ret -eq 2 ]; then
470
- printf "TEST: %-60s [SKIP]\n" "${t}"
471
- err_flush
1904
+ run_this=1
1905
+ for arg do
1906
+ [ "${arg}" != "${arg#--*}" ] && continue
1907
+ [ "${arg}" = "${name}" ] && run_this=1 && break
1908
+ run_this=0
1909
+ done
1910
+ if [ $run_this -eq 1 ]; then
1911
+ run_test "${name}" "${desc}"
1912
+ # if test was skipped no need to retry with nexthop objects
1913
+ [ $? -eq 2 ] && rerun_nh=0
1914
+
1915
+ if [ "${rerun_nh}" = "1" ]; then
1916
+ run_test_nh "${name}" "${desc}"
4721917 fi
473
- )
474
- [ $? -ne 0 ] && exitcode=1
1918
+ fi
1919
+ name=""
1920
+ desc=""
1921
+ rerun_nh=0
4751922 done
4761923
4771924 exit ${exitcode}