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

fib_offload_lib.sh (25157B)


      1# SPDX-License-Identifier: GPL-2.0
      2#
      3# Various helpers and tests to verify FIB offload.
      4
      5__fib_trap_check()
      6{
      7	local ns=$1; shift
      8	local family=$1; shift
      9	local route=$1; shift
     10	local should_fail=$1; shift
     11	local ret
     12
     13	ip -n $ns -j -p -$family route show $route \
     14		| jq -e '.[]["flags"] | contains(["trap"])' &> /dev/null
     15	ret=$?
     16	if [[ $should_fail == "true" ]]; then
     17		if [[ $ret -ne 0 ]]; then
     18			return 0
     19		else
     20			return 1
     21		fi
     22	fi
     23
     24	return $ret
     25}
     26
     27fib_trap_check()
     28{
     29	local ns=$1; shift
     30	local family=$1; shift
     31	local route=$1; shift
     32	local should_fail=$1; shift
     33
     34	busywait 5000 __fib_trap_check $ns $family "$route" $should_fail
     35}
     36
     37fib4_trap_check()
     38{
     39	local ns=$1; shift
     40	local route=$1; shift
     41	local should_fail=$1; shift
     42
     43	fib_trap_check $ns 4 "$route" $should_fail
     44}
     45
     46fib6_trap_check()
     47{
     48	local ns=$1; shift
     49	local route=$1; shift
     50	local should_fail=$1; shift
     51
     52	fib_trap_check $ns 6 "$route" $should_fail
     53}
     54
     55fib_ipv4_identical_routes_test()
     56{
     57	local ns=$1; shift
     58	local i
     59
     60	RET=0
     61
     62	for i in $(seq 1 3); do
     63		ip -n $ns link add name dummy$i type dummy
     64		ip -n $ns link set dev dummy$i up
     65	done
     66
     67	ip -n $ns route add 192.0.2.0/24 dev dummy1 tos 0 metric 1024
     68	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 tos 0 metric 1024" false
     69	check_err $? "Route not in hardware when should"
     70
     71	ip -n $ns route append 192.0.2.0/24 dev dummy2 tos 0 metric 1024
     72	fib4_trap_check $ns "192.0.2.0/24 dev dummy2 tos 0 metric 1024" true
     73	check_err $? "Appended route in hardware when should not"
     74
     75	ip -n $ns route prepend 192.0.2.0/24 dev dummy3 tos 0 metric 1024
     76	fib4_trap_check $ns "192.0.2.0/24 dev dummy3 tos 0 metric 1024" false
     77	check_err $? "Prepended route not in hardware when should"
     78
     79	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 tos 0 metric 1024" true
     80	check_err $? "Route was not replaced in hardware by prepended one"
     81
     82	log_test "IPv4 identical routes"
     83
     84	for i in $(seq 1 3); do
     85		ip -n $ns link del dev dummy$i
     86	done
     87}
     88
     89fib_ipv4_tos_test()
     90{
     91	local ns=$1; shift
     92
     93	RET=0
     94
     95	ip -n $ns link add name dummy1 type dummy
     96	ip -n $ns link set dev dummy1 up
     97
     98	ip -n $ns route add 192.0.2.0/24 dev dummy1 tos 0 metric 1024
     99	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 tos 0 metric 1024" false
    100	check_err $? "Route not in hardware when should"
    101
    102	ip -n $ns route add 192.0.2.0/24 dev dummy1 tos 8 metric 1024
    103	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 tos 8 metric 1024" false
    104	check_err $? "Highest TOS route not in hardware when should"
    105
    106	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 tos 0 metric 1024" true
    107	check_err $? "Lowest TOS route still in hardware when should not"
    108
    109	ip -n $ns route add 192.0.2.0/24 dev dummy1 tos 4 metric 1024
    110	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 tos 4 metric 1024" true
    111	check_err $? "Middle TOS route in hardware when should not"
    112
    113	log_test "IPv4 routes with TOS"
    114
    115	ip -n $ns link del dev dummy1
    116}
    117
    118fib_ipv4_metric_test()
    119{
    120	local ns=$1; shift
    121
    122	RET=0
    123
    124	ip -n $ns link add name dummy1 type dummy
    125	ip -n $ns link set dev dummy1 up
    126
    127	ip -n $ns route add 192.0.2.0/24 dev dummy1 metric 1024
    128	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1024" false
    129	check_err $? "Route not in hardware when should"
    130
    131	ip -n $ns route add 192.0.2.0/24 dev dummy1 metric 1022
    132	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1022" false
    133	check_err $? "Lowest metric route not in hardware when should"
    134
    135	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1024" true
    136	check_err $? "Highest metric route still in hardware when should not"
    137
    138	ip -n $ns route add 192.0.2.0/24 dev dummy1 metric 1023
    139	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1023" true
    140	check_err $? "Middle metric route in hardware when should not"
    141
    142	log_test "IPv4 routes with metric"
    143
    144	ip -n $ns link del dev dummy1
    145}
    146
    147fib_ipv4_replace_test()
    148{
    149	local ns=$1; shift
    150	local i
    151
    152	RET=0
    153
    154	for i in $(seq 1 2); do
    155		ip -n $ns link add name dummy$i type dummy
    156		ip -n $ns link set dev dummy$i up
    157	done
    158
    159	ip -n $ns route add 192.0.2.0/24 dev dummy1 metric 1024
    160	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1024" false
    161	check_err $? "Route not in hardware when should"
    162
    163	ip -n $ns route replace 192.0.2.0/24 dev dummy2 metric 1024
    164	fib4_trap_check $ns "192.0.2.0/24 dev dummy2 metric 1024" false
    165	check_err $? "Replacement route not in hardware when should"
    166
    167	# Add a route with an higher metric and make sure that replacing it
    168	# does not affect the lower metric one.
    169	ip -n $ns route add 192.0.2.0/24 dev dummy1 metric 1025
    170	ip -n $ns route replace 192.0.2.0/24 dev dummy2 metric 1025
    171
    172	fib4_trap_check $ns "192.0.2.0/24 dev dummy2 metric 1024" false
    173	check_err $? "Lowest metric route not in hardware when should"
    174	fib4_trap_check $ns "192.0.2.0/24 dev dummy2 metric 1025" true
    175	check_err $? "Highest metric route in hardware when should not"
    176
    177	log_test "IPv4 route replace"
    178
    179	for i in $(seq 1 2); do
    180		ip -n $ns link del dev dummy$i
    181	done
    182}
    183
    184fib_ipv4_delete_test()
    185{
    186	local ns=$1; shift
    187	local metric
    188
    189	RET=0
    190
    191	ip -n $ns link add name dummy1 type dummy
    192	ip -n $ns link set dev dummy1 up
    193
    194	# Insert multiple routes with the same prefix and length and varying
    195	# metrics. Make sure that throughout delete operations the lowest
    196	# metric route is the one in hardware.
    197	for metric in $(seq 1024 1026); do
    198		ip -n $ns route add 192.0.2.0/24 dev dummy1 metric $metric
    199	done
    200
    201	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1024" false
    202	check_err $? "Route not in hardware when should"
    203
    204	ip -n $ns route del 192.0.2.0/24 dev dummy1 metric 1024
    205	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1025" false
    206	check_err $? "Lowest metric route not in hardware when should"
    207
    208	ip -n $ns route del 192.0.2.0/24 dev dummy1 metric 1026
    209	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1025" false
    210	check_err $? "Sole route not in hardware when should"
    211
    212	log_test "IPv4 route delete"
    213
    214	ip -n $ns link del dev dummy1
    215}
    216
    217fib_ipv4_plen_test()
    218{
    219	local ns=$1; shift
    220
    221	RET=0
    222
    223	ip -n $ns link add name dummy1 type dummy
    224	ip -n $ns link set dev dummy1 up
    225
    226	# Add two routes with the same key and different prefix length and
    227	# make sure both are in hardware. It can be verified that both are
    228	# sharing the same leaf by checking the /proc/net/fib_trie
    229	ip -n $ns route add 192.0.2.0/24 dev dummy1
    230	ip -n $ns route add 192.0.2.0/25 dev dummy1
    231
    232	fib4_trap_check $ns "192.0.2.0/24 dev dummy1" false
    233	check_err $? "/24 not in hardware when should"
    234
    235	fib4_trap_check $ns "192.0.2.0/25 dev dummy1" false
    236	check_err $? "/25 not in hardware when should"
    237
    238	log_test "IPv4 routes with different prefix length"
    239
    240	ip -n $ns link del dev dummy1
    241}
    242
    243fib_ipv4_replay_metric_test()
    244{
    245	local ns=$1; shift
    246	local devlink_dev=$1; shift
    247
    248	RET=0
    249
    250	ip -n $ns link add name dummy1 type dummy
    251	ip -n $ns link set dev dummy1 up
    252
    253	ip -n $ns route add 192.0.2.0/24 dev dummy1 metric 1024
    254	ip -n $ns route add 192.0.2.0/24 dev dummy1 metric 1025
    255
    256	devlink -N $ns dev reload $devlink_dev
    257
    258	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1024" false
    259	check_err $? "Lowest metric route not in hardware when should"
    260
    261	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 metric 1025" true
    262	check_err $? "Highest metric route in hardware when should not"
    263
    264	log_test "IPv4 routes replay - metric"
    265
    266	ip -n $ns link del dev dummy1
    267}
    268
    269fib_ipv4_replay_tos_test()
    270{
    271	local ns=$1; shift
    272	local devlink_dev=$1; shift
    273
    274	RET=0
    275
    276	ip -n $ns link add name dummy1 type dummy
    277	ip -n $ns link set dev dummy1 up
    278
    279	ip -n $ns route add 192.0.2.0/24 dev dummy1 tos 0
    280	ip -n $ns route add 192.0.2.0/24 dev dummy1 tos 4
    281
    282	devlink -N $ns dev reload $devlink_dev
    283
    284	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 tos 4" false
    285	check_err $? "Highest TOS route not in hardware when should"
    286
    287	fib4_trap_check $ns "192.0.2.0/24 dev dummy1 tos 0" true
    288	check_err $? "Lowest TOS route in hardware when should not"
    289
    290	log_test "IPv4 routes replay - TOS"
    291
    292	ip -n $ns link del dev dummy1
    293}
    294
    295fib_ipv4_replay_plen_test()
    296{
    297	local ns=$1; shift
    298	local devlink_dev=$1; shift
    299
    300	RET=0
    301
    302	ip -n $ns link add name dummy1 type dummy
    303	ip -n $ns link set dev dummy1 up
    304
    305	ip -n $ns route add 192.0.2.0/24 dev dummy1
    306	ip -n $ns route add 192.0.2.0/25 dev dummy1
    307
    308	devlink -N $ns dev reload $devlink_dev
    309
    310	fib4_trap_check $ns "192.0.2.0/24 dev dummy1" false
    311	check_err $? "/24 not in hardware when should"
    312
    313	fib4_trap_check $ns "192.0.2.0/25 dev dummy1" false
    314	check_err $? "/25 not in hardware when should"
    315
    316	log_test "IPv4 routes replay - prefix length"
    317
    318	ip -n $ns link del dev dummy1
    319}
    320
    321fib_ipv4_flush_test()
    322{
    323	local ns=$1; shift
    324	local metric
    325
    326	RET=0
    327
    328	ip -n $ns link add name dummy1 type dummy
    329	ip -n $ns link set dev dummy1 up
    330
    331	# Exercise the routes flushing code paths by inserting various
    332	# prefix routes on a netdev and then deleting it.
    333	for metric in $(seq 1 20); do
    334		ip -n $ns route add 192.0.2.0/24 dev dummy1 metric $metric
    335	done
    336
    337	ip -n $ns link del dev dummy1
    338
    339	log_test "IPv4 routes flushing"
    340}
    341
    342fib_ipv6_add_test()
    343{
    344	local ns=$1; shift
    345
    346	RET=0
    347
    348	for i in $(seq 1 2); do
    349		ip -n $ns link add name dummy$i type dummy
    350		ip -n $ns link set dev dummy$i up
    351	done
    352
    353	ip -n $ns route add 2001:db8:1::/64 dev dummy1 metric 1024
    354	fib6_trap_check $ns "2001:db8:1::/64 dev dummy1 metric 1024" false
    355	check_err $? "Route not in hardware when should"
    356
    357	ip -n $ns route append 2001:db8:1::/64 dev dummy2 metric 1024
    358	fib6_trap_check $ns "2001:db8:1::/64 dev dummy2 metric 1024" true
    359	check_err $? "Route in hardware when should not"
    360
    361	fib6_trap_check $ns "2001:db8:1::/64 dev dummy1 metric 1024" false
    362	check_err $? "Route not in hardware after appending route"
    363
    364	log_test "IPv6 single route add"
    365
    366	for i in $(seq 1 2); do
    367		ip -n $ns link del dev dummy$i
    368	done
    369}
    370
    371fib_ipv6_metric_test()
    372{
    373	local ns=$1; shift
    374
    375	RET=0
    376
    377	ip -n $ns link add name dummy1 type dummy
    378	ip -n $ns link set dev dummy1 up
    379
    380	ip -n $ns route add 2001:db8:1::/64 dev dummy1 metric 1024
    381	fib6_trap_check $ns "2001:db8:1::/64 dev dummy1 metric 1024" false
    382	check_err $? "Route not in hardware when should"
    383
    384	ip -n $ns route add 2001:db8:1::/64 dev dummy1 metric 1022
    385	fib6_trap_check $ns "2001:db8:1::/64 dev dummy1 metric 1022" false
    386	check_err $? "Lowest metric route not in hardware when should"
    387
    388	fib6_trap_check $ns "2001:db8:1::/64 dev dummy1 metric 1024" true
    389	check_err $? "Highest metric route still in hardware when should not"
    390
    391	ip -n $ns route add 2001:db8:1::/64 dev dummy1 metric 1023
    392	fib6_trap_check $ns "2001:db8:1::/64 dev dummy1 metric 1023" true
    393	check_err $? "Middle metric route in hardware when should not"
    394
    395	log_test "IPv6 routes with metric"
    396
    397	ip -n $ns link del dev dummy1
    398}
    399
    400fib_ipv6_append_single_test()
    401{
    402	local ns=$1; shift
    403
    404	# When an IPv6 multipath route is added without the 'nexthop' keyword,
    405	# different code paths are taken compared to when the keyword is used.
    406	# This test tries to verify the former.
    407	RET=0
    408
    409	for i in $(seq 1 2); do
    410		ip -n $ns link add name dummy$i type dummy
    411		ip -n $ns link set dev dummy$i up
    412		ip -n $ns address add 2001:db8:$i::1/64 dev dummy$i
    413	done
    414
    415	ip -n $ns route add 2001:db8:10::/64 via 2001:db8:1::2 metric 1024
    416	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    417	check_err $? "Route not in hardware when should"
    418
    419	ip -n $ns route append 2001:db8:10::/64 via 2001:db8:2::2 metric 1024
    420	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    421	check_err $? "Route not in hardware after appending"
    422
    423	ip -n $ns route add 2001:db8:10::/64 via 2001:db8:1::2 metric 1025
    424	fib6_trap_check $ns "2001:db8:10::/64 metric 1025" true
    425	check_err $? "Route in hardware when should not"
    426
    427	ip -n $ns route append 2001:db8:10::/64 via 2001:db8:2::2 metric 1025
    428	fib6_trap_check $ns "2001:db8:10::/64 metric 1025" true
    429	check_err $? "Route in hardware when should not after appending"
    430
    431	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    432	check_err $? "Lowest metric route not in hardware when should"
    433
    434	log_test "IPv6 append single route without 'nexthop' keyword"
    435
    436	for i in $(seq 1 2); do
    437		ip -n $ns link del dev dummy$i
    438	done
    439}
    440
    441fib_ipv6_replace_single_test()
    442{
    443	local ns=$1; shift
    444	local i
    445
    446	RET=0
    447
    448	for i in $(seq 1 2); do
    449		ip -n $ns link add name dummy$i type dummy
    450		ip -n $ns link set dev dummy$i up
    451	done
    452
    453	ip -n $ns route add 2001:db8:1::/64 dev dummy1 metric 1024
    454	fib6_trap_check $ns "2001:db8:1::/64 dev dummy1 metric 1024" false
    455	check_err $? "Route not in hardware when should"
    456
    457	ip -n $ns route replace 2001:db8:1::/64 dev dummy2 metric 1024
    458	fib6_trap_check $ns "2001:db8:1::/64 dev dummy2 metric 1024" false
    459	check_err $? "Replacement route not in hardware when should"
    460
    461	# Add a route with an higher metric and make sure that replacing it
    462	# does not affect the lower metric one.
    463	ip -n $ns route add 2001:db8:1::/64 dev dummy1 metric 1025
    464	ip -n $ns route replace 2001:db8:1::/64 dev dummy2 metric 1025
    465
    466	fib6_trap_check $ns "2001:db8:1::/64 dev dummy2 metric 1024" false
    467	check_err $? "Lowest metric route not in hardware when should"
    468	fib6_trap_check $ns "2001:db8:1::/64 dev dummy2 metric 1025" true
    469	check_err $? "Highest metric route in hardware when should not"
    470
    471	log_test "IPv6 single route replace"
    472
    473	for i in $(seq 1 2); do
    474		ip -n $ns link del dev dummy$i
    475	done
    476}
    477
    478fib_ipv6_metric_multipath_test()
    479{
    480	local ns=$1; shift
    481
    482	RET=0
    483
    484	for i in $(seq 1 2); do
    485		ip -n $ns link add name dummy$i type dummy
    486		ip -n $ns link set dev dummy$i up
    487		ip -n $ns address add 2001:db8:$i::1/64 dev dummy$i
    488	done
    489
    490	ip -n $ns route add 2001:db8:10::/64 metric 1024 \
    491		nexthop via 2001:db8:1::2 dev dummy1 \
    492		nexthop via 2001:db8:2::2 dev dummy2
    493	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    494	check_err $? "Route not in hardware when should"
    495
    496	ip -n $ns route add 2001:db8:10::/64 metric 1022 \
    497		nexthop via 2001:db8:1::2 dev dummy1 \
    498		nexthop via 2001:db8:2::2 dev dummy2
    499	fib6_trap_check $ns "2001:db8:10::/64 metric 1022" false
    500	check_err $? "Lowest metric route not in hardware when should"
    501
    502	ip -n $ns route add 2001:db8:10::/64 metric 1023 \
    503		nexthop via 2001:db8:1::2 dev dummy1 \
    504		nexthop via 2001:db8:2::2 dev dummy2
    505	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" true
    506	check_err $? "Highest metric route still in hardware when should not"
    507
    508	fib6_trap_check $ns "2001:db8:10::/64 metric 1023" true
    509	check_err $? "Middle metric route in hardware when should not"
    510
    511	log_test "IPv6 multipath routes with metric"
    512
    513	for i in $(seq 1 2); do
    514		ip -n $ns link del dev dummy$i
    515	done
    516}
    517
    518fib_ipv6_append_multipath_test()
    519{
    520	local ns=$1; shift
    521
    522	RET=0
    523
    524	for i in $(seq 1 3); do
    525		ip -n $ns link add name dummy$i type dummy
    526		ip -n $ns link set dev dummy$i up
    527		ip -n $ns address add 2001:db8:$i::1/64 dev dummy$i
    528	done
    529
    530	ip -n $ns route add 2001:db8:10::/64 metric 1024 \
    531		nexthop via 2001:db8:1::2 dev dummy1
    532	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    533	check_err $? "Route not in hardware when should"
    534
    535	ip -n $ns route append 2001:db8:10::/64 metric 1024 \
    536		nexthop via 2001:db8:2::2 dev dummy2 \
    537		nexthop via 2001:db8:3::2 dev dummy3
    538	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    539	check_err $? "Route not in hardware after appending"
    540
    541	ip -n $ns route add 2001:db8:10::/64 metric 1025 \
    542		nexthop via 2001:db8:1::2 dev dummy1
    543	fib6_trap_check $ns "2001:db8:10::/64 metric 1025" true
    544	check_err $? "Route in hardware when should not"
    545
    546	ip -n $ns route append 2001:db8:10::/64 metric 1025 \
    547		nexthop via 2001:db8:2::2 dev dummy2 \
    548		nexthop via 2001:db8:3::2 dev dummy3
    549	fib6_trap_check $ns "2001:db8:10::/64 metric 1025" true
    550	check_err $? "Route in hardware when should not after appending"
    551
    552	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    553	check_err $? "Lowest metric route not in hardware when should"
    554
    555	log_test "IPv6 append multipath route with 'nexthop' keyword"
    556
    557	for i in $(seq 1 3); do
    558		ip -n $ns link del dev dummy$i
    559	done
    560}
    561
    562fib_ipv6_replace_multipath_test()
    563{
    564	local ns=$1; shift
    565	local i
    566
    567	RET=0
    568
    569	for i in $(seq 1 3); do
    570		ip -n $ns link add name dummy$i type dummy
    571		ip -n $ns link set dev dummy$i up
    572		ip -n $ns address add 2001:db8:$i::1/64 dev dummy$i
    573	done
    574
    575	ip -n $ns route add 2001:db8:10::/64 metric 1024 \
    576		nexthop via 2001:db8:1::2 dev dummy1 \
    577		nexthop via 2001:db8:2::2 dev dummy2
    578	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    579	check_err $? "Route not in hardware when should"
    580
    581	ip -n $ns route replace 2001:db8:10::/64 metric 1024 \
    582		nexthop via 2001:db8:1::2 dev dummy1 \
    583		nexthop via 2001:db8:3::2 dev dummy3
    584	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    585	check_err $? "Replacement route not in hardware when should"
    586
    587	# Add a route with an higher metric and make sure that replacing it
    588	# does not affect the lower metric one.
    589	ip -n $ns route add 2001:db8:10::/64 metric 1025 \
    590		nexthop via 2001:db8:1::2 dev dummy1 \
    591		nexthop via 2001:db8:2::2 dev dummy2
    592	ip -n $ns route replace 2001:db8:10::/64 metric 1025 \
    593		nexthop via 2001:db8:1::2 dev dummy1 \
    594		nexthop via 2001:db8:3::2 dev dummy3
    595
    596	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    597	check_err $? "Lowest metric route not in hardware when should"
    598	fib6_trap_check $ns "2001:db8:10::/64 metric 1025" true
    599	check_err $? "Highest metric route in hardware when should not"
    600
    601	log_test "IPv6 multipath route replace"
    602
    603	for i in $(seq 1 3); do
    604		ip -n $ns link del dev dummy$i
    605	done
    606}
    607
    608fib_ipv6_append_multipath_to_single_test()
    609{
    610	local ns=$1; shift
    611
    612	# Test that when the first route in the leaf is not a multipath route
    613	# and we try to append a multipath route with the same metric to it, it
    614	# is not notified.
    615	RET=0
    616
    617	for i in $(seq 1 2); do
    618		ip -n $ns link add name dummy$i type dummy
    619		ip -n $ns link set dev dummy$i up
    620		ip -n $ns address add 2001:db8:$i::1/64 dev dummy$i
    621	done
    622
    623	ip -n $ns route add 2001:db8:10::/64 dev dummy1 metric 1024
    624	fib6_trap_check $ns "2001:db8:10::/64 dev dummy1 metric 1024" false
    625	check_err $? "Route not in hardware when should"
    626
    627	ip -n $ns route append 2001:db8:10::/64 metric 1024 \
    628		nexthop via 2001:db8:2::2 dev dummy2
    629	fib6_trap_check $ns "2001:db8:10::/64 dev dummy2 metric 1024" true
    630	check_err $? "Route in hardware when should not"
    631
    632	fib6_trap_check $ns "2001:db8:10::/64 dev dummy1 metric 1024" false
    633	check_err $? "Route not in hardware after append"
    634
    635	log_test "IPv6 append multipath route to non-multipath route"
    636
    637	for i in $(seq 1 2); do
    638		ip -n $ns link del dev dummy$i
    639	done
    640}
    641
    642fib_ipv6_delete_single_test()
    643{
    644	local ns=$1; shift
    645
    646	# Test various deletion scenarios, where only a single route is
    647	# deleted from the FIB node.
    648	for i in $(seq 1 2); do
    649		ip -n $ns link add name dummy$i type dummy
    650		ip -n $ns link set dev dummy$i up
    651		ip -n $ns address add 2001:db8:$i::1/64 dev dummy$i
    652	done
    653
    654	# Test deletion of a single route when it is the only route in the FIB
    655	# node.
    656	RET=0
    657
    658	ip -n $ns route add 2001:db8:10::/64 dev dummy1 metric 1024
    659	ip -n $ns route del 2001:db8:10::/64 dev dummy1 metric 1024
    660
    661	log_test "IPv6 delete sole single route"
    662
    663	# Test that deletion of last route does not affect the first one.
    664	RET=0
    665
    666	ip -n $ns route add 2001:db8:10::/64 dev dummy1 metric 1024
    667	ip -n $ns route add 2001:db8:10::/64 dev dummy1 metric 1025
    668	ip -n $ns route del 2001:db8:10::/64 dev dummy1 metric 1025
    669
    670	fib6_trap_check $ns "2001:db8:10::/64 dev dummy1 metric 1024" false
    671	check_err $? "Route not in hardware after deleting higher metric route"
    672
    673	log_test "IPv6 delete single route not in hardware"
    674
    675	ip -n $ns route del 2001:db8:10::/64 dev dummy1 metric 1024
    676
    677	# Test that first route is replaced by next single route in the FIB
    678	# node.
    679	RET=0
    680
    681	ip -n $ns route add 2001:db8:10::/64 dev dummy1 metric 1024
    682	ip -n $ns route add 2001:db8:10::/64 dev dummy1 metric 1025
    683	ip -n $ns route del 2001:db8:10::/64 dev dummy1 metric 1024
    684
    685	fib6_trap_check $ns "2001:db8:10::/64 dev dummy1 metric 1025" false
    686	check_err $? "Route not in hardware after deleting lowest metric route"
    687
    688	log_test "IPv6 delete single route - replaced by single"
    689
    690	ip -n $ns route del 2001:db8:10::/64 dev dummy1 metric 1025
    691
    692	# Test that first route is replaced by next multipath route in the FIB
    693	# node.
    694	RET=0
    695
    696	ip -n $ns route add 2001:db8:10::/64 dev dummy1 metric 1024
    697	ip -n $ns route add 2001:db8:10::/64 metric 1025 \
    698		nexthop via 2001:db8:1::2 dev dummy1 \
    699		nexthop via 2001:db8:2::2 dev dummy2
    700	ip -n $ns route del 2001:db8:10::/64 dev dummy1 metric 1024
    701
    702	fib6_trap_check $ns "2001:db8:10::/64 metric 1025" false
    703	check_err $? "Route not in hardware after deleting lowest metric route"
    704
    705	log_test "IPv6 delete single route - replaced by multipath"
    706
    707	ip -n $ns route del 2001:db8:10::/64 metric 1025
    708
    709	# Test deletion of a single nexthop from a multipath route.
    710	ip -n $ns route add 2001:db8:10::/64 metric 1024 \
    711		nexthop via 2001:db8:1::2 dev dummy1 \
    712		nexthop via 2001:db8:2::2 dev dummy2
    713	ip -n $ns route del 2001:db8:10::/64 metric 1024 \
    714		nexthop via 2001:db8:1::2 dev dummy1
    715
    716	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    717	check_err $? "Route not in hardware after deleting a single nexthop"
    718
    719	log_test "IPv6 delete single nexthop"
    720
    721	ip -n $ns route del 2001:db8:10::/64 metric 1024
    722
    723	for i in $(seq 1 2); do
    724		ip -n $ns link del dev dummy$i
    725	done
    726}
    727
    728fib_ipv6_delete_multipath_test()
    729{
    730	local ns=$1; shift
    731
    732	# Test various deletion scenarios, where an entire multipath route is
    733	# deleted from the FIB node.
    734	for i in $(seq 1 2); do
    735		ip -n $ns link add name dummy$i type dummy
    736		ip -n $ns link set dev dummy$i up
    737		ip -n $ns address add 2001:db8:$i::1/64 dev dummy$i
    738	done
    739
    740	# Test deletion of a multipath route when it is the only route in the
    741	# FIB node.
    742	RET=0
    743
    744	ip -n $ns route add 2001:db8:10::/64 metric 1024 \
    745		nexthop via 2001:db8:1::2 dev dummy1 \
    746		nexthop via 2001:db8:2::2 dev dummy2
    747	ip -n $ns route del 2001:db8:10::/64 metric 1024
    748
    749	log_test "IPv6 delete sole multipath route"
    750
    751	# Test that deletion of last route does not affect the first one.
    752	RET=0
    753
    754	ip -n $ns route add 2001:db8:10::/64 metric 1024 \
    755		nexthop via 2001:db8:1::2 dev dummy1 \
    756		nexthop via 2001:db8:2::2 dev dummy2
    757	ip -n $ns route add 2001:db8:10::/64 metric 1025 \
    758		nexthop via 2001:db8:1::2 dev dummy1 \
    759		nexthop via 2001:db8:2::2 dev dummy2
    760	ip -n $ns route del 2001:db8:10::/64 metric 1025
    761
    762	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    763	check_err $? "Route not in hardware after deleting higher metric route"
    764
    765	log_test "IPv6 delete multipath route not in hardware"
    766
    767	ip -n $ns route del 2001:db8:10::/64 metric 1024
    768
    769	# Test that first route is replaced by next single route in the FIB
    770	# node.
    771	RET=0
    772
    773	ip -n $ns route add 2001:db8:10::/64 metric 1024 \
    774		nexthop via 2001:db8:1::2 dev dummy1 \
    775		nexthop via 2001:db8:2::2 dev dummy2
    776	ip -n $ns route add 2001:db8:10::/64 dev dummy1 metric 1025
    777	ip -n $ns route del 2001:db8:10::/64 metric 1024
    778
    779	fib6_trap_check $ns "2001:db8:10::/64 dev dummy1 metric 1025" false
    780	check_err $? "Route not in hardware after deleting lowest metric route"
    781
    782	log_test "IPv6 delete multipath route - replaced by single"
    783
    784	ip -n $ns route del 2001:db8:10::/64 dev dummy1 metric 1025
    785
    786	# Test that first route is replaced by next multipath route in the FIB
    787	# node.
    788	RET=0
    789
    790	ip -n $ns route add 2001:db8:10::/64 metric 1024 \
    791		nexthop via 2001:db8:1::2 dev dummy1 \
    792		nexthop via 2001:db8:2::2 dev dummy2
    793	ip -n $ns route add 2001:db8:10::/64 metric 1025 \
    794		nexthop via 2001:db8:1::2 dev dummy1 \
    795		nexthop via 2001:db8:2::2 dev dummy2
    796	ip -n $ns route del 2001:db8:10::/64 metric 1024
    797
    798	fib6_trap_check $ns "2001:db8:10::/64 metric 1025" false
    799	check_err $? "Route not in hardware after deleting lowest metric route"
    800
    801	log_test "IPv6 delete multipath route - replaced by multipath"
    802
    803	ip -n $ns route del 2001:db8:10::/64 metric 1025
    804
    805	for i in $(seq 1 2); do
    806		ip -n $ns link del dev dummy$i
    807	done
    808}
    809
    810fib_ipv6_replay_single_test()
    811{
    812	local ns=$1; shift
    813	local devlink_dev=$1; shift
    814
    815	RET=0
    816
    817	for i in $(seq 1 2); do
    818		ip -n $ns link add name dummy$i type dummy
    819		ip -n $ns link set dev dummy$i up
    820	done
    821
    822	ip -n $ns route add 2001:db8:1::/64 dev dummy1
    823	ip -n $ns route append 2001:db8:1::/64 dev dummy2
    824
    825	devlink -N $ns dev reload $devlink_dev
    826
    827	fib6_trap_check $ns "2001:db8:1::/64 dev dummy1" false
    828	check_err $? "First route not in hardware when should"
    829
    830	fib6_trap_check $ns "2001:db8:1::/64 dev dummy2" true
    831	check_err $? "Second route in hardware when should not"
    832
    833	log_test "IPv6 routes replay - single route"
    834
    835	for i in $(seq 1 2); do
    836		ip -n $ns link del dev dummy$i
    837	done
    838}
    839
    840fib_ipv6_replay_multipath_test()
    841{
    842	local ns=$1; shift
    843	local devlink_dev=$1; shift
    844
    845	RET=0
    846
    847	for i in $(seq 1 2); do
    848		ip -n $ns link add name dummy$i type dummy
    849		ip -n $ns link set dev dummy$i up
    850		ip -n $ns address add 2001:db8:$i::1/64 dev dummy$i
    851	done
    852
    853	ip -n $ns route add 2001:db8:10::/64 metric 1024 \
    854		nexthop via 2001:db8:1::2 dev dummy1 \
    855		nexthop via 2001:db8:2::2 dev dummy2
    856	ip -n $ns route add 2001:db8:10::/64 metric 1025 \
    857		nexthop via 2001:db8:1::2 dev dummy1 \
    858		nexthop via 2001:db8:2::2 dev dummy2
    859
    860	devlink -N $ns dev reload $devlink_dev
    861
    862	fib6_trap_check $ns "2001:db8:10::/64 metric 1024" false
    863	check_err $? "First route not in hardware when should"
    864
    865	fib6_trap_check $ns "2001:db8:10::/64 metric 1025" true
    866	check_err $? "Second route in hardware when should not"
    867
    868	log_test "IPv6 routes replay - multipath route"
    869
    870	for i in $(seq 1 2); do
    871		ip -n $ns link del dev dummy$i
    872	done
    873}