Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/netinet/fibs_test.sh
39483 views
1
#
2
# Copyright (c) 2014 Spectra Logic Corporation
3
# All rights reserved.
4
#
5
# Redistribution and use in source and binary forms, with or without
6
# modification, are permitted provided that the following conditions
7
# are met:
8
# 1. Redistributions of source code must retain the above copyright
9
# notice, this list of conditions, and the following disclaimer,
10
# without modification.
11
# 2. Redistributions in binary form must reproduce at minimum a disclaimer
12
# substantially similar to the "NO WARRANTY" disclaimer below
13
# ("Disclaimer") and any redistribution must be conditioned upon
14
# including a substantially similar Disclaimer requirement for further
15
# binary redistribution.
16
#
17
# NO WARRANTY
18
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR
21
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22
# HOLDERS OR CONTRIBUTORS BE LIABLE FOR SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
27
# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
# POSSIBILITY OF SUCH DAMAGES.
29
#
30
# Authors: Alan Somers (Spectra Logic Corporation)
31
#
32
33
# arpresolve should check the interface fib for routes to a target when
34
# creating an ARP table entry. This is a regression for kern/167947, where
35
# arpresolve only checked the default route.
36
#
37
# Outline:
38
# Create two connected epair(4) interfaces
39
# Use nping (from security/nmap) to send an ICMP echo request from one
40
# interface to the other, spoofing the source IP. The source IP must be
41
# spoofed, or else it will already have an entry in the arp table.
42
# Check whether an arp entry exists for the spoofed IP
43
atf_test_case arpresolve_checks_interface_fib cleanup
44
arpresolve_checks_interface_fib_head()
45
{
46
atf_set "descr" "arpresolve should check the interface fib, not the default fib, for routes"
47
atf_set "require.user" "root"
48
atf_set "require.progs" "nping"
49
}
50
arpresolve_checks_interface_fib_body()
51
{
52
# Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
53
# and a non-default fib
54
ADDR0="192.0.2.2"
55
ADDR1="192.0.2.3"
56
SUBNET="192.0.2.0"
57
# Due to bug TBD (regressed by multiple_fibs_on_same_subnet) we need
58
# diffferent subnet masks, or FIB1 won't have a subnet route.
59
MASK0="24"
60
MASK1="25"
61
# Spoof a MAC that is reserved per RFC7042
62
SPOOF_ADDR="192.0.2.4"
63
SPOOF_MAC="00:00:5E:00:53:00"
64
65
# Check system configuration
66
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
67
atf_skip "This test requires net.add_addr_allfibs=0"
68
fi
69
get_fibs 2
70
71
# Configure epair interfaces
72
get_epair
73
setup_iface "$EPAIRA" "$FIB0" inet ${ADDR0} ${MASK0}
74
setup_iface "$EPAIRB" "$FIB1" inet ${ADDR1} ${MASK1}
75
76
# Send an ICMP echo request with a spoofed source IP
77
setfib "$FIB0" nping -c 1 -e ${EPAIRA} -S ${SPOOF_ADDR} \
78
--source-mac ${SPOOF_MAC} --icmp --icmp-type "echo-request" \
79
--icmp-code 0 --icmp-id 0xdead --icmp-seq 1 --data 0xbeef \
80
${ADDR1}
81
# For informational and debugging purposes only, look for the
82
# characteristic error message
83
dmesg | grep "llinfo.*${SPOOF_ADDR}"
84
# Check that the ARP entry exists
85
atf_check -o match:"${SPOOF_ADDR}.*expires" setfib "$FIB1" arp ${SPOOF_ADDR}
86
}
87
arpresolve_checks_interface_fib_cleanup()
88
{
89
cleanup_ifaces
90
}
91
92
93
# Regression test for kern/187549
94
atf_test_case loopback_and_network_routes_on_nondefault_fib cleanup
95
loopback_and_network_routes_on_nondefault_fib_head()
96
{
97
atf_set "descr" "When creating and deleting loopback IPv4 routes, use the interface's fib"
98
atf_set "require.user" "root"
99
}
100
101
loopback_and_network_routes_on_nondefault_fib_body()
102
{
103
# Configure the TAP interface to use an RFC5737 nonrouteable address
104
# and a non-default fib
105
ADDR="192.0.2.2"
106
SUBNET="192.0.2.0"
107
MASK="24"
108
109
# Check system configuration
110
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
111
atf_skip "This test requires net.add_addr_allfibs=0"
112
fi
113
get_fibs 1
114
115
# Configure a TAP interface
116
setup_tap ${FIB0} inet ${ADDR} ${MASK}
117
118
# Check whether the host route exists in only the correct FIB
119
setfib ${FIB0} netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
120
if [ 0 -ne $? ]; then
121
setfib ${FIB0} netstat -rn -f inet
122
atf_fail "Host route did not appear in the correct FIB"
123
fi
124
setfib 0 netstat -rn -f inet | grep -q "^${ADDR}.*UHS.*lo0"
125
if [ 0 -eq $? ]; then
126
setfib 0 netstat -rn -f inet
127
atf_fail "Host route appeared in the wrong FIB"
128
fi
129
130
# Check whether the network route exists in only the correct FIB
131
setfib ${FIB0} netstat -rn -f inet | \
132
grep -q "^${SUBNET}/${MASK}.*${TAPD}"
133
if [ 0 -ne $? ]; then
134
setfib ${FIB0} netstat -rn -f inet
135
atf_fail "Network route did not appear in the correct FIB"
136
fi
137
setfib 0 netstat -rn -f inet | \
138
grep -q "^${SUBNET}/${MASK}.*${TAPD}"
139
if [ 0 -eq $? ]; then
140
setfib 0 netstat -rn -f inet
141
atf_fail "Network route appeared in the wrong FIB"
142
fi
143
}
144
145
loopback_and_network_routes_on_nondefault_fib_cleanup()
146
{
147
cleanup_ifaces
148
}
149
150
atf_test_case loopback_and_network_routes_on_nondefault_fib_inet6 cleanup
151
loopback_and_network_routes_on_nondefault_fib_inet6_head()
152
{
153
atf_set "descr" "When creating and deleting loopback IPv6 routes, use the interface's fib"
154
atf_set "require.user" "root"
155
}
156
157
loopback_and_network_routes_on_nondefault_fib_inet6_body()
158
{
159
# Configure the TAP interface to use a nonrouteable RFC3849
160
# address and a non-default fib
161
ADDR="2001:db8::2"
162
SUBNET="2001:db8::"
163
MASK="64"
164
165
# Check system configuration
166
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
167
atf_skip "This test requires net.add_addr_allfibs=0"
168
fi
169
get_fibs 1
170
171
# Configure a TAP interface
172
setup_tap ${FIB0} inet6 ${ADDR} ${MASK}
173
174
# Check whether the host route exists in only the correct FIB
175
setfib ${FIB0} netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0"
176
if [ 0 -ne $? ]; then
177
setfib ${FIB0} netstat -rn -f inet6
178
atf_fail "Host route did not appear in the correct FIB"
179
fi
180
setfib 0 netstat -rn -f inet6 | grep -q "^${ADDR}.*UHS.*lo0"
181
if [ 0 -eq $? ]; then
182
setfib 0 netstat -rn -f inet6
183
atf_fail "Host route appeared in the wrong FIB"
184
fi
185
186
# Check whether the network route exists in only the correct FIB
187
setfib ${FIB0} netstat -rn -f inet6 | \
188
grep -q "^${SUBNET}/${MASK}.*${TAPD}"
189
if [ 0 -ne $? ]; then
190
setfib ${FIB0} netstat -rn -f inet6
191
atf_fail "Network route did not appear in the correct FIB"
192
fi
193
setfib 0 netstat -rn -f inet6 | \
194
grep -q "^${SUBNET}/${MASK}.*${TAPD}"
195
if [ 0 -eq $? ]; then
196
setfib 0 netstat -rn -f inet6
197
atf_fail "Network route appeared in the wrong FIB"
198
fi
199
}
200
201
loopback_and_network_routes_on_nondefault_fib_inet6_cleanup()
202
{
203
cleanup_ifaces
204
}
205
206
207
# Regression test for kern/187552
208
atf_test_case default_route_with_multiple_fibs_on_same_subnet cleanup
209
default_route_with_multiple_fibs_on_same_subnet_head()
210
{
211
atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv4 routes"
212
atf_set "require.user" "root"
213
}
214
215
default_route_with_multiple_fibs_on_same_subnet_body()
216
{
217
# Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
218
# and a non-default fib
219
ADDR0="192.0.2.2"
220
ADDR1="192.0.2.3"
221
GATEWAY="192.0.2.1"
222
SUBNET="192.0.2.0"
223
MASK="24"
224
225
# Check system configuration
226
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
227
atf_skip "This test requires net.add_addr_allfibs=0"
228
fi
229
get_fibs 2
230
231
# Configure TAP interfaces
232
setup_tap "$FIB0" inet ${ADDR0} ${MASK}
233
TAP0=$TAP
234
setup_tap "$FIB1" inet ${ADDR1} ${MASK}
235
TAP1=$TAP
236
237
# Attempt to add default routes
238
setfib ${FIB0} route add default ${GATEWAY}
239
setfib ${FIB1} route add default ${GATEWAY}
240
241
# Verify that the default route exists for both fibs, with their
242
# respective interfaces.
243
atf_check -o match:"^default.*${TAP0}$" \
244
setfib ${FIB0} netstat -rn -f inet
245
atf_check -o match:"^default.*${TAP1}$" \
246
setfib ${FIB1} netstat -rn -f inet
247
}
248
249
default_route_with_multiple_fibs_on_same_subnet_cleanup()
250
{
251
cleanup_ifaces
252
}
253
254
atf_test_case default_route_with_multiple_fibs_on_same_subnet_inet6 cleanup
255
default_route_with_multiple_fibs_on_same_subnet_inet6_head()
256
{
257
atf_set "descr" "Multiple interfaces on the same subnet but with different fibs can both have default IPv6 routes"
258
atf_set "require.user" "root"
259
}
260
261
default_route_with_multiple_fibs_on_same_subnet_inet6_body()
262
{
263
# Configure the TAP interfaces to use nonrouteable RFC3849
264
# addresses and non-default FIBs
265
ADDR0="2001:db8::2"
266
ADDR1="2001:db8::3"
267
GATEWAY="2001:db8::1"
268
SUBNET="2001:db8::"
269
MASK="64"
270
271
# Check system configuration
272
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
273
atf_skip "This test requires net.add_addr_allfibs=0"
274
fi
275
get_fibs 2
276
277
# Configure TAP interfaces
278
setup_tap "$FIB0" inet6 ${ADDR0} ${MASK}
279
TAP0=$TAP
280
setup_tap "$FIB1" inet6 ${ADDR1} ${MASK}
281
TAP1=$TAP
282
283
# Attempt to add default routes
284
setfib ${FIB0} route -6 add default ${GATEWAY}
285
setfib ${FIB1} route -6 add default ${GATEWAY}
286
287
# Verify that the default route exists for both fibs, with their
288
# respective interfaces.
289
atf_check -o match:"^default.*${TAP0}$" \
290
setfib ${FIB0} netstat -rn -f inet6
291
atf_check -o match:"^default.*${TAP1}$" \
292
setfib ${FIB1} netstat -rn -f inet6
293
}
294
295
default_route_with_multiple_fibs_on_same_subnet_inet6_cleanup()
296
{
297
cleanup_ifaces
298
}
299
300
301
# Regression test for PR kern/189089
302
# Create two tap interfaces and assign them both the same IP address but with
303
# different netmasks, and both on the default FIB. Then remove one's IP
304
# address. Hopefully the machine won't panic.
305
atf_test_case same_ip_multiple_ifaces_fib0 cleanup
306
same_ip_multiple_ifaces_fib0_head()
307
{
308
atf_set "descr" "Can remove an IPv4 alias from an interface when the same IPv4 is also assigned to another interface."
309
atf_set "require.user" "root"
310
}
311
same_ip_multiple_ifaces_fib0_body()
312
{
313
ADDR="192.0.2.2"
314
MASK0="24"
315
MASK1="32"
316
317
# Unlike most of the tests in this file, this is applicable regardless
318
# of net.add_addr_allfibs
319
320
# Setup the interfaces, then remove one alias. It should not panic.
321
setup_tap 0 inet ${ADDR} ${MASK0}
322
TAP0=${TAP}
323
# After commit 361a8395f0b0e6f254fd138798232529679d99f6 it became
324
# an error to assign the same interface address twice.
325
atf_expect_fail "The test results in an ifconfig error and thus spuriously fails"
326
setup_tap 0 inet ${ADDR} ${MASK1}
327
TAP1=${TAP}
328
ifconfig ${TAP1} -alias ${ADDR}
329
330
# Do it again, in the opposite order. It should not panic.
331
setup_tap 0 inet ${ADDR} ${MASK0}
332
TAP0=${TAP}
333
setup_tap 0 inet ${ADDR} ${MASK1}
334
TAP1=${TAP}
335
ifconfig ${TAP0} -alias ${ADDR}
336
}
337
same_ip_multiple_ifaces_fib0_cleanup()
338
{
339
cleanup_ifaces
340
}
341
342
# Regression test for PR kern/189088
343
# Test that removing an IP address works even if the same IP is assigned to a
344
# different interface, on a different FIB. Tests the same code that whose
345
# panic was regressed by same_ip_multiple_ifaces_fib0.
346
# Create two tap interfaces and assign them both the same IP address but with
347
# different netmasks, and on different FIBs. Then remove one's IP
348
# address. Hopefully the machine won't panic. Also, the IP's hostroute should
349
# dissappear from the correct fib.
350
atf_test_case same_ip_multiple_ifaces cleanup
351
same_ip_multiple_ifaces_head()
352
{
353
atf_set "descr" "Can remove an IPv4 alias from an interface when the same address is also assigned to another interface, on non-default FIBs."
354
atf_set "require.user" "root"
355
}
356
same_ip_multiple_ifaces_body()
357
{
358
ADDR="192.0.2.2"
359
MASK0="24"
360
MASK1="32"
361
362
# Unlike most of the tests in this file, this is applicable regardless
363
# of net.add_addr_allfibs
364
get_fibs 4
365
366
# Setup the interfaces, then remove one alias. It should not panic.
367
setup_tap ${FIB0} inet ${ADDR} ${MASK0}
368
TAP0=${TAP}
369
setup_tap ${FIB1} inet ${ADDR} ${MASK1}
370
TAP1=${TAP}
371
ifconfig ${TAP1} -alias ${ADDR}
372
atf_check -o not-match:"^${ADDR}[[:space:]]" \
373
setfib ${FIB1} netstat -rn -f inet
374
375
# Do it again, in the opposite order. It should not panic.
376
setup_tap ${FIB2} inet ${ADDR} ${MASK0}
377
TAP0=${TAP}
378
setup_tap ${FIB3} inet ${ADDR} ${MASK1}
379
TAP1=${TAP}
380
ifconfig ${TAP0} -alias ${ADDR}
381
atf_check -o not-match:"^${ADDR}[[:space:]]" \
382
setfib ${FIB2} netstat -rn -f inet
383
}
384
same_ip_multiple_ifaces_cleanup()
385
{
386
# Due to PR kern/189088, we must destroy the interfaces in LIFO order
387
# in order for the routes to be correctly cleaned up.
388
for TAPD in `tail -r "ifaces_to_cleanup"`; do
389
echo ifconfig ${TAPD} destroy
390
ifconfig ${TAPD} destroy
391
done
392
}
393
394
atf_test_case same_ip_multiple_ifaces_inet6 cleanup
395
same_ip_multiple_ifaces_inet6_head()
396
{
397
atf_set "descr" "Can remove an IPv6 alias from an interface when the same address is also assigned to another interface, on non-default FIBs."
398
atf_set "require.user" "root"
399
}
400
same_ip_multiple_ifaces_inet6_body()
401
{
402
ADDR="2001:db8::2"
403
MASK0="64"
404
MASK1="128"
405
406
# Unlike most of the tests in this file, this is applicable regardless
407
# of net.add_addr_allfibs
408
get_fibs 2
409
410
# Setup the interfaces, then remove one alias. It should not panic.
411
setup_tap ${FIB0} inet6 ${ADDR} ${MASK0}
412
TAP0=${TAP}
413
setup_tap ${FIB1} inet6 ${ADDR} ${MASK1}
414
TAP1=${TAP}
415
atf_check -s exit:0 ifconfig ${TAP1} inet6 ${ADDR} -alias
416
atf_check -o not-match:"^${ADDR}[[:space:]]" \
417
setfib ${FIB1} netstat -rn -f inet6
418
ifconfig ${TAP1} destroy
419
ifconfig ${TAP0} destroy
420
421
# Do it again, in the opposite order. It should not panic.
422
setup_tap ${FIB0} inet6 ${ADDR} ${MASK0}
423
TAP0=${TAP}
424
setup_tap ${FIB1} inet6 ${ADDR} ${MASK1}
425
TAP1=${TAP}
426
atf_check -s exit:0 ifconfig ${TAP0} inet6 ${ADDR} -alias
427
atf_check -o not-match:"^${ADDR}[[:space:]]" \
428
setfib ${FIB0} netstat -rn -f inet6
429
}
430
same_ip_multiple_ifaces_inet6_cleanup()
431
{
432
cleanup_ifaces
433
}
434
435
atf_test_case slaac_on_nondefault_fib6 cleanup
436
slaac_on_nondefault_fib6_head()
437
{
438
atf_set "descr" "SLAAC correctly installs routes on non-default FIBs"
439
atf_set "require.user" "root"
440
atf_set "require.config" "allow_sysctl_side_effects"
441
}
442
slaac_on_nondefault_fib6_body()
443
{
444
# Configure the epair interfaces to use nonrouteable RFC3849
445
# addresses and non-default FIBs
446
PREFIX="2001:db8:$(printf "%x" `jot -r 1 0 65535`):$(printf "%x" `jot -r 1 0 65535`)"
447
ADDR="$PREFIX::2"
448
GATEWAY="$PREFIX::1"
449
SUBNET="$PREFIX:"
450
MASK="64"
451
452
# Check system configuration
453
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
454
atf_skip "This test requires net.add_addr_allfibs=0"
455
fi
456
get_fibs 2
457
458
sysctl -n "net.inet6.ip6.rfc6204w3" >> "rfc6204w3.state"
459
sysctl -n "net.inet6.ip6.forwarding" >> "forwarding.state"
460
# Enable forwarding so the kernel will send RAs
461
sysctl net.inet6.ip6.forwarding=1
462
# Enable RFC6204W3 mode so the kernel will enable default router
463
# selection while also forwarding packets
464
sysctl net.inet6.ip6.rfc6204w3=1
465
466
# Configure epair interfaces
467
get_epair
468
setup_iface "$EPAIRA" "$FIB0" inet6 ${ADDR} ${MASK}
469
echo setfib $FIB1 ifconfig "$EPAIRB" inet6 -ifdisabled accept_rtadv fib $FIB1 up
470
setfib $FIB1 ifconfig "$EPAIRB" inet6 -ifdisabled accept_rtadv fib $FIB1 up
471
rtadvd -p rtadvd.pid -C rtadvd.sock -c /dev/null "$EPAIRA"
472
rtsol "$EPAIRB"
473
474
# Check SLAAC address
475
atf_check -o match:"inet6 ${SUBNET}.*prefixlen ${MASK}.*autoconf" \
476
ifconfig "$EPAIRB"
477
# Check local route
478
atf_check -o match:"${SUBNET}.*\<UHS\>.*lo0" \
479
netstat -rnf inet6 -F $FIB1
480
# Check subnet route
481
atf_check -o match:"${SUBNET}:/${MASK}.*\<U\>.*$EPAIRB" \
482
netstat -rnf inet6 -F $FIB1
483
# Check default route
484
atf_check -o match:"default.*\<UG\>.*$EPAIRB" \
485
netstat -rnf inet6 -F $FIB1
486
487
# Check that none of the above routes appeared on other routes
488
for fib in $( seq 0 $(($(sysctl -n net.fibs) - 1))); do
489
if [ "$fib" = "$FIB1" -o "$fib" = "$FIB0" ]; then
490
continue
491
fi
492
atf_check -o not-match:"${SUBNET}.*\<UHS\>.*lo0" \
493
netstat -rnf inet6 -F $fib
494
atf_check -o not-match:"${SUBNET}:/${MASK}.*\<U\>.*$EPAIRB" \
495
netstat -rnf inet6 -F $fib
496
atf_check -o not-match:"default.*\<UG\>.*$EPAIRB" \
497
netstat -rnf inet6 -F $fib
498
done
499
}
500
slaac_on_nondefault_fib6_cleanup()
501
{
502
if [ -f "rtadvd.pid" ]; then
503
# rtadvd can take a long time to shutdown. Use SIGKILL to kill
504
# it right away. The downside to using SIGKILL is that it
505
# won't send final RAs to all interfaces, but we don't care
506
# because we're about to destroy its interface anyway.
507
pkill -kill -F rtadvd.pid
508
rm -f rtadvd.pid
509
fi
510
cleanup_ifaces
511
if [ -f "forwarding.state" ] ; then
512
sysctl "net.inet6.ip6.forwarding"=`cat "forwarding.state"`
513
rm "forwarding.state"
514
fi
515
if [ -f "rfc6204w3.state" ] ; then
516
sysctl "net.inet6.ip6.rfc6204w3"=`cat "rfc6204w3.state"`
517
rm "rfc6204w3.state"
518
fi
519
}
520
521
# Regression test for kern/187550
522
atf_test_case subnet_route_with_multiple_fibs_on_same_subnet cleanup
523
subnet_route_with_multiple_fibs_on_same_subnet_head()
524
{
525
atf_set "descr" "Multiple FIBs can have IPv4 subnet routes for the same subnet"
526
atf_set "require.user" "root"
527
}
528
529
subnet_route_with_multiple_fibs_on_same_subnet_body()
530
{
531
# Configure the TAP interfaces to use a RFC5737 nonrouteable addresses
532
# and a non-default fib
533
ADDR0="192.0.2.2"
534
ADDR1="192.0.2.3"
535
SUBNET="192.0.2.0"
536
MASK="24"
537
538
# Check system configuration
539
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
540
atf_skip "This test requires net.add_addr_allfibs=0"
541
fi
542
get_fibs 2
543
544
# Configure TAP interfaces
545
setup_tap "$FIB0" inet ${ADDR0} ${MASK}
546
setup_tap "$FIB1" inet ${ADDR1} ${MASK}
547
548
# Check that a subnet route exists on both fibs
549
atf_check -o ignore setfib "$FIB0" route get $ADDR1
550
atf_check -o ignore setfib "$FIB1" route get $ADDR0
551
}
552
553
subnet_route_with_multiple_fibs_on_same_subnet_cleanup()
554
{
555
cleanup_ifaces
556
}
557
558
atf_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6 cleanup
559
subnet_route_with_multiple_fibs_on_same_subnet_inet6_head()
560
{
561
atf_set "descr" "Multiple FIBs can have IPv6 subnet routes for the same subnet"
562
atf_set "require.user" "root"
563
}
564
565
subnet_route_with_multiple_fibs_on_same_subnet_inet6_body()
566
{
567
# Configure the TAP interfaces to use a RFC3849 nonrouteable addresses
568
# and a non-default fib
569
ADDR0="2001:db8::2"
570
ADDR1="2001:db8::3"
571
SUBNET="2001:db8::"
572
MASK="64"
573
574
# Check system configuration
575
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
576
atf_skip "This test requires net.add_addr_allfibs=0"
577
fi
578
get_fibs 2
579
580
# Configure TAP interfaces
581
setup_tap "$FIB0" inet6 ${ADDR0} ${MASK}
582
setup_tap "$FIB1" inet6 ${ADDR1} ${MASK}
583
584
# Check that a subnet route exists on both fibs
585
atf_check -o ignore setfib "$FIB0" route -6 get $ADDR1
586
atf_check -o ignore setfib "$FIB1" route -6 get $ADDR0
587
}
588
589
subnet_route_with_multiple_fibs_on_same_subnet_inet6_cleanup()
590
{
591
cleanup_ifaces
592
}
593
594
# Test that source address selection works correctly for UDP packets with
595
# SO_DONTROUTE set that are sent on non-default FIBs.
596
# This bug was discovered with "setfib 1 netperf -t UDP_STREAM -H some_host"
597
# Regression test for kern/187553
598
#
599
# The root cause was that ifa_ifwithnet() did not have a fib argument. It
600
# would return an address from an interface on any FIB that had a subnet route
601
# for the destination. If more than one were available, it would choose the
602
# most specific. This is most easily tested by creating a FIB without a
603
# default route, then trying to send a UDP packet with SO_DONTROUTE set to an
604
# address which is not routable on that FIB. Absent the fix for this bug,
605
# in_pcbladdr would choose an interface on any FIB with a default route. With
606
# the fix, you will get EUNREACH or ENETUNREACH.
607
atf_test_case udp_dontroute cleanup
608
udp_dontroute_head()
609
{
610
atf_set "descr" "Source address selection for UDP packets with SO_DONTROUTE on non-default FIBs works"
611
atf_set "require.user" "root"
612
}
613
614
udp_dontroute_body()
615
{
616
# Configure the TAP interface to use an RFC5737 nonrouteable address
617
# and a non-default fib
618
ADDR0="192.0.2.2"
619
ADDR1="192.0.2.3"
620
SUBNET="192.0.2.0"
621
MASK="24"
622
# Use a different IP on the same subnet as the target
623
TARGET="192.0.2.100"
624
SRCDIR=`atf_get_srcdir`
625
626
# Check system configuration
627
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
628
atf_skip "This test requires net.add_addr_allfibs=0"
629
fi
630
get_fibs 2
631
632
# Configure the TAP interfaces
633
setup_tap ${FIB0} inet ${ADDR0} ${MASK}
634
TARGET_TAP=${TAP}
635
setup_tap ${FIB1} inet ${ADDR1} ${MASK}
636
637
# Send a UDP packet with SO_DONTROUTE. In the failure case, it will
638
# return ENETUNREACH, or send the packet to the wrong tap
639
atf_check -o ignore setfib ${FIB0} \
640
${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP}
641
cleanup_ifaces
642
643
# Repeat, but this time target the other tap
644
setup_tap ${FIB0} inet ${ADDR0} ${MASK}
645
setup_tap ${FIB1} inet ${ADDR1} ${MASK}
646
TARGET_TAP=${TAP}
647
648
atf_check -o ignore setfib ${FIB1} \
649
${SRCDIR}/udp_dontroute ${TARGET} /dev/${TARGET_TAP}
650
}
651
652
udp_dontroute_cleanup()
653
{
654
cleanup_ifaces
655
}
656
657
atf_test_case udp_dontroute6 cleanup
658
udp_dontroute6_head()
659
{
660
atf_set "descr" "Source address selection for UDP IPv6 packets with SO_DONTROUTE on non-default FIBs works"
661
atf_set "require.user" "root"
662
}
663
664
udp_dontroute6_body()
665
{
666
if [ "$(atf_config_get ci false)" = "true" ]; then
667
atf_skip "https://bugs.freebsd.org/244172"
668
fi
669
# Configure the TAP interface to use an RFC3849 nonrouteable address
670
# and a non-default fib
671
ADDR0="2001:db8::2"
672
ADDR1="2001:db8::3"
673
SUBNET="2001:db8::"
674
MASK="64"
675
# Use a different IP on the same subnet as the target
676
TARGET="2001:db8::100"
677
SRCDIR=`atf_get_srcdir`
678
679
# Check system configuration
680
if [ 0 != `sysctl -n net.add_addr_allfibs` ]; then
681
atf_skip "This test requires net.add_addr_allfibs=0"
682
fi
683
get_fibs 2
684
685
# Configure the TAP interfaces. Use no_dad so the addresses will be
686
# ready right away and won't be marked as tentative until DAD
687
# completes.
688
setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad
689
TARGET_TAP=${TAP}
690
setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad
691
692
# Send a UDP packet with SO_DONTROUTE. In the failure case, it will
693
# return ENETUNREACH, or send the packet to the wrong tap
694
atf_check -o ignore setfib ${FIB0} \
695
${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP}
696
cleanup_ifaces
697
698
# Repeat, but this time target the other tap
699
setup_tap ${FIB0} inet6 ${ADDR0} ${MASK} no_dad
700
setup_tap ${FIB1} inet6 ${ADDR1} ${MASK} no_dad
701
TARGET_TAP=${TAP}
702
703
atf_check -o ignore setfib ${FIB1} \
704
${SRCDIR}/udp_dontroute -6 ${TARGET} /dev/${TARGET_TAP}
705
}
706
707
udp_dontroute6_cleanup()
708
{
709
cleanup_ifaces
710
}
711
712
713
atf_init_test_cases()
714
{
715
atf_add_test_case arpresolve_checks_interface_fib
716
atf_add_test_case loopback_and_network_routes_on_nondefault_fib
717
atf_add_test_case loopback_and_network_routes_on_nondefault_fib_inet6
718
atf_add_test_case default_route_with_multiple_fibs_on_same_subnet
719
atf_add_test_case default_route_with_multiple_fibs_on_same_subnet_inet6
720
atf_add_test_case same_ip_multiple_ifaces_fib0
721
atf_add_test_case same_ip_multiple_ifaces
722
atf_add_test_case same_ip_multiple_ifaces_inet6
723
atf_add_test_case slaac_on_nondefault_fib6
724
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet
725
atf_add_test_case subnet_route_with_multiple_fibs_on_same_subnet_inet6
726
atf_add_test_case udp_dontroute
727
atf_add_test_case udp_dontroute6
728
}
729
730
# Looks up one or more fibs from the configuration data and validates them.
731
# Returns the results in the env varilables FIB0, FIB1, etc.
732
733
# parameter numfibs The number of fibs to lookup
734
get_fibs()
735
{
736
NUMFIBS=$1
737
net_fibs=`sysctl -n net.fibs`
738
if [ $net_fibs -lt $(($NUMFIBS + 1)) ]; then
739
atf_check -o ignore sysctl net.fibs=$(($NUMFIBS + 1))
740
net_fibs=`sysctl -n net.fibs`
741
fi
742
i=0
743
while [ $i -lt "$NUMFIBS" ]; do
744
eval FIB${i}=$(($i + 1))
745
i=$(( $i + 1 ))
746
done
747
}
748
749
# Creates a new pair of connected epair(4) interface, registers them for
750
# cleanup, and returns their namen via the environment variables EPAIRA and
751
# EPAIRB
752
get_epair()
753
{
754
local EPAIRD
755
756
if (which pfctl && pfctl -s info | grep -q 'Status: Enabled') ||
757
[ `sysctl -n net.inet.ip.fw.enable` = "1" ] ||
758
(which ipf && ipf -V); then
759
atf_skip "firewalls interfere with this test"
760
fi
761
762
if EPAIRD=`ifconfig epair create`; then
763
# Record the epair device so we can clean it up later
764
echo ${EPAIRD} >> "ifaces_to_cleanup"
765
EPAIRA=${EPAIRD}
766
EPAIRB=${EPAIRD%a}b
767
else
768
atf_skip "Could not create epair(4) interfaces"
769
fi
770
}
771
772
# Creates a new tap(4) interface, registers it for cleanup, and returns the
773
# name via the environment variable TAP
774
get_tap()
775
{
776
local TAPD
777
778
if TAPD=`ifconfig tap create`; then
779
# Record the TAP device so we can clean it up later
780
echo ${TAPD} >> "ifaces_to_cleanup"
781
TAP=${TAPD}
782
else
783
atf_skip "Could not create a tap(4) interface"
784
fi
785
}
786
787
# Configure an ethernet interface
788
# parameters:
789
# Interface name
790
# fib
791
# Protocol (inet or inet6)
792
# IP address
793
# Netmask in number of bits (eg 24 or 8)
794
# Extra flags
795
# Return: None
796
setup_iface()
797
{
798
local IFACE=$1
799
local FIB=$2
800
local PROTO=$3
801
local ADDR=$4
802
local MASK=$5
803
local FLAGS=$6
804
atf_check setfib ${FIB} ifconfig $IFACE ${PROTO} ${ADDR}/${MASK} fib $FIB $FLAGS
805
}
806
807
# Create a tap(4) interface, configure it, and register it for cleanup.
808
# parameters:
809
# fib
810
# Protocol (inet or inet6)
811
# IP address
812
# Netmask in number of bits (eg 24 or 8)
813
# Extra flags
814
# Return: the tap interface name as the env variable TAP
815
setup_tap()
816
{
817
get_tap
818
setup_iface "$TAP" "$@"
819
}
820
821
cleanup_ifaces()
822
{
823
if [ -f ifaces_to_cleanup ]; then
824
for iface in $(cat ifaces_to_cleanup); do
825
echo ifconfig "${iface}" destroy
826
ifconfig "${iface}" destroy 2>/dev/null || true
827
done
828
rm -f ifaces_to_cleanup
829
fi
830
}
831
832