t_bridge.sh revision 1.19.8.1 1 # $NetBSD: t_bridge.sh,v 1.19.8.1 2024/09/05 09:27:13 martin Exp $
2 #
3 # Copyright (c) 2014 The NetBSD Foundation, Inc.
4 # All rights reserved.
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 NETBSD FOUNDATION, INC. AND CONTRIBUTORS
16 # ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
17 # TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18 # PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
19 # BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
20 # CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
21 # SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
23 # CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
24 # ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
25 # POSSIBILITY OF SUCH DAMAGE.
26 #
27
28 SOCK1=unix://commsock1
29 SOCK2=unix://commsock2
30 SOCK3=unix://commsock3
31 IP1=10.0.0.1
32 IP2=10.0.0.2
33 IP61=fc00::1
34 IP62=fc00::2
35 IPBR1=10.0.0.11
36 IPBR2=10.0.0.12
37 IP6BR1=fc00::11
38 IP6BR2=fc00::12
39
40 DEBUG=${DEBUG:-false}
41 TIMEOUT=5
42
43 setup_endpoint()
44 {
45 sock=${1}
46 addr=${2}
47 bus=${3}
48 mode=${4}
49
50 rump_server_add_iface $sock shmif0 $bus
51 export RUMP_SERVER=${sock}
52 if [ $mode = "ipv6" ]; then
53 atf_check -s exit:0 rump.ifconfig shmif0 inet6 ${addr}
54 else
55 atf_check -s exit:0 rump.ifconfig shmif0 inet ${addr} netmask 0xffffff00
56 fi
57
58 atf_check -s exit:0 rump.ifconfig shmif0 up
59 $DEBUG && rump.ifconfig shmif0
60 }
61
62 test_endpoint()
63 {
64 sock=${1}
65 addr=${2}
66 bus=${3}
67 mode=${4}
68
69 export RUMP_SERVER=${sock}
70 atf_check -s exit:0 -o match:shmif0 rump.ifconfig
71 if [ $mode = "ipv6" ]; then
72 atf_check -s exit:0 -o ignore rump.ping6 -n -c 1 -X $TIMEOUT ${addr}
73 else
74 atf_check -s exit:0 -o ignore rump.ping -n -w $TIMEOUT -c 1 ${addr}
75 fi
76 }
77
78 test_setup()
79 {
80 test_endpoint $SOCK1 $IP1 bus1 ipv4
81 test_endpoint $SOCK3 $IP2 bus2 ipv4
82
83 export RUMP_SERVER=$SOCK2
84 atf_check -s exit:0 -o match:shmif0 rump.ifconfig
85 atf_check -s exit:0 -o match:shmif1 rump.ifconfig
86 }
87
88 test_setup6()
89 {
90 test_endpoint $SOCK1 $IP61 bus1 ipv6
91 test_endpoint $SOCK3 $IP62 bus2 ipv6
92
93 export RUMP_SERVER=$SOCK2
94 atf_check -s exit:0 -o match:shmif0 rump.ifconfig
95 atf_check -s exit:0 -o match:shmif1 rump.ifconfig
96 }
97
98 setup_bridge_server()
99 {
100
101 rump_server_add_iface $SOCK2 shmif0 bus1
102 rump_server_add_iface $SOCK2 shmif1 bus2
103 export RUMP_SERVER=$SOCK2
104 atf_check -s exit:0 rump.ifconfig shmif0 up
105 atf_check -s exit:0 rump.ifconfig shmif1 up
106 }
107
108 setup()
109 {
110
111 rump_server_start $SOCK1 bridge
112 rump_server_start $SOCK2 bridge
113 rump_server_start $SOCK3 bridge
114
115 setup_endpoint $SOCK1 $IP1 bus1 ipv4
116 setup_endpoint $SOCK3 $IP2 bus2 ipv4
117 setup_bridge_server
118 }
119
120 setup6()
121 {
122
123 rump_server_start $SOCK1 netinet6 bridge
124 rump_server_start $SOCK2 netinet6 bridge
125 rump_server_start $SOCK3 netinet6 bridge
126
127 setup_endpoint $SOCK1 $IP61 bus1 ipv6
128 setup_endpoint $SOCK3 $IP62 bus2 ipv6
129 setup_bridge_server
130 }
131
132 setup_bridge()
133 {
134 export RUMP_SERVER=$SOCK2
135 rump_server_add_iface $SOCK2 bridge0
136 atf_check -s exit:0 rump.ifconfig bridge0 up
137
138 export LD_PRELOAD=/usr/lib/librumphijack.so
139 atf_check -s exit:0 /sbin/brconfig bridge0 add shmif0
140 atf_check -s exit:0 /sbin/brconfig bridge0 add shmif1
141 /sbin/brconfig bridge0
142 unset LD_PRELOAD
143 rump.ifconfig shmif0
144 rump.ifconfig shmif1
145 }
146
147 setup_member_ip()
148 {
149 export RUMP_SERVER=$SOCK2
150 export LD_PRELOAD=/usr/lib/librumphijack.so
151 atf_check -s exit:0 rump.ifconfig shmif0 $IPBR1/24
152 atf_check -s exit:0 rump.ifconfig shmif1 $IPBR2/24
153 atf_check -s exit:0 rump.ifconfig -w 10
154 /sbin/brconfig bridge0
155 unset LD_PRELOAD
156 rump.ifconfig shmif0
157 rump.ifconfig shmif1
158 }
159
160 setup_member_ip6()
161 {
162 export RUMP_SERVER=$SOCK2
163 export LD_PRELOAD=/usr/lib/librumphijack.so
164 atf_check -s exit:0 rump.ifconfig shmif0 inet6 $IP6BR1
165 atf_check -s exit:0 rump.ifconfig shmif1 inet6 $IP6BR2
166 atf_check -s exit:0 rump.ifconfig -w 10
167 /sbin/brconfig bridge0
168 unset LD_PRELOAD
169 rump.ifconfig shmif0
170 rump.ifconfig shmif1
171 }
172
173 teardown_bridge()
174 {
175 export RUMP_SERVER=$SOCK2
176 export LD_PRELOAD=/usr/lib/librumphijack.so
177 /sbin/brconfig bridge0
178 atf_check -s exit:0 /sbin/brconfig bridge0 delete shmif0
179 atf_check -s exit:0 /sbin/brconfig bridge0 delete shmif1
180 /sbin/brconfig bridge0
181 unset LD_PRELOAD
182 rump.ifconfig shmif0
183 rump.ifconfig shmif1
184 }
185
186 test_setup_bridge()
187 {
188 export RUMP_SERVER=$SOCK2
189 export LD_PRELOAD=/usr/lib/librumphijack.so
190 atf_check -s exit:0 -o match:shmif0 /sbin/brconfig bridge0
191 atf_check -s exit:0 -o match:shmif1 /sbin/brconfig bridge0
192 /sbin/brconfig bridge0
193 unset LD_PRELOAD
194 }
195
196 down_up_interfaces()
197 {
198 export RUMP_SERVER=$SOCK1
199 rump.ifconfig shmif0 down
200 rump.ifconfig shmif0 up
201 export RUMP_SERVER=$SOCK3
202 rump.ifconfig shmif0 down
203 rump.ifconfig shmif0 up
204 }
205
206 test_ping_failure()
207 {
208 export RUMP_SERVER=$SOCK1
209 atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP2
210 export RUMP_SERVER=$SOCK3
211 atf_check -s not-exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP1
212 }
213
214 test_ping_success()
215 {
216 export RUMP_SERVER=$SOCK1
217 rump.ifconfig -v shmif0
218 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP2
219 rump.ifconfig -v shmif0
220
221 export RUMP_SERVER=$SOCK3
222 rump.ifconfig -v shmif0
223 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IP1
224 rump.ifconfig -v shmif0
225 }
226
227 test_ping6_failure()
228 {
229 export RUMP_SERVER=$SOCK1
230 atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP62
231 export RUMP_SERVER=$SOCK3
232 atf_check -s not-exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP61
233 }
234
235 test_ping6_success()
236 {
237 export RUMP_SERVER=$SOCK1
238 rump.ifconfig -v shmif0
239 atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP62
240 rump.ifconfig -v shmif0
241
242 export RUMP_SERVER=$SOCK3
243 rump.ifconfig -v shmif0
244 atf_check -s exit:0 -o ignore rump.ping6 -q -n -c 1 -X $TIMEOUT $IP61
245 rump.ifconfig -v shmif0
246 }
247
248 test_ping_member()
249 {
250 export RUMP_SERVER=$SOCK1
251 rump.ifconfig -v shmif0
252 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR1
253 rump.ifconfig -v shmif0
254 # Test for PR#48104
255 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR2
256 rump.ifconfig -v shmif0
257
258 export RUMP_SERVER=$SOCK3
259 rump.ifconfig -v shmif0
260 # Test for PR#48104
261 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR1
262 rump.ifconfig -v shmif0
263 atf_check -s exit:0 -o ignore rump.ping -q -n -w $TIMEOUT -c 1 $IPBR2
264 rump.ifconfig -v shmif0
265 }
266
267 test_ping6_member()
268 {
269 export RUMP_SERVER=$SOCK1
270 rump.ifconfig -v shmif0
271 atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR1
272 rump.ifconfig -v shmif0
273 # Test for PR#48104
274 atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR2
275 rump.ifconfig -v shmif0
276
277 export RUMP_SERVER=$SOCK3
278 rump.ifconfig -v shmif0
279 # Test for PR#48104
280 atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR1
281 rump.ifconfig -v shmif0
282 atf_check -s exit:0 -o ignore rump.ping6 -q -n -X $TIMEOUT -c 1 $IP6BR2
283 rump.ifconfig -v shmif0
284 }
285
286 test_create_destroy()
287 {
288
289 rump_server_start $SOCK1 bridge
290
291 test_create_destroy_common $SOCK1 bridge0
292 }
293
294 test_ipv4()
295 {
296 setup
297 test_setup
298
299 # Enable once PR kern/49219 is fixed
300 #test_ping_failure
301
302 setup_bridge
303 sleep 1
304 test_setup_bridge
305 test_ping_success
306
307 teardown_bridge
308 test_ping_failure
309
310 rump_server_destroy_ifaces
311 }
312
313 test_ipv6()
314 {
315 setup6
316 test_setup6
317
318 test_ping6_failure
319
320 setup_bridge
321 sleep 1
322 test_setup_bridge
323 test_ping6_success
324
325 teardown_bridge
326 test_ping6_failure
327
328 rump_server_destroy_ifaces
329 }
330
331 test_member_ipv4()
332 {
333 setup
334 test_setup
335
336 # Enable once PR kern/49219 is fixed
337 #test_ping_failure
338
339 setup_bridge
340 sleep 1
341 test_setup_bridge
342 test_ping_success
343
344 setup_member_ip
345 test_ping_member
346
347 teardown_bridge
348 test_ping_failure
349
350 rump_server_destroy_ifaces
351 }
352
353 test_member_ipv6()
354 {
355 setup6
356 test_setup6
357
358 test_ping6_failure
359
360 setup_bridge
361 sleep 1
362 test_setup_bridge
363 test_ping6_success
364
365 setup_member_ip6
366 test_ping6_member
367
368 teardown_bridge
369 test_ping6_failure
370
371 rump_server_destroy_ifaces
372 }
373
374 BUS_SHMIF0=./bus0
375 BUS_SHMIF1=./bus1
376 BUS_SHMIF2=./bus2
377
378 unpack_file()
379 {
380
381 atf_check -s exit:0 uudecode $(atf_get_srcdir)/${1}.uue
382 }
383
384 reset_if_stats()
385 {
386
387 for ifname in shmif0 shmif1 shmif2
388 do
389 atf_check -s exit:0 -o ignore rump.ifconfig -z $ifname
390 done
391 }
392
393 test_protection()
394 {
395
396 unpack_file unicast.pcap
397 unpack_file broadcast.pcap
398
399 rump_server_start $SOCK1 bridge
400 rump_server_add_iface $SOCK1 shmif0 $BUS_SHMIF0
401 rump_server_add_iface $SOCK1 shmif1 $BUS_SHMIF1
402 rump_server_add_iface $SOCK1 shmif2 $BUS_SHMIF2
403
404 export RUMP_SERVER=$SOCK1
405 atf_check -s exit:0 rump.ifconfig shmif0 up
406 atf_check -s exit:0 rump.ifconfig shmif1 up
407 atf_check -s exit:0 rump.ifconfig shmif2 up
408
409 atf_check -s exit:0 rump.ifconfig bridge0 create
410 atf_check -s exit:0 rump.ifconfig bridge0 up
411
412 atf_check -s exit:0 $HIJACKING brconfig bridge0 add shmif0 add shmif1 add shmif2
413 $DEBUG && rump.ifconfig
414
415 # Protected interfaces: -
416 # Learning: -
417 # Input: unicast through shmif0
418 # Output: shmif1, shmif2
419 reset_if_stats
420 atf_check -s exit:0 -o ignore shmif_pcapin unicast.pcap ${BUS_SHMIF0}
421 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0
422 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif1
423 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif2
424 $DEBUG && rump.ifconfig -v bridge0
425
426 # Protected interfaces: -
427 # Learning: -
428 # Input: broadcast through shmif0
429 # Output: shmif1, shmif2
430 reset_if_stats
431 atf_check -s exit:0 -o ignore shmif_pcapin broadcast.pcap ${BUS_SHMIF0}
432 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0
433 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif1
434 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif2
435 $DEBUG && rump.ifconfig -v bridge0
436
437 # Protect shmif0 and shmif2
438 atf_check -s exit:0 $HIJACKING brconfig bridge0 protect shmif0
439 atf_check -s exit:0 $HIJACKING brconfig bridge0 protect shmif2
440 atf_check -s exit:0 \
441 -o match:"shmif0.+PROTECTED" \
442 -o match:"shmif2.+PROTECTED" \
443 -o not-match:"shmif1.+PROTECTED" \
444 $HIJACKING brconfig bridge0
445
446 # Protected interfaces: shmif0 shmif2
447 # Learning: -
448 # Input: unicast through shmif0
449 # Output: shmif1
450 reset_if_stats
451 atf_check -s exit:0 -o ignore shmif_pcapin unicast.pcap ${BUS_SHMIF0}
452 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0
453 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif1
454 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif2
455 $DEBUG && rump.ifconfig -v bridge0
456
457 # Protected interfaces: shmif0 shmif2
458 # Learning: -
459 # Input: broadcast through shmif0
460 # Output: shmif1
461 reset_if_stats
462 atf_check -s exit:0 -o ignore shmif_pcapin broadcast.pcap ${BUS_SHMIF0}
463 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0
464 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif1
465 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif2
466 $DEBUG && rump.ifconfig -v bridge0
467
468 # Insert a route 00:aa:aa:aa:aa:aa shmif2 to test forwarding path of known-unicast-frame
469 atf_check -s exit:0 $HIJACKING brconfig bridge0 static shmif2 00:aa:aa:aa:aa:aa
470 atf_check -s exit:0 -o match:'00:aa:aa:aa:aa:aa shmif2 0 flags=1<STATIC>' \
471 $HIJACKING brconfig bridge0
472 $DEBUG && $HIJACKING brconfig bridge0
473
474 # Protected interfaces: shmif0 shmif2
475 # Learning: 00:aa:aa:aa:aa:aa shmif2
476 # Input: broadcast through shmif0
477 # Output: -
478 reset_if_stats
479 atf_check -s exit:0 -o ignore shmif_pcapin unicast.pcap ${BUS_SHMIF0}
480 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0
481 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif1
482 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif2
483 $DEBUG && rump.ifconfig -v bridge0
484
485 # Unprotect shmif2
486 atf_check -s exit:0 $HIJACKING brconfig bridge0 -protect shmif2
487 atf_check -s exit:0 \
488 -o match:"shmif0.+PROTECTED" \
489 -o not-match:"shmif2.+PROTECTED" \
490 -o not-match:"shmif1.+PROTECTED" \
491 $HIJACKING brconfig bridge0
492
493 # Protected interfaces: shmif0
494 # Learning: 00:aa:aa:aa:aa:aa shmif2
495 # Input: broadcast through shmif0
496 # Output: shmif2
497 reset_if_stats
498 atf_check -s exit:0 -o ignore shmif_pcapin unicast.pcap ${BUS_SHMIF0}
499 atf_check -s exit:0 -o match:"input: 1 packet" rump.ifconfig -v shmif0
500 atf_check -s exit:0 -o match:"output: 0 packet" rump.ifconfig -v shmif1
501 atf_check -s exit:0 -o match:"output: 1 packet" rump.ifconfig -v shmif2
502 $DEBUG && rump.ifconfig -v bridge0
503
504 rump_server_destroy_ifaces
505 }
506
507 add_test()
508 {
509 local name=$1
510 local desc="$2"
511
512 atf_test_case "bridge_${name}" cleanup
513 eval "bridge_${name}_head() {
514 atf_set descr \"${desc}\"
515 atf_set require.progs rump_server
516 }
517 bridge_${name}_body() {
518 test_${name}
519 }
520 bridge_${name}_cleanup() {
521 \$DEBUG && dump
522 cleanup
523 }"
524 atf_add_test_case "bridge_${name}"
525 }
526
527 atf_init_test_cases()
528 {
529
530 add_test create_destroy "Tests creating/destroying bridge interfaces"
531 add_test ipv4 "Does basic if_bridge tests (IPv4)"
532 add_test ipv6 "Does basic if_bridge tests (IPv6)"
533 add_test member_ipv4 "Tests if_bridge with members with an IP address (IPv4)"
534 add_test member_ipv6 "Tests if_bridge with members with an IP address (IPv6)"
535 add_test protection "Tests interface protection"
536 }
537