Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1#!/bin/bash
2# SPDX-License-Identifier: GPL-2.0
3
4# +------------------+
5# | H1 (v$h1) |
6# | 2001:db8:1::2/64 |
7# | 198.51.100.2/28 |
8# | $h1 + |
9# +-------------|----+
10# |
11# +-------------|-------------------------------+
12# | SW1 | |
13# | $rp1 + |
14# | 198.51.100.1/28 |
15# | 2001:db8:1::1/64 |
16# | |
17# | 2001:db8:2::1/64 2001:db8:3::1/64 |
18# | 198.51.100.17/28 198.51.100.33/28 |
19# | $rp2 + $rp3 + |
20# +--------------|--------------------------|---+
21# | |
22# | |
23# +--------------|---+ +--------------|---+
24# | H2 (v$h2) | | | H3 (v$h3) | |
25# | $h2 + | | $h3 + |
26# | 198.51.100.18/28 | | 198.51.100.34/28 |
27# | 2001:db8:2::2/64 | | 2001:db8:3::2/64 |
28# +------------------+ +------------------+
29#
30
31ALL_TESTS="mcast_v4 mcast_v6 rpf_v4 rpf_v6 unres_v4 unres_v6"
32NUM_NETIFS=6
33source lib.sh
34source tc_common.sh
35
36h1_create()
37{
38 simple_if_init $h1 198.51.100.2/28 2001:db8:1::2/64
39
40 ip route add 198.51.100.16/28 vrf v$h1 nexthop via 198.51.100.1
41 ip route add 198.51.100.32/28 vrf v$h1 nexthop via 198.51.100.1
42
43 ip route add 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::1
44 ip route add 2001:db8:3::/64 vrf v$h1 nexthop via 2001:db8:1::1
45
46 tc qdisc add dev $h1 ingress
47}
48
49h1_destroy()
50{
51 tc qdisc del dev $h1 ingress
52
53 ip route del 2001:db8:3::/64 vrf v$h1
54 ip route del 2001:db8:2::/64 vrf v$h1
55
56 ip route del 198.51.100.32/28 vrf v$h1
57 ip route del 198.51.100.16/28 vrf v$h1
58
59 simple_if_fini $h1 198.51.100.2/28 2001:db8:1::2/64
60}
61
62h2_create()
63{
64 simple_if_init $h2 198.51.100.18/28 2001:db8:2::2/64
65
66 ip route add 198.51.100.0/28 vrf v$h2 nexthop via 198.51.100.17
67 ip route add 198.51.100.32/28 vrf v$h2 nexthop via 198.51.100.17
68
69 ip route add 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::1
70 ip route add 2001:db8:3::/64 vrf v$h2 nexthop via 2001:db8:2::1
71
72 tc qdisc add dev $h2 ingress
73}
74
75h2_destroy()
76{
77 tc qdisc del dev $h2 ingress
78
79 ip route del 2001:db8:3::/64 vrf v$h2
80 ip route del 2001:db8:1::/64 vrf v$h2
81
82 ip route del 198.51.100.32/28 vrf v$h2
83 ip route del 198.51.100.0/28 vrf v$h2
84
85 simple_if_fini $h2 198.51.100.18/28 2001:db8:2::2/64
86}
87
88h3_create()
89{
90 simple_if_init $h3 198.51.100.34/28 2001:db8:3::2/64
91
92 ip route add 198.51.100.0/28 vrf v$h3 nexthop via 198.51.100.33
93 ip route add 198.51.100.16/28 vrf v$h3 nexthop via 198.51.100.33
94
95 ip route add 2001:db8:1::/64 vrf v$h3 nexthop via 2001:db8:3::1
96 ip route add 2001:db8:2::/64 vrf v$h3 nexthop via 2001:db8:3::1
97
98 tc qdisc add dev $h3 ingress
99}
100
101h3_destroy()
102{
103 tc qdisc del dev $h3 ingress
104
105 ip route del 2001:db8:2::/64 vrf v$h3
106 ip route del 2001:db8:1::/64 vrf v$h3
107
108 ip route del 198.51.100.16/28 vrf v$h3
109 ip route del 198.51.100.0/28 vrf v$h3
110
111 simple_if_fini $h3 198.51.100.34/28 2001:db8:3::2/64
112}
113
114router_create()
115{
116 ip link set dev $rp1 up
117 ip link set dev $rp2 up
118 ip link set dev $rp3 up
119
120 ip address add 198.51.100.1/28 dev $rp1
121 ip address add 198.51.100.17/28 dev $rp2
122 ip address add 198.51.100.33/28 dev $rp3
123
124 ip address add 2001:db8:1::1/64 dev $rp1
125 ip address add 2001:db8:2::1/64 dev $rp2
126 ip address add 2001:db8:3::1/64 dev $rp3
127
128 tc qdisc add dev $rp3 ingress
129}
130
131router_destroy()
132{
133 tc qdisc del dev $rp3 ingress
134
135 ip address del 2001:db8:3::1/64 dev $rp3
136 ip address del 2001:db8:2::1/64 dev $rp2
137 ip address del 2001:db8:1::1/64 dev $rp1
138
139 ip address del 198.51.100.33/28 dev $rp3
140 ip address del 198.51.100.17/28 dev $rp2
141 ip address del 198.51.100.1/28 dev $rp1
142
143 ip link set dev $rp3 down
144 ip link set dev $rp2 down
145 ip link set dev $rp1 down
146}
147
148setup_prepare()
149{
150 h1=${NETIFS[p1]}
151 rp1=${NETIFS[p2]}
152
153 rp2=${NETIFS[p3]}
154 h2=${NETIFS[p4]}
155
156 rp3=${NETIFS[p5]}
157 h3=${NETIFS[p6]}
158
159 adf_mcd_start || exit "$EXIT_STATUS"
160
161 vrf_prepare
162
163 h1_create
164 h2_create
165 h3_create
166
167 router_create
168
169 forwarding_enable
170}
171
172cleanup()
173{
174 pre_cleanup
175
176 forwarding_restore
177
178 router_destroy
179
180 h3_destroy
181 h2_destroy
182 h1_destroy
183
184 vrf_cleanup
185
186 defer_scopes_cleanup
187}
188
189create_mcast_sg()
190{
191 local if_name=$1; shift
192 local s_addr=$1; shift
193 local mcast=$1; shift
194 local dest_ifs=("${@}")
195
196 mc_cli add "$if_name" "$s_addr" "$mcast" "${dest_ifs[@]}"
197}
198
199delete_mcast_sg()
200{
201 local if_name=$1; shift
202 local s_addr=$1; shift
203 local mcast=$1; shift
204 local dest_ifs=("${@}")
205
206 mc_cli remove "$if_name" "$s_addr" "$mcast" "${dest_ifs[@]}"
207}
208
209mcast_v4()
210{
211 # Add two interfaces to an MC group, send a packet to the MC group and
212 # verify packets are received on both. Then delete the route and verify
213 # packets are no longer received.
214
215 RET=0
216
217 tc filter add dev $h2 ingress protocol ip pref 1 handle 122 flower \
218 dst_ip 225.1.2.3 action drop
219 tc filter add dev $h3 ingress protocol ip pref 1 handle 133 flower \
220 dst_ip 225.1.2.3 action drop
221
222 create_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
223
224 # Send frames with the corresponding L2 destination address.
225 $MZ $h1 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
226 -A 198.51.100.2 -B 225.1.2.3 -q
227
228 tc_check_packets "dev $h2 ingress" 122 5
229 check_err $? "Multicast not received on first host"
230 tc_check_packets "dev $h3 ingress" 133 5
231 check_err $? "Multicast not received on second host"
232
233 delete_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
234
235 $MZ $h1 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
236 -A 198.51.100.2 -B 225.1.2.3 -q
237
238 tc_check_packets "dev $h2 ingress" 122 5
239 check_err $? "Multicast received on host although deleted"
240 tc_check_packets "dev $h3 ingress" 133 5
241 check_err $? "Multicast received on second host although deleted"
242
243 tc filter del dev $h3 ingress protocol ip pref 1 handle 133 flower
244 tc filter del dev $h2 ingress protocol ip pref 1 handle 122 flower
245
246 log_test "mcast IPv4"
247}
248
249mcast_v6()
250{
251 # Add two interfaces to an MC group, send a packet to the MC group and
252 # verify packets are received on both. Then delete the route and verify
253 # packets are no longer received.
254
255 RET=0
256
257 tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 122 flower \
258 dst_ip ff0e::3 action drop
259 tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 133 flower \
260 dst_ip ff0e::3 action drop
261
262 create_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
263
264 # Send frames with the corresponding L2 destination address.
265 $MZ $h1 -6 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 \
266 -b 33:33:00:00:00:03 -A 2001:db8:1::2 -B ff0e::3 -q
267
268 tc_check_packets "dev $h2 ingress" 122 5
269 check_err $? "Multicast not received on first host"
270 tc_check_packets "dev $h3 ingress" 133 5
271 check_err $? "Multicast not received on second host"
272
273 delete_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
274
275 $MZ $h1 -6 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 \
276 -b 33:33:00:00:00:03 -A 2001:db8:1::2 -B ff0e::3 -q
277
278 tc_check_packets "dev $h2 ingress" 122 5
279 check_err $? "Multicast received on first host although deleted"
280 tc_check_packets "dev $h3 ingress" 133 5
281 check_err $? "Multicast received on second host although deleted"
282
283 tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 133 flower
284 tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 122 flower
285
286 log_test "mcast IPv6"
287}
288
289rpf_v4()
290{
291 # Add a multicast route from first router port to the other two. Send
292 # matching packets and test that both hosts receive them. Then, send
293 # the same packets via the third router port and test that they do not
294 # reach any host due to RPF check. A filter with 'skip_hw' is added to
295 # test that devices capable of multicast routing offload trap those
296 # packets. The filter is essentialy a NOP in other scenarios.
297
298 RET=0
299
300 tc filter add dev $h1 ingress protocol ip pref 1 handle 1 flower \
301 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
302 tc filter add dev $h2 ingress protocol ip pref 1 handle 1 flower \
303 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
304 tc filter add dev $h3 ingress protocol ip pref 1 handle 1 flower \
305 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
306 tc filter add dev $rp3 ingress protocol ip pref 1 handle 1 flower \
307 skip_hw dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action pass
308
309 create_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
310
311 $MZ $h1 -c 5 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
312 -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
313 -A 198.51.100.2 -B 225.1.2.3 -q
314
315 tc_check_packets "dev $h2 ingress" 1 5
316 check_err $? "Multicast not received on first host"
317 tc_check_packets "dev $h3 ingress" 1 5
318 check_err $? "Multicast not received on second host"
319
320 $MZ $h3 -c 5 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
321 -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
322 -A 198.51.100.2 -B 225.1.2.3 -q
323
324 tc_check_packets "dev $h1 ingress" 1 0
325 check_err $? "Multicast received on first host when should not"
326 tc_check_packets "dev $h2 ingress" 1 5
327 check_err $? "Multicast received on second host when should not"
328 tc_check_packets "dev $rp3 ingress" 1 5
329 check_err $? "Packets not trapped due to RPF check"
330
331 delete_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
332
333 tc filter del dev $rp3 ingress protocol ip pref 1 handle 1 flower
334 tc filter del dev $h3 ingress protocol ip pref 1 handle 1 flower
335 tc filter del dev $h2 ingress protocol ip pref 1 handle 1 flower
336 tc filter del dev $h1 ingress protocol ip pref 1 handle 1 flower
337
338 log_test "RPF IPv4"
339}
340
341rpf_v6()
342{
343 RET=0
344
345 tc filter add dev $h1 ingress protocol ipv6 pref 1 handle 1 flower \
346 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
347 tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 1 flower \
348 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
349 tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 1 flower \
350 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
351 tc filter add dev $rp3 ingress protocol ipv6 pref 1 handle 1 flower \
352 skip_hw dst_ip ff0e::3 ip_proto udp dst_port 12345 action pass
353
354 create_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
355
356 $MZ $h1 -6 -c 5 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
357 -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
358 -A 2001:db8:1::2 -B ff0e::3 -q
359
360 tc_check_packets "dev $h2 ingress" 1 5
361 check_err $? "Multicast not received on first host"
362 tc_check_packets "dev $h3 ingress" 1 5
363 check_err $? "Multicast not received on second host"
364
365 $MZ $h3 -6 -c 5 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
366 -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
367 -A 2001:db8:1::2 -B ff0e::3 -q
368
369 tc_check_packets "dev $h1 ingress" 1 0
370 check_err $? "Multicast received on first host when should not"
371 tc_check_packets "dev $h2 ingress" 1 5
372 check_err $? "Multicast received on second host when should not"
373 tc_check_packets "dev $rp3 ingress" 1 5
374 check_err $? "Packets not trapped due to RPF check"
375
376 delete_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
377
378 tc filter del dev $rp3 ingress protocol ipv6 pref 1 handle 1 flower
379 tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 1 flower
380 tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 1 flower
381 tc filter del dev $h1 ingress protocol ipv6 pref 1 handle 1 flower
382
383 log_test "RPF IPv6"
384}
385
386unres_v4()
387{
388 # Send a multicast packet not corresponding to an installed route,
389 # causing the kernel to queue the packet for resolution and emit an
390 # IGMPMSG_NOCACHE notification. smcrouted will react to this
391 # notification by consulting its (*, G) list and installing an (S, G)
392 # route, which will be used to forward the queued packet.
393
394 RET=0
395
396 tc filter add dev $h2 ingress protocol ip pref 1 handle 1 flower \
397 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
398 tc filter add dev $h3 ingress protocol ip pref 1 handle 1 flower \
399 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
400
401 # Forwarding should fail before installing a matching (*, G).
402 $MZ $h1 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
403 -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
404 -A 198.51.100.2 -B 225.1.2.3 -q
405
406 tc_check_packets "dev $h2 ingress" 1 0
407 check_err $? "Multicast received on first host when should not"
408 tc_check_packets "dev $h3 ingress" 1 0
409 check_err $? "Multicast received on second host when should not"
410
411 # Create (*, G). Will not be installed in the kernel.
412 create_mcast_sg $rp1 0.0.0.0 225.1.2.3 $rp2 $rp3
413
414 $MZ $h1 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
415 -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
416 -A 198.51.100.2 -B 225.1.2.3 -q
417
418 tc_check_packets "dev $h2 ingress" 1 1
419 check_err $? "Multicast not received on first host"
420 tc_check_packets "dev $h3 ingress" 1 1
421 check_err $? "Multicast not received on second host"
422
423 delete_mcast_sg $rp1 0.0.0.0 225.1.2.3 $rp2 $rp3
424
425 tc filter del dev $h3 ingress protocol ip pref 1 handle 1 flower
426 tc filter del dev $h2 ingress protocol ip pref 1 handle 1 flower
427
428 log_test "Unresolved queue IPv4"
429}
430
431unres_v6()
432{
433 # Send a multicast packet not corresponding to an installed route,
434 # causing the kernel to queue the packet for resolution and emit an
435 # MRT6MSG_NOCACHE notification. smcrouted will react to this
436 # notification by consulting its (*, G) list and installing an (S, G)
437 # route, which will be used to forward the queued packet.
438
439 RET=0
440
441 tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 1 flower \
442 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
443 tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 1 flower \
444 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
445
446 # Forwarding should fail before installing a matching (*, G).
447 $MZ $h1 -6 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
448 -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
449 -A 2001:db8:1::2 -B ff0e::3 -q
450
451 tc_check_packets "dev $h2 ingress" 1 0
452 check_err $? "Multicast received on first host when should not"
453 tc_check_packets "dev $h3 ingress" 1 0
454 check_err $? "Multicast received on second host when should not"
455
456 # Create (*, G). Will not be installed in the kernel.
457 create_mcast_sg $rp1 :: ff0e::3 $rp2 $rp3
458
459 $MZ $h1 -6 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
460 -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
461 -A 2001:db8:1::2 -B ff0e::3 -q
462
463 tc_check_packets "dev $h2 ingress" 1 1
464 check_err $? "Multicast not received on first host"
465 tc_check_packets "dev $h3 ingress" 1 1
466 check_err $? "Multicast not received on second host"
467
468 delete_mcast_sg $rp1 :: ff0e::3 $rp2 $rp3
469
470 tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 1 flower
471 tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 1 flower
472
473 log_test "Unresolved queue IPv6"
474}
475
476trap cleanup EXIT
477
478setup_prepare
479setup_wait
480
481tests_run
482
483exit $EXIT_STATUS