Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 
0004 # IPv4 and IPv6 onlink tests
0005 
0006 PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
0007 VERBOSE=0
0008 
0009 # Network interfaces
0010 # - odd in current namespace; even in peer ns
0011 declare -A NETIFS
0012 # default VRF
0013 NETIFS[p1]=veth1
0014 NETIFS[p2]=veth2
0015 NETIFS[p3]=veth3
0016 NETIFS[p4]=veth4
0017 # VRF
0018 NETIFS[p5]=veth5
0019 NETIFS[p6]=veth6
0020 NETIFS[p7]=veth7
0021 NETIFS[p8]=veth8
0022 
0023 # /24 network
0024 declare -A V4ADDRS
0025 V4ADDRS[p1]=169.254.1.1
0026 V4ADDRS[p2]=169.254.1.2
0027 V4ADDRS[p3]=169.254.3.1
0028 V4ADDRS[p4]=169.254.3.2
0029 V4ADDRS[p5]=169.254.5.1
0030 V4ADDRS[p6]=169.254.5.2
0031 V4ADDRS[p7]=169.254.7.1
0032 V4ADDRS[p8]=169.254.7.2
0033 
0034 # /64 network
0035 declare -A V6ADDRS
0036 V6ADDRS[p1]=2001:db8:101::1
0037 V6ADDRS[p2]=2001:db8:101::2
0038 V6ADDRS[p3]=2001:db8:301::1
0039 V6ADDRS[p4]=2001:db8:301::2
0040 V6ADDRS[p5]=2001:db8:501::1
0041 V6ADDRS[p6]=2001:db8:501::2
0042 V6ADDRS[p7]=2001:db8:701::1
0043 V6ADDRS[p8]=2001:db8:701::2
0044 
0045 # Test networks:
0046 # [1] = default table
0047 # [2] = VRF
0048 #
0049 # /32 host routes
0050 declare -A TEST_NET4
0051 TEST_NET4[1]=169.254.101
0052 TEST_NET4[2]=169.254.102
0053 # /128 host routes
0054 declare -A TEST_NET6
0055 TEST_NET6[1]=2001:db8:101
0056 TEST_NET6[2]=2001:db8:102
0057 
0058 # connected gateway
0059 CONGW[1]=169.254.1.254
0060 CONGW[2]=169.254.3.254
0061 CONGW[3]=169.254.5.254
0062 
0063 # recursive gateway
0064 RECGW4[1]=169.254.11.254
0065 RECGW4[2]=169.254.12.254
0066 RECGW6[1]=2001:db8:11::64
0067 RECGW6[2]=2001:db8:12::64
0068 
0069 # for v4 mapped to v6
0070 declare -A TEST_NET4IN6IN6
0071 TEST_NET4IN6[1]=10.1.1.254
0072 TEST_NET4IN6[2]=10.2.1.254
0073 
0074 # mcast address
0075 MCAST6=ff02::1
0076 
0077 
0078 PEER_NS=bart
0079 PEER_CMD="ip netns exec ${PEER_NS}"
0080 VRF=lisa
0081 VRF_TABLE=1101
0082 PBR_TABLE=101
0083 
0084 ################################################################################
0085 # utilities
0086 
0087 log_test()
0088 {
0089         local rc=$1
0090         local expected=$2
0091         local msg="$3"
0092 
0093         if [ ${rc} -eq ${expected} ]; then
0094                 nsuccess=$((nsuccess+1))
0095                 printf "    TEST: %-50s  [ OK ]\n" "${msg}"
0096         else
0097                 nfail=$((nfail+1))
0098                 printf "    TEST: %-50s  [FAIL]\n" "${msg}"
0099                 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
0100                         echo
0101                         echo "hit enter to continue, 'q' to quit"
0102                         read a
0103                         [ "$a" = "q" ] && exit 1
0104                 fi
0105         fi
0106 }
0107 
0108 log_section()
0109 {
0110         echo
0111         echo "######################################################################"
0112         echo "TEST SECTION: $*"
0113         echo "######################################################################"
0114 }
0115 
0116 log_subsection()
0117 {
0118         echo
0119         echo "#########################################"
0120         echo "TEST SUBSECTION: $*"
0121 }
0122 
0123 run_cmd()
0124 {
0125         local cmd="$*"
0126         local out
0127         local rc
0128 
0129         if [ "$VERBOSE" = "1" ]; then
0130                 printf "    COMMAND: $cmd\n"
0131         fi
0132 
0133         out=$(eval $cmd 2>&1)
0134         rc=$?
0135         if [ "$VERBOSE" = "1" -a -n "$out" ]; then
0136                 echo "    $out"
0137         fi
0138 
0139         [ "$VERBOSE" = "1" ] && echo
0140 
0141         return $rc
0142 }
0143 
0144 get_linklocal()
0145 {
0146         local dev=$1
0147         local pfx
0148         local addr
0149 
0150         addr=$(${pfx} ip -6 -br addr show dev ${dev} | \
0151         awk '{
0152                 for (i = 3; i <= NF; ++i) {
0153                         if ($i ~ /^fe80/)
0154                                 print $i
0155                 }
0156         }'
0157         )
0158         addr=${addr/\/*}
0159 
0160         [ -z "$addr" ] && return 1
0161 
0162         echo $addr
0163 
0164         return 0
0165 }
0166 
0167 ################################################################################
0168 #
0169 
0170 setup()
0171 {
0172         echo
0173         echo "########################################"
0174         echo "Configuring interfaces"
0175 
0176         set -e
0177 
0178         # create namespace
0179         ip netns add ${PEER_NS}
0180         ip -netns ${PEER_NS} li set lo up
0181 
0182         # add vrf table
0183         ip li add ${VRF} type vrf table ${VRF_TABLE}
0184         ip li set ${VRF} up
0185         ip ro add table ${VRF_TABLE} unreachable default metric 8192
0186         ip -6 ro add table ${VRF_TABLE} unreachable default metric 8192
0187 
0188         # create test interfaces
0189         ip li add ${NETIFS[p1]} type veth peer name ${NETIFS[p2]}
0190         ip li add ${NETIFS[p3]} type veth peer name ${NETIFS[p4]}
0191         ip li add ${NETIFS[p5]} type veth peer name ${NETIFS[p6]}
0192         ip li add ${NETIFS[p7]} type veth peer name ${NETIFS[p8]}
0193 
0194         # enslave vrf interfaces
0195         for n in 5 7; do
0196                 ip li set ${NETIFS[p${n}]} vrf ${VRF}
0197         done
0198 
0199         # add addresses
0200         for n in 1 3 5 7; do
0201                 ip li set ${NETIFS[p${n}]} up
0202                 ip addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
0203                 ip addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
0204         done
0205 
0206         # move peer interfaces to namespace and add addresses
0207         for n in 2 4 6 8; do
0208                 ip li set ${NETIFS[p${n}]} netns ${PEER_NS} up
0209                 ip -netns ${PEER_NS} addr add ${V4ADDRS[p${n}]}/24 dev ${NETIFS[p${n}]}
0210                 ip -netns ${PEER_NS} addr add ${V6ADDRS[p${n}]}/64 dev ${NETIFS[p${n}]} nodad
0211         done
0212 
0213         ip -6 ro add default via ${V6ADDRS[p3]/::[0-9]/::64}
0214         ip -6 ro add table ${VRF_TABLE} default via ${V6ADDRS[p7]/::[0-9]/::64}
0215 
0216         set +e
0217 }
0218 
0219 cleanup()
0220 {
0221         # make sure we start from a clean slate
0222         ip netns del ${PEER_NS} 2>/dev/null
0223         for n in 1 3 5 7; do
0224                 ip link del ${NETIFS[p${n}]} 2>/dev/null
0225         done
0226         ip link del ${VRF} 2>/dev/null
0227         ip ro flush table ${VRF_TABLE}
0228         ip -6 ro flush table ${VRF_TABLE}
0229 }
0230 
0231 ################################################################################
0232 # IPv4 tests
0233 #
0234 
0235 run_ip()
0236 {
0237         local table="$1"
0238         local prefix="$2"
0239         local gw="$3"
0240         local dev="$4"
0241         local exp_rc="$5"
0242         local desc="$6"
0243 
0244         # dev arg may be empty
0245         [ -n "${dev}" ] && dev="dev ${dev}"
0246 
0247         run_cmd ip ro add table "${table}" "${prefix}"/32 via "${gw}" "${dev}" onlink
0248         log_test $? ${exp_rc} "${desc}"
0249 }
0250 
0251 run_ip_mpath()
0252 {
0253         local table="$1"
0254         local prefix="$2"
0255         local nh1="$3"
0256         local nh2="$4"
0257         local exp_rc="$5"
0258         local desc="$6"
0259 
0260         # dev arg may be empty
0261         [ -n "${dev}" ] && dev="dev ${dev}"
0262 
0263         run_cmd ip ro add table "${table}" "${prefix}"/32 \
0264                 nexthop via ${nh1} nexthop via ${nh2}
0265         log_test $? ${exp_rc} "${desc}"
0266 }
0267 
0268 valid_onlink_ipv4()
0269 {
0270         # - unicast connected, unicast recursive
0271         #
0272         log_subsection "default VRF - main table"
0273 
0274         run_ip 254 ${TEST_NET4[1]}.1 ${CONGW[1]} ${NETIFS[p1]} 0 "unicast connected"
0275         run_ip 254 ${TEST_NET4[1]}.2 ${RECGW4[1]} ${NETIFS[p1]} 0 "unicast recursive"
0276 
0277         log_subsection "VRF ${VRF}"
0278 
0279         run_ip ${VRF_TABLE} ${TEST_NET4[2]}.1 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected"
0280         run_ip ${VRF_TABLE} ${TEST_NET4[2]}.2 ${RECGW4[2]} ${NETIFS[p5]} 0 "unicast recursive"
0281 
0282         log_subsection "VRF device, PBR table"
0283 
0284         run_ip ${PBR_TABLE} ${TEST_NET4[2]}.3 ${CONGW[3]} ${NETIFS[p5]} 0 "unicast connected"
0285         run_ip ${PBR_TABLE} ${TEST_NET4[2]}.4 ${RECGW4[2]} ${NETIFS[p5]} 0 "unicast recursive"
0286 
0287         # multipath version
0288         #
0289         log_subsection "default VRF - main table - multipath"
0290 
0291         run_ip_mpath 254 ${TEST_NET4[1]}.5 \
0292                 "${CONGW[1]} dev ${NETIFS[p1]} onlink" \
0293                 "${CONGW[2]} dev ${NETIFS[p3]} onlink" \
0294                 0 "unicast connected - multipath"
0295 
0296         run_ip_mpath 254 ${TEST_NET4[1]}.6 \
0297                 "${RECGW4[1]} dev ${NETIFS[p1]} onlink" \
0298                 "${RECGW4[2]} dev ${NETIFS[p3]} onlink" \
0299                 0 "unicast recursive - multipath"
0300 
0301         run_ip_mpath 254 ${TEST_NET4[1]}.7 \
0302                 "${CONGW[1]} dev ${NETIFS[p1]}"        \
0303                 "${CONGW[2]} dev ${NETIFS[p3]} onlink" \
0304                 0 "unicast connected - multipath onlink first only"
0305 
0306         run_ip_mpath 254 ${TEST_NET4[1]}.8 \
0307                 "${CONGW[1]} dev ${NETIFS[p1]} onlink" \
0308                 "${CONGW[2]} dev ${NETIFS[p3]}"        \
0309                 0 "unicast connected - multipath onlink second only"
0310 }
0311 
0312 invalid_onlink_ipv4()
0313 {
0314         run_ip 254 ${TEST_NET4[1]}.11 ${V4ADDRS[p1]} ${NETIFS[p1]} 2 \
0315                 "Invalid gw - local unicast address"
0316 
0317         run_ip ${VRF_TABLE} ${TEST_NET4[2]}.11 ${V4ADDRS[p5]} ${NETIFS[p5]} 2 \
0318                 "Invalid gw - local unicast address, VRF"
0319 
0320         run_ip 254 ${TEST_NET4[1]}.101 ${V4ADDRS[p1]} "" 2 "No nexthop device given"
0321 
0322         run_ip 254 ${TEST_NET4[1]}.102 ${V4ADDRS[p3]} ${NETIFS[p1]} 2 \
0323                 "Gateway resolves to wrong nexthop device"
0324 
0325         run_ip ${VRF_TABLE} ${TEST_NET4[2]}.103 ${V4ADDRS[p7]} ${NETIFS[p5]} 2 \
0326                 "Gateway resolves to wrong nexthop device - VRF"
0327 }
0328 
0329 ################################################################################
0330 # IPv6 tests
0331 #
0332 
0333 run_ip6()
0334 {
0335         local table="$1"
0336         local prefix="$2"
0337         local gw="$3"
0338         local dev="$4"
0339         local exp_rc="$5"
0340         local desc="$6"
0341 
0342         # dev arg may be empty
0343         [ -n "${dev}" ] && dev="dev ${dev}"
0344 
0345         run_cmd ip -6 ro add table "${table}" "${prefix}"/128 via "${gw}" "${dev}" onlink
0346         log_test $? ${exp_rc} "${desc}"
0347 }
0348 
0349 run_ip6_mpath()
0350 {
0351         local table="$1"
0352         local prefix="$2"
0353         local opts="$3"
0354         local nh1="$4"
0355         local nh2="$5"
0356         local exp_rc="$6"
0357         local desc="$7"
0358 
0359         run_cmd ip -6 ro add table "${table}" "${prefix}"/128 "${opts}" \
0360                 nexthop via ${nh1} nexthop via ${nh2}
0361         log_test $? ${exp_rc} "${desc}"
0362 }
0363 
0364 valid_onlink_ipv6()
0365 {
0366         # - unicast connected, unicast recursive, v4-mapped
0367         #
0368         log_subsection "default VRF - main table"
0369 
0370         run_ip6 254 ${TEST_NET6[1]}::1 ${V6ADDRS[p1]/::*}::64 ${NETIFS[p1]} 0 "unicast connected"
0371         run_ip6 254 ${TEST_NET6[1]}::2 ${RECGW6[1]} ${NETIFS[p1]} 0 "unicast recursive"
0372         run_ip6 254 ${TEST_NET6[1]}::3 ::ffff:${TEST_NET4IN6[1]} ${NETIFS[p1]} 0 "v4-mapped"
0373 
0374         log_subsection "VRF ${VRF}"
0375 
0376         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::1 ${V6ADDRS[p5]/::*}::64 ${NETIFS[p5]} 0 "unicast connected"
0377         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::2 ${RECGW6[2]} ${NETIFS[p5]} 0 "unicast recursive"
0378         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::3 ::ffff:${TEST_NET4IN6[2]} ${NETIFS[p5]} 0 "v4-mapped"
0379 
0380         log_subsection "VRF device, PBR table"
0381 
0382         run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::4 ${V6ADDRS[p5]/::*}::64 ${NETIFS[p5]} 0 "unicast connected"
0383         run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::5 ${RECGW6[2]} ${NETIFS[p5]} 0 "unicast recursive"
0384         run_ip6 ${PBR_TABLE} ${TEST_NET6[2]}::6 ::ffff:${TEST_NET4IN6[2]} ${NETIFS[p5]} 0 "v4-mapped"
0385 
0386         # multipath version
0387         #
0388         log_subsection "default VRF - main table - multipath"
0389 
0390         run_ip6_mpath 254 ${TEST_NET6[1]}::4 "onlink" \
0391                 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]}" \
0392                 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]}" \
0393                 0 "unicast connected - multipath onlink"
0394 
0395         run_ip6_mpath 254 ${TEST_NET6[1]}::5 "onlink" \
0396                 "${RECGW6[1]} dev ${NETIFS[p1]}" \
0397                 "${RECGW6[2]} dev ${NETIFS[p3]}" \
0398                 0 "unicast recursive - multipath onlink"
0399 
0400         run_ip6_mpath 254 ${TEST_NET6[1]}::6 "onlink" \
0401                 "::ffff:${TEST_NET4IN6[1]} dev ${NETIFS[p1]}" \
0402                 "::ffff:${TEST_NET4IN6[2]} dev ${NETIFS[p3]}" \
0403                 0 "v4-mapped - multipath onlink"
0404 
0405         run_ip6_mpath 254 ${TEST_NET6[1]}::7 "" \
0406                 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]} onlink" \
0407                 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]} onlink" \
0408                 0 "unicast connected - multipath onlink both nexthops"
0409 
0410         run_ip6_mpath 254 ${TEST_NET6[1]}::8 "" \
0411                 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]} onlink" \
0412                 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]}" \
0413                 0 "unicast connected - multipath onlink first only"
0414 
0415         run_ip6_mpath 254 ${TEST_NET6[1]}::9 "" \
0416                 "${V6ADDRS[p1]/::*}::64 dev ${NETIFS[p1]}"        \
0417                 "${V6ADDRS[p3]/::*}::64 dev ${NETIFS[p3]} onlink" \
0418                 0 "unicast connected - multipath onlink second only"
0419 }
0420 
0421 invalid_onlink_ipv6()
0422 {
0423         local lladdr
0424 
0425         lladdr=$(get_linklocal ${NETIFS[p1]}) || return 1
0426 
0427         run_ip6 254 ${TEST_NET6[1]}::11 ${V6ADDRS[p1]} ${NETIFS[p1]} 2 \
0428                 "Invalid gw - local unicast address"
0429         run_ip6 254 ${TEST_NET6[1]}::12 ${lladdr} ${NETIFS[p1]} 2 \
0430                 "Invalid gw - local linklocal address"
0431         run_ip6 254 ${TEST_NET6[1]}::12 ${MCAST6} ${NETIFS[p1]} 2 \
0432                 "Invalid gw - multicast address"
0433 
0434         lladdr=$(get_linklocal ${NETIFS[p5]}) || return 1
0435         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::11 ${V6ADDRS[p5]} ${NETIFS[p5]} 2 \
0436                 "Invalid gw - local unicast address, VRF"
0437         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::12 ${lladdr} ${NETIFS[p5]} 2 \
0438                 "Invalid gw - local linklocal address, VRF"
0439         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::12 ${MCAST6} ${NETIFS[p5]} 2 \
0440                 "Invalid gw - multicast address, VRF"
0441 
0442         run_ip6 254 ${TEST_NET6[1]}::101 ${V6ADDRS[p1]} "" 2 \
0443                 "No nexthop device given"
0444 
0445         # default VRF validation is done against LOCAL table
0446         # run_ip6 254 ${TEST_NET6[1]}::102 ${V6ADDRS[p3]/::[0-9]/::64} ${NETIFS[p1]} 2 \
0447         #       "Gateway resolves to wrong nexthop device"
0448 
0449         run_ip6 ${VRF_TABLE} ${TEST_NET6[2]}::103 ${V6ADDRS[p7]/::[0-9]/::64} ${NETIFS[p5]} 2 \
0450                 "Gateway resolves to wrong nexthop device - VRF"
0451 }
0452 
0453 run_onlink_tests()
0454 {
0455         log_section "IPv4 onlink"
0456         log_subsection "Valid onlink commands"
0457         valid_onlink_ipv4
0458         log_subsection "Invalid onlink commands"
0459         invalid_onlink_ipv4
0460 
0461         log_section "IPv6 onlink"
0462         log_subsection "Valid onlink commands"
0463         valid_onlink_ipv6
0464         log_subsection "Invalid onlink commands"
0465         invalid_onlink_ipv6
0466 }
0467 
0468 ################################################################################
0469 # usage
0470 
0471 usage()
0472 {
0473         cat <<EOF
0474 usage: ${0##*/} OPTS
0475 
0476         -p          Pause on fail
0477         -v          verbose mode (show commands and output)
0478 EOF
0479 }
0480 
0481 ################################################################################
0482 # main
0483 
0484 nsuccess=0
0485 nfail=0
0486 
0487 while getopts :t:pPhv o
0488 do
0489         case $o in
0490                 p) PAUSE_ON_FAIL=yes;;
0491                 v) VERBOSE=$(($VERBOSE + 1));;
0492                 h) usage; exit 0;;
0493                 *) usage; exit 1;;
0494         esac
0495 done
0496 
0497 cleanup
0498 setup
0499 run_onlink_tests
0500 cleanup
0501 
0502 if [ "$TESTS" != "none" ]; then
0503         printf "\nTests passed: %3d\n" ${nsuccess}
0504         printf "Tests failed: %3d\n"   ${nfail}
0505 fi