Back to home page

OSCL-LXR

 
 

    


0001 #!/bin/bash
0002 # SPDX-License-Identifier: GPL-2.0
0003 
0004 # This test is for checking IPv4 and IPv6 FIB rules API
0005 
0006 # Kselftest framework requirement - SKIP code is 4.
0007 ksft_skip=4
0008 
0009 ret=0
0010 
0011 PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no}
0012 IP="ip -netns testns"
0013 
0014 RTABLE=100
0015 GW_IP4=192.51.100.2
0016 SRC_IP=192.51.100.3
0017 GW_IP6=2001:db8:1::2
0018 SRC_IP6=2001:db8:1::3
0019 
0020 DEV_ADDR=192.51.100.1
0021 DEV_ADDR6=2001:db8:1::1
0022 DEV=dummy0
0023 TESTS="fib_rule6 fib_rule4"
0024 
0025 log_test()
0026 {
0027         local rc=$1
0028         local expected=$2
0029         local msg="$3"
0030 
0031         if [ ${rc} -eq ${expected} ]; then
0032                 nsuccess=$((nsuccess+1))
0033                 printf "\n    TEST: %-50s  [ OK ]\n" "${msg}"
0034         else
0035                 ret=1
0036                 nfail=$((nfail+1))
0037                 printf "\n    TEST: %-50s  [FAIL]\n" "${msg}"
0038                 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then
0039                         echo
0040                         echo "hit enter to continue, 'q' to quit"
0041                         read a
0042                         [ "$a" = "q" ] && exit 1
0043                 fi
0044         fi
0045 }
0046 
0047 log_section()
0048 {
0049         echo
0050         echo "######################################################################"
0051         echo "TEST SECTION: $*"
0052         echo "######################################################################"
0053 }
0054 
0055 setup()
0056 {
0057         set -e
0058         ip netns add testns
0059         $IP link set dev lo up
0060 
0061         $IP link add dummy0 type dummy
0062         $IP link set dev dummy0 up
0063         $IP address add $DEV_ADDR/24 dev dummy0
0064         $IP -6 address add $DEV_ADDR6/64 dev dummy0
0065 
0066         set +e
0067 }
0068 
0069 cleanup()
0070 {
0071         $IP link del dev dummy0 &> /dev/null
0072         ip netns del testns
0073 }
0074 
0075 fib_check_iproute_support()
0076 {
0077         ip rule help 2>&1 | grep -q $1
0078         if [ $? -ne 0 ]; then
0079                 echo "SKIP: iproute2 iprule too old, missing $1 match"
0080                 return 1
0081         fi
0082 
0083         ip route get help 2>&1 | grep -q $2
0084         if [ $? -ne 0 ]; then
0085                 echo "SKIP: iproute2 get route too old, missing $2 match"
0086                 return 1
0087         fi
0088 
0089         return 0
0090 }
0091 
0092 fib_rule6_del()
0093 {
0094         $IP -6 rule del $1
0095         log_test $? 0 "rule6 del $1"
0096 }
0097 
0098 fib_rule6_del_by_pref()
0099 {
0100         pref=$($IP -6 rule show $1 table $RTABLE | cut -d ":" -f 1)
0101         $IP -6 rule del pref $pref
0102 }
0103 
0104 fib_rule6_test_match_n_redirect()
0105 {
0106         local match="$1"
0107         local getmatch="$2"
0108         local description="$3"
0109 
0110         $IP -6 rule add $match table $RTABLE
0111         $IP -6 route get $GW_IP6 $getmatch | grep -q "table $RTABLE"
0112         log_test $? 0 "rule6 check: $description"
0113 
0114         fib_rule6_del_by_pref "$match"
0115         log_test $? 0 "rule6 del by pref: $description"
0116 }
0117 
0118 fib_rule6_test_reject()
0119 {
0120         local match="$1"
0121         local rc
0122 
0123         $IP -6 rule add $match table $RTABLE 2>/dev/null
0124         rc=$?
0125         log_test $rc 2 "rule6 check: $match"
0126 
0127         if [ $rc -eq 0 ]; then
0128                 $IP -6 rule del $match table $RTABLE
0129         fi
0130 }
0131 
0132 fib_rule6_test()
0133 {
0134         local getmatch
0135         local match
0136         local cnt
0137 
0138         # setup the fib rule redirect route
0139         $IP -6 route add table $RTABLE default via $GW_IP6 dev $DEV onlink
0140 
0141         match="oif $DEV"
0142         fib_rule6_test_match_n_redirect "$match" "$match" "oif redirect to table"
0143 
0144         match="from $SRC_IP6 iif $DEV"
0145         fib_rule6_test_match_n_redirect "$match" "$match" "iif redirect to table"
0146 
0147         # Reject dsfield (tos) options which have ECN bits set
0148         for cnt in $(seq 1 3); do
0149                 match="dsfield $cnt"
0150                 fib_rule6_test_reject "$match"
0151         done
0152 
0153         # Don't take ECN bits into account when matching on dsfield
0154         match="tos 0x10"
0155         for cnt in "0x10" "0x11" "0x12" "0x13"; do
0156                 # Using option 'tos' instead of 'dsfield' as old iproute2
0157                 # versions don't support 'dsfield' in ip rule show.
0158                 getmatch="tos $cnt"
0159                 fib_rule6_test_match_n_redirect "$match" "$getmatch" \
0160                                                 "$getmatch redirect to table"
0161         done
0162 
0163         match="fwmark 0x64"
0164         getmatch="mark 0x64"
0165         fib_rule6_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table"
0166 
0167         fib_check_iproute_support "uidrange" "uid"
0168         if [ $? -eq 0 ]; then
0169                 match="uidrange 100-100"
0170                 getmatch="uid 100"
0171                 fib_rule6_test_match_n_redirect "$match" "$getmatch" "uid redirect to table"
0172         fi
0173 
0174         fib_check_iproute_support "sport" "sport"
0175         if [ $? -eq 0 ]; then
0176                 match="sport 666 dport 777"
0177                 fib_rule6_test_match_n_redirect "$match" "$match" "sport and dport redirect to table"
0178         fi
0179 
0180         fib_check_iproute_support "ipproto" "ipproto"
0181         if [ $? -eq 0 ]; then
0182                 match="ipproto tcp"
0183                 fib_rule6_test_match_n_redirect "$match" "$match" "ipproto match"
0184         fi
0185 
0186         fib_check_iproute_support "ipproto" "ipproto"
0187         if [ $? -eq 0 ]; then
0188                 match="ipproto ipv6-icmp"
0189                 fib_rule6_test_match_n_redirect "$match" "$match" "ipproto ipv6-icmp match"
0190         fi
0191 }
0192 
0193 fib_rule4_del()
0194 {
0195         $IP rule del $1
0196         log_test $? 0 "del $1"
0197 }
0198 
0199 fib_rule4_del_by_pref()
0200 {
0201         pref=$($IP rule show $1 table $RTABLE | cut -d ":" -f 1)
0202         $IP rule del pref $pref
0203 }
0204 
0205 fib_rule4_test_match_n_redirect()
0206 {
0207         local match="$1"
0208         local getmatch="$2"
0209         local description="$3"
0210 
0211         $IP rule add $match table $RTABLE
0212         $IP route get $GW_IP4 $getmatch | grep -q "table $RTABLE"
0213         log_test $? 0 "rule4 check: $description"
0214 
0215         fib_rule4_del_by_pref "$match"
0216         log_test $? 0 "rule4 del by pref: $description"
0217 }
0218 
0219 fib_rule4_test_reject()
0220 {
0221         local match="$1"
0222         local rc
0223 
0224         $IP rule add $match table $RTABLE 2>/dev/null
0225         rc=$?
0226         log_test $rc 2 "rule4 check: $match"
0227 
0228         if [ $rc -eq 0 ]; then
0229                 $IP rule del $match table $RTABLE
0230         fi
0231 }
0232 
0233 fib_rule4_test()
0234 {
0235         local getmatch
0236         local match
0237         local cnt
0238 
0239         # setup the fib rule redirect route
0240         $IP route add table $RTABLE default via $GW_IP4 dev $DEV onlink
0241 
0242         match="oif $DEV"
0243         fib_rule4_test_match_n_redirect "$match" "$match" "oif redirect to table"
0244 
0245         # need enable forwarding and disable rp_filter temporarily as all the
0246         # addresses are in the same subnet and egress device == ingress device.
0247         ip netns exec testns sysctl -qw net.ipv4.ip_forward=1
0248         ip netns exec testns sysctl -qw net.ipv4.conf.$DEV.rp_filter=0
0249         match="from $SRC_IP iif $DEV"
0250         fib_rule4_test_match_n_redirect "$match" "$match" "iif redirect to table"
0251         ip netns exec testns sysctl -qw net.ipv4.ip_forward=0
0252 
0253         # Reject dsfield (tos) options which have ECN bits set
0254         for cnt in $(seq 1 3); do
0255                 match="dsfield $cnt"
0256                 fib_rule4_test_reject "$match"
0257         done
0258 
0259         # Don't take ECN bits into account when matching on dsfield
0260         match="tos 0x10"
0261         for cnt in "0x10" "0x11" "0x12" "0x13"; do
0262                 # Using option 'tos' instead of 'dsfield' as old iproute2
0263                 # versions don't support 'dsfield' in ip rule show.
0264                 getmatch="tos $cnt"
0265                 fib_rule4_test_match_n_redirect "$match" "$getmatch" \
0266                                                 "$getmatch redirect to table"
0267         done
0268 
0269         match="fwmark 0x64"
0270         getmatch="mark 0x64"
0271         fib_rule4_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table"
0272 
0273         fib_check_iproute_support "uidrange" "uid"
0274         if [ $? -eq 0 ]; then
0275                 match="uidrange 100-100"
0276                 getmatch="uid 100"
0277                 fib_rule4_test_match_n_redirect "$match" "$getmatch" "uid redirect to table"
0278         fi
0279 
0280         fib_check_iproute_support "sport" "sport"
0281         if [ $? -eq 0 ]; then
0282                 match="sport 666 dport 777"
0283                 fib_rule4_test_match_n_redirect "$match" "$match" "sport and dport redirect to table"
0284         fi
0285 
0286         fib_check_iproute_support "ipproto" "ipproto"
0287         if [ $? -eq 0 ]; then
0288                 match="ipproto tcp"
0289                 fib_rule4_test_match_n_redirect "$match" "$match" "ipproto tcp match"
0290         fi
0291 
0292         fib_check_iproute_support "ipproto" "ipproto"
0293         if [ $? -eq 0 ]; then
0294                 match="ipproto icmp"
0295                 fib_rule4_test_match_n_redirect "$match" "$match" "ipproto icmp match"
0296         fi
0297 }
0298 
0299 run_fibrule_tests()
0300 {
0301         log_section "IPv4 fib rule"
0302         fib_rule4_test
0303         log_section "IPv6 fib rule"
0304         fib_rule6_test
0305 }
0306 ################################################################################
0307 # usage
0308 
0309 usage()
0310 {
0311         cat <<EOF
0312 usage: ${0##*/} OPTS
0313 
0314         -t <test>   Test(s) to run (default: all)
0315                     (options: $TESTS)
0316 EOF
0317 }
0318 
0319 ################################################################################
0320 # main
0321 
0322 while getopts ":t:h" opt; do
0323         case $opt in
0324                 t) TESTS=$OPTARG;;
0325                 h) usage; exit 0;;
0326                 *) usage; exit 1;;
0327         esac
0328 done
0329 
0330 if [ "$(id -u)" -ne 0 ];then
0331         echo "SKIP: Need root privileges"
0332         exit $ksft_skip
0333 fi
0334 
0335 if [ ! -x "$(command -v ip)" ]; then
0336         echo "SKIP: Could not run test without ip tool"
0337         exit $ksft_skip
0338 fi
0339 
0340 # start clean
0341 cleanup &> /dev/null
0342 setup
0343 for t in $TESTS
0344 do
0345         case $t in
0346         fib_rule6_test|fib_rule6)               fib_rule6_test;;
0347         fib_rule4_test|fib_rule4)               fib_rule4_test;;
0348 
0349         help) echo "Test names: $TESTS"; exit 0;;
0350 
0351         esac
0352 done
0353 cleanup
0354 
0355 if [ "$TESTS" != "none" ]; then
0356         printf "\nTests passed: %3d\n" ${nsuccess}
0357         printf "Tests failed: %3d\n"   ${nfail}
0358 fi
0359 
0360 exit $ret