0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031 ALL_TESTS="mcast_v4 mcast_v6 rpf_v4 rpf_v6 unres_v4 unres_v6"
0032 NUM_NETIFS=6
0033 source lib.sh
0034 source tc_common.sh
0035
0036 require_command $MCD
0037 require_command $MC_CLI
0038 table_name=selftests
0039
0040 h1_create()
0041 {
0042 simple_if_init $h1 198.51.100.2/28 2001:db8:1::2/64
0043
0044 ip route add 198.51.100.16/28 vrf v$h1 nexthop via 198.51.100.1
0045 ip route add 198.51.100.32/28 vrf v$h1 nexthop via 198.51.100.1
0046
0047 ip route add 2001:db8:2::/64 vrf v$h1 nexthop via 2001:db8:1::1
0048 ip route add 2001:db8:3::/64 vrf v$h1 nexthop via 2001:db8:1::1
0049
0050 tc qdisc add dev $h1 ingress
0051 }
0052
0053 h1_destroy()
0054 {
0055 tc qdisc del dev $h1 ingress
0056
0057 ip route del 2001:db8:3::/64 vrf v$h1
0058 ip route del 2001:db8:2::/64 vrf v$h1
0059
0060 ip route del 198.51.100.32/28 vrf v$h1
0061 ip route del 198.51.100.16/28 vrf v$h1
0062
0063 simple_if_fini $h1 198.51.100.2/28 2001:db8:1::2/64
0064 }
0065
0066 h2_create()
0067 {
0068 simple_if_init $h2 198.51.100.18/28 2001:db8:2::2/64
0069
0070 ip route add 198.51.100.0/28 vrf v$h2 nexthop via 198.51.100.17
0071 ip route add 198.51.100.32/28 vrf v$h2 nexthop via 198.51.100.17
0072
0073 ip route add 2001:db8:1::/64 vrf v$h2 nexthop via 2001:db8:2::1
0074 ip route add 2001:db8:3::/64 vrf v$h2 nexthop via 2001:db8:2::1
0075
0076 tc qdisc add dev $h2 ingress
0077 }
0078
0079 h2_destroy()
0080 {
0081 tc qdisc del dev $h2 ingress
0082
0083 ip route del 2001:db8:3::/64 vrf v$h2
0084 ip route del 2001:db8:1::/64 vrf v$h2
0085
0086 ip route del 198.51.100.32/28 vrf v$h2
0087 ip route del 198.51.100.0/28 vrf v$h2
0088
0089 simple_if_fini $h2 198.51.100.18/28 2001:db8:2::2/64
0090 }
0091
0092 h3_create()
0093 {
0094 simple_if_init $h3 198.51.100.34/28 2001:db8:3::2/64
0095
0096 ip route add 198.51.100.0/28 vrf v$h3 nexthop via 198.51.100.33
0097 ip route add 198.51.100.16/28 vrf v$h3 nexthop via 198.51.100.33
0098
0099 ip route add 2001:db8:1::/64 vrf v$h3 nexthop via 2001:db8:3::1
0100 ip route add 2001:db8:2::/64 vrf v$h3 nexthop via 2001:db8:3::1
0101
0102 tc qdisc add dev $h3 ingress
0103 }
0104
0105 h3_destroy()
0106 {
0107 tc qdisc del dev $h3 ingress
0108
0109 ip route del 2001:db8:2::/64 vrf v$h3
0110 ip route del 2001:db8:1::/64 vrf v$h3
0111
0112 ip route del 198.51.100.16/28 vrf v$h3
0113 ip route del 198.51.100.0/28 vrf v$h3
0114
0115 simple_if_fini $h3 198.51.100.34/28 2001:db8:3::2/64
0116 }
0117
0118 router_create()
0119 {
0120 ip link set dev $rp1 up
0121 ip link set dev $rp2 up
0122 ip link set dev $rp3 up
0123
0124 ip address add 198.51.100.1/28 dev $rp1
0125 ip address add 198.51.100.17/28 dev $rp2
0126 ip address add 198.51.100.33/28 dev $rp3
0127
0128 ip address add 2001:db8:1::1/64 dev $rp1
0129 ip address add 2001:db8:2::1/64 dev $rp2
0130 ip address add 2001:db8:3::1/64 dev $rp3
0131
0132 tc qdisc add dev $rp3 ingress
0133 }
0134
0135 router_destroy()
0136 {
0137 tc qdisc del dev $rp3 ingress
0138
0139 ip address del 2001:db8:3::1/64 dev $rp3
0140 ip address del 2001:db8:2::1/64 dev $rp2
0141 ip address del 2001:db8:1::1/64 dev $rp1
0142
0143 ip address del 198.51.100.33/28 dev $rp3
0144 ip address del 198.51.100.17/28 dev $rp2
0145 ip address del 198.51.100.1/28 dev $rp1
0146
0147 ip link set dev $rp3 down
0148 ip link set dev $rp2 down
0149 ip link set dev $rp1 down
0150 }
0151
0152 start_mcd()
0153 {
0154 SMCROUTEDIR="$(mktemp -d)"
0155
0156 for ((i = 1; i <= $NUM_NETIFS; ++i)); do
0157 echo "phyint ${NETIFS[p$i]} enable" >> \
0158 $SMCROUTEDIR/$table_name.conf
0159 done
0160
0161 $MCD -N -I $table_name -f $SMCROUTEDIR/$table_name.conf \
0162 -P $SMCROUTEDIR/$table_name.pid
0163 }
0164
0165 kill_mcd()
0166 {
0167 pkill $MCD
0168 rm -rf $SMCROUTEDIR
0169 }
0170
0171 setup_prepare()
0172 {
0173 h1=${NETIFS[p1]}
0174 rp1=${NETIFS[p2]}
0175
0176 rp2=${NETIFS[p3]}
0177 h2=${NETIFS[p4]}
0178
0179 rp3=${NETIFS[p5]}
0180 h3=${NETIFS[p6]}
0181
0182 start_mcd
0183
0184 vrf_prepare
0185
0186 h1_create
0187 h2_create
0188 h3_create
0189
0190 router_create
0191
0192 forwarding_enable
0193 }
0194
0195 cleanup()
0196 {
0197 pre_cleanup
0198
0199 forwarding_restore
0200
0201 router_destroy
0202
0203 h3_destroy
0204 h2_destroy
0205 h1_destroy
0206
0207 vrf_cleanup
0208
0209 kill_mcd
0210 }
0211
0212 create_mcast_sg()
0213 {
0214 local if_name=$1; shift
0215 local s_addr=$1; shift
0216 local mcast=$1; shift
0217 local dest_ifs=${@}
0218
0219 $MC_CLI -I $table_name add $if_name $s_addr $mcast $dest_ifs
0220 }
0221
0222 delete_mcast_sg()
0223 {
0224 local if_name=$1; shift
0225 local s_addr=$1; shift
0226 local mcast=$1; shift
0227 local dest_ifs=${@}
0228
0229 $MC_CLI -I $table_name remove $if_name $s_addr $mcast $dest_ifs
0230 }
0231
0232 mcast_v4()
0233 {
0234
0235
0236
0237
0238 RET=0
0239
0240 tc filter add dev $h2 ingress protocol ip pref 1 handle 122 flower \
0241 dst_ip 225.1.2.3 action drop
0242 tc filter add dev $h3 ingress protocol ip pref 1 handle 133 flower \
0243 dst_ip 225.1.2.3 action drop
0244
0245 create_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
0246
0247
0248 $MZ $h1 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
0249 -A 198.51.100.2 -B 225.1.2.3 -q
0250
0251 tc_check_packets "dev $h2 ingress" 122 5
0252 check_err $? "Multicast not received on first host"
0253 tc_check_packets "dev $h3 ingress" 133 5
0254 check_err $? "Multicast not received on second host"
0255
0256 delete_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
0257
0258 $MZ $h1 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
0259 -A 198.51.100.2 -B 225.1.2.3 -q
0260
0261 tc_check_packets "dev $h2 ingress" 122 5
0262 check_err $? "Multicast received on host although deleted"
0263 tc_check_packets "dev $h3 ingress" 133 5
0264 check_err $? "Multicast received on second host although deleted"
0265
0266 tc filter del dev $h3 ingress protocol ip pref 1 handle 133 flower
0267 tc filter del dev $h2 ingress protocol ip pref 1 handle 122 flower
0268
0269 log_test "mcast IPv4"
0270 }
0271
0272 mcast_v6()
0273 {
0274
0275
0276
0277
0278 RET=0
0279
0280 tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 122 flower \
0281 dst_ip ff0e::3 action drop
0282 tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 133 flower \
0283 dst_ip ff0e::3 action drop
0284
0285 create_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
0286
0287
0288 $MZ $h1 -6 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 \
0289 -b 33:33:00:00:00:03 -A 2001:db8:1::2 -B ff0e::3 -q
0290
0291 tc_check_packets "dev $h2 ingress" 122 5
0292 check_err $? "Multicast not received on first host"
0293 tc_check_packets "dev $h3 ingress" 133 5
0294 check_err $? "Multicast not received on second host"
0295
0296 delete_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
0297
0298 $MZ $h1 -6 -c 5 -p 128 -t udp -a 00:11:22:33:44:55 \
0299 -b 33:33:00:00:00:03 -A 2001:db8:1::2 -B ff0e::3 -q
0300
0301 tc_check_packets "dev $h2 ingress" 122 5
0302 check_err $? "Multicast received on first host although deleted"
0303 tc_check_packets "dev $h3 ingress" 133 5
0304 check_err $? "Multicast received on second host although deleted"
0305
0306 tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 133 flower
0307 tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 122 flower
0308
0309 log_test "mcast IPv6"
0310 }
0311
0312 rpf_v4()
0313 {
0314
0315
0316
0317
0318
0319
0320
0321 RET=0
0322
0323 tc filter add dev $h1 ingress protocol ip pref 1 handle 1 flower \
0324 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
0325 tc filter add dev $h2 ingress protocol ip pref 1 handle 1 flower \
0326 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
0327 tc filter add dev $h3 ingress protocol ip pref 1 handle 1 flower \
0328 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
0329 tc filter add dev $rp3 ingress protocol ip pref 1 handle 1 flower \
0330 skip_hw dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action pass
0331
0332 create_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
0333
0334 $MZ $h1 -c 5 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
0335 -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
0336 -A 198.51.100.2 -B 225.1.2.3 -q
0337
0338 tc_check_packets "dev $h2 ingress" 1 5
0339 check_err $? "Multicast not received on first host"
0340 tc_check_packets "dev $h3 ingress" 1 5
0341 check_err $? "Multicast not received on second host"
0342
0343 $MZ $h3 -c 5 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
0344 -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
0345 -A 198.51.100.2 -B 225.1.2.3 -q
0346
0347 tc_check_packets "dev $h1 ingress" 1 0
0348 check_err $? "Multicast received on first host when should not"
0349 tc_check_packets "dev $h2 ingress" 1 5
0350 check_err $? "Multicast received on second host when should not"
0351 tc_check_packets "dev $rp3 ingress" 1 5
0352 check_err $? "Packets not trapped due to RPF check"
0353
0354 delete_mcast_sg $rp1 198.51.100.2 225.1.2.3 $rp2 $rp3
0355
0356 tc filter del dev $rp3 ingress protocol ip pref 1 handle 1 flower
0357 tc filter del dev $h3 ingress protocol ip pref 1 handle 1 flower
0358 tc filter del dev $h2 ingress protocol ip pref 1 handle 1 flower
0359 tc filter del dev $h1 ingress protocol ip pref 1 handle 1 flower
0360
0361 log_test "RPF IPv4"
0362 }
0363
0364 rpf_v6()
0365 {
0366 RET=0
0367
0368 tc filter add dev $h1 ingress protocol ipv6 pref 1 handle 1 flower \
0369 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
0370 tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 1 flower \
0371 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
0372 tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 1 flower \
0373 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
0374 tc filter add dev $rp3 ingress protocol ipv6 pref 1 handle 1 flower \
0375 skip_hw dst_ip ff0e::3 ip_proto udp dst_port 12345 action pass
0376
0377 create_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
0378
0379 $MZ $h1 -6 -c 5 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
0380 -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
0381 -A 2001:db8:1::2 -B ff0e::3 -q
0382
0383 tc_check_packets "dev $h2 ingress" 1 5
0384 check_err $? "Multicast not received on first host"
0385 tc_check_packets "dev $h3 ingress" 1 5
0386 check_err $? "Multicast not received on second host"
0387
0388 $MZ $h3 -6 -c 5 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
0389 -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
0390 -A 2001:db8:1::2 -B ff0e::3 -q
0391
0392 tc_check_packets "dev $h1 ingress" 1 0
0393 check_err $? "Multicast received on first host when should not"
0394 tc_check_packets "dev $h2 ingress" 1 5
0395 check_err $? "Multicast received on second host when should not"
0396 tc_check_packets "dev $rp3 ingress" 1 5
0397 check_err $? "Packets not trapped due to RPF check"
0398
0399 delete_mcast_sg $rp1 2001:db8:1::2 ff0e::3 $rp2 $rp3
0400
0401 tc filter del dev $rp3 ingress protocol ipv6 pref 1 handle 1 flower
0402 tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 1 flower
0403 tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 1 flower
0404 tc filter del dev $h1 ingress protocol ipv6 pref 1 handle 1 flower
0405
0406 log_test "RPF IPv6"
0407 }
0408
0409 unres_v4()
0410 {
0411
0412
0413
0414
0415
0416
0417 RET=0
0418
0419 tc filter add dev $h2 ingress protocol ip pref 1 handle 1 flower \
0420 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
0421 tc filter add dev $h3 ingress protocol ip pref 1 handle 1 flower \
0422 dst_ip 225.1.2.3 ip_proto udp dst_port 12345 action drop
0423
0424
0425 $MZ $h1 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
0426 -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
0427 -A 198.51.100.2 -B 225.1.2.3 -q
0428
0429 tc_check_packets "dev $h2 ingress" 1 0
0430 check_err $? "Multicast received on first host when should not"
0431 tc_check_packets "dev $h3 ingress" 1 0
0432 check_err $? "Multicast received on second host when should not"
0433
0434
0435 create_mcast_sg $rp1 0.0.0.0 225.1.2.3 $rp2 $rp3
0436
0437 $MZ $h1 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
0438 -a 00:11:22:33:44:55 -b 01:00:5e:01:02:03 \
0439 -A 198.51.100.2 -B 225.1.2.3 -q
0440
0441 tc_check_packets "dev $h2 ingress" 1 1
0442 check_err $? "Multicast not received on first host"
0443 tc_check_packets "dev $h3 ingress" 1 1
0444 check_err $? "Multicast not received on second host"
0445
0446 delete_mcast_sg $rp1 0.0.0.0 225.1.2.3 $rp2 $rp3
0447
0448 tc filter del dev $h3 ingress protocol ip pref 1 handle 1 flower
0449 tc filter del dev $h2 ingress protocol ip pref 1 handle 1 flower
0450
0451 log_test "Unresolved queue IPv4"
0452 }
0453
0454 unres_v6()
0455 {
0456
0457
0458
0459
0460
0461
0462 RET=0
0463
0464 tc filter add dev $h2 ingress protocol ipv6 pref 1 handle 1 flower \
0465 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
0466 tc filter add dev $h3 ingress protocol ipv6 pref 1 handle 1 flower \
0467 dst_ip ff0e::3 ip_proto udp dst_port 12345 action drop
0468
0469
0470 $MZ $h1 -6 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
0471 -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
0472 -A 2001:db8:1::2 -B ff0e::3 -q
0473
0474 tc_check_packets "dev $h2 ingress" 1 0
0475 check_err $? "Multicast received on first host when should not"
0476 tc_check_packets "dev $h3 ingress" 1 0
0477 check_err $? "Multicast received on second host when should not"
0478
0479
0480 create_mcast_sg $rp1 :: ff0e::3 $rp2 $rp3
0481
0482 $MZ $h1 -6 -c 1 -p 128 -t udp "ttl=10,sp=54321,dp=12345" \
0483 -a 00:11:22:33:44:55 -b 33:33:00:00:00:03 \
0484 -A 2001:db8:1::2 -B ff0e::3 -q
0485
0486 tc_check_packets "dev $h2 ingress" 1 1
0487 check_err $? "Multicast not received on first host"
0488 tc_check_packets "dev $h3 ingress" 1 1
0489 check_err $? "Multicast not received on second host"
0490
0491 delete_mcast_sg $rp1 :: ff0e::3 $rp2 $rp3
0492
0493 tc filter del dev $h3 ingress protocol ipv6 pref 1 handle 1 flower
0494 tc filter del dev $h2 ingress protocol ipv6 pref 1 handle 1 flower
0495
0496 log_test "Unresolved queue IPv6"
0497 }
0498
0499 trap cleanup EXIT
0500
0501 setup_prepare
0502 setup_wait
0503
0504 tests_run
0505
0506 exit $EXIT_STATUS