Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/tests/sys/netinet/carp.sh
104894 views
1
#
2
# SPDX-License-Identifier: BSD-2-Clause
3
#
4
# Copyright (c) 2020 Kristof Provost <[email protected]>
5
#
6
# Redistribution and use in source and binary forms, with or without
7
# modification, are permitted provided that the following conditions
8
# are met:
9
# 1. Redistributions of source code must retain the above copyright
10
# notice, this list of conditions and the following disclaimer.
11
# 2. Redistributions in binary form must reproduce the above copyright
12
# notice, this list of conditions and the following disclaimer in the
13
# documentation and/or other materials provided with the distribution.
14
#
15
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16
# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18
# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19
# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21
# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22
# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25
# SUCH DAMAGE.
26
27
. $(atf_get_srcdir)/../common/vnet.subr
28
29
is_master()
30
{
31
jail=$1
32
itf=$2
33
34
jexec ${jail} ifconfig ${itf} | grep -E '(carp|vrrp)' | grep MASTER
35
}
36
37
wait_for_carp()
38
{
39
jail1=$1
40
itf1=$2
41
jail2=$3
42
itf2=$4
43
44
while [ -z "$(is_master ${jail1} ${itf1})" ] &&
45
[ -z "$(is_master ${jail2} ${itf2})" ]; do
46
sleep 0.1
47
done
48
49
if [ -n "$(is_master ${jail1} ${itf1})" ] &&
50
[ -n "$(is_master ${jail2} ${itf2})" ]; then
51
atf_fail "Both jails are master"
52
fi
53
}
54
55
carp_init()
56
{
57
if ! kldstat -q -m carp; then
58
atf_skip "This test requires carp"
59
fi
60
61
vnet_init
62
}
63
64
atf_test_case "basic_v4" "cleanup"
65
basic_v4_head()
66
{
67
atf_set descr 'Basic CARP test (IPv4)'
68
atf_set require.user root
69
}
70
71
basic_v4_body()
72
{
73
carp_init
74
vnet_init_bridge
75
76
bridge=$(vnet_mkbridge)
77
epair_one=$(vnet_mkepair)
78
epair_two=$(vnet_mkepair)
79
80
vnet_mkjail carp_basic_v4_one ${bridge} ${epair_one}a ${epair_two}a
81
vnet_mkjail carp_basic_v4_two ${epair_one}b
82
vnet_mkjail carp_basic_v4_three ${epair_two}b
83
84
jexec carp_basic_v4_one ifconfig ${bridge} 192.0.2.4/29 up
85
jexec carp_basic_v4_one ifconfig ${bridge} addm ${epair_one}a \
86
addm ${epair_two}a
87
jexec carp_basic_v4_one ifconfig ${epair_one}a up
88
jexec carp_basic_v4_one ifconfig ${epair_two}a up
89
90
jexec carp_basic_v4_two ifconfig ${epair_one}b 192.0.2.202/29 up
91
jexec carp_basic_v4_two ifconfig ${epair_one}b add vhid 1 192.0.2.1/29
92
93
sleep 0.2
94
jexec carp_basic_v4_three ifconfig ${epair_two}b 192.0.2.203/29 up
95
jexec carp_basic_v4_three ifconfig ${epair_two}b add vhid 1 \
96
192.0.2.1/29
97
98
wait_for_carp carp_basic_v4_two ${epair_one}b \
99
carp_basic_v4_three ${epair_two}b
100
101
atf_check -s exit:0 -o ignore jexec carp_basic_v4_one \
102
ping -c 3 192.0.2.1
103
}
104
105
basic_v4_cleanup()
106
{
107
vnet_cleanup
108
}
109
110
atf_test_case "vrrp_v4" "cleanup"
111
vrrp_v4_head()
112
{
113
atf_set descr 'Basic VRRP test (IPv4)'
114
atf_set require.user root
115
}
116
117
vrrp_v4_body()
118
{
119
carp_init
120
vnet_init_bridge
121
122
j=vrrp_basic_v4
123
124
bridge=$(vnet_mkbridge)
125
epair_one=$(vnet_mkepair)
126
epair_two=$(vnet_mkepair)
127
128
vnet_mkjail ${j}_one ${bridge} ${epair_one}a ${epair_two}a
129
vnet_mkjail ${j}_two ${epair_one}b
130
vnet_mkjail ${j}_three ${epair_two}b
131
132
jexec ${j}_one ifconfig ${bridge} 192.0.2.4/29 up
133
jexec ${j}_one ifconfig ${bridge} addm ${epair_one}a \
134
addm ${epair_two}a
135
jexec ${j}_one ifconfig ${epair_one}a up
136
jexec ${j}_one ifconfig ${epair_two}a up
137
138
jexec ${j}_two ifconfig ${epair_one}b 192.0.2.202/29 up
139
jexec ${j}_two ifconfig ${epair_one}b add vhid 1 carpver 3 192.0.2.1/29
140
141
sleep 0.2
142
jexec ${j}_three ifconfig ${epair_two}b 192.0.2.203/29 up
143
jexec ${j}_three ifconfig ${epair_two}b add vhid 1 carpver 3 \
144
192.0.2.1/29
145
146
wait_for_carp ${j}_two ${epair_one}b \
147
${j}_three ${epair_two}b
148
149
atf_check -s exit:0 -o ignore jexec ${j}_one \
150
ping -c 3 192.0.2.1
151
}
152
153
vrrp_v4_cleanup()
154
{
155
vnet_cleanup
156
}
157
158
atf_test_case "unicast_v4" "cleanup"
159
unicast_v4_head()
160
{
161
atf_set descr 'Unicast CARP test (IPv4)'
162
atf_set require.user root
163
}
164
165
unicast_v4_body()
166
{
167
carp_init
168
169
epair_one=$(vnet_mkepair)
170
epair_two=$(vnet_mkepair)
171
172
vnet_mkjail carp_uni_v4_one ${epair_one}a ${epair_two}a
173
vnet_mkjail carp_uni_v4_two ${epair_one}b
174
vnet_mkjail carp_uni_v4_three ${epair_two}b
175
176
jexec carp_uni_v4_one sysctl net.inet.ip.forwarding=1
177
jexec carp_uni_v4_one ifconfig ${epair_one}a inet 198.51.100.1/25
178
jexec carp_uni_v4_one ifconfig ${epair_two}a inet 198.51.100.129/25
179
180
jexec carp_uni_v4_two sysctl net.inet.ip.forwarding=1
181
jexec carp_uni_v4_two ifconfig ${epair_one}b 198.51.100.2/25 up
182
jexec carp_uni_v4_two route add 198.51.100.224 198.51.100.1
183
# A peer address x.x.x.224 to catch PR 284872
184
jexec carp_uni_v4_two ifconfig ${epair_one}b add vhid 1 \
185
peer 198.51.100.224 192.0.2.1/32
186
187
sleep 0.2
188
jexec carp_uni_v4_three sysctl net.inet.ip.forwarding=1
189
jexec carp_uni_v4_three ifconfig ${epair_two}b 198.51.100.224/25 up
190
jexec carp_uni_v4_three route add 198.51.100.2 198.51.100.129
191
jexec carp_uni_v4_three ifconfig ${epair_two}b add vhid 1 \
192
peer 198.51.100.2 192.0.2.1/32
193
194
# Sanity check
195
atf_check -s exit:0 -o ignore jexec carp_uni_v4_two \
196
ping -c 1 198.51.100.224
197
198
wait_for_carp carp_uni_v4_two ${epair_one}b \
199
carp_uni_v4_three ${epair_two}b
200
201
# Setup RIPv2 route daemon
202
jexec carp_uni_v4_two routed -s -Pripv2
203
jexec carp_uni_v4_three routed -s -Pripv2
204
jexec carp_uni_v4_one routed -Pripv2
205
206
# XXX Wait for route propagation
207
sleep 3
208
209
atf_check -s exit:0 -o ignore jexec carp_uni_v4_one \
210
ping -c 3 192.0.2.1
211
212
# Check that we remain in unicast when tweaking settings
213
atf_check -s exit:0 -o ignore \
214
jexec carp_uni_v4_two ifconfig ${epair_one}b vhid 1 advskew 2
215
atf_check -s exit:0 -o match:"peer 198.51.100.224" \
216
jexec carp_uni_v4_two ifconfig ${epair_one}b
217
}
218
219
unicast_v4_cleanup()
220
{
221
jexec carp_uni_v4_one killall routed
222
jexec carp_uni_v4_two killall routed
223
jexec carp_uni_v4_three killall routed
224
vnet_cleanup
225
}
226
227
atf_test_case "basic_v6" "cleanup"
228
basic_v6_head()
229
{
230
atf_set descr 'Basic CARP test (IPv6)'
231
atf_set require.user root
232
}
233
234
basic_v6_body()
235
{
236
carp_init
237
vnet_init_bridge
238
239
bridge=$(vnet_mkbridge)
240
epair_one=$(vnet_mkepair)
241
epair_two=$(vnet_mkepair)
242
243
vnet_mkjail carp_basic_v6_one ${bridge} ${epair_one}a ${epair_two}a
244
vnet_mkjail carp_basic_v6_two ${epair_one}b
245
vnet_mkjail carp_basic_v6_three ${epair_two}b
246
247
jexec carp_basic_v6_one ifconfig ${bridge} inet6 2001:db8::0:4/64 up \
248
no_dad
249
jexec carp_basic_v6_one ifconfig ${bridge} addm ${epair_one}a \
250
addm ${epair_two}a
251
jexec carp_basic_v6_one ifconfig ${epair_one}a up
252
jexec carp_basic_v6_one ifconfig ${epair_two}a up
253
254
jexec carp_basic_v6_two ifconfig ${epair_one}b inet6 \
255
2001:db8::1:2/64 up no_dad
256
jexec carp_basic_v6_two ifconfig ${epair_one}b inet6 add vhid 1 \
257
2001:db8::0:1/64
258
259
sleep 0.2
260
jexec carp_basic_v6_three ifconfig ${epair_two}b inet6 2001:db8::1:3/64 up no_dad
261
jexec carp_basic_v6_three ifconfig ${epair_two}b inet6 add vhid 1 \
262
2001:db8::0:1/64
263
264
wait_for_carp carp_basic_v6_two ${epair_one}b \
265
carp_basic_v6_three ${epair_two}b
266
267
atf_check -s exit:0 -o ignore jexec carp_basic_v6_one \
268
ping -6 -c 3 2001:db8::0:1
269
}
270
271
basic_v6_cleanup()
272
{
273
vnet_cleanup
274
}
275
276
atf_test_case "vrrp_v6" "cleanup"
277
vrrp_v6_head()
278
{
279
atf_set descr 'Basic VRRP test (IPv6)'
280
atf_set require.user root
281
}
282
283
vrrp_v6_body()
284
{
285
carp_init
286
vnet_init_bridge
287
288
j=carp_basic_v6
289
290
bridge=$(vnet_mkbridge)
291
epair_one=$(vnet_mkepair)
292
epair_two=$(vnet_mkepair)
293
294
vnet_mkjail ${j}_one ${bridge} ${epair_one}a ${epair_two}a
295
vnet_mkjail ${j}_two ${epair_one}b
296
vnet_mkjail ${j}_three ${epair_two}b
297
298
jexec ${j}_one ifconfig ${bridge} inet6 2001:db8::0:4/64 up \
299
no_dad
300
jexec ${j}_one ifconfig ${bridge} addm ${epair_one}a \
301
addm ${epair_two}a
302
jexec ${j}_one ifconfig ${epair_one}a up
303
jexec ${j}_one ifconfig ${epair_two}a up
304
305
jexec ${j}_two ifconfig ${epair_one}b inet6 \
306
2001:db8::1:2/64 up no_dad
307
jexec ${j}_two ifconfig ${epair_one}b inet6 add vhid 1 carpver 3 \
308
2001:db8::0:1/64
309
310
sleep 0.2
311
jexec ${j}_three ifconfig ${epair_two}b inet6 2001:db8::1:3/64 up no_dad
312
jexec ${j}_three ifconfig ${epair_two}b inet6 add vhid 1 carpver 3 \
313
2001:db8::0:1/64
314
315
wait_for_carp ${j}_two ${epair_one}b \
316
${j}_three ${epair_two}b
317
318
atf_check -s exit:0 -o ignore jexec ${j}_one \
319
ping -6 -c 3 2001:db8::0:1
320
}
321
322
vrrp_v6_cleanup()
323
{
324
vnet_cleanup
325
}
326
327
atf_test_case "unicast_v6" "cleanup"
328
unicast_v6_head()
329
{
330
atf_set descr 'Unicast CARP test (IPv6)'
331
atf_set require.user root
332
}
333
334
unicast_v6_body()
335
{
336
carp_init
337
vnet_init_bridge
338
339
bridge=$(vnet_mkbridge)
340
epair_one=$(vnet_mkepair)
341
epair_two=$(vnet_mkepair)
342
343
vnet_mkjail carp_uni_v6_one ${bridge} ${epair_one}a ${epair_two}a
344
vnet_mkjail carp_uni_v6_two ${epair_one}b
345
vnet_mkjail carp_uni_v6_three ${epair_two}b
346
347
jexec carp_uni_v6_one sysctl net.inet6.ip6.forwarding=1
348
jexec carp_uni_v6_one ifconfig ${bridge} addm ${epair_one}a \
349
addm ${epair_two}a
350
jexec carp_uni_v6_one ifconfig ${epair_one}a up
351
jexec carp_uni_v6_one ifconfig ${epair_two}a up
352
jexec carp_uni_v6_one ifconfig ${bridge} inet6 2001:db8::0:4/64 up \
353
no_dad
354
jexec carp_uni_v6_one ifconfig ${bridge} inet6 alias 2001:db8:1::1/64 \
355
no_dad up
356
jexec carp_uni_v6_one ifconfig ${bridge} inet6 alias 2001:db8:2::1/64 \
357
no_dad up
358
359
jexec carp_uni_v6_two ifconfig ${epair_one}b inet6 2001:db8:1::2/64 \
360
no_dad up
361
jexec carp_uni_v6_two route -6 add default 2001:db8:1::1
362
jexec carp_uni_v6_two ifconfig ${epair_one}b inet6 add vhid 1 \
363
peer6 2001:db8:2::2 \
364
2001:db8::0:1/64
365
366
sleep 0.2
367
jexec carp_uni_v6_three ifconfig ${epair_two}b inet6 2001:db8:2::2/64 \
368
no_dad up
369
jexec carp_uni_v6_three route -6 add default 2001:db8:2::1
370
jexec carp_uni_v6_three ifconfig ${epair_two}b inet6 add vhid 1 \
371
peer6 2001:db8:1::2 \
372
2001:db8::0:1/64
373
374
# Sanity check
375
atf_check -s exit:0 -o ignore jexec carp_uni_v6_two \
376
ping -6 -c 1 2001:db8:2::2
377
378
wait_for_carp carp_uni_v6_two ${epair_one}b \
379
carp_uni_v6_three ${epair_two}b
380
381
atf_check -s exit:0 -o ignore jexec carp_uni_v6_one \
382
ping -6 -c 3 2001:db8::0:1
383
}
384
385
unicast_v6_cleanup()
386
{
387
vnet_cleanup
388
}
389
390
atf_test_case "unicast_ll_v6" "cleanup"
391
unicast_ll_v6_head()
392
{
393
atf_set descr 'Unicast CARP test (IPv6, link-local)'
394
atf_set require.user root
395
}
396
397
unicast_ll_v6_body()
398
{
399
carp_init
400
vnet_init_bridge
401
402
j=carp_uni_ll_v6
403
404
bridge=$(vnet_mkbridge)
405
epair_one=$(vnet_mkepair)
406
epair_two=$(vnet_mkepair)
407
408
vnet_mkjail ${j}_one ${bridge} ${epair_one}a ${epair_two}a
409
vnet_mkjail ${j}_two ${epair_one}b
410
vnet_mkjail ${j}_three ${epair_two}b
411
412
jexec ${j}_one ifconfig ${bridge} addm ${epair_one}a \
413
addm ${epair_two}a
414
jexec ${j}_one ifconfig ${epair_one}a up
415
jexec ${j}_one ifconfig ${epair_two}a up
416
jexec ${j}_one ifconfig ${bridge} inet6 2001:db8::0:4/64 up \
417
no_dad
418
jexec ${j}_one ifconfig ${bridge} inet6 alias 2001:db8:1::1/64 \
419
no_dad up
420
421
jexec ${j}_two ifconfig ${epair_one}b inet6 2001:db8:1::2/64 \
422
no_dad up
423
jexec ${j}_three ifconfig ${epair_two}b inet6 2001:db8:1::3/64 \
424
no_dad up
425
426
ll_one=$(jexec ${j}_two ifconfig ${epair_one}b | awk "/ .*%${epair_one}b.* / { print \$2 }" | cut -d % -f 1)
427
ll_two=$(jexec ${j}_three ifconfig ${epair_two}b | awk "/ .*%${epair_two}b.* / { print \$2 }" | cut -d % -f 1)
428
429
jexec ${j}_two ifconfig ${epair_one}b inet6 add vhid 1 \
430
peer6 ${ll_two} \
431
2001:db8::0:1/64
432
sleep 0.2
433
jexec ${j}_three ifconfig ${epair_two}b inet6 add vhid 1 \
434
peer6 ${ll_one} \
435
2001:db8::0:1/64
436
437
# Sanity check
438
atf_check -s exit:0 -o ignore jexec ${j}_two \
439
ping -6 -c 1 2001:db8:1::3
440
441
wait_for_carp ${j}_two ${epair_one}b \
442
${j}_three ${epair_two}b
443
444
atf_check -s exit:0 -o ignore jexec ${j}_one \
445
ping -6 -c 3 2001:db8::0:1
446
}
447
448
unicast_ll_v6_cleanup()
449
{
450
vnet_cleanup
451
}
452
453
atf_test_case "negative_demotion" "cleanup"
454
negative_demotion_head()
455
{
456
atf_set descr 'Test PR #259528'
457
atf_set require.user root
458
}
459
460
negative_demotion_body()
461
{
462
carp_init
463
464
epair=$(vnet_mkepair)
465
466
vnet_mkjail one ${epair}a
467
jexec one sysctl net.inet.carp.preempt=1
468
jexec one ifconfig ${epair}a 192.0.2.1/24 up
469
jexec one ifconfig ${epair}a add vhid 1 192.0.2.254/24 \
470
advskew 0 pass foobar
471
472
vnet_mkjail two ${epair}b
473
jexec two sysctl net.inet.carp.preempt=1
474
jexec two ifconfig ${epair}b 192.0.2.2/24 up
475
jexec two ifconfig ${epair}b add vhid 1 192.0.2.254/24 \
476
advskew 100 pass foobar
477
478
# Allow things to settle
479
wait_for_carp one ${epair}a two ${epair}b
480
481
if is_master one ${epair}a && is_master two ${epair}b
482
then
483
atf_fail "Two masters!"
484
fi
485
486
jexec one sysctl net.inet.carp.demotion=-1
487
sleep 3
488
489
if is_master one ${epair}a && is_master two ${epair}b
490
then
491
atf_fail "Two masters!"
492
fi
493
}
494
495
negative_demotion_cleanup()
496
{
497
vnet_cleanup
498
}
499
500
501
502
atf_test_case "nd6_ns_source_mac" "cleanup"
503
nd6_ns_source_mac_head()
504
{
505
atf_set descr 'CARP ndp neighbor solicitation MAC source test (IPv6)'
506
atf_set require.user root
507
}
508
509
nd6_ns_source_mac_body()
510
{
511
carp_init
512
vnet_init_bridge
513
514
bridge=$(vnet_mkbridge)
515
epair_one=$(vnet_mkepair)
516
epair_two=$(vnet_mkepair)
517
518
vnet_mkjail carp_ndp_v6_bridge ${bridge} ${epair_one}a ${epair_two}a
519
vnet_mkjail carp_ndp_v6_master ${epair_one}b
520
vnet_mkjail carp_ndp_v6_slave ${epair_two}b
521
522
jexec carp_ndp_v6_bridge ifconfig ${bridge} inet6 2001:db8::0:4/64 up \
523
no_dad
524
jexec carp_ndp_v6_bridge ifconfig ${bridge} addm ${epair_one}a \
525
addm ${epair_two}a
526
jexec carp_ndp_v6_bridge ifconfig ${epair_one}a up
527
jexec carp_ndp_v6_bridge ifconfig ${epair_two}a up
528
529
jexec carp_ndp_v6_master ifconfig ${epair_one}b inet6 \
530
2001:db8::1:2/64 up no_dad
531
jexec carp_ndp_v6_master ifconfig ${epair_one}b inet6 add vhid 1 \
532
advskew 0 2001:db8::0:1/64
533
534
jexec carp_ndp_v6_slave ifconfig ${epair_two}b inet6 \
535
2001:db8::1:3/64 up no_dad
536
jexec carp_ndp_v6_slave ifconfig ${epair_two}b inet6 add vhid 1 \
537
advskew 100 2001:db8::0:1/64
538
539
wait_for_carp carp_ndp_v6_master ${epair_one}b \
540
carp_ndp_v6_slave ${epair_two}b
541
542
# carp_ndp_v6_master is MASTER
543
544
# trigger a NS from the virtual IP from the BACKUP
545
atf_check -s exit:2 -o ignore jexec carp_ndp_v6_slave \
546
ping -6 -c 3 -S 2001:db8::0:1 2001:db8::0:4
547
548
# trigger a NS from the virtual IP from the MASTER,
549
# this ping should work
550
atf_check -s exit:0 -o ignore jexec carp_ndp_v6_master \
551
ping -6 -c 3 -S 2001:db8::0:1 2001:db8::0:4
552
553
# ndp entry should be for the virtual mac
554
atf_check -o match:'2001:db8::1 +00:00:5e:00:01:01' \
555
jexec carp_ndp_v6_bridge ndp -an
556
}
557
558
nd6_ns_source_mac_cleanup()
559
{
560
vnet_cleanup
561
}
562
563
564
atf_test_case "switch" "cleanup"
565
switch_head()
566
{
567
atf_set descr 'Switch between master and backup'
568
atf_set require.user root
569
}
570
571
switch_body()
572
{
573
carp_init
574
575
epair=$(vnet_mkepair)
576
577
ifconfig ${epair}a up
578
ifconfig ${epair}a vhid 1 advskew 100 192.0.2.1/24
579
ifconfig ${epair}a vhid 1 state backup
580
ifconfig ${epair}a vhid 1 state master
581
}
582
583
switch_cleanup()
584
{
585
vnet_cleanup
586
}
587
588
atf_init_test_cases()
589
{
590
atf_add_test_case "basic_v4"
591
atf_add_test_case "vrrp_v4"
592
atf_add_test_case "unicast_v4"
593
atf_add_test_case "basic_v6"
594
atf_add_test_case "vrrp_v6"
595
atf_add_test_case "unicast_v6"
596
atf_add_test_case "unicast_ll_v6"
597
atf_add_test_case "negative_demotion"
598
atf_add_test_case "nd6_ns_source_mac"
599
atf_add_test_case "switch"
600
}
601
602