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-onlink-tests.sh (12409B)


      1#!/bin/bash
      2# SPDX-License-Identifier: GPL-2.0
      3
      4# IPv4 and IPv6 onlink tests
      5
      6PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
      7VERBOSE=0
      8
      9# Network interfaces
     10# - odd in current namespace; even in peer ns
     11declare -A NETIFS
     12# default VRF
     13NETIFS[p1]=veth1
     14NETIFS[p2]=veth2
     15NETIFS[p3]=veth3
     16NETIFS[p4]=veth4
     17# VRF
     18NETIFS[p5]=veth5
     19NETIFS[p6]=veth6
     20NETIFS[p7]=veth7
     21NETIFS[p8]=veth8
     22
     23# /24 network
     24declare -A V4ADDRS
     25V4ADDRS[p1]=169.254.1.1
     26V4ADDRS[p2]=169.254.1.2
     27V4ADDRS[p3]=169.254.3.1
     28V4ADDRS[p4]=169.254.3.2
     29V4ADDRS[p5]=169.254.5.1
     30V4ADDRS[p6]=169.254.5.2
     31V4ADDRS[p7]=169.254.7.1
     32V4ADDRS[p8]=169.254.7.2
     33
     34# /64 network
     35declare -A V6ADDRS
     36V6ADDRS[p1]=2001:db8:101::1
     37V6ADDRS[p2]=2001:db8:101::2
     38V6ADDRS[p3]=2001:db8:301::1
     39V6ADDRS[p4]=2001:db8:301::2
     40V6ADDRS[p5]=2001:db8:501::1
     41V6ADDRS[p6]=2001:db8:501::2
     42V6ADDRS[p7]=2001:db8:701::1
     43V6ADDRS[p8]=2001:db8:701::2
     44
     45# Test networks:
     46# [1] = default table
     47# [2] = VRF
     48#
     49# /32 host routes
     50declare -A TEST_NET4
     51TEST_NET4[1]=169.254.101
     52TEST_NET4[2]=169.254.102
     53# /128 host routes
     54declare -A TEST_NET6
     55TEST_NET6[1]=2001:db8:101
     56TEST_NET6[2]=2001:db8:102
     57
     58# connected gateway
     59CONGW[1]=169.254.1.254
     60CONGW[2]=169.254.3.254
     61CONGW[3]=169.254.5.254
     62
     63# recursive gateway
     64RECGW4[1]=169.254.11.254
     65RECGW4[2]=169.254.12.254
     66RECGW6[1]=2001:db8:11::64
     67RECGW6[2]=2001:db8:12::64
     68
     69# for v4 mapped to v6
     70declare -A TEST_NET4IN6IN6
     71TEST_NET4IN6[1]=10.1.1.254
     72TEST_NET4IN6[2]=10.2.1.254
     73
     74# mcast address
     75MCAST6=ff02::1
     76
     77
     78PEER_NS=bart
     79PEER_CMD="ip netns exec ${PEER_NS}"
     80VRF=lisa
     81VRF_TABLE=1101
     82PBR_TABLE=101
     83
     84################################################################################
     85# utilities
     86
     87log_test()
     88{
     89	local rc=$1
     90	local expected=$2
     91	local msg="$3"
     92
     93	if [ ${rc} -eq ${expected} ]; then
     94		nsuccess=$((nsuccess+1))
     95		printf "    TEST: %-50s  [ OK ]\n" "${msg}"
     96	else
     97		nfail=$((nfail+1))
     98		printf "    TEST: %-50s  [FAIL]\n" "${msg}"
     99		if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
    100			echo
    101			echo "hit enter to continue, 'q' to quit"
    102			read a
    103			[ "$a" = "q" ] && exit 1
    104		fi
    105	fi
    106}
    107
    108log_section()
    109{
    110	echo
    111	echo "######################################################################"
    112	echo "TEST SECTION: $*"
    113	echo "######################################################################"
    114}
    115
    116log_subsection()
    117{
    118	echo
    119	echo "#########################################"
    120	echo "TEST SUBSECTION: $*"
    121}
    122
    123run_cmd()
    124{
    125	local cmd="$*"
    126	local out
    127	local rc
    128
    129	if [ "$VERBOSE" = "1" ]; then
    130		printf "    COMMAND: $cmd\n"
    131	fi
    132
    133	out=$(eval $cmd 2>&1)
    134	rc=$?
    135	if [ "$VERBOSE" = "1" -a -n "$out" ]; then
    136		echo "    $out"
    137	fi
    138
    139	[ "$VERBOSE" = "1" ] && echo
    140
    141	return $rc
    142}
    143
    144get_linklocal()
    145{
    146	local dev=$1
    147	local pfx
    148	local addr
    149
    150	addr=$(${pfx} ip -6 -br addr show dev ${dev} | \
    151	awk '{
    152		for (i = 3; i <= NF; ++i) {
    153			if ($i ~ /^fe80/)
    154				print $i
    155		}
    156	}'
    157	)
    158	addr=${addr/\/*}
    159
    160	[ -z "$addr" ] && return 1
    161
    162	echo $addr
    163
    164	return 0
    165}
    166
    167################################################################################
    168#
    169
    170setup()
    171{
    172	echo
    173	echo "########################################"
    174	echo "Configuring interfaces"
    175
    176	set -e
    177
    178	# create namespace
    179	ip netns add ${PEER_NS}
    180	ip -netns ${PEER_NS} li set lo up
    181
    182	# add vrf table
    183	ip li add ${VRF} type vrf table ${VRF_TABLE}
    184	ip li set ${VRF} up
    185	ip ro add table ${VRF_TABLE} unreachable default metric 8192
    186	ip -6 ro add table ${VRF_TABLE} unreachable default metric 8192
    187
    188	# create test interfaces
    189	ip li add ${NETIFS[p1]} type veth peer name ${NETIFS[p2]}
    190	ip li add ${NETIFS[p3]} type veth peer name ${NETIFS[p4]}
    191	ip li add ${NETIFS[p5]} type veth peer name ${NETIFS[p6]}
    192	ip li add ${NETIFS[p7]} type veth peer name ${NETIFS[p8]}
    193
    194	# enslave vrf interfaces
    195	for n in 5 7; do
    196		ip li set ${NETIFS[p${n}]} vrf ${VRF}
    197	done
    198
    199	# add addresses
    200	for n in 1 3 5 7; do
    201		ip li set ${NETIFS[p${n}]} up
    202		ip addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
    203		ip addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
    204	done
    205
    206	# move peer interfaces to namespace and add addresses
    207	for n in 2 4 6 8; do
    208		ip li set ${NETIFS[p${n}]} netns ${PEER_NS} up
    209		ip -netns ${PEER_NS} addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
    210		ip -netns ${PEER_NS} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
    211	done
    212
    213	ip -6 ro add default via ${V6ADDRS[p3]/::[0-9]/::64}
    214	ip -6 ro add table ${VRF_TABLE} default via ${V6ADDRS[p7]/::[0-9]/::64}
    215
    216	set +e
    217}
    218
    219cleanup()
    220{
    221	# make sure we start from a clean slate
    222	ip netns del ${PEER_NS} 2>/dev/null
    223	for n in 1 3 5 7; do
    224		ip link del ${NETIFS[p${n}]} 2>/dev/null
    225	done
    226	ip link del ${VRF} 2>/dev/null
    227	ip ro flush table ${VRF_TABLE}
    228	ip -6 ro flush table ${VRF_TABLE}
    229}
    230
    231################################################################################
    232# IPv4 tests
    233#
    234
    235run_ip()
    236{
    237	local table="$1"
    238	local prefix="$2"
    239	local gw="$3"
    240	local dev="$4"
    241	local exp_rc="$5"
    242	local desc="$6"
    243
    244	# dev arg may be empty
    245	[ -n "${dev}" ] && dev="dev ${dev}"
    246
    247	run_cmd ip ro add table "${table}" "${prefix}"/32 via "${gw}" "${dev}" onlink
    248	log_test $? ${exp_rc} "${desc}"
    249}
    250
    251run_ip_mpath()
    252{
    253	local table="$1"
    254	local prefix="$2"
    255	local nh1="$3"
    256	local nh2="$4"
    257	local exp_rc="$5"
    258	local desc="$6"
    259
    260	# dev arg may be empty
    261	[ -n "${dev}" ] && dev="dev ${dev}"
    262
    263	run_cmd ip ro add table "${table}" "${prefix}"/32 \
    264		nexthop via ${nh1} nexthop via ${nh2}
    265	log_test $? ${exp_rc} "${desc}"
    266}
    267
    268valid_onlink_ipv4()
    269{
    270	# - unicast connected, unicast recursive
    271	#
    272	log_subsection "default VRF - main table"
    273
    274	run_ip 254 ${TEST_NET4[1]}.1 ${CONGW[1]} ${NETIFS[p1]} 0 "unicast connected"
    275	run_ip 254 ${TEST_NET4[1]}.2 ${RECGW4[1]} ${NETIFS[p1]} 0 "unicast recursive"
    276
    277	log_subsection "VRF ${VRF}"
    278
    279	run_ip ${VRF_TABLE} ${TEST_NET4[2]}.1 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected"
    280	run_ip ${VRF_TABLE} ${TEST_NET4[2]}.2 ${RECGW4[2]} ${NETIFS[p5]} 0 "unicast recursive"
    281
    282	log_subsection "VRF device, PBR table"
    283
    284	run_ip ${PBR_TABLE} ${TEST_NET4[2]}.3 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected"
    285	run_ip ${PBR_TABLE} ${TEST_NET4[2]}.4 ${RECGW4[2]} ${NETIFS[p5]} 0 "unicast recursive"
    286
    287	# multipath version
    288	#
    289	log_subsection "default VRF - main table - multipath"
    290
    291	run_ip_mpath 254 ${TEST_NET4[1]}.5 \
    292		"${CONGW[1]} dev ${NETIFS[p1]} onlink" \
    293		"${CONGW[2]} dev ${NETIFS[p3]} onlink" \
    294		0 "unicast connected - multipath"
    295
    296	run_ip_mpath 254 ${TEST_NET4[1]}.6 \
    297		"${RECGW4[1]} dev ${NETIFS[p1]} onlink" \
    298		"${RECGW4[2]} dev ${NETIFS[p3]} onlink" \
    299		0 "unicast recursive - multipath"
    300
    301	run_ip_mpath 254 ${TEST_NET4[1]}.7 \
    302		"${CONGW[1]} dev ${NETIFS[p1]}"        \
    303		"${CONGW[2]} dev ${NETIFS[p3]} onlink" \
    304		0 "unicast connected - multipath onlink first only"
    305
    306	run_ip_mpath 254 ${TEST_NET4[1]}.8 \
    307		"${CONGW[1]} dev ${NETIFS[p1]} onlink" \
    308		"${CONGW[2]} dev ${NETIFS[p3]}"        \
    309		0 "unicast connected - multipath onlink second only"
    310}
    311
    312invalid_onlink_ipv4()
    313{
    314	run_ip 254 ${TEST_NET4[1]}.11 ${V4ADDRS[p1]} ${NETIFS[p1]} 2 \
    315		"Invalid gw - local unicast address"
    316
    317	run_ip ${VRF_TABLE} ${TEST_NET4[2]}.11 ${V4ADDRS[p5]} ${NETIFS[p5]} 2 \
    318		"Invalid gw - local unicast address, VRF"
    319
    320	run_ip 254 ${TEST_NET4[1]}.101 ${V4ADDRS[p1]} "" 2 "No nexthop device given"
    321
    322	run_ip 254 ${TEST_NET4[1]}.102 ${V4ADDRS[p3]} ${NETIFS[p1]} 2 \
    323		"Gateway resolves to wrong nexthop device"
    324
    325	run_ip ${VRF_TABLE} ${TEST_NET4[2]}.103 ${V4ADDRS[p7]} ${NETIFS[p5]} 2 \
    326		"Gateway resolves to wrong nexthop device - VRF"
    327}
    328
    329################################################################################
    330# IPv6 tests
    331#
    332
    333run_ip6()
    334{
    335	local table="$1"
    336	local prefix="$2"
    337	local gw="$3"
    338	local dev="$4"
    339	local exp_rc="$5"
    340	local desc="$6"
    341
    342	# dev arg may be empty
    343	[ -n "${dev}" ] && dev="dev ${dev}"
    344
    345	run_cmd ip -6 ro add table "${table}" "${prefix}"/128 via "${gw}" "${dev}" onlink
    346	log_test $? ${exp_rc} "${desc}"
    347}
    348
    349run_ip6_mpath()
    350{
    351	local table="$1"
    352	local prefix="$2"
    353	local opts="$3"
    354	local nh1="$4"
    355	local nh2="$5"
    356	local exp_rc="$6"
    357	local desc="$7"
    358
    359	run_cmd ip -6 ro add table "${table}" "${prefix}"/128 "${opts}" \
    360		nexthop via ${nh1} nexthop via ${nh2}
    361	log_test $? ${exp_rc} "${desc}"
    362}
    363
    364valid_onlink_ipv6()
    365{
    366	# - unicast connected, unicast recursive, v4-mapped
    367	#
    368	log_subsection "default VRF - main table"
    369
    370	run_ip6 254 ${TEST_NET6[1]}::1 ${V6ADDRS[p1]/::*}::64 ${NETIFS[p1]} 0 "unicast connected"
    371	run_ip6 254 ${TEST_NET6[1]}::2 ${RECGW6[1]} ${NETIFS[p1]} 0 "unicast recursive"
    372	run_ip6 254 ${TEST_NET6[1]}::3 ::ffff:${TEST_NET4IN6[1]} ${NETIFS[p1]} 0 "v4-mapped"
    373
    374	log_subsection "VRF ${VRF}"
    375
    376	run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::1 ${V6ADDRS[p5]/::*}::64 ${NETIFS[p5]} 0 "unicast connected"
    377	run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::2 ${RECGW6[2]} ${NETIFS[p5]} 0 "unicast recursive"
    378	run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::3 ::ffff:${TEST_NET4IN6[2]} ${NETIFS[p5]} 0 "v4-mapped"
    379
    380	log_subsection "VRF device, PBR table"
    381
    382	run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::4 ${V6ADDRS[p5]/::*}::64 ${NETIFS[p5]} 0 "unicast connected"
    383	run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::5 ${RECGW6[2]} ${NETIFS[p5]} 0 "unicast recursive"
    384	run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::6 ::ffff:${TEST_NET4IN6[2]} ${NETIFS[p5]} 0 "v4-mapped"
    385
    386	# multipath version
    387	#
    388	log_subsection "default VRF - main table - multipath"
    389
    390	run_ip6_mpath 254 ${TEST_NET6[1]}::4 "onlink" \
    391		"${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]}" \
    392		"${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]}" \
    393		0 "unicast connected - multipath onlink"
    394
    395	run_ip6_mpath 254 ${TEST_NET6[1]}::5 "onlink" \
    396		"${RECGW6[1]} dev ${NETIFS[p1]}" \
    397		"${RECGW6[2]} dev ${NETIFS[p3]}" \
    398		0 "unicast recursive - multipath onlink"
    399
    400	run_ip6_mpath 254 ${TEST_NET6[1]}::6 "onlink" \
    401		"::ffff:${TEST_NET4IN6[1]} dev ${NETIFS[p1]}" \
    402		"::ffff:${TEST_NET4IN6[2]} dev ${NETIFS[p3]}" \
    403		0 "v4-mapped - multipath onlink"
    404
    405	run_ip6_mpath 254 ${TEST_NET6[1]}::7 "" \
    406		"${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]} onlink" \
    407		"${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]} onlink" \
    408		0 "unicast connected - multipath onlink both nexthops"
    409
    410	run_ip6_mpath 254 ${TEST_NET6[1]}::8 "" \
    411		"${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]} onlink" \
    412		"${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]}" \
    413		0 "unicast connected - multipath onlink first only"
    414
    415	run_ip6_mpath 254 ${TEST_NET6[1]}::9 "" \
    416		"${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]}"        \
    417		"${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]} onlink" \
    418		0 "unicast connected - multipath onlink second only"
    419}
    420
    421invalid_onlink_ipv6()
    422{
    423	local lladdr
    424
    425	lladdr=$(get_linklocal ${NETIFS[p1]}) || return 1
    426
    427	run_ip6 254 ${TEST_NET6[1]}::11 ${V6ADDRS[p1]} ${NETIFS[p1]} 2 \
    428		"Invalid gw - local unicast address"
    429	run_ip6 254 ${TEST_NET6[1]}::12 ${lladdr} ${NETIFS[p1]} 2 \
    430		"Invalid gw - local linklocal address"
    431	run_ip6 254 ${TEST_NET6[1]}::12 ${MCAST6} ${NETIFS[p1]} 2 \
    432		"Invalid gw - multicast address"
    433
    434	lladdr=$(get_linklocal ${NETIFS[p5]}) || return 1
    435	run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::11 ${V6ADDRS[p5]} ${NETIFS[p5]} 2 \
    436		"Invalid gw - local unicast address, VRF"
    437	run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::12 ${lladdr} ${NETIFS[p5]} 2 \
    438		"Invalid gw - local linklocal address, VRF"
    439	run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::12 ${MCAST6} ${NETIFS[p5]} 2 \
    440		"Invalid gw - multicast address, VRF"
    441
    442	run_ip6 254 ${TEST_NET6[1]}::101 ${V6ADDRS[p1]} "" 2 \
    443		"No nexthop device given"
    444
    445	# default VRF validation is done against LOCAL table
    446	# run_ip6 254 ${TEST_NET6[1]}::102 ${V6ADDRS[p3]/::[0-9]/::64} ${NETIFS[p1]} 2 \
    447	#	"Gateway resolves to wrong nexthop device"
    448
    449	run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::103 ${V6ADDRS[p7]/::[0-9]/::64} ${NETIFS[p5]} 2 \
    450		"Gateway resolves to wrong nexthop device - VRF"
    451}
    452
    453run_onlink_tests()
    454{
    455	log_section "IPv4 onlink"
    456	log_subsection "Valid onlink commands"
    457	valid_onlink_ipv4
    458	log_subsection "Invalid onlink commands"
    459	invalid_onlink_ipv4
    460
    461	log_section "IPv6 onlink"
    462	log_subsection "Valid onlink commands"
    463	valid_onlink_ipv6
    464	log_subsection "Invalid onlink commands"
    465	invalid_onlink_ipv6
    466}
    467
    468################################################################################
    469# usage
    470
    471usage()
    472{
    473	cat <<EOF
    474usage: ${0##*/} OPTS
    475
    476        -p          Pause on fail
    477        -v          verbose mode (show commands and output)
    478EOF
    479}
    480
    481################################################################################
    482# main
    483
    484nsuccess=0
    485nfail=0
    486
    487while getopts :t:pPhv o
    488do
    489	case $o in
    490		p) PAUSE_ON_FAIL=yes;;
    491		v) VERBOSE=$(($VERBOSE + 1));;
    492		h) usage; exit 0;;
    493		*) usage; exit 1;;
    494	esac
    495done
    496
    497cleanup
    498setup
    499run_onlink_tests
    500cleanup
    501
    502if [ "$TESTS" != "none" ]; then
    503	printf "\nTests passed: %3d\n" ${nsuccess}
    504	printf "Tests failed: %3d\n"   ${nfail}
    505fi