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