cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

devlink_trap_l3_drops.sh (16812B)


      1#!/bin/bash
      2# SPDX-License-Identifier: GPL-2.0
      3#
      4# Test devlink-trap L3 drops functionality over mlxsw. Each registered L3 drop
      5# packet trap is tested to make sure it is triggered under the right
      6# conditions.
      7
      8# +---------------------------------+
      9# | H1 (vrf)                        |
     10# |    + $h1                        |
     11# |    | 192.0.2.1/24               |
     12# |    | 2001:db8:1::1/64           |
     13# |    |                            |
     14# |    |  default via 192.0.2.2     |
     15# |    |  default via 2001:db8:1::2 |
     16# +----|----------------------------+
     17#      |
     18# +----|----------------------------------------------------------------------+
     19# | SW |                                                                      |
     20# |    + $rp1                                                                 |
     21# |        192.0.2.2/24                                                       |
     22# |        2001:db8:1::2/64                                                   |
     23# |                                                                           |
     24# |        2001:db8:2::2/64                                                   |
     25# |        198.51.100.2/24                                                    |
     26# |    + $rp2                                                                 |
     27# |    |                                                                      |
     28# +----|----------------------------------------------------------------------+
     29#      |
     30# +----|----------------------------+
     31# |    |  default via 198.51.100.2  |
     32# |    |  default via 2001:db8:2::2 |
     33# |    |                            |
     34# |    | 2001:db8:2::1/64           |
     35# |    | 198.51.100.1/24            |
     36# |    + $h2                        |
     37# | H2 (vrf)                        |
     38# +---------------------------------+
     39
     40lib_dir=$(dirname $0)/../../../net/forwarding
     41
     42ALL_TESTS="
     43	non_ip_test
     44	uc_dip_over_mc_dmac_test
     45	dip_is_loopback_test
     46	sip_is_mc_test
     47	sip_is_loopback_test
     48	ip_header_corrupted_test
     49	ipv4_sip_is_limited_bc_test
     50	ipv6_mc_dip_reserved_scope_test
     51	ipv6_mc_dip_interface_local_scope_test
     52	blackhole_route_test
     53	irif_disabled_test
     54	erif_disabled_test
     55	blackhole_nexthop_test
     56"
     57
     58NUM_NETIFS=4
     59source $lib_dir/lib.sh
     60source $lib_dir/tc_common.sh
     61source $lib_dir/devlink_lib.sh
     62
     63h1_create()
     64{
     65	simple_if_init $h1 192.0.2.1/24 2001:db8:1::1/64
     66
     67	ip -4 route add default vrf v$h1 nexthop via 192.0.2.2
     68	ip -6 route add default vrf v$h1 nexthop via 2001:db8:1::2
     69}
     70
     71h1_destroy()
     72{
     73	ip -6 route del default vrf v$h1 nexthop via 2001:db8:1::2
     74	ip -4 route del default vrf v$h1 nexthop via 192.0.2.2
     75
     76	simple_if_fini $h1 192.0.2.1/24 2001:db8:1::1/64
     77}
     78
     79h2_create()
     80{
     81	simple_if_init $h2 $h2_ipv4/24 $h2_ipv6/64
     82
     83	ip -4 route add default vrf v$h2 nexthop via 198.51.100.2
     84	ip -6 route add default vrf v$h2 nexthop via 2001:db8:2::2
     85}
     86
     87h2_destroy()
     88{
     89	ip -6 route del default vrf v$h2 nexthop via 2001:db8:2::2
     90	ip -4 route del default vrf v$h2 nexthop via 198.51.100.2
     91
     92	simple_if_fini $h2 $h2_ipv4/24 $h2_ipv6/64
     93}
     94
     95router_create()
     96{
     97	ip link set dev $rp1 up
     98	ip link set dev $rp2 up
     99
    100	tc qdisc add dev $rp2 clsact
    101
    102	__addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
    103	__addr_add_del $rp2 add 198.51.100.2/24 2001:db8:2::2/64
    104}
    105
    106router_destroy()
    107{
    108	__addr_add_del $rp2 del 198.51.100.2/24 2001:db8:2::2/64
    109	__addr_add_del $rp1 del 192.0.2.2/24 2001:db8:1::2/64
    110
    111	tc qdisc del dev $rp2 clsact
    112
    113	ip link set dev $rp2 down
    114	ip link set dev $rp1 down
    115}
    116
    117setup_prepare()
    118{
    119	h1=${NETIFS[p1]}
    120	rp1=${NETIFS[p2]}
    121
    122	rp2=${NETIFS[p3]}
    123	h2=${NETIFS[p4]}
    124
    125	h1mac=$(mac_get $h1)
    126	rp1mac=$(mac_get $rp1)
    127
    128	h1_ipv4=192.0.2.1
    129	h2_ipv4=198.51.100.1
    130	h1_ipv6=2001:db8:1::1
    131	h2_ipv6=2001:db8:2::1
    132
    133	vrf_prepare
    134	forwarding_enable
    135
    136	h1_create
    137	h2_create
    138
    139	router_create
    140}
    141
    142cleanup()
    143{
    144	pre_cleanup
    145
    146	router_destroy
    147
    148	h2_destroy
    149	h1_destroy
    150
    151	forwarding_restore
    152	vrf_cleanup
    153}
    154
    155ping_check()
    156{
    157	trap_name=$1; shift
    158
    159	devlink_trap_action_set $trap_name "trap"
    160	ping_do $h1 $h2_ipv4
    161	check_err $? "Packets that should not be trapped were trapped"
    162	devlink_trap_action_set $trap_name "drop"
    163}
    164
    165non_ip_test()
    166{
    167	local trap_name="non_ip"
    168	local mz_pid
    169
    170	RET=0
    171
    172	ping_check $trap_name
    173
    174	tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
    175		flower dst_ip $h2_ipv4 action drop
    176
    177	# Generate non-IP packets to the router
    178	$MZ $h1 -c 0 -p 100 -d 1msec -B $h2_ipv4 -q "$rp1mac $h1mac \
    179		00:00 de:ad:be:ef" &
    180	mz_pid=$!
    181
    182	devlink_trap_drop_test $trap_name $rp2 101
    183
    184	log_test "Non IP"
    185
    186	devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
    187}
    188
    189__uc_dip_over_mc_dmac_test()
    190{
    191	local desc=$1; shift
    192	local proto=$1; shift
    193	local dip=$1; shift
    194	local flags=${1:-""}; shift
    195	local trap_name="uc_dip_over_mc_dmac"
    196	local dmac=01:02:03:04:05:06
    197	local mz_pid
    198
    199	RET=0
    200
    201	ping_check $trap_name
    202
    203	tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
    204		flower ip_proto udp src_port 54321 dst_port 12345 action drop
    205
    206	# Generate IP packets with a unicast IP and a multicast destination MAC
    207	$MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $dmac \
    208		-B $dip -d 1msec -q &
    209	mz_pid=$!
    210
    211	devlink_trap_drop_test $trap_name $rp2 101
    212
    213	log_test "Unicast destination IP over multicast destination MAC: $desc"
    214
    215	devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
    216}
    217
    218uc_dip_over_mc_dmac_test()
    219{
    220	__uc_dip_over_mc_dmac_test "IPv4" "ip" $h2_ipv4
    221	__uc_dip_over_mc_dmac_test "IPv6" "ipv6" $h2_ipv6 "-6"
    222}
    223
    224__sip_is_loopback_test()
    225{
    226	local desc=$1; shift
    227	local proto=$1; shift
    228	local sip=$1; shift
    229	local dip=$1; shift
    230	local flags=${1:-""}; shift
    231	local trap_name="sip_is_loopback_address"
    232	local mz_pid
    233
    234	RET=0
    235
    236	ping_check $trap_name
    237
    238	tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
    239		flower src_ip $sip action drop
    240
    241	# Generate packets with loopback source IP
    242	$MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \
    243		-b $rp1mac -B $dip -d 1msec -q &
    244	mz_pid=$!
    245
    246	devlink_trap_drop_test $trap_name $rp2 101
    247
    248	log_test "Source IP is loopback address: $desc"
    249
    250	devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
    251}
    252
    253sip_is_loopback_test()
    254{
    255	__sip_is_loopback_test "IPv4" "ip" "127.0.0.0/8" $h2_ipv4
    256	__sip_is_loopback_test "IPv6" "ipv6" "::1" $h2_ipv6 "-6"
    257}
    258
    259__dip_is_loopback_test()
    260{
    261	local desc=$1; shift
    262	local proto=$1; shift
    263	local dip=$1; shift
    264	local flags=${1:-""}; shift
    265	local trap_name="dip_is_loopback_address"
    266	local mz_pid
    267
    268	RET=0
    269
    270	ping_check $trap_name
    271
    272	tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
    273		flower dst_ip $dip action drop
    274
    275	# Generate packets with loopback destination IP
    276	$MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \
    277		-B $dip -d 1msec -q &
    278	mz_pid=$!
    279
    280	devlink_trap_drop_test $trap_name $rp2 101
    281
    282	log_test "Destination IP is loopback address: $desc"
    283
    284	devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
    285}
    286
    287dip_is_loopback_test()
    288{
    289	__dip_is_loopback_test "IPv4" "ip" "127.0.0.0/8"
    290	__dip_is_loopback_test "IPv6" "ipv6" "::1" "-6"
    291}
    292
    293__sip_is_mc_test()
    294{
    295	local desc=$1; shift
    296	local proto=$1; shift
    297	local sip=$1; shift
    298	local dip=$1; shift
    299	local flags=${1:-""}; shift
    300	local trap_name="sip_is_mc"
    301	local mz_pid
    302
    303	RET=0
    304
    305	ping_check $trap_name
    306
    307	tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
    308		flower src_ip $sip action drop
    309
    310	# Generate packets with multicast source IP
    311	$MZ $h1 $flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip \
    312		-b $rp1mac -B $dip -d 1msec -q &
    313	mz_pid=$!
    314
    315	devlink_trap_drop_test $trap_name $rp2 101
    316
    317	log_test "Source IP is multicast: $desc"
    318
    319	devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
    320}
    321
    322sip_is_mc_test()
    323{
    324	__sip_is_mc_test "IPv4" "ip" "239.1.1.1" $h2_ipv4
    325	__sip_is_mc_test "IPv6" "ipv6" "FF02::2" $h2_ipv6 "-6"
    326}
    327
    328ipv4_sip_is_limited_bc_test()
    329{
    330	local trap_name="ipv4_sip_is_limited_bc"
    331	local sip=255.255.255.255
    332	local mz_pid
    333
    334	RET=0
    335
    336	ping_check $trap_name
    337
    338	tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
    339		flower src_ip $sip action drop
    340
    341	# Generate packets with limited broadcast source IP
    342	$MZ $h1 -t udp "sp=54321,dp=12345" -c 0 -p 100 -A $sip -b $rp1mac \
    343		-B $h2_ipv4 -d 1msec -q &
    344	mz_pid=$!
    345
    346	devlink_trap_drop_test $trap_name $rp2 101
    347
    348	log_test "IPv4 source IP is limited broadcast"
    349
    350	devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
    351}
    352
    353ipv4_payload_get()
    354{
    355	local ipver=$1; shift
    356	local ihl=$1; shift
    357	local checksum=$1; shift
    358
    359	p=$(:
    360		)"08:00:"$(                   : ETH type
    361		)"$ipver"$(                   : IP version
    362		)"$ihl:"$(                    : IHL
    363		)"00:"$(		      : IP TOS
    364		)"00:F4:"$(                   : IP total length
    365		)"00:00:"$(                   : IP identification
    366		)"20:00:"$(                   : IP flags + frag off
    367		)"30:"$(                      : IP TTL
    368		)"01:"$(                      : IP proto
    369		)"$checksum:"$(               : IP header csum
    370		)"$h1_ipv4:"$(                : IP saddr
    371	        )"$h2_ipv4:"$(                : IP daddr
    372		)
    373	echo $p
    374}
    375
    376__ipv4_header_corrupted_test()
    377{
    378	local desc=$1; shift
    379	local ipver=$1; shift
    380	local ihl=$1; shift
    381	local checksum=$1; shift
    382	local trap_name="ip_header_corrupted"
    383	local payload
    384	local mz_pid
    385
    386	RET=0
    387
    388	ping_check $trap_name
    389
    390	tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
    391		flower dst_ip $h2_ipv4 action drop
    392
    393	payload=$(ipv4_payload_get $ipver $ihl $checksum)
    394
    395	# Generate packets with corrupted IP header
    396	$MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &
    397	mz_pid=$!
    398
    399	devlink_trap_drop_test $trap_name $rp2 101
    400
    401	log_test "IP header corrupted: $desc: IPv4"
    402
    403	devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
    404}
    405
    406ipv6_payload_get()
    407{
    408	local ipver=$1; shift
    409
    410	p=$(:
    411		)"86:DD:"$(                  : ETH type
    412		)"$ipver"$(                  : IP version
    413		)"0:0:"$(                    : Traffic class
    414		)"0:00:00:"$(		     : Flow label
    415		)"00:00:"$(                  : Payload length
    416		)"01:"$(                     : Next header
    417		)"04:"$(                     : Hop limit
    418		)"$h1_ipv6:"$(      	     : IP saddr
    419		)"$h2_ipv6:"$(               : IP daddr
    420		)
    421	echo $p
    422}
    423
    424__ipv6_header_corrupted_test()
    425{
    426	local desc=$1; shift
    427	local ipver=$1; shift
    428	local trap_name="ip_header_corrupted"
    429	local payload
    430	local mz_pid
    431
    432	RET=0
    433
    434	ping_check $trap_name
    435
    436	tc filter add dev $rp2 egress protocol ip pref 1 handle 101 \
    437		flower dst_ip $h2_ipv4 action drop
    438
    439	payload=$(ipv6_payload_get $ipver)
    440
    441	# Generate packets with corrupted IP header
    442	$MZ $h1 -c 0 -d 1msec -a $h1mac -b $rp1mac -q p=$payload &
    443	mz_pid=$!
    444
    445	devlink_trap_drop_test $trap_name $rp2 101
    446
    447	log_test "IP header corrupted: $desc: IPv6"
    448
    449	devlink_trap_drop_cleanup $mz_pid $rp2 "ip" 1 101
    450}
    451
    452ip_header_corrupted_test()
    453{
    454	# Each test uses one wrong value. The three values below are correct.
    455	local ipv="4"
    456	local ihl="5"
    457	local checksum="00:F4"
    458
    459	__ipv4_header_corrupted_test "wrong IP version" 5 $ihl $checksum
    460	__ipv4_header_corrupted_test "wrong IHL" $ipv 4 $checksum
    461	__ipv4_header_corrupted_test "wrong checksum" $ipv $ihl "00:00"
    462	__ipv6_header_corrupted_test "wrong IP version" 5
    463}
    464
    465ipv6_mc_dip_reserved_scope_test()
    466{
    467	local trap_name="ipv6_mc_dip_reserved_scope"
    468	local dip=FF00::
    469	local mz_pid
    470
    471	RET=0
    472
    473	ping_check $trap_name
    474
    475	tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \
    476		flower dst_ip $dip action drop
    477
    478	# Generate packets with reserved scope destination IP
    479	$MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \
    480		"33:33:00:00:00:00" -B $dip -d 1msec -q &
    481	mz_pid=$!
    482
    483	devlink_trap_drop_test $trap_name $rp2 101
    484
    485	log_test "IPv6 multicast destination IP reserved scope"
    486
    487	devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101
    488}
    489
    490ipv6_mc_dip_interface_local_scope_test()
    491{
    492	local trap_name="ipv6_mc_dip_interface_local_scope"
    493	local dip=FF01::
    494	local mz_pid
    495
    496	RET=0
    497
    498	ping_check $trap_name
    499
    500	tc filter add dev $rp2 egress protocol ipv6 pref 1 handle 101 \
    501		flower dst_ip $dip action drop
    502
    503	# Generate packets with interface local scope destination IP
    504	$MZ $h1 -6 -t udp "sp=54321,dp=12345" -c 0 -p 100 -b \
    505		"33:33:00:00:00:00" -B $dip -d 1msec -q &
    506	mz_pid=$!
    507
    508	devlink_trap_drop_test $trap_name $rp2 101
    509
    510	log_test "IPv6 multicast destination IP interface-local scope"
    511
    512	devlink_trap_drop_cleanup $mz_pid $rp2 "ipv6" 1 101
    513}
    514
    515__blackhole_route_test()
    516{
    517	local flags=$1; shift
    518	local subnet=$1; shift
    519	local proto=$1; shift
    520	local dip=$1; shift
    521	local ip_proto=${1:-"icmp"}; shift
    522	local trap_name="blackhole_route"
    523	local mz_pid
    524
    525	RET=0
    526
    527	ping_check $trap_name
    528
    529	ip -$flags route add blackhole $subnet
    530	tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
    531		flower skip_hw dst_ip $dip ip_proto $ip_proto action drop
    532
    533	# Generate packets to the blackhole route
    534	$MZ $h1 -$flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \
    535		-B $dip -d 1msec -q &
    536	mz_pid=$!
    537
    538	devlink_trap_drop_test $trap_name $rp2 101
    539	log_test "Blackhole route: IPv$flags"
    540
    541	devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
    542	ip -$flags route del blackhole $subnet
    543}
    544
    545blackhole_route_test()
    546{
    547	__blackhole_route_test "4" "198.51.100.0/30" "ip" $h2_ipv4
    548	__blackhole_route_test "6" "2001:db8:2::/120" "ipv6" $h2_ipv6 "icmpv6"
    549}
    550
    551irif_disabled_test()
    552{
    553	local trap_name="irif_disabled"
    554	local t0_packets t0_bytes
    555	local t1_packets t1_bytes
    556	local mz_pid
    557
    558	RET=0
    559
    560	ping_check $trap_name
    561
    562	devlink_trap_action_set $trap_name "trap"
    563
    564	# When RIF of a physical port ("Sub-port RIF") is destroyed, we first
    565	# block the STP of the {Port, VLAN} so packets cannot get into the RIF.
    566	# Using bridge enables us to see this trap because when bridge is
    567	# destroyed, there is a small time window that packets can go into the
    568	# RIF, while it is disabled.
    569	ip link add dev br0 type bridge
    570	ip link set dev $rp1 master br0
    571	ip address flush dev $rp1
    572	__addr_add_del br0 add 192.0.2.2/24
    573	ip li set dev br0 up
    574
    575	t0_packets=$(devlink_trap_rx_packets_get $trap_name)
    576	t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
    577
    578	# Generate packets to h2 through br0 RIF that will be removed later
    579	$MZ $h1 -t udp "sp=54321,dp=12345" -c 0 -p 100 -a own -b $rp1mac \
    580		-B $h2_ipv4 -q &
    581	mz_pid=$!
    582
    583	# Wait before removing br0 RIF to allow packets to go into the bridge.
    584	sleep 1
    585
    586	# Flushing address will dismantle the RIF
    587	ip address flush dev br0
    588
    589	t1_packets=$(devlink_trap_rx_packets_get $trap_name)
    590	t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
    591
    592	if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
    593		check_err 1 "Trap stats idle when packets should be trapped"
    594	fi
    595
    596	log_test "Ingress RIF disabled"
    597
    598	kill $mz_pid && wait $mz_pid &> /dev/null
    599	ip link set dev $rp1 nomaster
    600	__addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
    601	ip link del dev br0 type bridge
    602	devlink_trap_action_set $trap_name "drop"
    603}
    604
    605erif_disabled_test()
    606{
    607	local trap_name="erif_disabled"
    608	local t0_packets t0_bytes
    609	local t1_packets t1_bytes
    610	local mz_pid
    611
    612	RET=0
    613
    614	ping_check $trap_name
    615
    616	devlink_trap_action_set $trap_name "trap"
    617	ip link add dev br0 type bridge
    618	ip add flush dev $rp1
    619	ip link set dev $rp1 master br0
    620	__addr_add_del br0 add 192.0.2.2/24
    621	ip link set dev br0 up
    622
    623	t0_packets=$(devlink_trap_rx_packets_get $trap_name)
    624	t0_bytes=$(devlink_trap_rx_bytes_get $trap_name)
    625
    626	rp2mac=$(mac_get $rp2)
    627
    628	# Generate packets that should go out through br0 RIF that will be
    629	# removed later
    630	$MZ $h2 -t udp "sp=54321,dp=12345" -c 0 -p 100 -a own -b $rp2mac \
    631		-B 192.0.2.1 -q &
    632	mz_pid=$!
    633
    634	sleep 5
    635	# Unlinking the port from the bridge will disable the RIF associated
    636	# with br0 as it is no longer an upper of any mlxsw port.
    637	ip link set dev $rp1 nomaster
    638
    639	t1_packets=$(devlink_trap_rx_packets_get $trap_name)
    640	t1_bytes=$(devlink_trap_rx_bytes_get $trap_name)
    641
    642	if [[ $t0_packets -eq $t1_packets && $t0_bytes -eq $t1_bytes ]]; then
    643		check_err 1 "Trap stats idle when packets should be trapped"
    644	fi
    645
    646	log_test "Egress RIF disabled"
    647
    648	kill $mz_pid && wait $mz_pid &> /dev/null
    649	__addr_add_del $rp1 add 192.0.2.2/24 2001:db8:1::2/64
    650	ip link del dev br0 type bridge
    651	devlink_trap_action_set $trap_name "drop"
    652}
    653
    654__blackhole_nexthop_test()
    655{
    656	local flags=$1; shift
    657	local subnet=$1; shift
    658	local proto=$1; shift
    659	local dip=$1; shift
    660	local trap_name="blackhole_nexthop"
    661	local mz_pid
    662
    663	RET=0
    664
    665	ip -$flags nexthop add id 1 blackhole
    666	ip -$flags route add $subnet nhid 1
    667	tc filter add dev $rp2 egress protocol $proto pref 1 handle 101 \
    668		flower skip_hw dst_ip $dip ip_proto udp action drop
    669
    670	# Generate packets to the blackhole nexthop
    671	$MZ $h1 -$flags -t udp "sp=54321,dp=12345" -c 0 -p 100 -b $rp1mac \
    672		-B $dip -d 1msec -q &
    673	mz_pid=$!
    674
    675	devlink_trap_drop_test $trap_name $rp2 101
    676	log_test "Blackhole nexthop: IPv$flags"
    677
    678	devlink_trap_drop_cleanup $mz_pid $rp2 $proto 1 101
    679	ip -$flags route del $subnet
    680	ip -$flags nexthop del id 1
    681}
    682
    683blackhole_nexthop_test()
    684{
    685	__blackhole_nexthop_test "4" "198.51.100.0/30" "ip" $h2_ipv4
    686	__blackhole_nexthop_test "6" "2001:db8:2::/120" "ipv6" $h2_ipv6
    687}
    688
    689trap cleanup EXIT
    690
    691setup_prepare
    692setup_wait
    693
    694tests_run
    695
    696exit $EXIT_STATUS