~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/tools/testing/selftests/net/forwarding/router_multicast.sh

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php