1*4882a593Smuzhiyun#!/bin/bash 2*4882a593Smuzhiyun# SPDX-License-Identifier: GPL-2.0 3*4882a593Smuzhiyun 4*4882a593Smuzhiyun# This test is for checking IPv4 and IPv6 FIB behavior in response to 5*4882a593Smuzhiyun# different events. 6*4882a593Smuzhiyun 7*4882a593Smuzhiyunret=0 8*4882a593Smuzhiyun# Kselftest framework requirement - SKIP code is 4. 9*4882a593Smuzhiyunksft_skip=4 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun# all tests in this script. Can be overridden with -t option 12*4882a593SmuzhiyunTESTS="unregister down carrier nexthop suppress ipv6_rt ipv4_rt ipv6_addr_metric ipv4_addr_metric ipv6_route_metrics ipv4_route_metrics ipv4_route_v6_gw rp_filter ipv4_del_addr" 13*4882a593Smuzhiyun 14*4882a593SmuzhiyunVERBOSE=0 15*4882a593SmuzhiyunPAUSE_ON_FAIL=no 16*4882a593SmuzhiyunPAUSE=no 17*4882a593SmuzhiyunIP="ip -netns ns1" 18*4882a593SmuzhiyunNS_EXEC="ip netns exec ns1" 19*4882a593Smuzhiyun 20*4882a593Smuzhiyunwhich ping6 > /dev/null 2>&1 && ping6=$(which ping6) || ping6=$(which ping) 21*4882a593Smuzhiyun 22*4882a593Smuzhiyunlog_test() 23*4882a593Smuzhiyun{ 24*4882a593Smuzhiyun local rc=$1 25*4882a593Smuzhiyun local expected=$2 26*4882a593Smuzhiyun local msg="$3" 27*4882a593Smuzhiyun 28*4882a593Smuzhiyun if [ ${rc} -eq ${expected} ]; then 29*4882a593Smuzhiyun printf " TEST: %-60s [ OK ]\n" "${msg}" 30*4882a593Smuzhiyun nsuccess=$((nsuccess+1)) 31*4882a593Smuzhiyun else 32*4882a593Smuzhiyun ret=1 33*4882a593Smuzhiyun nfail=$((nfail+1)) 34*4882a593Smuzhiyun printf " TEST: %-60s [FAIL]\n" "${msg}" 35*4882a593Smuzhiyun if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 36*4882a593Smuzhiyun echo 37*4882a593Smuzhiyun echo "hit enter to continue, 'q' to quit" 38*4882a593Smuzhiyun read a 39*4882a593Smuzhiyun [ "$a" = "q" ] && exit 1 40*4882a593Smuzhiyun fi 41*4882a593Smuzhiyun fi 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun if [ "${PAUSE}" = "yes" ]; then 44*4882a593Smuzhiyun echo 45*4882a593Smuzhiyun echo "hit enter to continue, 'q' to quit" 46*4882a593Smuzhiyun read a 47*4882a593Smuzhiyun [ "$a" = "q" ] && exit 1 48*4882a593Smuzhiyun fi 49*4882a593Smuzhiyun} 50*4882a593Smuzhiyun 51*4882a593Smuzhiyunsetup() 52*4882a593Smuzhiyun{ 53*4882a593Smuzhiyun set -e 54*4882a593Smuzhiyun ip netns add ns1 55*4882a593Smuzhiyun ip netns set ns1 auto 56*4882a593Smuzhiyun $IP link set dev lo up 57*4882a593Smuzhiyun ip netns exec ns1 sysctl -qw net.ipv4.ip_forward=1 58*4882a593Smuzhiyun ip netns exec ns1 sysctl -qw net.ipv6.conf.all.forwarding=1 59*4882a593Smuzhiyun 60*4882a593Smuzhiyun $IP link add dummy0 type dummy 61*4882a593Smuzhiyun $IP link set dev dummy0 up 62*4882a593Smuzhiyun $IP address add 198.51.100.1/24 dev dummy0 63*4882a593Smuzhiyun $IP -6 address add 2001:db8:1::1/64 dev dummy0 64*4882a593Smuzhiyun set +e 65*4882a593Smuzhiyun 66*4882a593Smuzhiyun} 67*4882a593Smuzhiyun 68*4882a593Smuzhiyuncleanup() 69*4882a593Smuzhiyun{ 70*4882a593Smuzhiyun $IP link del dev dummy0 &> /dev/null 71*4882a593Smuzhiyun ip netns del ns1 72*4882a593Smuzhiyun ip netns del ns2 &> /dev/null 73*4882a593Smuzhiyun} 74*4882a593Smuzhiyun 75*4882a593Smuzhiyunget_linklocal() 76*4882a593Smuzhiyun{ 77*4882a593Smuzhiyun local dev=$1 78*4882a593Smuzhiyun local addr 79*4882a593Smuzhiyun 80*4882a593Smuzhiyun addr=$($IP -6 -br addr show dev ${dev} | \ 81*4882a593Smuzhiyun awk '{ 82*4882a593Smuzhiyun for (i = 3; i <= NF; ++i) { 83*4882a593Smuzhiyun if ($i ~ /^fe80/) 84*4882a593Smuzhiyun print $i 85*4882a593Smuzhiyun } 86*4882a593Smuzhiyun }' 87*4882a593Smuzhiyun ) 88*4882a593Smuzhiyun addr=${addr/\/*} 89*4882a593Smuzhiyun 90*4882a593Smuzhiyun [ -z "$addr" ] && return 1 91*4882a593Smuzhiyun 92*4882a593Smuzhiyun echo $addr 93*4882a593Smuzhiyun 94*4882a593Smuzhiyun return 0 95*4882a593Smuzhiyun} 96*4882a593Smuzhiyun 97*4882a593Smuzhiyunfib_unreg_unicast_test() 98*4882a593Smuzhiyun{ 99*4882a593Smuzhiyun echo 100*4882a593Smuzhiyun echo "Single path route test" 101*4882a593Smuzhiyun 102*4882a593Smuzhiyun setup 103*4882a593Smuzhiyun 104*4882a593Smuzhiyun echo " Start point" 105*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.2 &> /dev/null 106*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 107*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 108*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 109*4882a593Smuzhiyun 110*4882a593Smuzhiyun set -e 111*4882a593Smuzhiyun $IP link del dev dummy0 112*4882a593Smuzhiyun set +e 113*4882a593Smuzhiyun 114*4882a593Smuzhiyun echo " Nexthop device deleted" 115*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.2 &> /dev/null 116*4882a593Smuzhiyun log_test $? 2 "IPv4 fibmatch - no route" 117*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 118*4882a593Smuzhiyun log_test $? 2 "IPv6 fibmatch - no route" 119*4882a593Smuzhiyun 120*4882a593Smuzhiyun cleanup 121*4882a593Smuzhiyun} 122*4882a593Smuzhiyun 123*4882a593Smuzhiyunfib_unreg_multipath_test() 124*4882a593Smuzhiyun{ 125*4882a593Smuzhiyun 126*4882a593Smuzhiyun echo 127*4882a593Smuzhiyun echo "Multipath route test" 128*4882a593Smuzhiyun 129*4882a593Smuzhiyun setup 130*4882a593Smuzhiyun 131*4882a593Smuzhiyun set -e 132*4882a593Smuzhiyun $IP link add dummy1 type dummy 133*4882a593Smuzhiyun $IP link set dev dummy1 up 134*4882a593Smuzhiyun $IP address add 192.0.2.1/24 dev dummy1 135*4882a593Smuzhiyun $IP -6 address add 2001:db8:2::1/64 dev dummy1 136*4882a593Smuzhiyun 137*4882a593Smuzhiyun $IP route add 203.0.113.0/24 \ 138*4882a593Smuzhiyun nexthop via 198.51.100.2 dev dummy0 \ 139*4882a593Smuzhiyun nexthop via 192.0.2.2 dev dummy1 140*4882a593Smuzhiyun $IP -6 route add 2001:db8:3::/64 \ 141*4882a593Smuzhiyun nexthop via 2001:db8:1::2 dev dummy0 \ 142*4882a593Smuzhiyun nexthop via 2001:db8:2::2 dev dummy1 143*4882a593Smuzhiyun set +e 144*4882a593Smuzhiyun 145*4882a593Smuzhiyun echo " Start point" 146*4882a593Smuzhiyun $IP route get fibmatch 203.0.113.1 &> /dev/null 147*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 148*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 149*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 150*4882a593Smuzhiyun 151*4882a593Smuzhiyun set -e 152*4882a593Smuzhiyun $IP link del dev dummy0 153*4882a593Smuzhiyun set +e 154*4882a593Smuzhiyun 155*4882a593Smuzhiyun echo " One nexthop device deleted" 156*4882a593Smuzhiyun $IP route get fibmatch 203.0.113.1 &> /dev/null 157*4882a593Smuzhiyun log_test $? 2 "IPv4 - multipath route removed on delete" 158*4882a593Smuzhiyun 159*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 160*4882a593Smuzhiyun # In IPv6 we do not flush the entire multipath route. 161*4882a593Smuzhiyun log_test $? 0 "IPv6 - multipath down to single path" 162*4882a593Smuzhiyun 163*4882a593Smuzhiyun set -e 164*4882a593Smuzhiyun $IP link del dev dummy1 165*4882a593Smuzhiyun set +e 166*4882a593Smuzhiyun 167*4882a593Smuzhiyun echo " Second nexthop device deleted" 168*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 169*4882a593Smuzhiyun log_test $? 2 "IPv6 - no route" 170*4882a593Smuzhiyun 171*4882a593Smuzhiyun cleanup 172*4882a593Smuzhiyun} 173*4882a593Smuzhiyun 174*4882a593Smuzhiyunfib_unreg_test() 175*4882a593Smuzhiyun{ 176*4882a593Smuzhiyun fib_unreg_unicast_test 177*4882a593Smuzhiyun fib_unreg_multipath_test 178*4882a593Smuzhiyun} 179*4882a593Smuzhiyun 180*4882a593Smuzhiyunfib_down_unicast_test() 181*4882a593Smuzhiyun{ 182*4882a593Smuzhiyun echo 183*4882a593Smuzhiyun echo "Single path, admin down" 184*4882a593Smuzhiyun 185*4882a593Smuzhiyun setup 186*4882a593Smuzhiyun 187*4882a593Smuzhiyun echo " Start point" 188*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.2 &> /dev/null 189*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 190*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 191*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 192*4882a593Smuzhiyun 193*4882a593Smuzhiyun set -e 194*4882a593Smuzhiyun $IP link set dev dummy0 down 195*4882a593Smuzhiyun set +e 196*4882a593Smuzhiyun 197*4882a593Smuzhiyun echo " Route deleted on down" 198*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.2 &> /dev/null 199*4882a593Smuzhiyun log_test $? 2 "IPv4 fibmatch" 200*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 201*4882a593Smuzhiyun log_test $? 2 "IPv6 fibmatch" 202*4882a593Smuzhiyun 203*4882a593Smuzhiyun cleanup 204*4882a593Smuzhiyun} 205*4882a593Smuzhiyun 206*4882a593Smuzhiyunfib_down_multipath_test_do() 207*4882a593Smuzhiyun{ 208*4882a593Smuzhiyun local down_dev=$1 209*4882a593Smuzhiyun local up_dev=$2 210*4882a593Smuzhiyun 211*4882a593Smuzhiyun $IP route get fibmatch 203.0.113.1 \ 212*4882a593Smuzhiyun oif $down_dev &> /dev/null 213*4882a593Smuzhiyun log_test $? 2 "IPv4 fibmatch on down device" 214*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:3::1 \ 215*4882a593Smuzhiyun oif $down_dev &> /dev/null 216*4882a593Smuzhiyun log_test $? 2 "IPv6 fibmatch on down device" 217*4882a593Smuzhiyun 218*4882a593Smuzhiyun $IP route get fibmatch 203.0.113.1 \ 219*4882a593Smuzhiyun oif $up_dev &> /dev/null 220*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch on up device" 221*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:3::1 \ 222*4882a593Smuzhiyun oif $up_dev &> /dev/null 223*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch on up device" 224*4882a593Smuzhiyun 225*4882a593Smuzhiyun $IP route get fibmatch 203.0.113.1 | \ 226*4882a593Smuzhiyun grep $down_dev | grep -q "dead linkdown" 227*4882a593Smuzhiyun log_test $? 0 "IPv4 flags on down device" 228*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:3::1 | \ 229*4882a593Smuzhiyun grep $down_dev | grep -q "dead linkdown" 230*4882a593Smuzhiyun log_test $? 0 "IPv6 flags on down device" 231*4882a593Smuzhiyun 232*4882a593Smuzhiyun $IP route get fibmatch 203.0.113.1 | \ 233*4882a593Smuzhiyun grep $up_dev | grep -q "dead linkdown" 234*4882a593Smuzhiyun log_test $? 1 "IPv4 flags on up device" 235*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:3::1 | \ 236*4882a593Smuzhiyun grep $up_dev | grep -q "dead linkdown" 237*4882a593Smuzhiyun log_test $? 1 "IPv6 flags on up device" 238*4882a593Smuzhiyun} 239*4882a593Smuzhiyun 240*4882a593Smuzhiyunfib_down_multipath_test() 241*4882a593Smuzhiyun{ 242*4882a593Smuzhiyun echo 243*4882a593Smuzhiyun echo "Admin down multipath" 244*4882a593Smuzhiyun 245*4882a593Smuzhiyun setup 246*4882a593Smuzhiyun 247*4882a593Smuzhiyun set -e 248*4882a593Smuzhiyun $IP link add dummy1 type dummy 249*4882a593Smuzhiyun $IP link set dev dummy1 up 250*4882a593Smuzhiyun 251*4882a593Smuzhiyun $IP address add 192.0.2.1/24 dev dummy1 252*4882a593Smuzhiyun $IP -6 address add 2001:db8:2::1/64 dev dummy1 253*4882a593Smuzhiyun 254*4882a593Smuzhiyun $IP route add 203.0.113.0/24 \ 255*4882a593Smuzhiyun nexthop via 198.51.100.2 dev dummy0 \ 256*4882a593Smuzhiyun nexthop via 192.0.2.2 dev dummy1 257*4882a593Smuzhiyun $IP -6 route add 2001:db8:3::/64 \ 258*4882a593Smuzhiyun nexthop via 2001:db8:1::2 dev dummy0 \ 259*4882a593Smuzhiyun nexthop via 2001:db8:2::2 dev dummy1 260*4882a593Smuzhiyun set +e 261*4882a593Smuzhiyun 262*4882a593Smuzhiyun echo " Verify start point" 263*4882a593Smuzhiyun $IP route get fibmatch 203.0.113.1 &> /dev/null 264*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 265*4882a593Smuzhiyun 266*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 267*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 268*4882a593Smuzhiyun 269*4882a593Smuzhiyun set -e 270*4882a593Smuzhiyun $IP link set dev dummy0 down 271*4882a593Smuzhiyun set +e 272*4882a593Smuzhiyun 273*4882a593Smuzhiyun echo " One device down, one up" 274*4882a593Smuzhiyun fib_down_multipath_test_do "dummy0" "dummy1" 275*4882a593Smuzhiyun 276*4882a593Smuzhiyun set -e 277*4882a593Smuzhiyun $IP link set dev dummy0 up 278*4882a593Smuzhiyun $IP link set dev dummy1 down 279*4882a593Smuzhiyun set +e 280*4882a593Smuzhiyun 281*4882a593Smuzhiyun echo " Other device down and up" 282*4882a593Smuzhiyun fib_down_multipath_test_do "dummy1" "dummy0" 283*4882a593Smuzhiyun 284*4882a593Smuzhiyun set -e 285*4882a593Smuzhiyun $IP link set dev dummy0 down 286*4882a593Smuzhiyun set +e 287*4882a593Smuzhiyun 288*4882a593Smuzhiyun echo " Both devices down" 289*4882a593Smuzhiyun $IP route get fibmatch 203.0.113.1 &> /dev/null 290*4882a593Smuzhiyun log_test $? 2 "IPv4 fibmatch" 291*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:3::1 &> /dev/null 292*4882a593Smuzhiyun log_test $? 2 "IPv6 fibmatch" 293*4882a593Smuzhiyun 294*4882a593Smuzhiyun $IP link del dev dummy1 295*4882a593Smuzhiyun cleanup 296*4882a593Smuzhiyun} 297*4882a593Smuzhiyun 298*4882a593Smuzhiyunfib_down_test() 299*4882a593Smuzhiyun{ 300*4882a593Smuzhiyun fib_down_unicast_test 301*4882a593Smuzhiyun fib_down_multipath_test 302*4882a593Smuzhiyun} 303*4882a593Smuzhiyun 304*4882a593Smuzhiyun# Local routes should not be affected when carrier changes. 305*4882a593Smuzhiyunfib_carrier_local_test() 306*4882a593Smuzhiyun{ 307*4882a593Smuzhiyun echo 308*4882a593Smuzhiyun echo "Local carrier tests - single path" 309*4882a593Smuzhiyun 310*4882a593Smuzhiyun setup 311*4882a593Smuzhiyun 312*4882a593Smuzhiyun set -e 313*4882a593Smuzhiyun $IP link set dev dummy0 carrier on 314*4882a593Smuzhiyun set +e 315*4882a593Smuzhiyun 316*4882a593Smuzhiyun echo " Start point" 317*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.1 &> /dev/null 318*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 319*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null 320*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 321*4882a593Smuzhiyun 322*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.1 | \ 323*4882a593Smuzhiyun grep -q "linkdown" 324*4882a593Smuzhiyun log_test $? 1 "IPv4 - no linkdown flag" 325*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::1 | \ 326*4882a593Smuzhiyun grep -q "linkdown" 327*4882a593Smuzhiyun log_test $? 1 "IPv6 - no linkdown flag" 328*4882a593Smuzhiyun 329*4882a593Smuzhiyun set -e 330*4882a593Smuzhiyun $IP link set dev dummy0 carrier off 331*4882a593Smuzhiyun sleep 1 332*4882a593Smuzhiyun set +e 333*4882a593Smuzhiyun 334*4882a593Smuzhiyun echo " Carrier off on nexthop" 335*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.1 &> /dev/null 336*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 337*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::1 &> /dev/null 338*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 339*4882a593Smuzhiyun 340*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.1 | \ 341*4882a593Smuzhiyun grep -q "linkdown" 342*4882a593Smuzhiyun log_test $? 1 "IPv4 - linkdown flag set" 343*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::1 | \ 344*4882a593Smuzhiyun grep -q "linkdown" 345*4882a593Smuzhiyun log_test $? 1 "IPv6 - linkdown flag set" 346*4882a593Smuzhiyun 347*4882a593Smuzhiyun set -e 348*4882a593Smuzhiyun $IP address add 192.0.2.1/24 dev dummy0 349*4882a593Smuzhiyun $IP -6 address add 2001:db8:2::1/64 dev dummy0 350*4882a593Smuzhiyun set +e 351*4882a593Smuzhiyun 352*4882a593Smuzhiyun echo " Route to local address with carrier down" 353*4882a593Smuzhiyun $IP route get fibmatch 192.0.2.1 &> /dev/null 354*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 355*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:2::1 &> /dev/null 356*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 357*4882a593Smuzhiyun 358*4882a593Smuzhiyun $IP route get fibmatch 192.0.2.1 | \ 359*4882a593Smuzhiyun grep -q "linkdown" 360*4882a593Smuzhiyun log_test $? 1 "IPv4 linkdown flag set" 361*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:2::1 | \ 362*4882a593Smuzhiyun grep -q "linkdown" 363*4882a593Smuzhiyun log_test $? 1 "IPv6 linkdown flag set" 364*4882a593Smuzhiyun 365*4882a593Smuzhiyun cleanup 366*4882a593Smuzhiyun} 367*4882a593Smuzhiyun 368*4882a593Smuzhiyunfib_carrier_unicast_test() 369*4882a593Smuzhiyun{ 370*4882a593Smuzhiyun ret=0 371*4882a593Smuzhiyun 372*4882a593Smuzhiyun echo 373*4882a593Smuzhiyun echo "Single path route carrier test" 374*4882a593Smuzhiyun 375*4882a593Smuzhiyun setup 376*4882a593Smuzhiyun 377*4882a593Smuzhiyun set -e 378*4882a593Smuzhiyun $IP link set dev dummy0 carrier on 379*4882a593Smuzhiyun set +e 380*4882a593Smuzhiyun 381*4882a593Smuzhiyun echo " Start point" 382*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.2 &> /dev/null 383*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 384*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 385*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 386*4882a593Smuzhiyun 387*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.2 | \ 388*4882a593Smuzhiyun grep -q "linkdown" 389*4882a593Smuzhiyun log_test $? 1 "IPv4 no linkdown flag" 390*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::2 | \ 391*4882a593Smuzhiyun grep -q "linkdown" 392*4882a593Smuzhiyun log_test $? 1 "IPv6 no linkdown flag" 393*4882a593Smuzhiyun 394*4882a593Smuzhiyun set -e 395*4882a593Smuzhiyun $IP link set dev dummy0 carrier off 396*4882a593Smuzhiyun sleep 1 397*4882a593Smuzhiyun set +e 398*4882a593Smuzhiyun 399*4882a593Smuzhiyun echo " Carrier down" 400*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.2 &> /dev/null 401*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 402*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::2 &> /dev/null 403*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 404*4882a593Smuzhiyun 405*4882a593Smuzhiyun $IP route get fibmatch 198.51.100.2 | \ 406*4882a593Smuzhiyun grep -q "linkdown" 407*4882a593Smuzhiyun log_test $? 0 "IPv4 linkdown flag set" 408*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:1::2 | \ 409*4882a593Smuzhiyun grep -q "linkdown" 410*4882a593Smuzhiyun log_test $? 0 "IPv6 linkdown flag set" 411*4882a593Smuzhiyun 412*4882a593Smuzhiyun set -e 413*4882a593Smuzhiyun $IP address add 192.0.2.1/24 dev dummy0 414*4882a593Smuzhiyun $IP -6 address add 2001:db8:2::1/64 dev dummy0 415*4882a593Smuzhiyun set +e 416*4882a593Smuzhiyun 417*4882a593Smuzhiyun echo " Second address added with carrier down" 418*4882a593Smuzhiyun $IP route get fibmatch 192.0.2.2 &> /dev/null 419*4882a593Smuzhiyun log_test $? 0 "IPv4 fibmatch" 420*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:2::2 &> /dev/null 421*4882a593Smuzhiyun log_test $? 0 "IPv6 fibmatch" 422*4882a593Smuzhiyun 423*4882a593Smuzhiyun $IP route get fibmatch 192.0.2.2 | \ 424*4882a593Smuzhiyun grep -q "linkdown" 425*4882a593Smuzhiyun log_test $? 0 "IPv4 linkdown flag set" 426*4882a593Smuzhiyun $IP -6 route get fibmatch 2001:db8:2::2 | \ 427*4882a593Smuzhiyun grep -q "linkdown" 428*4882a593Smuzhiyun log_test $? 0 "IPv6 linkdown flag set" 429*4882a593Smuzhiyun 430*4882a593Smuzhiyun cleanup 431*4882a593Smuzhiyun} 432*4882a593Smuzhiyun 433*4882a593Smuzhiyunfib_carrier_test() 434*4882a593Smuzhiyun{ 435*4882a593Smuzhiyun fib_carrier_local_test 436*4882a593Smuzhiyun fib_carrier_unicast_test 437*4882a593Smuzhiyun} 438*4882a593Smuzhiyun 439*4882a593Smuzhiyunfib_rp_filter_test() 440*4882a593Smuzhiyun{ 441*4882a593Smuzhiyun echo 442*4882a593Smuzhiyun echo "IPv4 rp_filter tests" 443*4882a593Smuzhiyun 444*4882a593Smuzhiyun setup 445*4882a593Smuzhiyun 446*4882a593Smuzhiyun set -e 447*4882a593Smuzhiyun ip netns add ns2 448*4882a593Smuzhiyun ip netns set ns2 auto 449*4882a593Smuzhiyun 450*4882a593Smuzhiyun ip -netns ns2 link set dev lo up 451*4882a593Smuzhiyun 452*4882a593Smuzhiyun $IP link add name veth1 type veth peer name veth2 453*4882a593Smuzhiyun $IP link set dev veth2 netns ns2 454*4882a593Smuzhiyun $IP address add 192.0.2.1/24 dev veth1 455*4882a593Smuzhiyun ip -netns ns2 address add 192.0.2.1/24 dev veth2 456*4882a593Smuzhiyun $IP link set dev veth1 up 457*4882a593Smuzhiyun ip -netns ns2 link set dev veth2 up 458*4882a593Smuzhiyun 459*4882a593Smuzhiyun $IP link set dev lo address 52:54:00:6a:c7:5e 460*4882a593Smuzhiyun $IP link set dev veth1 address 52:54:00:6a:c7:5e 461*4882a593Smuzhiyun ip -netns ns2 link set dev lo address 52:54:00:6a:c7:5e 462*4882a593Smuzhiyun ip -netns ns2 link set dev veth2 address 52:54:00:6a:c7:5e 463*4882a593Smuzhiyun 464*4882a593Smuzhiyun # 1. (ns2) redirect lo's egress to veth2's egress 465*4882a593Smuzhiyun ip netns exec ns2 tc qdisc add dev lo parent root handle 1: fq_codel 466*4882a593Smuzhiyun ip netns exec ns2 tc filter add dev lo parent 1: protocol arp basic \ 467*4882a593Smuzhiyun action mirred egress redirect dev veth2 468*4882a593Smuzhiyun ip netns exec ns2 tc filter add dev lo parent 1: protocol ip basic \ 469*4882a593Smuzhiyun action mirred egress redirect dev veth2 470*4882a593Smuzhiyun 471*4882a593Smuzhiyun # 2. (ns1) redirect veth1's ingress to lo's ingress 472*4882a593Smuzhiyun $NS_EXEC tc qdisc add dev veth1 ingress 473*4882a593Smuzhiyun $NS_EXEC tc filter add dev veth1 ingress protocol arp basic \ 474*4882a593Smuzhiyun action mirred ingress redirect dev lo 475*4882a593Smuzhiyun $NS_EXEC tc filter add dev veth1 ingress protocol ip basic \ 476*4882a593Smuzhiyun action mirred ingress redirect dev lo 477*4882a593Smuzhiyun 478*4882a593Smuzhiyun # 3. (ns1) redirect lo's egress to veth1's egress 479*4882a593Smuzhiyun $NS_EXEC tc qdisc add dev lo parent root handle 1: fq_codel 480*4882a593Smuzhiyun $NS_EXEC tc filter add dev lo parent 1: protocol arp basic \ 481*4882a593Smuzhiyun action mirred egress redirect dev veth1 482*4882a593Smuzhiyun $NS_EXEC tc filter add dev lo parent 1: protocol ip basic \ 483*4882a593Smuzhiyun action mirred egress redirect dev veth1 484*4882a593Smuzhiyun 485*4882a593Smuzhiyun # 4. (ns2) redirect veth2's ingress to lo's ingress 486*4882a593Smuzhiyun ip netns exec ns2 tc qdisc add dev veth2 ingress 487*4882a593Smuzhiyun ip netns exec ns2 tc filter add dev veth2 ingress protocol arp basic \ 488*4882a593Smuzhiyun action mirred ingress redirect dev lo 489*4882a593Smuzhiyun ip netns exec ns2 tc filter add dev veth2 ingress protocol ip basic \ 490*4882a593Smuzhiyun action mirred ingress redirect dev lo 491*4882a593Smuzhiyun 492*4882a593Smuzhiyun $NS_EXEC sysctl -qw net.ipv4.conf.all.rp_filter=1 493*4882a593Smuzhiyun $NS_EXEC sysctl -qw net.ipv4.conf.all.accept_local=1 494*4882a593Smuzhiyun $NS_EXEC sysctl -qw net.ipv4.conf.all.route_localnet=1 495*4882a593Smuzhiyun ip netns exec ns2 sysctl -qw net.ipv4.conf.all.rp_filter=1 496*4882a593Smuzhiyun ip netns exec ns2 sysctl -qw net.ipv4.conf.all.accept_local=1 497*4882a593Smuzhiyun ip netns exec ns2 sysctl -qw net.ipv4.conf.all.route_localnet=1 498*4882a593Smuzhiyun set +e 499*4882a593Smuzhiyun 500*4882a593Smuzhiyun run_cmd "ip netns exec ns2 ping -w1 -c1 192.0.2.1" 501*4882a593Smuzhiyun log_test $? 0 "rp_filter passes local packets" 502*4882a593Smuzhiyun 503*4882a593Smuzhiyun run_cmd "ip netns exec ns2 ping -w1 -c1 127.0.0.1" 504*4882a593Smuzhiyun log_test $? 0 "rp_filter passes loopback packets" 505*4882a593Smuzhiyun 506*4882a593Smuzhiyun cleanup 507*4882a593Smuzhiyun} 508*4882a593Smuzhiyun 509*4882a593Smuzhiyun################################################################################ 510*4882a593Smuzhiyun# Tests on nexthop spec 511*4882a593Smuzhiyun 512*4882a593Smuzhiyun# run 'ip route add' with given spec 513*4882a593Smuzhiyunadd_rt() 514*4882a593Smuzhiyun{ 515*4882a593Smuzhiyun local desc="$1" 516*4882a593Smuzhiyun local erc=$2 517*4882a593Smuzhiyun local vrf=$3 518*4882a593Smuzhiyun local pfx=$4 519*4882a593Smuzhiyun local gw=$5 520*4882a593Smuzhiyun local dev=$6 521*4882a593Smuzhiyun local cmd out rc 522*4882a593Smuzhiyun 523*4882a593Smuzhiyun [ "$vrf" = "-" ] && vrf="default" 524*4882a593Smuzhiyun [ -n "$gw" ] && gw="via $gw" 525*4882a593Smuzhiyun [ -n "$dev" ] && dev="dev $dev" 526*4882a593Smuzhiyun 527*4882a593Smuzhiyun cmd="$IP route add vrf $vrf $pfx $gw $dev" 528*4882a593Smuzhiyun if [ "$VERBOSE" = "1" ]; then 529*4882a593Smuzhiyun printf "\n COMMAND: $cmd\n" 530*4882a593Smuzhiyun fi 531*4882a593Smuzhiyun 532*4882a593Smuzhiyun out=$(eval $cmd 2>&1) 533*4882a593Smuzhiyun rc=$? 534*4882a593Smuzhiyun if [ "$VERBOSE" = "1" -a -n "$out" ]; then 535*4882a593Smuzhiyun echo " $out" 536*4882a593Smuzhiyun fi 537*4882a593Smuzhiyun log_test $rc $erc "$desc" 538*4882a593Smuzhiyun} 539*4882a593Smuzhiyun 540*4882a593Smuzhiyunfib4_nexthop() 541*4882a593Smuzhiyun{ 542*4882a593Smuzhiyun echo 543*4882a593Smuzhiyun echo "IPv4 nexthop tests" 544*4882a593Smuzhiyun 545*4882a593Smuzhiyun echo "<<< write me >>>" 546*4882a593Smuzhiyun} 547*4882a593Smuzhiyun 548*4882a593Smuzhiyunfib6_nexthop() 549*4882a593Smuzhiyun{ 550*4882a593Smuzhiyun local lldummy=$(get_linklocal dummy0) 551*4882a593Smuzhiyun local llv1=$(get_linklocal dummy0) 552*4882a593Smuzhiyun 553*4882a593Smuzhiyun if [ -z "$lldummy" ]; then 554*4882a593Smuzhiyun echo "Failed to get linklocal address for dummy0" 555*4882a593Smuzhiyun return 1 556*4882a593Smuzhiyun fi 557*4882a593Smuzhiyun if [ -z "$llv1" ]; then 558*4882a593Smuzhiyun echo "Failed to get linklocal address for veth1" 559*4882a593Smuzhiyun return 1 560*4882a593Smuzhiyun fi 561*4882a593Smuzhiyun 562*4882a593Smuzhiyun echo 563*4882a593Smuzhiyun echo "IPv6 nexthop tests" 564*4882a593Smuzhiyun 565*4882a593Smuzhiyun add_rt "Directly connected nexthop, unicast address" 0 \ 566*4882a593Smuzhiyun - 2001:db8:101::/64 2001:db8:1::2 567*4882a593Smuzhiyun add_rt "Directly connected nexthop, unicast address with device" 0 \ 568*4882a593Smuzhiyun - 2001:db8:102::/64 2001:db8:1::2 "dummy0" 569*4882a593Smuzhiyun add_rt "Gateway is linklocal address" 0 \ 570*4882a593Smuzhiyun - 2001:db8:103::1/64 $llv1 "veth0" 571*4882a593Smuzhiyun 572*4882a593Smuzhiyun # fails because LL address requires a device 573*4882a593Smuzhiyun add_rt "Gateway is linklocal address, no device" 2 \ 574*4882a593Smuzhiyun - 2001:db8:104::1/64 $llv1 575*4882a593Smuzhiyun 576*4882a593Smuzhiyun # local address can not be a gateway 577*4882a593Smuzhiyun add_rt "Gateway can not be local unicast address" 2 \ 578*4882a593Smuzhiyun - 2001:db8:105::/64 2001:db8:1::1 579*4882a593Smuzhiyun add_rt "Gateway can not be local unicast address, with device" 2 \ 580*4882a593Smuzhiyun - 2001:db8:106::/64 2001:db8:1::1 "dummy0" 581*4882a593Smuzhiyun add_rt "Gateway can not be a local linklocal address" 2 \ 582*4882a593Smuzhiyun - 2001:db8:107::1/64 $lldummy "dummy0" 583*4882a593Smuzhiyun 584*4882a593Smuzhiyun # VRF tests 585*4882a593Smuzhiyun add_rt "Gateway can be local address in a VRF" 0 \ 586*4882a593Smuzhiyun - 2001:db8:108::/64 2001:db8:51::2 587*4882a593Smuzhiyun add_rt "Gateway can be local address in a VRF, with device" 0 \ 588*4882a593Smuzhiyun - 2001:db8:109::/64 2001:db8:51::2 "veth0" 589*4882a593Smuzhiyun add_rt "Gateway can be local linklocal address in a VRF" 0 \ 590*4882a593Smuzhiyun - 2001:db8:110::1/64 $llv1 "veth0" 591*4882a593Smuzhiyun 592*4882a593Smuzhiyun add_rt "Redirect to VRF lookup" 0 \ 593*4882a593Smuzhiyun - 2001:db8:111::/64 "" "red" 594*4882a593Smuzhiyun 595*4882a593Smuzhiyun add_rt "VRF route, gateway can be local address in default VRF" 0 \ 596*4882a593Smuzhiyun red 2001:db8:112::/64 2001:db8:51::1 597*4882a593Smuzhiyun 598*4882a593Smuzhiyun # local address in same VRF fails 599*4882a593Smuzhiyun add_rt "VRF route, gateway can not be a local address" 2 \ 600*4882a593Smuzhiyun red 2001:db8:113::1/64 2001:db8:2::1 601*4882a593Smuzhiyun add_rt "VRF route, gateway can not be a local addr with device" 2 \ 602*4882a593Smuzhiyun red 2001:db8:114::1/64 2001:db8:2::1 "dummy1" 603*4882a593Smuzhiyun} 604*4882a593Smuzhiyun 605*4882a593Smuzhiyun# Default VRF: 606*4882a593Smuzhiyun# dummy0 - 198.51.100.1/24 2001:db8:1::1/64 607*4882a593Smuzhiyun# veth0 - 192.0.2.1/24 2001:db8:51::1/64 608*4882a593Smuzhiyun# 609*4882a593Smuzhiyun# VRF red: 610*4882a593Smuzhiyun# dummy1 - 192.168.2.1/24 2001:db8:2::1/64 611*4882a593Smuzhiyun# veth1 - 192.0.2.2/24 2001:db8:51::2/64 612*4882a593Smuzhiyun# 613*4882a593Smuzhiyun# [ dummy0 veth0 ]--[ veth1 dummy1 ] 614*4882a593Smuzhiyun 615*4882a593Smuzhiyunfib_nexthop_test() 616*4882a593Smuzhiyun{ 617*4882a593Smuzhiyun setup 618*4882a593Smuzhiyun 619*4882a593Smuzhiyun set -e 620*4882a593Smuzhiyun 621*4882a593Smuzhiyun $IP -4 rule add pref 32765 table local 622*4882a593Smuzhiyun $IP -4 rule del pref 0 623*4882a593Smuzhiyun $IP -6 rule add pref 32765 table local 624*4882a593Smuzhiyun $IP -6 rule del pref 0 625*4882a593Smuzhiyun 626*4882a593Smuzhiyun $IP link add red type vrf table 1 627*4882a593Smuzhiyun $IP link set red up 628*4882a593Smuzhiyun $IP -4 route add vrf red unreachable default metric 4278198272 629*4882a593Smuzhiyun $IP -6 route add vrf red unreachable default metric 4278198272 630*4882a593Smuzhiyun 631*4882a593Smuzhiyun $IP link add veth0 type veth peer name veth1 632*4882a593Smuzhiyun $IP link set dev veth0 up 633*4882a593Smuzhiyun $IP address add 192.0.2.1/24 dev veth0 634*4882a593Smuzhiyun $IP -6 address add 2001:db8:51::1/64 dev veth0 635*4882a593Smuzhiyun 636*4882a593Smuzhiyun $IP link set dev veth1 vrf red up 637*4882a593Smuzhiyun $IP address add 192.0.2.2/24 dev veth1 638*4882a593Smuzhiyun $IP -6 address add 2001:db8:51::2/64 dev veth1 639*4882a593Smuzhiyun 640*4882a593Smuzhiyun $IP link add dummy1 type dummy 641*4882a593Smuzhiyun $IP link set dev dummy1 vrf red up 642*4882a593Smuzhiyun $IP address add 192.168.2.1/24 dev dummy1 643*4882a593Smuzhiyun $IP -6 address add 2001:db8:2::1/64 dev dummy1 644*4882a593Smuzhiyun set +e 645*4882a593Smuzhiyun 646*4882a593Smuzhiyun sleep 1 647*4882a593Smuzhiyun fib4_nexthop 648*4882a593Smuzhiyun fib6_nexthop 649*4882a593Smuzhiyun 650*4882a593Smuzhiyun ( 651*4882a593Smuzhiyun $IP link del dev dummy1 652*4882a593Smuzhiyun $IP link del veth0 653*4882a593Smuzhiyun $IP link del red 654*4882a593Smuzhiyun ) 2>/dev/null 655*4882a593Smuzhiyun cleanup 656*4882a593Smuzhiyun} 657*4882a593Smuzhiyun 658*4882a593Smuzhiyunfib_suppress_test() 659*4882a593Smuzhiyun{ 660*4882a593Smuzhiyun echo 661*4882a593Smuzhiyun echo "FIB rule with suppress_prefixlength" 662*4882a593Smuzhiyun setup 663*4882a593Smuzhiyun 664*4882a593Smuzhiyun $IP link add dummy1 type dummy 665*4882a593Smuzhiyun $IP link set dummy1 up 666*4882a593Smuzhiyun $IP -6 route add default dev dummy1 667*4882a593Smuzhiyun $IP -6 rule add table main suppress_prefixlength 0 668*4882a593Smuzhiyun ping -f -c 1000 -W 1 1234::1 >/dev/null 2>&1 669*4882a593Smuzhiyun $IP -6 rule del table main suppress_prefixlength 0 670*4882a593Smuzhiyun $IP link del dummy1 671*4882a593Smuzhiyun 672*4882a593Smuzhiyun # If we got here without crashing, we're good. 673*4882a593Smuzhiyun log_test 0 0 "FIB rule suppress test" 674*4882a593Smuzhiyun 675*4882a593Smuzhiyun cleanup 676*4882a593Smuzhiyun} 677*4882a593Smuzhiyun 678*4882a593Smuzhiyun################################################################################ 679*4882a593Smuzhiyun# Tests on route add and replace 680*4882a593Smuzhiyun 681*4882a593Smuzhiyunrun_cmd() 682*4882a593Smuzhiyun{ 683*4882a593Smuzhiyun local cmd="$1" 684*4882a593Smuzhiyun local out 685*4882a593Smuzhiyun local stderr="2>/dev/null" 686*4882a593Smuzhiyun 687*4882a593Smuzhiyun if [ "$VERBOSE" = "1" ]; then 688*4882a593Smuzhiyun printf " COMMAND: $cmd\n" 689*4882a593Smuzhiyun stderr= 690*4882a593Smuzhiyun fi 691*4882a593Smuzhiyun 692*4882a593Smuzhiyun out=$(eval $cmd $stderr) 693*4882a593Smuzhiyun rc=$? 694*4882a593Smuzhiyun if [ "$VERBOSE" = "1" -a -n "$out" ]; then 695*4882a593Smuzhiyun echo " $out" 696*4882a593Smuzhiyun fi 697*4882a593Smuzhiyun 698*4882a593Smuzhiyun [ "$VERBOSE" = "1" ] && echo 699*4882a593Smuzhiyun 700*4882a593Smuzhiyun return $rc 701*4882a593Smuzhiyun} 702*4882a593Smuzhiyun 703*4882a593Smuzhiyuncheck_expected() 704*4882a593Smuzhiyun{ 705*4882a593Smuzhiyun local out="$1" 706*4882a593Smuzhiyun local expected="$2" 707*4882a593Smuzhiyun local rc=0 708*4882a593Smuzhiyun 709*4882a593Smuzhiyun [ "${out}" = "${expected}" ] && return 0 710*4882a593Smuzhiyun 711*4882a593Smuzhiyun if [ -z "${out}" ]; then 712*4882a593Smuzhiyun if [ "$VERBOSE" = "1" ]; then 713*4882a593Smuzhiyun printf "\nNo route entry found\n" 714*4882a593Smuzhiyun printf "Expected:\n" 715*4882a593Smuzhiyun printf " ${expected}\n" 716*4882a593Smuzhiyun fi 717*4882a593Smuzhiyun return 1 718*4882a593Smuzhiyun fi 719*4882a593Smuzhiyun 720*4882a593Smuzhiyun # tricky way to convert output to 1-line without ip's 721*4882a593Smuzhiyun # messy '\'; this drops all extra white space 722*4882a593Smuzhiyun out=$(echo ${out}) 723*4882a593Smuzhiyun if [ "${out}" != "${expected}" ]; then 724*4882a593Smuzhiyun rc=1 725*4882a593Smuzhiyun if [ "${VERBOSE}" = "1" ]; then 726*4882a593Smuzhiyun printf " Unexpected route entry. Have:\n" 727*4882a593Smuzhiyun printf " ${out}\n" 728*4882a593Smuzhiyun printf " Expected:\n" 729*4882a593Smuzhiyun printf " ${expected}\n\n" 730*4882a593Smuzhiyun fi 731*4882a593Smuzhiyun fi 732*4882a593Smuzhiyun 733*4882a593Smuzhiyun return $rc 734*4882a593Smuzhiyun} 735*4882a593Smuzhiyun 736*4882a593Smuzhiyun# add route for a prefix, flushing any existing routes first 737*4882a593Smuzhiyun# expected to be the first step of a test 738*4882a593Smuzhiyunadd_route6() 739*4882a593Smuzhiyun{ 740*4882a593Smuzhiyun local pfx="$1" 741*4882a593Smuzhiyun local nh="$2" 742*4882a593Smuzhiyun local out 743*4882a593Smuzhiyun 744*4882a593Smuzhiyun if [ "$VERBOSE" = "1" ]; then 745*4882a593Smuzhiyun echo 746*4882a593Smuzhiyun echo " ##################################################" 747*4882a593Smuzhiyun echo 748*4882a593Smuzhiyun fi 749*4882a593Smuzhiyun 750*4882a593Smuzhiyun run_cmd "$IP -6 ro flush ${pfx}" 751*4882a593Smuzhiyun [ $? -ne 0 ] && exit 1 752*4882a593Smuzhiyun 753*4882a593Smuzhiyun out=$($IP -6 ro ls match ${pfx}) 754*4882a593Smuzhiyun if [ -n "$out" ]; then 755*4882a593Smuzhiyun echo "Failed to flush routes for prefix used for tests." 756*4882a593Smuzhiyun exit 1 757*4882a593Smuzhiyun fi 758*4882a593Smuzhiyun 759*4882a593Smuzhiyun run_cmd "$IP -6 ro add ${pfx} ${nh}" 760*4882a593Smuzhiyun if [ $? -ne 0 ]; then 761*4882a593Smuzhiyun echo "Failed to add initial route for test." 762*4882a593Smuzhiyun exit 1 763*4882a593Smuzhiyun fi 764*4882a593Smuzhiyun} 765*4882a593Smuzhiyun 766*4882a593Smuzhiyun# add initial route - used in replace route tests 767*4882a593Smuzhiyunadd_initial_route6() 768*4882a593Smuzhiyun{ 769*4882a593Smuzhiyun add_route6 "2001:db8:104::/64" "$1" 770*4882a593Smuzhiyun} 771*4882a593Smuzhiyun 772*4882a593Smuzhiyuncheck_route6() 773*4882a593Smuzhiyun{ 774*4882a593Smuzhiyun local pfx 775*4882a593Smuzhiyun local expected="$1" 776*4882a593Smuzhiyun local out 777*4882a593Smuzhiyun local rc=0 778*4882a593Smuzhiyun 779*4882a593Smuzhiyun set -- $expected 780*4882a593Smuzhiyun pfx=$1 781*4882a593Smuzhiyun 782*4882a593Smuzhiyun out=$($IP -6 ro ls match ${pfx} | sed -e 's/ pref medium//') 783*4882a593Smuzhiyun check_expected "${out}" "${expected}" 784*4882a593Smuzhiyun} 785*4882a593Smuzhiyun 786*4882a593Smuzhiyunroute_cleanup() 787*4882a593Smuzhiyun{ 788*4882a593Smuzhiyun $IP li del red 2>/dev/null 789*4882a593Smuzhiyun $IP li del dummy1 2>/dev/null 790*4882a593Smuzhiyun $IP li del veth1 2>/dev/null 791*4882a593Smuzhiyun $IP li del veth3 2>/dev/null 792*4882a593Smuzhiyun 793*4882a593Smuzhiyun cleanup &> /dev/null 794*4882a593Smuzhiyun} 795*4882a593Smuzhiyun 796*4882a593Smuzhiyunroute_setup() 797*4882a593Smuzhiyun{ 798*4882a593Smuzhiyun route_cleanup 799*4882a593Smuzhiyun setup 800*4882a593Smuzhiyun 801*4882a593Smuzhiyun [ "${VERBOSE}" = "1" ] && set -x 802*4882a593Smuzhiyun set -e 803*4882a593Smuzhiyun 804*4882a593Smuzhiyun ip netns add ns2 805*4882a593Smuzhiyun ip netns set ns2 auto 806*4882a593Smuzhiyun ip -netns ns2 link set dev lo up 807*4882a593Smuzhiyun ip netns exec ns2 sysctl -qw net.ipv4.ip_forward=1 808*4882a593Smuzhiyun ip netns exec ns2 sysctl -qw net.ipv6.conf.all.forwarding=1 809*4882a593Smuzhiyun 810*4882a593Smuzhiyun $IP li add veth1 type veth peer name veth2 811*4882a593Smuzhiyun $IP li add veth3 type veth peer name veth4 812*4882a593Smuzhiyun 813*4882a593Smuzhiyun $IP li set veth1 up 814*4882a593Smuzhiyun $IP li set veth3 up 815*4882a593Smuzhiyun $IP li set veth2 netns ns2 up 816*4882a593Smuzhiyun $IP li set veth4 netns ns2 up 817*4882a593Smuzhiyun ip -netns ns2 li add dummy1 type dummy 818*4882a593Smuzhiyun ip -netns ns2 li set dummy1 up 819*4882a593Smuzhiyun 820*4882a593Smuzhiyun $IP -6 addr add 2001:db8:101::1/64 dev veth1 nodad 821*4882a593Smuzhiyun $IP -6 addr add 2001:db8:103::1/64 dev veth3 nodad 822*4882a593Smuzhiyun $IP addr add 172.16.101.1/24 dev veth1 823*4882a593Smuzhiyun $IP addr add 172.16.103.1/24 dev veth3 824*4882a593Smuzhiyun 825*4882a593Smuzhiyun ip -netns ns2 -6 addr add 2001:db8:101::2/64 dev veth2 nodad 826*4882a593Smuzhiyun ip -netns ns2 -6 addr add 2001:db8:103::2/64 dev veth4 nodad 827*4882a593Smuzhiyun ip -netns ns2 -6 addr add 2001:db8:104::1/64 dev dummy1 nodad 828*4882a593Smuzhiyun 829*4882a593Smuzhiyun ip -netns ns2 addr add 172.16.101.2/24 dev veth2 830*4882a593Smuzhiyun ip -netns ns2 addr add 172.16.103.2/24 dev veth4 831*4882a593Smuzhiyun ip -netns ns2 addr add 172.16.104.1/24 dev dummy1 832*4882a593Smuzhiyun 833*4882a593Smuzhiyun set +e 834*4882a593Smuzhiyun} 835*4882a593Smuzhiyun 836*4882a593Smuzhiyun# assumption is that basic add of a single path route works 837*4882a593Smuzhiyun# otherwise just adding an address on an interface is broken 838*4882a593Smuzhiyunipv6_rt_add() 839*4882a593Smuzhiyun{ 840*4882a593Smuzhiyun local rc 841*4882a593Smuzhiyun 842*4882a593Smuzhiyun echo 843*4882a593Smuzhiyun echo "IPv6 route add / append tests" 844*4882a593Smuzhiyun 845*4882a593Smuzhiyun # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 846*4882a593Smuzhiyun add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 847*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2" 848*4882a593Smuzhiyun log_test $? 2 "Attempt to add duplicate route - gw" 849*4882a593Smuzhiyun 850*4882a593Smuzhiyun # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 851*4882a593Smuzhiyun add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 852*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:104::/64 dev veth3" 853*4882a593Smuzhiyun log_test $? 2 "Attempt to add duplicate route - dev only" 854*4882a593Smuzhiyun 855*4882a593Smuzhiyun # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 856*4882a593Smuzhiyun add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 857*4882a593Smuzhiyun run_cmd "$IP -6 ro add unreachable 2001:db8:104::/64" 858*4882a593Smuzhiyun log_test $? 2 "Attempt to add duplicate route - reject route" 859*4882a593Smuzhiyun 860*4882a593Smuzhiyun # route append with same prefix adds a new route 861*4882a593Smuzhiyun # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 862*4882a593Smuzhiyun add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 863*4882a593Smuzhiyun run_cmd "$IP -6 ro append 2001:db8:104::/64 via 2001:db8:103::2" 864*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1" 865*4882a593Smuzhiyun log_test $? 0 "Append nexthop to existing route - gw" 866*4882a593Smuzhiyun 867*4882a593Smuzhiyun # insert mpath directly 868*4882a593Smuzhiyun add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 869*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1" 870*4882a593Smuzhiyun log_test $? 0 "Add multipath route" 871*4882a593Smuzhiyun 872*4882a593Smuzhiyun add_route6 "2001:db8:104::/64" "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 873*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:104::/64 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 874*4882a593Smuzhiyun log_test $? 2 "Attempt to add duplicate multipath route" 875*4882a593Smuzhiyun 876*4882a593Smuzhiyun # insert of a second route without append but different metric 877*4882a593Smuzhiyun add_route6 "2001:db8:104::/64" "via 2001:db8:101::2" 878*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::2 metric 512" 879*4882a593Smuzhiyun rc=$? 880*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 881*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:104::/64 via 2001:db8:103::3 metric 256" 882*4882a593Smuzhiyun rc=$? 883*4882a593Smuzhiyun fi 884*4882a593Smuzhiyun log_test $rc 0 "Route add with different metrics" 885*4882a593Smuzhiyun 886*4882a593Smuzhiyun run_cmd "$IP -6 ro del 2001:db8:104::/64 metric 512" 887*4882a593Smuzhiyun rc=$? 888*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 889*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 via 2001:db8:103::3 dev veth3 metric 256 2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024" 890*4882a593Smuzhiyun rc=$? 891*4882a593Smuzhiyun fi 892*4882a593Smuzhiyun log_test $rc 0 "Route delete with metric" 893*4882a593Smuzhiyun} 894*4882a593Smuzhiyun 895*4882a593Smuzhiyunipv6_rt_replace_single() 896*4882a593Smuzhiyun{ 897*4882a593Smuzhiyun # single path with single path 898*4882a593Smuzhiyun # 899*4882a593Smuzhiyun add_initial_route6 "via 2001:db8:101::2" 900*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:103::2" 901*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 902*4882a593Smuzhiyun log_test $? 0 "Single path with single path" 903*4882a593Smuzhiyun 904*4882a593Smuzhiyun # single path with multipath 905*4882a593Smuzhiyun # 906*4882a593Smuzhiyun add_initial_route6 "nexthop via 2001:db8:101::2" 907*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::2" 908*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1" 909*4882a593Smuzhiyun log_test $? 0 "Single path with multipath" 910*4882a593Smuzhiyun 911*4882a593Smuzhiyun # single path with single path using MULTIPATH attribute 912*4882a593Smuzhiyun # 913*4882a593Smuzhiyun add_initial_route6 "via 2001:db8:101::2" 914*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:103::2" 915*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 via 2001:db8:103::2 dev veth3 metric 1024" 916*4882a593Smuzhiyun log_test $? 0 "Single path with single path via multipath attribute" 917*4882a593Smuzhiyun 918*4882a593Smuzhiyun # route replace fails - invalid nexthop 919*4882a593Smuzhiyun add_initial_route6 "via 2001:db8:101::2" 920*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:104::2" 921*4882a593Smuzhiyun if [ $? -eq 0 ]; then 922*4882a593Smuzhiyun # previous command is expected to fail so if it returns 0 923*4882a593Smuzhiyun # that means the test failed. 924*4882a593Smuzhiyun log_test 0 1 "Invalid nexthop" 925*4882a593Smuzhiyun else 926*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 via 2001:db8:101::2 dev veth1 metric 1024" 927*4882a593Smuzhiyun log_test $? 0 "Invalid nexthop" 928*4882a593Smuzhiyun fi 929*4882a593Smuzhiyun 930*4882a593Smuzhiyun # replace non-existent route 931*4882a593Smuzhiyun # - note use of change versus replace since ip adds NLM_F_CREATE 932*4882a593Smuzhiyun # for replace 933*4882a593Smuzhiyun add_initial_route6 "via 2001:db8:101::2" 934*4882a593Smuzhiyun run_cmd "$IP -6 ro change 2001:db8:105::/64 via 2001:db8:101::2" 935*4882a593Smuzhiyun log_test $? 2 "Single path - replace of non-existent route" 936*4882a593Smuzhiyun} 937*4882a593Smuzhiyun 938*4882a593Smuzhiyunipv6_rt_replace_mpath() 939*4882a593Smuzhiyun{ 940*4882a593Smuzhiyun # multipath with multipath 941*4882a593Smuzhiyun add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 942*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 943*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::3 dev veth1 weight 1 nexthop via 2001:db8:103::3 dev veth3 weight 1" 944*4882a593Smuzhiyun log_test $? 0 "Multipath with multipath" 945*4882a593Smuzhiyun 946*4882a593Smuzhiyun # multipath with single 947*4882a593Smuzhiyun add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 948*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 via 2001:db8:101::3" 949*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 950*4882a593Smuzhiyun log_test $? 0 "Multipath with single path" 951*4882a593Smuzhiyun 952*4882a593Smuzhiyun # multipath with single 953*4882a593Smuzhiyun add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 954*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3" 955*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 via 2001:db8:101::3 dev veth1 metric 1024" 956*4882a593Smuzhiyun log_test $? 0 "Multipath with single path via multipath attribute" 957*4882a593Smuzhiyun 958*4882a593Smuzhiyun # multipath with dev-only 959*4882a593Smuzhiyun add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 960*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 dev veth1" 961*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 dev veth1 metric 1024" 962*4882a593Smuzhiyun log_test $? 0 "Multipath with dev-only" 963*4882a593Smuzhiyun 964*4882a593Smuzhiyun # route replace fails - invalid nexthop 1 965*4882a593Smuzhiyun add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 966*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:111::3 nexthop via 2001:db8:103::3" 967*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1" 968*4882a593Smuzhiyun log_test $? 0 "Multipath - invalid first nexthop" 969*4882a593Smuzhiyun 970*4882a593Smuzhiyun # route replace fails - invalid nexthop 2 971*4882a593Smuzhiyun add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 972*4882a593Smuzhiyun run_cmd "$IP -6 ro replace 2001:db8:104::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:113::3" 973*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1" 974*4882a593Smuzhiyun log_test $? 0 "Multipath - invalid second nexthop" 975*4882a593Smuzhiyun 976*4882a593Smuzhiyun # multipath non-existent route 977*4882a593Smuzhiyun add_initial_route6 "nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 978*4882a593Smuzhiyun run_cmd "$IP -6 ro change 2001:db8:105::/64 nexthop via 2001:db8:101::3 nexthop via 2001:db8:103::3" 979*4882a593Smuzhiyun log_test $? 2 "Multipath - replace of non-existent route" 980*4882a593Smuzhiyun} 981*4882a593Smuzhiyun 982*4882a593Smuzhiyunipv6_rt_replace() 983*4882a593Smuzhiyun{ 984*4882a593Smuzhiyun echo 985*4882a593Smuzhiyun echo "IPv6 route replace tests" 986*4882a593Smuzhiyun 987*4882a593Smuzhiyun ipv6_rt_replace_single 988*4882a593Smuzhiyun ipv6_rt_replace_mpath 989*4882a593Smuzhiyun} 990*4882a593Smuzhiyun 991*4882a593Smuzhiyunipv6_route_test() 992*4882a593Smuzhiyun{ 993*4882a593Smuzhiyun route_setup 994*4882a593Smuzhiyun 995*4882a593Smuzhiyun ipv6_rt_add 996*4882a593Smuzhiyun ipv6_rt_replace 997*4882a593Smuzhiyun 998*4882a593Smuzhiyun route_cleanup 999*4882a593Smuzhiyun} 1000*4882a593Smuzhiyun 1001*4882a593Smuzhiyunip_addr_metric_check() 1002*4882a593Smuzhiyun{ 1003*4882a593Smuzhiyun ip addr help 2>&1 | grep -q metric 1004*4882a593Smuzhiyun if [ $? -ne 0 ]; then 1005*4882a593Smuzhiyun echo "iproute2 command does not support metric for addresses. Skipping test" 1006*4882a593Smuzhiyun return 1 1007*4882a593Smuzhiyun fi 1008*4882a593Smuzhiyun 1009*4882a593Smuzhiyun return 0 1010*4882a593Smuzhiyun} 1011*4882a593Smuzhiyun 1012*4882a593Smuzhiyunipv6_addr_metric_test() 1013*4882a593Smuzhiyun{ 1014*4882a593Smuzhiyun local rc 1015*4882a593Smuzhiyun 1016*4882a593Smuzhiyun echo 1017*4882a593Smuzhiyun echo "IPv6 prefix route tests" 1018*4882a593Smuzhiyun 1019*4882a593Smuzhiyun ip_addr_metric_check || return 1 1020*4882a593Smuzhiyun 1021*4882a593Smuzhiyun setup 1022*4882a593Smuzhiyun 1023*4882a593Smuzhiyun set -e 1024*4882a593Smuzhiyun $IP li add dummy1 type dummy 1025*4882a593Smuzhiyun $IP li add dummy2 type dummy 1026*4882a593Smuzhiyun $IP li set dummy1 up 1027*4882a593Smuzhiyun $IP li set dummy2 up 1028*4882a593Smuzhiyun 1029*4882a593Smuzhiyun # default entry is metric 256 1030*4882a593Smuzhiyun run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64" 1031*4882a593Smuzhiyun run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64" 1032*4882a593Smuzhiyun set +e 1033*4882a593Smuzhiyun 1034*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 256 2001:db8:104::/64 dev dummy2 proto kernel metric 256" 1035*4882a593Smuzhiyun log_test $? 0 "Default metric" 1036*4882a593Smuzhiyun 1037*4882a593Smuzhiyun set -e 1038*4882a593Smuzhiyun run_cmd "$IP -6 addr flush dev dummy1" 1039*4882a593Smuzhiyun run_cmd "$IP -6 addr add dev dummy1 2001:db8:104::1/64 metric 257" 1040*4882a593Smuzhiyun set +e 1041*4882a593Smuzhiyun 1042*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 256 2001:db8:104::/64 dev dummy1 proto kernel metric 257" 1043*4882a593Smuzhiyun log_test $? 0 "User specified metric on first device" 1044*4882a593Smuzhiyun 1045*4882a593Smuzhiyun set -e 1046*4882a593Smuzhiyun run_cmd "$IP -6 addr flush dev dummy2" 1047*4882a593Smuzhiyun run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::2/64 metric 258" 1048*4882a593Smuzhiyun set +e 1049*4882a593Smuzhiyun 1050*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 dev dummy1 proto kernel metric 257 2001:db8:104::/64 dev dummy2 proto kernel metric 258" 1051*4882a593Smuzhiyun log_test $? 0 "User specified metric on second device" 1052*4882a593Smuzhiyun 1053*4882a593Smuzhiyun run_cmd "$IP -6 addr del dev dummy1 2001:db8:104::1/64 metric 257" 1054*4882a593Smuzhiyun rc=$? 1055*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1056*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 258" 1057*4882a593Smuzhiyun rc=$? 1058*4882a593Smuzhiyun fi 1059*4882a593Smuzhiyun log_test $rc 0 "Delete of address on first device" 1060*4882a593Smuzhiyun 1061*4882a593Smuzhiyun run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::2/64 metric 259" 1062*4882a593Smuzhiyun rc=$? 1063*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1064*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 1065*4882a593Smuzhiyun rc=$? 1066*4882a593Smuzhiyun fi 1067*4882a593Smuzhiyun log_test $rc 0 "Modify metric of address" 1068*4882a593Smuzhiyun 1069*4882a593Smuzhiyun # verify prefix route removed on down 1070*4882a593Smuzhiyun run_cmd "ip netns exec ns1 sysctl -qw net.ipv6.conf.all.keep_addr_on_down=1" 1071*4882a593Smuzhiyun run_cmd "$IP li set dev dummy2 down" 1072*4882a593Smuzhiyun rc=$? 1073*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1074*4882a593Smuzhiyun out=$($IP -6 ro ls match 2001:db8:104::/64) 1075*4882a593Smuzhiyun check_expected "${out}" "" 1076*4882a593Smuzhiyun rc=$? 1077*4882a593Smuzhiyun fi 1078*4882a593Smuzhiyun log_test $rc 0 "Prefix route removed on link down" 1079*4882a593Smuzhiyun 1080*4882a593Smuzhiyun # verify prefix route re-inserted with assigned metric 1081*4882a593Smuzhiyun run_cmd "$IP li set dev dummy2 up" 1082*4882a593Smuzhiyun rc=$? 1083*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1084*4882a593Smuzhiyun check_route6 "2001:db8:104::/64 dev dummy2 proto kernel metric 259" 1085*4882a593Smuzhiyun rc=$? 1086*4882a593Smuzhiyun fi 1087*4882a593Smuzhiyun log_test $rc 0 "Prefix route with metric on link up" 1088*4882a593Smuzhiyun 1089*4882a593Smuzhiyun # verify peer metric added correctly 1090*4882a593Smuzhiyun set -e 1091*4882a593Smuzhiyun run_cmd "$IP -6 addr flush dev dummy2" 1092*4882a593Smuzhiyun run_cmd "$IP -6 addr add dev dummy2 2001:db8:104::1 peer 2001:db8:104::2 metric 260" 1093*4882a593Smuzhiyun set +e 1094*4882a593Smuzhiyun 1095*4882a593Smuzhiyun check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 260" 1096*4882a593Smuzhiyun log_test $? 0 "Set metric with peer route on local side" 1097*4882a593Smuzhiyun check_route6 "2001:db8:104::2 dev dummy2 proto kernel metric 260" 1098*4882a593Smuzhiyun log_test $? 0 "Set metric with peer route on peer side" 1099*4882a593Smuzhiyun 1100*4882a593Smuzhiyun set -e 1101*4882a593Smuzhiyun run_cmd "$IP -6 addr change dev dummy2 2001:db8:104::1 peer 2001:db8:104::3 metric 261" 1102*4882a593Smuzhiyun set +e 1103*4882a593Smuzhiyun 1104*4882a593Smuzhiyun check_route6 "2001:db8:104::1 dev dummy2 proto kernel metric 261" 1105*4882a593Smuzhiyun log_test $? 0 "Modify metric and peer address on local side" 1106*4882a593Smuzhiyun check_route6 "2001:db8:104::3 dev dummy2 proto kernel metric 261" 1107*4882a593Smuzhiyun log_test $? 0 "Modify metric and peer address on peer side" 1108*4882a593Smuzhiyun 1109*4882a593Smuzhiyun $IP li del dummy1 1110*4882a593Smuzhiyun $IP li del dummy2 1111*4882a593Smuzhiyun cleanup 1112*4882a593Smuzhiyun} 1113*4882a593Smuzhiyun 1114*4882a593Smuzhiyunipv6_route_metrics_test() 1115*4882a593Smuzhiyun{ 1116*4882a593Smuzhiyun local rc 1117*4882a593Smuzhiyun 1118*4882a593Smuzhiyun echo 1119*4882a593Smuzhiyun echo "IPv6 routes with metrics" 1120*4882a593Smuzhiyun 1121*4882a593Smuzhiyun route_setup 1122*4882a593Smuzhiyun 1123*4882a593Smuzhiyun # 1124*4882a593Smuzhiyun # single path with metrics 1125*4882a593Smuzhiyun # 1126*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:111::/64 via 2001:db8:101::2 mtu 1400" 1127*4882a593Smuzhiyun rc=$? 1128*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1129*4882a593Smuzhiyun check_route6 "2001:db8:111::/64 via 2001:db8:101::2 dev veth1 metric 1024 mtu 1400" 1130*4882a593Smuzhiyun rc=$? 1131*4882a593Smuzhiyun fi 1132*4882a593Smuzhiyun log_test $rc 0 "Single path route with mtu metric" 1133*4882a593Smuzhiyun 1134*4882a593Smuzhiyun 1135*4882a593Smuzhiyun # 1136*4882a593Smuzhiyun # multipath via separate routes with metrics 1137*4882a593Smuzhiyun # 1138*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:112::/64 via 2001:db8:101::2 mtu 1400" 1139*4882a593Smuzhiyun run_cmd "$IP -6 ro append 2001:db8:112::/64 via 2001:db8:103::2" 1140*4882a593Smuzhiyun rc=$? 1141*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1142*4882a593Smuzhiyun check_route6 "2001:db8:112::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1" 1143*4882a593Smuzhiyun rc=$? 1144*4882a593Smuzhiyun fi 1145*4882a593Smuzhiyun log_test $rc 0 "Multipath route via 2 single routes with mtu metric on first" 1146*4882a593Smuzhiyun 1147*4882a593Smuzhiyun # second route is coalesced to first to make a multipath route. 1148*4882a593Smuzhiyun # MTU of the second path is hidden from display! 1149*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:113::/64 via 2001:db8:101::2" 1150*4882a593Smuzhiyun run_cmd "$IP -6 ro append 2001:db8:113::/64 via 2001:db8:103::2 mtu 1400" 1151*4882a593Smuzhiyun rc=$? 1152*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1153*4882a593Smuzhiyun check_route6 "2001:db8:113::/64 metric 1024 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1" 1154*4882a593Smuzhiyun rc=$? 1155*4882a593Smuzhiyun fi 1156*4882a593Smuzhiyun log_test $rc 0 "Multipath route via 2 single routes with mtu metric on 2nd" 1157*4882a593Smuzhiyun 1158*4882a593Smuzhiyun run_cmd "$IP -6 ro del 2001:db8:113::/64 via 2001:db8:101::2" 1159*4882a593Smuzhiyun if [ $? -eq 0 ]; then 1160*4882a593Smuzhiyun check_route6 "2001:db8:113::/64 via 2001:db8:103::2 dev veth3 metric 1024 mtu 1400" 1161*4882a593Smuzhiyun log_test $? 0 " MTU of second leg" 1162*4882a593Smuzhiyun fi 1163*4882a593Smuzhiyun 1164*4882a593Smuzhiyun # 1165*4882a593Smuzhiyun # multipath with metrics 1166*4882a593Smuzhiyun # 1167*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:115::/64 mtu 1400 nexthop via 2001:db8:101::2 nexthop via 2001:db8:103::2" 1168*4882a593Smuzhiyun rc=$? 1169*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1170*4882a593Smuzhiyun check_route6 "2001:db8:115::/64 metric 1024 mtu 1400 nexthop via 2001:db8:101::2 dev veth1 weight 1 nexthop via 2001:db8:103::2 dev veth3 weight 1" 1171*4882a593Smuzhiyun rc=$? 1172*4882a593Smuzhiyun fi 1173*4882a593Smuzhiyun log_test $rc 0 "Multipath route with mtu metric" 1174*4882a593Smuzhiyun 1175*4882a593Smuzhiyun $IP -6 ro add 2001:db8:104::/64 via 2001:db8:101::2 mtu 1300 1176*4882a593Smuzhiyun run_cmd "ip netns exec ns1 ${ping6} -w1 -c1 -s 1500 2001:db8:104::1" 1177*4882a593Smuzhiyun log_test $? 0 "Using route with mtu metric" 1178*4882a593Smuzhiyun 1179*4882a593Smuzhiyun run_cmd "$IP -6 ro add 2001:db8:114::/64 via 2001:db8:101::2 congctl lock foo" 1180*4882a593Smuzhiyun log_test $? 2 "Invalid metric (fails metric_convert)" 1181*4882a593Smuzhiyun 1182*4882a593Smuzhiyun route_cleanup 1183*4882a593Smuzhiyun} 1184*4882a593Smuzhiyun 1185*4882a593Smuzhiyun# add route for a prefix, flushing any existing routes first 1186*4882a593Smuzhiyun# expected to be the first step of a test 1187*4882a593Smuzhiyunadd_route() 1188*4882a593Smuzhiyun{ 1189*4882a593Smuzhiyun local pfx="$1" 1190*4882a593Smuzhiyun local nh="$2" 1191*4882a593Smuzhiyun local out 1192*4882a593Smuzhiyun 1193*4882a593Smuzhiyun if [ "$VERBOSE" = "1" ]; then 1194*4882a593Smuzhiyun echo 1195*4882a593Smuzhiyun echo " ##################################################" 1196*4882a593Smuzhiyun echo 1197*4882a593Smuzhiyun fi 1198*4882a593Smuzhiyun 1199*4882a593Smuzhiyun run_cmd "$IP ro flush ${pfx}" 1200*4882a593Smuzhiyun [ $? -ne 0 ] && exit 1 1201*4882a593Smuzhiyun 1202*4882a593Smuzhiyun out=$($IP ro ls match ${pfx}) 1203*4882a593Smuzhiyun if [ -n "$out" ]; then 1204*4882a593Smuzhiyun echo "Failed to flush routes for prefix used for tests." 1205*4882a593Smuzhiyun exit 1 1206*4882a593Smuzhiyun fi 1207*4882a593Smuzhiyun 1208*4882a593Smuzhiyun run_cmd "$IP ro add ${pfx} ${nh}" 1209*4882a593Smuzhiyun if [ $? -ne 0 ]; then 1210*4882a593Smuzhiyun echo "Failed to add initial route for test." 1211*4882a593Smuzhiyun exit 1 1212*4882a593Smuzhiyun fi 1213*4882a593Smuzhiyun} 1214*4882a593Smuzhiyun 1215*4882a593Smuzhiyun# add initial route - used in replace route tests 1216*4882a593Smuzhiyunadd_initial_route() 1217*4882a593Smuzhiyun{ 1218*4882a593Smuzhiyun add_route "172.16.104.0/24" "$1" 1219*4882a593Smuzhiyun} 1220*4882a593Smuzhiyun 1221*4882a593Smuzhiyuncheck_route() 1222*4882a593Smuzhiyun{ 1223*4882a593Smuzhiyun local pfx 1224*4882a593Smuzhiyun local expected="$1" 1225*4882a593Smuzhiyun local out 1226*4882a593Smuzhiyun 1227*4882a593Smuzhiyun set -- $expected 1228*4882a593Smuzhiyun pfx=$1 1229*4882a593Smuzhiyun [ "${pfx}" = "unreachable" ] && pfx=$2 1230*4882a593Smuzhiyun 1231*4882a593Smuzhiyun out=$($IP ro ls match ${pfx}) 1232*4882a593Smuzhiyun check_expected "${out}" "${expected}" 1233*4882a593Smuzhiyun} 1234*4882a593Smuzhiyun 1235*4882a593Smuzhiyun# assumption is that basic add of a single path route works 1236*4882a593Smuzhiyun# otherwise just adding an address on an interface is broken 1237*4882a593Smuzhiyunipv4_rt_add() 1238*4882a593Smuzhiyun{ 1239*4882a593Smuzhiyun local rc 1240*4882a593Smuzhiyun 1241*4882a593Smuzhiyun echo 1242*4882a593Smuzhiyun echo "IPv4 route add / append tests" 1243*4882a593Smuzhiyun 1244*4882a593Smuzhiyun # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1245*4882a593Smuzhiyun add_route "172.16.104.0/24" "via 172.16.101.2" 1246*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2" 1247*4882a593Smuzhiyun log_test $? 2 "Attempt to add duplicate route - gw" 1248*4882a593Smuzhiyun 1249*4882a593Smuzhiyun # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1250*4882a593Smuzhiyun add_route "172.16.104.0/24" "via 172.16.101.2" 1251*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.104.0/24 dev veth3" 1252*4882a593Smuzhiyun log_test $? 2 "Attempt to add duplicate route - dev only" 1253*4882a593Smuzhiyun 1254*4882a593Smuzhiyun # route add same prefix - fails with EEXISTS b/c ip adds NLM_F_EXCL 1255*4882a593Smuzhiyun add_route "172.16.104.0/24" "via 172.16.101.2" 1256*4882a593Smuzhiyun run_cmd "$IP ro add unreachable 172.16.104.0/24" 1257*4882a593Smuzhiyun log_test $? 2 "Attempt to add duplicate route - reject route" 1258*4882a593Smuzhiyun 1259*4882a593Smuzhiyun # iproute2 prepend only sets NLM_F_CREATE 1260*4882a593Smuzhiyun # - adds a new route; does NOT convert existing route to ECMP 1261*4882a593Smuzhiyun add_route "172.16.104.0/24" "via 172.16.101.2" 1262*4882a593Smuzhiyun run_cmd "$IP ro prepend 172.16.104.0/24 via 172.16.103.2" 1263*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.103.2 dev veth3 172.16.104.0/24 via 172.16.101.2 dev veth1" 1264*4882a593Smuzhiyun log_test $? 0 "Add new nexthop for existing prefix" 1265*4882a593Smuzhiyun 1266*4882a593Smuzhiyun # route append with same prefix adds a new route 1267*4882a593Smuzhiyun # - iproute2 sets NLM_F_CREATE | NLM_F_APPEND 1268*4882a593Smuzhiyun add_route "172.16.104.0/24" "via 172.16.101.2" 1269*4882a593Smuzhiyun run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1270*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.2 dev veth3" 1271*4882a593Smuzhiyun log_test $? 0 "Append nexthop to existing route - gw" 1272*4882a593Smuzhiyun 1273*4882a593Smuzhiyun add_route "172.16.104.0/24" "via 172.16.101.2" 1274*4882a593Smuzhiyun run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1275*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 dev veth3 scope link" 1276*4882a593Smuzhiyun log_test $? 0 "Append nexthop to existing route - dev only" 1277*4882a593Smuzhiyun 1278*4882a593Smuzhiyun add_route "172.16.104.0/24" "via 172.16.101.2" 1279*4882a593Smuzhiyun run_cmd "$IP ro append unreachable 172.16.104.0/24" 1280*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 unreachable 172.16.104.0/24" 1281*4882a593Smuzhiyun log_test $? 0 "Append nexthop to existing route - reject route" 1282*4882a593Smuzhiyun 1283*4882a593Smuzhiyun run_cmd "$IP ro flush 172.16.104.0/24" 1284*4882a593Smuzhiyun run_cmd "$IP ro add unreachable 172.16.104.0/24" 1285*4882a593Smuzhiyun run_cmd "$IP ro append 172.16.104.0/24 via 172.16.103.2" 1286*4882a593Smuzhiyun check_route "unreachable 172.16.104.0/24 172.16.104.0/24 via 172.16.103.2 dev veth3" 1287*4882a593Smuzhiyun log_test $? 0 "Append nexthop to existing reject route - gw" 1288*4882a593Smuzhiyun 1289*4882a593Smuzhiyun run_cmd "$IP ro flush 172.16.104.0/24" 1290*4882a593Smuzhiyun run_cmd "$IP ro add unreachable 172.16.104.0/24" 1291*4882a593Smuzhiyun run_cmd "$IP ro append 172.16.104.0/24 dev veth3" 1292*4882a593Smuzhiyun check_route "unreachable 172.16.104.0/24 172.16.104.0/24 dev veth3 scope link" 1293*4882a593Smuzhiyun log_test $? 0 "Append nexthop to existing reject route - dev only" 1294*4882a593Smuzhiyun 1295*4882a593Smuzhiyun # insert mpath directly 1296*4882a593Smuzhiyun add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1297*4882a593Smuzhiyun check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1" 1298*4882a593Smuzhiyun log_test $? 0 "add multipath route" 1299*4882a593Smuzhiyun 1300*4882a593Smuzhiyun add_route "172.16.104.0/24" "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1301*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1302*4882a593Smuzhiyun log_test $? 2 "Attempt to add duplicate multipath route" 1303*4882a593Smuzhiyun 1304*4882a593Smuzhiyun # insert of a second route without append but different metric 1305*4882a593Smuzhiyun add_route "172.16.104.0/24" "via 172.16.101.2" 1306*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.2 metric 512" 1307*4882a593Smuzhiyun rc=$? 1308*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1309*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.104.0/24 via 172.16.103.3 metric 256" 1310*4882a593Smuzhiyun rc=$? 1311*4882a593Smuzhiyun fi 1312*4882a593Smuzhiyun log_test $rc 0 "Route add with different metrics" 1313*4882a593Smuzhiyun 1314*4882a593Smuzhiyun run_cmd "$IP ro del 172.16.104.0/24 metric 512" 1315*4882a593Smuzhiyun rc=$? 1316*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1317*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.101.2 dev veth1 172.16.104.0/24 via 172.16.103.3 dev veth3 metric 256" 1318*4882a593Smuzhiyun rc=$? 1319*4882a593Smuzhiyun fi 1320*4882a593Smuzhiyun log_test $rc 0 "Route delete with metric" 1321*4882a593Smuzhiyun} 1322*4882a593Smuzhiyun 1323*4882a593Smuzhiyunipv4_rt_replace_single() 1324*4882a593Smuzhiyun{ 1325*4882a593Smuzhiyun # single path with single path 1326*4882a593Smuzhiyun # 1327*4882a593Smuzhiyun add_initial_route "via 172.16.101.2" 1328*4882a593Smuzhiyun run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.103.2" 1329*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1330*4882a593Smuzhiyun log_test $? 0 "Single path with single path" 1331*4882a593Smuzhiyun 1332*4882a593Smuzhiyun # single path with multipath 1333*4882a593Smuzhiyun # 1334*4882a593Smuzhiyun add_initial_route "nexthop via 172.16.101.2" 1335*4882a593Smuzhiyun run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.2" 1336*4882a593Smuzhiyun check_route "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1" 1337*4882a593Smuzhiyun log_test $? 0 "Single path with multipath" 1338*4882a593Smuzhiyun 1339*4882a593Smuzhiyun # single path with reject 1340*4882a593Smuzhiyun # 1341*4882a593Smuzhiyun add_initial_route "nexthop via 172.16.101.2" 1342*4882a593Smuzhiyun run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1343*4882a593Smuzhiyun check_route "unreachable 172.16.104.0/24" 1344*4882a593Smuzhiyun log_test $? 0 "Single path with reject route" 1345*4882a593Smuzhiyun 1346*4882a593Smuzhiyun # single path with single path using MULTIPATH attribute 1347*4882a593Smuzhiyun # 1348*4882a593Smuzhiyun add_initial_route "via 172.16.101.2" 1349*4882a593Smuzhiyun run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.103.2" 1350*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.103.2 dev veth3" 1351*4882a593Smuzhiyun log_test $? 0 "Single path with single path via multipath attribute" 1352*4882a593Smuzhiyun 1353*4882a593Smuzhiyun # route replace fails - invalid nexthop 1354*4882a593Smuzhiyun add_initial_route "via 172.16.101.2" 1355*4882a593Smuzhiyun run_cmd "$IP ro replace 172.16.104.0/24 via 2001:db8:104::2" 1356*4882a593Smuzhiyun if [ $? -eq 0 ]; then 1357*4882a593Smuzhiyun # previous command is expected to fail so if it returns 0 1358*4882a593Smuzhiyun # that means the test failed. 1359*4882a593Smuzhiyun log_test 0 1 "Invalid nexthop" 1360*4882a593Smuzhiyun else 1361*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.101.2 dev veth1" 1362*4882a593Smuzhiyun log_test $? 0 "Invalid nexthop" 1363*4882a593Smuzhiyun fi 1364*4882a593Smuzhiyun 1365*4882a593Smuzhiyun # replace non-existent route 1366*4882a593Smuzhiyun # - note use of change versus replace since ip adds NLM_F_CREATE 1367*4882a593Smuzhiyun # for replace 1368*4882a593Smuzhiyun add_initial_route "via 172.16.101.2" 1369*4882a593Smuzhiyun run_cmd "$IP ro change 172.16.105.0/24 via 172.16.101.2" 1370*4882a593Smuzhiyun log_test $? 2 "Single path - replace of non-existent route" 1371*4882a593Smuzhiyun} 1372*4882a593Smuzhiyun 1373*4882a593Smuzhiyunipv4_rt_replace_mpath() 1374*4882a593Smuzhiyun{ 1375*4882a593Smuzhiyun # multipath with multipath 1376*4882a593Smuzhiyun add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1377*4882a593Smuzhiyun run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1378*4882a593Smuzhiyun check_route "172.16.104.0/24 nexthop via 172.16.101.3 dev veth1 weight 1 nexthop via 172.16.103.3 dev veth3 weight 1" 1379*4882a593Smuzhiyun log_test $? 0 "Multipath with multipath" 1380*4882a593Smuzhiyun 1381*4882a593Smuzhiyun # multipath with single 1382*4882a593Smuzhiyun add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1383*4882a593Smuzhiyun run_cmd "$IP ro replace 172.16.104.0/24 via 172.16.101.3" 1384*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1385*4882a593Smuzhiyun log_test $? 0 "Multipath with single path" 1386*4882a593Smuzhiyun 1387*4882a593Smuzhiyun # multipath with single 1388*4882a593Smuzhiyun add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1389*4882a593Smuzhiyun run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3" 1390*4882a593Smuzhiyun check_route "172.16.104.0/24 via 172.16.101.3 dev veth1" 1391*4882a593Smuzhiyun log_test $? 0 "Multipath with single path via multipath attribute" 1392*4882a593Smuzhiyun 1393*4882a593Smuzhiyun # multipath with reject 1394*4882a593Smuzhiyun add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1395*4882a593Smuzhiyun run_cmd "$IP ro replace unreachable 172.16.104.0/24" 1396*4882a593Smuzhiyun check_route "unreachable 172.16.104.0/24" 1397*4882a593Smuzhiyun log_test $? 0 "Multipath with reject route" 1398*4882a593Smuzhiyun 1399*4882a593Smuzhiyun # route replace fails - invalid nexthop 1 1400*4882a593Smuzhiyun add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1401*4882a593Smuzhiyun run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.111.3 nexthop via 172.16.103.3" 1402*4882a593Smuzhiyun check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1" 1403*4882a593Smuzhiyun log_test $? 0 "Multipath - invalid first nexthop" 1404*4882a593Smuzhiyun 1405*4882a593Smuzhiyun # route replace fails - invalid nexthop 2 1406*4882a593Smuzhiyun add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1407*4882a593Smuzhiyun run_cmd "$IP ro replace 172.16.104.0/24 nexthop via 172.16.101.3 nexthop via 172.16.113.3" 1408*4882a593Smuzhiyun check_route "172.16.104.0/24 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1" 1409*4882a593Smuzhiyun log_test $? 0 "Multipath - invalid second nexthop" 1410*4882a593Smuzhiyun 1411*4882a593Smuzhiyun # multipath non-existent route 1412*4882a593Smuzhiyun add_initial_route "nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1413*4882a593Smuzhiyun run_cmd "$IP ro change 172.16.105.0/24 nexthop via 172.16.101.3 nexthop via 172.16.103.3" 1414*4882a593Smuzhiyun log_test $? 2 "Multipath - replace of non-existent route" 1415*4882a593Smuzhiyun} 1416*4882a593Smuzhiyun 1417*4882a593Smuzhiyunipv4_rt_replace() 1418*4882a593Smuzhiyun{ 1419*4882a593Smuzhiyun echo 1420*4882a593Smuzhiyun echo "IPv4 route replace tests" 1421*4882a593Smuzhiyun 1422*4882a593Smuzhiyun ipv4_rt_replace_single 1423*4882a593Smuzhiyun ipv4_rt_replace_mpath 1424*4882a593Smuzhiyun} 1425*4882a593Smuzhiyun 1426*4882a593Smuzhiyun# checks that cached input route on VRF port is deleted 1427*4882a593Smuzhiyun# when VRF is deleted 1428*4882a593Smuzhiyunipv4_local_rt_cache() 1429*4882a593Smuzhiyun{ 1430*4882a593Smuzhiyun run_cmd "ip addr add 10.0.0.1/32 dev lo" 1431*4882a593Smuzhiyun run_cmd "ip netns add test-ns" 1432*4882a593Smuzhiyun run_cmd "ip link add veth-outside type veth peer name veth-inside" 1433*4882a593Smuzhiyun run_cmd "ip link add vrf-100 type vrf table 1100" 1434*4882a593Smuzhiyun run_cmd "ip link set veth-outside master vrf-100" 1435*4882a593Smuzhiyun run_cmd "ip link set veth-inside netns test-ns" 1436*4882a593Smuzhiyun run_cmd "ip link set veth-outside up" 1437*4882a593Smuzhiyun run_cmd "ip link set vrf-100 up" 1438*4882a593Smuzhiyun run_cmd "ip route add 10.1.1.1/32 dev veth-outside table 1100" 1439*4882a593Smuzhiyun run_cmd "ip netns exec test-ns ip link set veth-inside up" 1440*4882a593Smuzhiyun run_cmd "ip netns exec test-ns ip addr add 10.1.1.1/32 dev veth-inside" 1441*4882a593Smuzhiyun run_cmd "ip netns exec test-ns ip route add 10.0.0.1/32 dev veth-inside" 1442*4882a593Smuzhiyun run_cmd "ip netns exec test-ns ip route add default via 10.0.0.1" 1443*4882a593Smuzhiyun run_cmd "ip netns exec test-ns ping 10.0.0.1 -c 1 -i 1" 1444*4882a593Smuzhiyun run_cmd "ip link delete vrf-100" 1445*4882a593Smuzhiyun 1446*4882a593Smuzhiyun # if we do not hang test is a success 1447*4882a593Smuzhiyun log_test $? 0 "Cached route removed from VRF port device" 1448*4882a593Smuzhiyun} 1449*4882a593Smuzhiyun 1450*4882a593Smuzhiyunipv4_route_test() 1451*4882a593Smuzhiyun{ 1452*4882a593Smuzhiyun route_setup 1453*4882a593Smuzhiyun 1454*4882a593Smuzhiyun ipv4_rt_add 1455*4882a593Smuzhiyun ipv4_rt_replace 1456*4882a593Smuzhiyun ipv4_local_rt_cache 1457*4882a593Smuzhiyun 1458*4882a593Smuzhiyun route_cleanup 1459*4882a593Smuzhiyun} 1460*4882a593Smuzhiyun 1461*4882a593Smuzhiyunipv4_addr_metric_test() 1462*4882a593Smuzhiyun{ 1463*4882a593Smuzhiyun local rc 1464*4882a593Smuzhiyun 1465*4882a593Smuzhiyun echo 1466*4882a593Smuzhiyun echo "IPv4 prefix route tests" 1467*4882a593Smuzhiyun 1468*4882a593Smuzhiyun ip_addr_metric_check || return 1 1469*4882a593Smuzhiyun 1470*4882a593Smuzhiyun setup 1471*4882a593Smuzhiyun 1472*4882a593Smuzhiyun set -e 1473*4882a593Smuzhiyun $IP li add dummy1 type dummy 1474*4882a593Smuzhiyun $IP li add dummy2 type dummy 1475*4882a593Smuzhiyun $IP li set dummy1 up 1476*4882a593Smuzhiyun $IP li set dummy2 up 1477*4882a593Smuzhiyun 1478*4882a593Smuzhiyun # default entry is metric 256 1479*4882a593Smuzhiyun run_cmd "$IP addr add dev dummy1 172.16.104.1/24" 1480*4882a593Smuzhiyun run_cmd "$IP addr add dev dummy2 172.16.104.2/24" 1481*4882a593Smuzhiyun set +e 1482*4882a593Smuzhiyun 1483*4882a593Smuzhiyun check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2" 1484*4882a593Smuzhiyun log_test $? 0 "Default metric" 1485*4882a593Smuzhiyun 1486*4882a593Smuzhiyun set -e 1487*4882a593Smuzhiyun run_cmd "$IP addr flush dev dummy1" 1488*4882a593Smuzhiyun run_cmd "$IP addr add dev dummy1 172.16.104.1/24 metric 257" 1489*4882a593Smuzhiyun set +e 1490*4882a593Smuzhiyun 1491*4882a593Smuzhiyun check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257" 1492*4882a593Smuzhiyun log_test $? 0 "User specified metric on first device" 1493*4882a593Smuzhiyun 1494*4882a593Smuzhiyun set -e 1495*4882a593Smuzhiyun run_cmd "$IP addr flush dev dummy2" 1496*4882a593Smuzhiyun run_cmd "$IP addr add dev dummy2 172.16.104.2/24 metric 258" 1497*4882a593Smuzhiyun set +e 1498*4882a593Smuzhiyun 1499*4882a593Smuzhiyun check_route "172.16.104.0/24 dev dummy1 proto kernel scope link src 172.16.104.1 metric 257 172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258" 1500*4882a593Smuzhiyun log_test $? 0 "User specified metric on second device" 1501*4882a593Smuzhiyun 1502*4882a593Smuzhiyun run_cmd "$IP addr del dev dummy1 172.16.104.1/24 metric 257" 1503*4882a593Smuzhiyun rc=$? 1504*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1505*4882a593Smuzhiyun check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 258" 1506*4882a593Smuzhiyun rc=$? 1507*4882a593Smuzhiyun fi 1508*4882a593Smuzhiyun log_test $rc 0 "Delete of address on first device" 1509*4882a593Smuzhiyun 1510*4882a593Smuzhiyun run_cmd "$IP addr change dev dummy2 172.16.104.2/24 metric 259" 1511*4882a593Smuzhiyun rc=$? 1512*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1513*4882a593Smuzhiyun check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1514*4882a593Smuzhiyun rc=$? 1515*4882a593Smuzhiyun fi 1516*4882a593Smuzhiyun log_test $rc 0 "Modify metric of address" 1517*4882a593Smuzhiyun 1518*4882a593Smuzhiyun # verify prefix route removed on down 1519*4882a593Smuzhiyun run_cmd "$IP li set dev dummy2 down" 1520*4882a593Smuzhiyun rc=$? 1521*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1522*4882a593Smuzhiyun out=$($IP ro ls match 172.16.104.0/24) 1523*4882a593Smuzhiyun check_expected "${out}" "" 1524*4882a593Smuzhiyun rc=$? 1525*4882a593Smuzhiyun fi 1526*4882a593Smuzhiyun log_test $rc 0 "Prefix route removed on link down" 1527*4882a593Smuzhiyun 1528*4882a593Smuzhiyun # verify prefix route re-inserted with assigned metric 1529*4882a593Smuzhiyun run_cmd "$IP li set dev dummy2 up" 1530*4882a593Smuzhiyun rc=$? 1531*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1532*4882a593Smuzhiyun check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.2 metric 259" 1533*4882a593Smuzhiyun rc=$? 1534*4882a593Smuzhiyun fi 1535*4882a593Smuzhiyun log_test $rc 0 "Prefix route with metric on link up" 1536*4882a593Smuzhiyun 1537*4882a593Smuzhiyun # explicitly check for metric changes on edge scenarios 1538*4882a593Smuzhiyun run_cmd "$IP addr flush dev dummy2" 1539*4882a593Smuzhiyun run_cmd "$IP addr add dev dummy2 172.16.104.0/24 metric 259" 1540*4882a593Smuzhiyun run_cmd "$IP addr change dev dummy2 172.16.104.0/24 metric 260" 1541*4882a593Smuzhiyun rc=$? 1542*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1543*4882a593Smuzhiyun check_route "172.16.104.0/24 dev dummy2 proto kernel scope link src 172.16.104.0 metric 260" 1544*4882a593Smuzhiyun rc=$? 1545*4882a593Smuzhiyun fi 1546*4882a593Smuzhiyun log_test $rc 0 "Modify metric of .0/24 address" 1547*4882a593Smuzhiyun 1548*4882a593Smuzhiyun run_cmd "$IP addr flush dev dummy2" 1549*4882a593Smuzhiyun run_cmd "$IP addr add dev dummy2 172.16.104.1/32 peer 172.16.104.2 metric 260" 1550*4882a593Smuzhiyun rc=$? 1551*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1552*4882a593Smuzhiyun check_route "172.16.104.2 dev dummy2 proto kernel scope link src 172.16.104.1 metric 260" 1553*4882a593Smuzhiyun rc=$? 1554*4882a593Smuzhiyun fi 1555*4882a593Smuzhiyun log_test $rc 0 "Set metric of address with peer route" 1556*4882a593Smuzhiyun 1557*4882a593Smuzhiyun run_cmd "$IP addr change dev dummy2 172.16.104.1/32 peer 172.16.104.3 metric 261" 1558*4882a593Smuzhiyun rc=$? 1559*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1560*4882a593Smuzhiyun check_route "172.16.104.3 dev dummy2 proto kernel scope link src 172.16.104.1 metric 261" 1561*4882a593Smuzhiyun rc=$? 1562*4882a593Smuzhiyun fi 1563*4882a593Smuzhiyun log_test $rc 0 "Modify metric and peer address for peer route" 1564*4882a593Smuzhiyun 1565*4882a593Smuzhiyun $IP li del dummy1 1566*4882a593Smuzhiyun $IP li del dummy2 1567*4882a593Smuzhiyun cleanup 1568*4882a593Smuzhiyun} 1569*4882a593Smuzhiyun 1570*4882a593Smuzhiyunipv4_route_metrics_test() 1571*4882a593Smuzhiyun{ 1572*4882a593Smuzhiyun local rc 1573*4882a593Smuzhiyun 1574*4882a593Smuzhiyun echo 1575*4882a593Smuzhiyun echo "IPv4 route add / append tests" 1576*4882a593Smuzhiyun 1577*4882a593Smuzhiyun route_setup 1578*4882a593Smuzhiyun 1579*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 mtu 1400" 1580*4882a593Smuzhiyun rc=$? 1581*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1582*4882a593Smuzhiyun check_route "172.16.111.0/24 via 172.16.101.2 dev veth1 mtu 1400" 1583*4882a593Smuzhiyun rc=$? 1584*4882a593Smuzhiyun fi 1585*4882a593Smuzhiyun log_test $rc 0 "Single path route with mtu metric" 1586*4882a593Smuzhiyun 1587*4882a593Smuzhiyun 1588*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 nexthop via 172.16.103.2" 1589*4882a593Smuzhiyun rc=$? 1590*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1591*4882a593Smuzhiyun check_route "172.16.112.0/24 mtu 1400 nexthop via 172.16.101.2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1" 1592*4882a593Smuzhiyun rc=$? 1593*4882a593Smuzhiyun fi 1594*4882a593Smuzhiyun log_test $rc 0 "Multipath route with mtu metric" 1595*4882a593Smuzhiyun 1596*4882a593Smuzhiyun $IP ro add 172.16.104.0/24 via 172.16.101.2 mtu 1300 1597*4882a593Smuzhiyun run_cmd "ip netns exec ns1 ping -w1 -c1 -s 1500 172.16.104.1" 1598*4882a593Smuzhiyun log_test $? 0 "Using route with mtu metric" 1599*4882a593Smuzhiyun 1600*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.111.0/24 via 172.16.101.2 congctl lock foo" 1601*4882a593Smuzhiyun log_test $? 2 "Invalid metric (fails metric_convert)" 1602*4882a593Smuzhiyun 1603*4882a593Smuzhiyun route_cleanup 1604*4882a593Smuzhiyun} 1605*4882a593Smuzhiyun 1606*4882a593Smuzhiyunipv4_del_addr_test() 1607*4882a593Smuzhiyun{ 1608*4882a593Smuzhiyun echo 1609*4882a593Smuzhiyun echo "IPv4 delete address route tests" 1610*4882a593Smuzhiyun 1611*4882a593Smuzhiyun setup 1612*4882a593Smuzhiyun 1613*4882a593Smuzhiyun set -e 1614*4882a593Smuzhiyun $IP li add dummy1 type dummy 1615*4882a593Smuzhiyun $IP li set dummy1 up 1616*4882a593Smuzhiyun $IP li add dummy2 type dummy 1617*4882a593Smuzhiyun $IP li set dummy2 up 1618*4882a593Smuzhiyun $IP li add red type vrf table 1111 1619*4882a593Smuzhiyun $IP li set red up 1620*4882a593Smuzhiyun $IP ro add vrf red unreachable default 1621*4882a593Smuzhiyun $IP li set dummy2 vrf red 1622*4882a593Smuzhiyun 1623*4882a593Smuzhiyun $IP addr add dev dummy1 172.16.104.1/24 1624*4882a593Smuzhiyun $IP addr add dev dummy1 172.16.104.11/24 1625*4882a593Smuzhiyun $IP addr add dev dummy1 172.16.104.12/24 1626*4882a593Smuzhiyun $IP addr add dev dummy1 172.16.104.13/24 1627*4882a593Smuzhiyun $IP addr add dev dummy2 172.16.104.1/24 1628*4882a593Smuzhiyun $IP addr add dev dummy2 172.16.104.11/24 1629*4882a593Smuzhiyun $IP addr add dev dummy2 172.16.104.12/24 1630*4882a593Smuzhiyun $IP route add 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11 1631*4882a593Smuzhiyun $IP route add 172.16.106.0/24 dev lo src 172.16.104.12 1632*4882a593Smuzhiyun $IP route add table 0 172.16.107.0/24 via 172.16.104.2 src 172.16.104.13 1633*4882a593Smuzhiyun $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11 1634*4882a593Smuzhiyun $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12 1635*4882a593Smuzhiyun set +e 1636*4882a593Smuzhiyun 1637*4882a593Smuzhiyun # removing address from device in vrf should only remove route from vrf table 1638*4882a593Smuzhiyun echo " Regular FIB info" 1639*4882a593Smuzhiyun 1640*4882a593Smuzhiyun $IP addr del dev dummy2 172.16.104.11/24 1641*4882a593Smuzhiyun $IP ro ls vrf red | grep -q 172.16.105.0/24 1642*4882a593Smuzhiyun log_test $? 1 "Route removed from VRF when source address deleted" 1643*4882a593Smuzhiyun 1644*4882a593Smuzhiyun $IP ro ls | grep -q 172.16.105.0/24 1645*4882a593Smuzhiyun log_test $? 0 "Route in default VRF not removed" 1646*4882a593Smuzhiyun 1647*4882a593Smuzhiyun $IP addr add dev dummy2 172.16.104.11/24 1648*4882a593Smuzhiyun $IP route add vrf red 172.16.105.0/24 via 172.16.104.2 src 172.16.104.11 1649*4882a593Smuzhiyun 1650*4882a593Smuzhiyun $IP addr del dev dummy1 172.16.104.11/24 1651*4882a593Smuzhiyun $IP ro ls | grep -q 172.16.105.0/24 1652*4882a593Smuzhiyun log_test $? 1 "Route removed in default VRF when source address deleted" 1653*4882a593Smuzhiyun 1654*4882a593Smuzhiyun $IP ro ls vrf red | grep -q 172.16.105.0/24 1655*4882a593Smuzhiyun log_test $? 0 "Route in VRF is not removed by address delete" 1656*4882a593Smuzhiyun 1657*4882a593Smuzhiyun # removing address from device in vrf should only remove route from vrf 1658*4882a593Smuzhiyun # table even when the associated fib info only differs in table ID 1659*4882a593Smuzhiyun echo " Identical FIB info with different table ID" 1660*4882a593Smuzhiyun 1661*4882a593Smuzhiyun $IP addr del dev dummy2 172.16.104.12/24 1662*4882a593Smuzhiyun $IP ro ls vrf red | grep -q 172.16.106.0/24 1663*4882a593Smuzhiyun log_test $? 1 "Route removed from VRF when source address deleted" 1664*4882a593Smuzhiyun 1665*4882a593Smuzhiyun $IP ro ls | grep -q 172.16.106.0/24 1666*4882a593Smuzhiyun log_test $? 0 "Route in default VRF not removed" 1667*4882a593Smuzhiyun 1668*4882a593Smuzhiyun $IP addr add dev dummy2 172.16.104.12/24 1669*4882a593Smuzhiyun $IP route add vrf red 172.16.106.0/24 dev lo src 172.16.104.12 1670*4882a593Smuzhiyun 1671*4882a593Smuzhiyun $IP addr del dev dummy1 172.16.104.12/24 1672*4882a593Smuzhiyun $IP ro ls | grep -q 172.16.106.0/24 1673*4882a593Smuzhiyun log_test $? 1 "Route removed in default VRF when source address deleted" 1674*4882a593Smuzhiyun 1675*4882a593Smuzhiyun $IP ro ls vrf red | grep -q 172.16.106.0/24 1676*4882a593Smuzhiyun log_test $? 0 "Route in VRF is not removed by address delete" 1677*4882a593Smuzhiyun 1678*4882a593Smuzhiyun # removing address from device in default vrf should remove route from 1679*4882a593Smuzhiyun # the default vrf even when route was inserted with a table ID of 0. 1680*4882a593Smuzhiyun echo " Table ID 0" 1681*4882a593Smuzhiyun 1682*4882a593Smuzhiyun $IP addr del dev dummy1 172.16.104.13/24 1683*4882a593Smuzhiyun $IP ro ls | grep -q 172.16.107.0/24 1684*4882a593Smuzhiyun log_test $? 1 "Route removed in default VRF when source address deleted" 1685*4882a593Smuzhiyun 1686*4882a593Smuzhiyun $IP li del dummy1 1687*4882a593Smuzhiyun $IP li del dummy2 1688*4882a593Smuzhiyun cleanup 1689*4882a593Smuzhiyun} 1690*4882a593Smuzhiyun 1691*4882a593Smuzhiyun 1692*4882a593Smuzhiyunipv4_route_v6_gw_test() 1693*4882a593Smuzhiyun{ 1694*4882a593Smuzhiyun local rc 1695*4882a593Smuzhiyun 1696*4882a593Smuzhiyun echo 1697*4882a593Smuzhiyun echo "IPv4 route with IPv6 gateway tests" 1698*4882a593Smuzhiyun 1699*4882a593Smuzhiyun route_setup 1700*4882a593Smuzhiyun sleep 2 1701*4882a593Smuzhiyun 1702*4882a593Smuzhiyun # 1703*4882a593Smuzhiyun # single path route 1704*4882a593Smuzhiyun # 1705*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.104.0/24 via inet6 2001:db8:101::2" 1706*4882a593Smuzhiyun rc=$? 1707*4882a593Smuzhiyun log_test $rc 0 "Single path route with IPv6 gateway" 1708*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1709*4882a593Smuzhiyun check_route "172.16.104.0/24 via inet6 2001:db8:101::2 dev veth1" 1710*4882a593Smuzhiyun fi 1711*4882a593Smuzhiyun 1712*4882a593Smuzhiyun run_cmd "ip netns exec ns1 ping -w1 -c1 172.16.104.1" 1713*4882a593Smuzhiyun log_test $rc 0 "Single path route with IPv6 gateway - ping" 1714*4882a593Smuzhiyun 1715*4882a593Smuzhiyun run_cmd "$IP ro del 172.16.104.0/24 via inet6 2001:db8:101::2" 1716*4882a593Smuzhiyun rc=$? 1717*4882a593Smuzhiyun log_test $rc 0 "Single path route delete" 1718*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1719*4882a593Smuzhiyun check_route "172.16.112.0/24" 1720*4882a593Smuzhiyun fi 1721*4882a593Smuzhiyun 1722*4882a593Smuzhiyun # 1723*4882a593Smuzhiyun # multipath - v6 then v4 1724*4882a593Smuzhiyun # 1725*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3" 1726*4882a593Smuzhiyun rc=$? 1727*4882a593Smuzhiyun log_test $rc 0 "Multipath route add - v6 nexthop then v4" 1728*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1729*4882a593Smuzhiyun check_route "172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1 nexthop via 172.16.103.2 dev veth3 weight 1" 1730*4882a593Smuzhiyun fi 1731*4882a593Smuzhiyun 1732*4882a593Smuzhiyun run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1" 1733*4882a593Smuzhiyun log_test $? 2 " Multipath route delete - nexthops in wrong order" 1734*4882a593Smuzhiyun 1735*4882a593Smuzhiyun run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3" 1736*4882a593Smuzhiyun log_test $? 0 " Multipath route delete exact match" 1737*4882a593Smuzhiyun 1738*4882a593Smuzhiyun # 1739*4882a593Smuzhiyun # multipath - v4 then v6 1740*4882a593Smuzhiyun # 1741*4882a593Smuzhiyun run_cmd "$IP ro add 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1" 1742*4882a593Smuzhiyun rc=$? 1743*4882a593Smuzhiyun log_test $rc 0 "Multipath route add - v4 nexthop then v6" 1744*4882a593Smuzhiyun if [ $rc -eq 0 ]; then 1745*4882a593Smuzhiyun check_route "172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 weight 1 nexthop via inet6 2001:db8:101::2 dev veth1 weight 1" 1746*4882a593Smuzhiyun fi 1747*4882a593Smuzhiyun 1748*4882a593Smuzhiyun run_cmd "$IP ro del 172.16.104.0/24 nexthop via inet6 2001:db8:101::2 dev veth1 nexthop via 172.16.103.2 dev veth3" 1749*4882a593Smuzhiyun log_test $? 2 " Multipath route delete - nexthops in wrong order" 1750*4882a593Smuzhiyun 1751*4882a593Smuzhiyun run_cmd "$IP ro del 172.16.104.0/24 nexthop via 172.16.103.2 dev veth3 nexthop via inet6 2001:db8:101::2 dev veth1" 1752*4882a593Smuzhiyun log_test $? 0 " Multipath route delete exact match" 1753*4882a593Smuzhiyun 1754*4882a593Smuzhiyun route_cleanup 1755*4882a593Smuzhiyun} 1756*4882a593Smuzhiyun 1757*4882a593Smuzhiyun################################################################################ 1758*4882a593Smuzhiyun# usage 1759*4882a593Smuzhiyun 1760*4882a593Smuzhiyunusage() 1761*4882a593Smuzhiyun{ 1762*4882a593Smuzhiyun cat <<EOF 1763*4882a593Smuzhiyunusage: ${0##*/} OPTS 1764*4882a593Smuzhiyun 1765*4882a593Smuzhiyun -t <test> Test(s) to run (default: all) 1766*4882a593Smuzhiyun (options: $TESTS) 1767*4882a593Smuzhiyun -p Pause on fail 1768*4882a593Smuzhiyun -P Pause after each test before cleanup 1769*4882a593Smuzhiyun -v verbose mode (show commands and output) 1770*4882a593SmuzhiyunEOF 1771*4882a593Smuzhiyun} 1772*4882a593Smuzhiyun 1773*4882a593Smuzhiyun################################################################################ 1774*4882a593Smuzhiyun# main 1775*4882a593Smuzhiyun 1776*4882a593Smuzhiyunwhile getopts :t:pPhv o 1777*4882a593Smuzhiyundo 1778*4882a593Smuzhiyun case $o in 1779*4882a593Smuzhiyun t) TESTS=$OPTARG;; 1780*4882a593Smuzhiyun p) PAUSE_ON_FAIL=yes;; 1781*4882a593Smuzhiyun P) PAUSE=yes;; 1782*4882a593Smuzhiyun v) VERBOSE=$(($VERBOSE + 1));; 1783*4882a593Smuzhiyun h) usage; exit 0;; 1784*4882a593Smuzhiyun *) usage; exit 1;; 1785*4882a593Smuzhiyun esac 1786*4882a593Smuzhiyundone 1787*4882a593Smuzhiyun 1788*4882a593SmuzhiyunPEER_CMD="ip netns exec ${PEER_NS}" 1789*4882a593Smuzhiyun 1790*4882a593Smuzhiyun# make sure we don't pause twice 1791*4882a593Smuzhiyun[ "${PAUSE}" = "yes" ] && PAUSE_ON_FAIL=no 1792*4882a593Smuzhiyun 1793*4882a593Smuzhiyunif [ "$(id -u)" -ne 0 ];then 1794*4882a593Smuzhiyun echo "SKIP: Need root privileges" 1795*4882a593Smuzhiyun exit $ksft_skip; 1796*4882a593Smuzhiyunfi 1797*4882a593Smuzhiyun 1798*4882a593Smuzhiyunif [ ! -x "$(command -v ip)" ]; then 1799*4882a593Smuzhiyun echo "SKIP: Could not run test without ip tool" 1800*4882a593Smuzhiyun exit $ksft_skip 1801*4882a593Smuzhiyunfi 1802*4882a593Smuzhiyun 1803*4882a593Smuzhiyunip route help 2>&1 | grep -q fibmatch 1804*4882a593Smuzhiyunif [ $? -ne 0 ]; then 1805*4882a593Smuzhiyun echo "SKIP: iproute2 too old, missing fibmatch" 1806*4882a593Smuzhiyun exit $ksft_skip 1807*4882a593Smuzhiyunfi 1808*4882a593Smuzhiyun 1809*4882a593Smuzhiyun# start clean 1810*4882a593Smuzhiyuncleanup &> /dev/null 1811*4882a593Smuzhiyun 1812*4882a593Smuzhiyunfor t in $TESTS 1813*4882a593Smuzhiyundo 1814*4882a593Smuzhiyun case $t in 1815*4882a593Smuzhiyun fib_unreg_test|unregister) fib_unreg_test;; 1816*4882a593Smuzhiyun fib_down_test|down) fib_down_test;; 1817*4882a593Smuzhiyun fib_carrier_test|carrier) fib_carrier_test;; 1818*4882a593Smuzhiyun fib_rp_filter_test|rp_filter) fib_rp_filter_test;; 1819*4882a593Smuzhiyun fib_nexthop_test|nexthop) fib_nexthop_test;; 1820*4882a593Smuzhiyun fib_suppress_test|suppress) fib_suppress_test;; 1821*4882a593Smuzhiyun ipv6_route_test|ipv6_rt) ipv6_route_test;; 1822*4882a593Smuzhiyun ipv4_route_test|ipv4_rt) ipv4_route_test;; 1823*4882a593Smuzhiyun ipv6_addr_metric) ipv6_addr_metric_test;; 1824*4882a593Smuzhiyun ipv4_addr_metric) ipv4_addr_metric_test;; 1825*4882a593Smuzhiyun ipv4_del_addr) ipv4_del_addr_test;; 1826*4882a593Smuzhiyun ipv6_route_metrics) ipv6_route_metrics_test;; 1827*4882a593Smuzhiyun ipv4_route_metrics) ipv4_route_metrics_test;; 1828*4882a593Smuzhiyun ipv4_route_v6_gw) ipv4_route_v6_gw_test;; 1829*4882a593Smuzhiyun 1830*4882a593Smuzhiyun help) echo "Test names: $TESTS"; exit 0;; 1831*4882a593Smuzhiyun esac 1832*4882a593Smuzhiyundone 1833*4882a593Smuzhiyun 1834*4882a593Smuzhiyunif [ "$TESTS" != "none" ]; then 1835*4882a593Smuzhiyun printf "\nTests passed: %3d\n" ${nsuccess} 1836*4882a593Smuzhiyun printf "Tests failed: %3d\n" ${nfail} 1837*4882a593Smuzhiyunfi 1838*4882a593Smuzhiyun 1839*4882a593Smuzhiyunexit $ret 1840