selftests: forwarding: Add test cases for unresolved multicast routes
authorIdo Schimmel <idosch@nvidia.com>
Wed, 14 Sep 2022 07:53:39 +0000 (10:53 +0300)
committerJakub Kicinski <kuba@kernel.org>
Tue, 20 Sep 2022 15:22:15 +0000 (08:22 -0700)
Add IPv4 and IPv6 test cases for unresolved multicast routes, testing
that queued packets are forwarded after installing a matching (S, G)
route.

The test cases can be used to reproduce the bugs fixed in "ipmr: Always
call ip{,6}_mr_forward() from RCU read-side critical section".

Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
tools/testing/selftests/net/forwarding/router_multicast.sh

index 57e90c873a2cf4e6e326ed57b6410414a9dcb597..5a58b1ec8aefb573c944834502084e3d46c4aaf5 100755 (executable)
@@ -28,7 +28,7 @@
 # +------------------+       +------------------+
 #
 
-ALL_TESTS="mcast_v4 mcast_v6 rpf_v4 rpf_v6"
+ALL_TESTS="mcast_v4 mcast_v6 rpf_v4 rpf_v6 unres_v4 unres_v6"
 NUM_NETIFS=6
 source lib.sh
 source tc_common.sh
@@ -406,6 +406,96 @@ rpf_v6()
        log_test "RPF IPv6"
 }
 
+unres_v4()
+{
+       # Send a multicast packet not corresponding to an installed route,
+       # causing the kernel to queue the packet for resolution and emit an
+       # IGMPMSG_NOCACHE notification. smcrouted will react to this
+       # notification by consulting its (*, G) list and installing an (S, G)
+       # route, which will be used to forward the queued packet.
+
+       RET=0
+
+       tc filter add dev $h2 ingress protocol ip pref 1 handle 1 flower \
+               dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
+       tc filter add dev $h3 ingress protocol ip pref 1 handle 1 flower \
+               dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
+
+       # Forwarding should fail before installing a matching (*, G).
+       $MZ $h1 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
+               -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
+               -A 198.51.100.2 -B 225.1.2.3 -q
+
+       tc_check_packets "dev $h2 ingress" 1 0
+       check_err $? "Multicast received on first host when should not"
+       tc_check_packets "dev $h3 ingress" 1 0
+       check_err $? "Multicast received on second host when should not"
+
+       # Create (*, G). Will not be installed in the kernel.
+       create_mcast_sg $rp1 0.0.0.0 225.1.2.3 $rp2 $rp3
+
+       $MZ $h1 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
+               -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
+               -A 198.51.100.2 -B 225.1.2.3 -q
+
+       tc_check_packets "dev $h2 ingress" 1 1
+       check_err $? "Multicast not received on first host"
+       tc_check_packets "dev $h3 ingress" 1 1
+       check_err $? "Multicast not received on second host"
+
+       delete_mcast_sg $rp1 0.0.0.0 225.1.2.3 $rp2 $rp3
+
+       tc filter del dev $h3 ingress protocol ip pref 1 handle 1 flower
+       tc filter del dev $h2 ingress protocol ip pref 1 handle 1 flower
+
+       log_test "Unresolved queue IPv4"
+}
+
+unres_v6()
+{
+       # Send a multicast packet not corresponding to an installed route,
+       # causing the kernel to queue the packet for resolution and emit an
+       # MRT6MSG_NOCACHE notification. smcrouted will react to this
+       # notification by consulting its (*, G) list and installing an (S, G)
+       # route, which will be used to forward the queued packet.
+
+       RET=0
+
+       tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 1 flower \
+               dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
+       tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 1 flower \
+               dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
+
+       # Forwarding should fail before installing a matching (*, G).
+       $MZ $h1 -6 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
+               -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
+               -A 2001:db8:1::2 -B ff0e::3 -q
+
+       tc_check_packets "dev $h2 ingress" 1 0
+       check_err $? "Multicast received on first host when should not"
+       tc_check_packets "dev $h3 ingress" 1 0
+       check_err $? "Multicast received on second host when should not"
+
+       # Create (*, G). Will not be installed in the kernel.
+       create_mcast_sg $rp1 :: ff0e::3 $rp2 $rp3
+
+       $MZ $h1 -6 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
+               -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
+               -A 2001:db8:1::2 -B ff0e::3 -q
+
+       tc_check_packets "dev $h2 ingress" 1 1
+       check_err $? "Multicast not received on first host"
+       tc_check_packets "dev $h3 ingress" 1 1
+       check_err $? "Multicast not received on second host"
+
+       delete_mcast_sg $rp1 :: ff0e::3 $rp2 $rp3
+
+       tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 1 flower
+       tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 1 flower
+
+       log_test "Unresolved queue IPv6"
+}
+
 trap cleanup EXIT
 
 setup_prepare