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
0032
0033
0034
0035
0036
0037
0038
0039
0040 lib_dir=$(dirname $0)/../../../net/forwarding
0041
0042 ALL_TESTS="
0043 mtu_value_is_too_small_test
0044 ttl_value_is_too_small_test
0045 mc_reverse_path_forwarding_test
0046 reject_route_test
0047 unresolved_neigh_test
0048 ipv4_lpm_miss_test
0049 ipv6_lpm_miss_test
0050 "
0051
0052 NUM_NETIFS=4
0053 source $lib_dir/lib.sh
0054 source $lib_dir/tc_common.sh
0055 source $lib_dir/devlink_lib.sh
0056
0057 require_command $MCD
0058 require_command $MC_CLI
0059 table_name=selftests
0060
0061 h1_create()
0062 {
0063 simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
0064
0065 ip -4 route add default vrf v$h1 nexthop via 192.0.2.2
0066 ip -6 route add default vrf v$h1 nexthop via 2001:db8:1::2
0067
0068 tc qdisc add dev $h1 clsact
0069 }
0070
0071 h1_destroy()
0072 {
0073 tc qdisc del dev $h1 clsact
0074
0075 ip -6 route del default vrf v$h1 nexthop via 2001:db8:1::2
0076 ip -4 route del default vrf v$h1 nexthop via 192.0.2.2
0077
0078 simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
0079 }
0080
0081 h2_create()
0082 {
0083 simple_if_init $h2 198.51.100.1/24 2001:db8:2::1/64
0084
0085 ip -4 route add default vrf v$h2 nexthop via 198.51.100.2
0086 ip -6 route add default vrf v$h2 nexthop via 2001:db8:2::2
0087 }
0088
0089 h2_destroy()
0090 {
0091 ip -6 route del default vrf v$h2 nexthop via 2001:db8:2::2
0092 ip -4 route del default vrf v$h2 nexthop via 198.51.100.2
0093
0094 simple_if_fini $h2 198.51.100.1/24 2001:db8:2::1/64
0095 }
0096
0097 router_create()
0098 {
0099 ip link set dev $rp1 up
0100 ip link set dev $rp2 up
0101
0102 tc qdisc add dev $rp2 clsact
0103
0104 __addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
0105 __addr_add_del $rp2 add 198.51.100.2/24 2001:db8:2::2/64
0106 }
0107
0108 router_destroy()
0109 {
0110 __addr_add_del $rp2 del 198.51.100.2/24 2001:db8:2::2/64
0111 __addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64
0112
0113 tc qdisc del dev $rp2 clsact
0114
0115 ip link set dev $rp2 down
0116 ip link set dev $rp1 down
0117 }
0118
0119 setup_prepare()
0120 {
0121 h1=${NETIFS[p1]}
0122 rp1=${NETIFS[p2]}
0123
0124 rp2=${NETIFS[p3]}
0125 h2=${NETIFS[p4]}
0126
0127 rp1mac=$(mac_get $rp1)
0128
0129 start_mcd
0130
0131 vrf_prepare
0132 forwarding_enable
0133
0134 h1_create
0135 h2_create
0136
0137 router_create
0138 }
0139
0140 cleanup()
0141 {
0142 pre_cleanup
0143
0144 router_destroy
0145
0146 h2_destroy
0147 h1_destroy
0148
0149 forwarding_restore
0150 vrf_cleanup
0151
0152 kill_mcd
0153 }
0154
0155 ping_check()
0156 {
0157 ping_do $h1 198.51.100.1
0158 check_err $? "Packets that should not be trapped were trapped"
0159 }
0160
0161 trap_action_check()
0162 {
0163 local trap_name=$1; shift
0164 local expected_action=$1; shift
0165
0166 action=$(devlink_trap_action_get $trap_name)
0167 if [ "$action" != $expected_action ]; then
0168 check_err 1 "Trap $trap_name has wrong action: $action"
0169 fi
0170 }
0171
0172 mtu_value_is_too_small_test()
0173 {
0174 local trap_name="mtu_value_is_too_small"
0175 local expected_action="trap"
0176 local mz_pid
0177
0178 RET=0
0179
0180 ping_check $trap_name
0181 trap_action_check $trap_name $expected_action
0182
0183
0184
0185 tc filter add dev $h1 ingress protocol ip pref 1 handle 101 \
0186 flower skip_hw ip_proto icmp type 3 code 4 action pass
0187
0188 mtu_set $rp2 1300
0189
0190
0191
0192 $MZ $h1 -t udp "sp=54321,dp=12345,df" -p 1400 -c 0 -d 1msec -b $rp1mac \
0193 -B 198.51.100.1 -q &
0194 mz_pid=$!
0195
0196 devlink_trap_exception_test $trap_name
0197
0198 tc_check_packets_hitting "dev $h1 ingress" 101
0199 check_err $? "Packets were not received to h1"
0200
0201 log_test "MTU value is too small"
0202
0203 mtu_restore $rp2
0204
0205 kill $mz_pid && wait $mz_pid &> /dev/null
0206 tc filter del dev $h1 ingress protocol ip pref 1 handle 101 flower
0207 }
0208
0209 __ttl_value_is_too_small_test()
0210 {
0211 local ttl_val=$1; shift
0212 local trap_name="ttl_value_is_too_small"
0213 local expected_action="trap"
0214 local mz_pid
0215
0216 RET=0
0217
0218 ping_check $trap_name
0219 trap_action_check $trap_name $expected_action
0220
0221
0222
0223 tc filter add dev $h1 ingress protocol ip pref 1 handle 101 \
0224 flower skip_hw ip_proto icmp type 11 code 0 action pass
0225
0226
0227 $MZ $h1 -t udp "ttl=$ttl_val,sp=54321,dp=12345" -c 0 -d 1msec \
0228 -b $rp1mac -B 198.51.100.1 -q &
0229 mz_pid=$!
0230
0231 devlink_trap_exception_test $trap_name
0232
0233 tc_check_packets_hitting "dev $h1 ingress" 101
0234 check_err $? "Packets were not received to h1"
0235
0236 log_test "TTL value is too small: TTL=$ttl_val"
0237
0238 kill $mz_pid && wait $mz_pid &> /dev/null
0239 tc filter del dev $h1 ingress protocol ip pref 1 handle 101 flower
0240 }
0241
0242 ttl_value_is_too_small_test()
0243 {
0244 __ttl_value_is_too_small_test 0
0245 __ttl_value_is_too_small_test 1
0246 }
0247
0248 start_mcd()
0249 {
0250 SMCROUTEDIR="$(mktemp -d)"
0251 for ((i = 1; i <= $NUM_NETIFS; ++i)); do
0252 echo "phyint ${NETIFS[p$i]} enable" >> \
0253 $SMCROUTEDIR/$table_name.conf
0254 done
0255
0256 $MCD -N -I $table_name -f $SMCROUTEDIR/$table_name.conf \
0257 -P $SMCROUTEDIR/$table_name.pid
0258 }
0259
0260 kill_mcd()
0261 {
0262 pkill $MCD
0263 rm -rf $SMCROUTEDIR
0264 }
0265
0266 __mc_reverse_path_forwarding_test()
0267 {
0268 local desc=$1; shift
0269 local src_ip=$1; shift
0270 local dst_ip=$1; shift
0271 local dst_mac=$1; shift
0272 local proto=$1; shift
0273 local flags=${1:-""}; shift
0274 local trap_name="mc_reverse_path_forwarding"
0275 local expected_action="trap"
0276 local mz_pid
0277
0278 RET=0
0279
0280 ping_check $trap_name
0281 trap_action_check $trap_name $expected_action
0282
0283 tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
0284 flower dst_ip $dst_ip ip_proto udp action drop
0285
0286 $MC_CLI -I $table_name add $rp1 $src_ip $dst_ip $rp2
0287
0288
0289 $MZ $h2 $flags -t udp "sp=54321,dp=12345" -c 0 -p 128 \
0290 -a 00:11:22:33:44:55 -b $dst_mac \
0291 -A $src_ip -B $dst_ip -q &
0292
0293 mz_pid=$!
0294
0295 devlink_trap_exception_test $trap_name
0296
0297 tc_check_packets "dev $rp2 egress" 101 0
0298 check_err $? "Packets were not dropped"
0299
0300 log_test "Multicast reverse path forwarding: $desc"
0301
0302 kill $mz_pid && wait $mz_pid &> /dev/null
0303 tc filter del dev $rp2 egress protocol $proto pref 1 handle 101 flower
0304 }
0305
0306 mc_reverse_path_forwarding_test()
0307 {
0308 __mc_reverse_path_forwarding_test "IPv4" "192.0.2.1" "225.1.2.3" \
0309 "01:00:5e:01:02:03" "ip"
0310 __mc_reverse_path_forwarding_test "IPv6" "2001:db8:1::1" "ff0e::3" \
0311 "33:33:00:00:00:03" "ipv6" "-6"
0312 }
0313
0314 __reject_route_test()
0315 {
0316 local desc=$1; shift
0317 local dst_ip=$1; shift
0318 local proto=$1; shift
0319 local ip_proto=$1; shift
0320 local type=$1; shift
0321 local code=$1; shift
0322 local unreachable=$1; shift
0323 local flags=${1:-""}; shift
0324 local trap_name="reject_route"
0325 local expected_action="trap"
0326 local mz_pid
0327
0328 RET=0
0329
0330 ping_check $trap_name
0331 trap_action_check $trap_name $expected_action
0332
0333 tc filter add dev $h1 ingress protocol $proto pref 1 handle 101 flower \
0334 skip_hw ip_proto $ip_proto type $type code $code action pass
0335
0336 ip route add unreachable $unreachable
0337
0338
0339 $MZ $flags $h1 -t udp "sp=54321,dp=12345" -c 0 -d 1msec -b $rp1mac \
0340 -B $dst_ip -q &
0341 mz_pid=$!
0342
0343 devlink_trap_exception_test $trap_name
0344
0345 tc_check_packets_hitting "dev $h1 ingress" 101
0346 check_err $? "ICMP packet was not received to h1"
0347
0348 log_test "Reject route: $desc"
0349
0350 kill $mz_pid && wait $mz_pid &> /dev/null
0351 ip route del unreachable $unreachable
0352 tc filter del dev $h1 ingress protocol $proto pref 1 handle 101 flower
0353 }
0354
0355 reject_route_test()
0356 {
0357
0358
0359 __reject_route_test "IPv4" 198.51.100.1 "ip" "icmp" 3 1 \
0360 "198.51.100.0/26"
0361
0362
0363 __reject_route_test "IPv6" 2001:db8:2::1 "ipv6" "icmpv6" 1 0 \
0364 "2001:db8:2::0/66" "-6"
0365 }
0366
0367 __host_miss_test()
0368 {
0369 local desc=$1; shift
0370 local dip=$1; shift
0371 local trap_name="unresolved_neigh"
0372 local expected_action="trap"
0373 local mz_pid
0374
0375 RET=0
0376
0377 ping_check $trap_name
0378 trap_action_check $trap_name $expected_action
0379
0380 ip neigh flush dev $rp2
0381
0382 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
0383
0384
0385
0386 ping_do $h1 $dip
0387 check_err $? "ping failed: $desc"
0388
0389 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
0390
0391 if [[ $t0_packets -eq $t1_packets ]]; then
0392 check_err 1 "Trap counter did not increase"
0393 fi
0394
0395 log_test "Unresolved neigh: host miss: $desc"
0396 }
0397
0398 __invalid_nexthop_test()
0399 {
0400 local desc=$1; shift
0401 local dip=$1; shift
0402 local extra_add=$1; shift
0403 local subnet=$1; shift
0404 local via_add=$1; shift
0405 local trap_name="unresolved_neigh"
0406 local expected_action="trap"
0407 local mz_pid
0408
0409 RET=0
0410
0411 ping_check $trap_name
0412 trap_action_check $trap_name $expected_action
0413
0414 ip address add $extra_add/$subnet dev $h2
0415
0416
0417 ip $flags route add $dip via $extra_add dev $rp2
0418
0419
0420
0421
0422
0423 ping_do $h1 $dip
0424
0425 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
0426 ping_do $h1 $dip
0427 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
0428
0429 if [[ $t0_packets -ne $t1_packets ]]; then
0430 check_err 1 "Trap counter increased when it should not"
0431 fi
0432
0433 ip $flags route del $dip via $extra_add dev $rp2
0434
0435
0436
0437 ip $flags route add $dip via $via_add dev $h2
0438
0439 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
0440 ping_do $h1 $dip
0441 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
0442
0443 if [[ $t0_packets -eq $t1_packets ]]; then
0444 check_err 1 "Trap counter did not increase"
0445 fi
0446
0447 ip $flags route del $dip via $via_add dev $h2
0448 ip address del $extra_add/$subnet dev $h2
0449 log_test "Unresolved neigh: nexthop does not exist: $desc"
0450 }
0451
0452 __invalid_nexthop_bucket_test()
0453 {
0454 local desc=$1; shift
0455 local dip=$1; shift
0456 local via_add=$1; shift
0457 local trap_name="unresolved_neigh"
0458
0459 RET=0
0460
0461
0462
0463 ip nexthop add id 1 via $via_add dev $rp2
0464 ip nexthop add id 10 group 1 type resilient buckets 32
0465 ip route add $dip nhid 10
0466
0467 t0_packets=$(devlink_trap_rx_packets_get $trap_name)
0468 ping_do $h1 $dip
0469 t1_packets=$(devlink_trap_rx_packets_get $trap_name)
0470
0471 if [[ $t0_packets -eq $t1_packets ]]; then
0472 check_err 1 "Trap counter did not increase"
0473 fi
0474
0475 ip route del $dip nhid 10
0476 ip nexthop del id 10
0477 ip nexthop del id 1
0478 log_test "Unresolved neigh: nexthop bucket does not exist: $desc"
0479 }
0480
0481 unresolved_neigh_test()
0482 {
0483 __host_miss_test "IPv4" 198.51.100.1
0484 __host_miss_test "IPv6" 2001:db8:2::1
0485 __invalid_nexthop_test "IPv4" 198.51.100.1 198.51.100.3 24 198.51.100.4
0486 __invalid_nexthop_test "IPv6" 2001:db8:2::1 2001:db8:2::3 64 \
0487 2001:db8:2::4
0488 __invalid_nexthop_bucket_test "IPv4" 198.51.100.1 198.51.100.4
0489 __invalid_nexthop_bucket_test "IPv6" 2001:db8:2::1 2001:db8:2::4
0490 }
0491
0492 vrf_without_routes_create()
0493 {
0494
0495
0496
0497 sysctl_set net.ipv6.conf.$rp1.keep_addr_on_down 1
0498 sysctl_set net.ipv6.conf.$rp2.keep_addr_on_down 1
0499
0500 ip link add dev vrf1 type vrf table 101
0501 ip link set dev $rp1 master vrf1
0502 ip link set dev $rp2 master vrf1
0503 ip link set dev vrf1 up
0504
0505
0506 setup_wait
0507 }
0508
0509 vrf_without_routes_destroy()
0510 {
0511 ip link set dev $rp1 nomaster
0512 ip link set dev $rp2 nomaster
0513 ip link del dev vrf1
0514
0515 sysctl_restore net.ipv6.conf.$rp2.keep_addr_on_down
0516 sysctl_restore net.ipv6.conf.$rp1.keep_addr_on_down
0517
0518
0519 setup_wait
0520 }
0521
0522 ipv4_lpm_miss_test()
0523 {
0524 local trap_name="ipv4_lpm_miss"
0525 local expected_action="trap"
0526 local mz_pid
0527
0528 RET=0
0529
0530 ping_check $trap_name
0531 trap_action_check $trap_name $expected_action
0532
0533
0534 vrf_without_routes_create
0535
0536
0537 $MZ $h1 -t udp "sp=54321,dp=12345" -c 0 -d 1msec -b $rp1mac \
0538 -B 203.0.113.1 -q &
0539 mz_pid=$!
0540
0541 devlink_trap_exception_test $trap_name
0542
0543 log_test "LPM miss: IPv4"
0544
0545 kill $mz_pid && wait $mz_pid &> /dev/null
0546 vrf_without_routes_destroy
0547 }
0548
0549 ipv6_lpm_miss_test()
0550 {
0551 local trap_name="ipv6_lpm_miss"
0552 local expected_action="trap"
0553 local mz_pid
0554
0555 RET=0
0556
0557 ping_check $trap_name
0558 trap_action_check $trap_name $expected_action
0559
0560
0561 vrf_without_routes_create
0562
0563
0564 $MZ -6 $h1 -t udp "sp=54321,dp=12345" -c 0 -d 1msec -b $rp1mac \
0565 -B 2001:db8::1 -q &
0566 mz_pid=$!
0567
0568 devlink_trap_exception_test $trap_name
0569
0570 log_test "LPM miss: IPv6"
0571
0572 kill $mz_pid && wait $mz_pid &> /dev/null
0573 vrf_without_routes_destroy
0574 }
0575
0576 trap cleanup EXIT
0577
0578 setup_prepare
0579 setup_wait
0580
0581 tests_run
0582
0583 exit $EXIT_STATUS