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" 32NUM_NETIFS=6 33source lib.sh 34source tc_common.sh 35 36require_command $MCD 37require_command $MC_CLI 38table_name=selftests 39 40h1_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 51h1_destroy() 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 129router_destroy() 130{ 131 ip address del 2001:db8:3::1/64 dev $rp3 132 ip address del 2001:db8:2::1/64 dev $rp2 133 ip address del 2001:db8:1::1/64 dev $rp1 134 135 ip address del 198.51.100.33/28 dev $rp3 136 ip address del 198.51.100.17/28 dev $rp2 137 ip address del 198.51.100.1/28 dev $rp1 138 139 ip link set dev $rp3 down 140 ip link set dev $rp2 down 141 ip link set dev $rp1 down 142} 143 144start_mcd() 145{ 146 SMCROUTEDIR="$(mktemp -d)" 147 148 for ((i = 1; i <= $NUM_NETIFS; ++i)); do 149 echo "phyint ${NETIFS[p$i]} enable" >> \ 150 $SMCROUTEDIR/$table_name.conf 151 done 152 153 $MCD -N -I $table_name -f $SMCROUTEDIR/$table_name.conf \ 154 -P $SMCROUTEDIR/$table_name.pid 155} 156 157kill_mcd() 158{ 159 pkill $MCD 160 rm -rf $SMCROUTEDIR 161} 162 163setup_prepare() 164{ 165 h1=${NETIFS[p1]} 166 rp1=${NETIFS[p2]} 167 168 rp2=${NETIFS[p3]} 169 h2=${NETIFS[p4]} 170 171 rp3=${NETIFS[p5]} 172 h3=${NETIFS[p6]} 173 174 start_mcd 175 176 vrf_prepare 177 178 h1_create 179 h2_create 180 h3_create 181 182 router_create 183 184 forwarding_enable 185} 186 187cleanup() 188{ 189 pre_cleanup 190 191 forwarding_restore 192 193 router_destroy 194 195 h3_destroy 196 h2_destroy 197 h1_destroy 198 199 vrf_cleanup 200 201 kill_mcd 202} 203 204create_mcast_sg() 205{ 206 local if_name=$1; shift 207 local s_addr=$1; shift 208 local mcast=$1; shift 209 local dest_ifs=${@} 210 211 $MC_CLI -I $table_name add $if_name $s_addr $mcast $dest_ifs 212} 213 214delete_mcast_sg() 215{ 216 local if_name=$1; shift 217 local s_addr=$1; shift 218 local mcast=$1; shift 219 local dest_ifs=${@} 220 221 $MC_CLI -I $table_name remove $if_name $s_addr $mcast $dest_ifs 222} 223 224mcast_v4() 225{ 226 # Add two interfaces to an MC group, send a packet to the MC group and 227 # verify packets are received on both. Then delete the route and verify 228 # packets are no longer received. 229 230 RET=0 231 232 tc filter add dev $h2 ingress protocol ip pref 1 handle 122 flower \ 233 dst_ip 225.1.2.3 action drop 234 tc filter add dev $h3 ingress protocol ip pref 1 handle 133 flower \ 235 dst_ip 225.1.2.3 action drop 236 237 create_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3 238 239 # Send frames with the corresponding L2 destination address. 240 $MZ $h1 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \ 241 -A 198.51.100.2 -B 225.1.2.3 -q 242 243 tc_check_packets "dev $h2 ingress" 122 5 244 check_err $? "Multicast not received on first host" 245 tc_check_packets "dev $h3 ingress" 133 5 246 check_err $? "Multicast not received on second host" 247 248 delete_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3 249 250 $MZ $h1 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \ 251 -A 198.51.100.2 -B 225.1.2.3 -q 252 253 tc_check_packets "dev $h2 ingress" 122 5 254 check_err $? "Multicast received on host although deleted" 255 tc_check_packets "dev $h3 ingress" 133 5 256 check_err $? "Multicast received on second host although deleted" 257 258 tc filter del dev $h3 ingress protocol ip pref 1 handle 133 flower 259 tc filter del dev $h2 ingress protocol ip pref 1 handle 122 flower 260 261 log_test "mcast IPv4" 262} 263 264mcast_v6() 265{ 266 # Add two interfaces to an MC group, send a packet to the MC group and 267 # verify packets are received on both. Then delete the route and verify 268 # packets are no longer received. 269 270 RET=0 271 272 tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 122 flower \ 273 dst_ip ff0e::3 action drop 274 tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 133 flower \ 275 dst_ip ff0e::3 action drop 276 277 create_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3 278 279 # Send frames with the corresponding L2 destination address. 280 $MZ $h1 -6 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 \ 281 -b 33:33:00:00:00:03 -A 2001:db8:1::2 -B ff0e::3 -q 282 283 tc_check_packets "dev $h2 ingress" 122 5 284 check_err $? "Multicast not received on first host" 285 tc_check_packets "dev $h3 ingress" 133 5 286 check_err $? "Multicast not received on second host" 287 288 delete_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3 289 290 $MZ $h1 -6 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 \ 291 -b 33:33:00:00:00:03 -A 2001:db8:1::2 -B ff0e::3 -q 292 293 tc_check_packets "dev $h2 ingress" 122 5 294 check_err $? "Multicast received on first host although deleted" 295 tc_check_packets "dev $h3 ingress" 133 5 296 check_err $? "Multicast received on second host although deleted" 297 298 tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 133 flower 299 tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 122 flower 300 301 log_test "mcast IPv6" 302} 303 304trap cleanup EXIT 305 306setup_prepare 307setup_wait 308 309tests_run 310 311exit $EXIT_STATUS 312