1#!/bin/bash 2# SPDX-License-Identifier: GPL-2.0 3 4# This test is for checking IPv4 and IPv6 FIB rules API 5 6# Kselftest framework requirement - SKIP code is 4. 7ksft_skip=4 8 9ret=0 10 11PAUSE_ON_FAIL=${PAUSE_ON_FAIL:=no} 12IP="ip -netns testns" 13 14RTABLE=100 15GW_IP4=192.51.100.2 16SRC_IP=192.51.100.3 17GW_IP6=2001:db8:1::2 18SRC_IP6=2001:db8:1::3 19 20DEV_ADDR=192.51.100.1 21DEV_ADDR6=2001:db8:1::1 22DEV=dummy0 23 24log_test() 25{ 26 local rc=$1 27 local expected=$2 28 local msg="$3" 29 30 if [ ${rc} -eq ${expected} ]; then 31 nsuccess=$((nsuccess+1)) 32 printf "\n TEST: %-50s [ OK ]\n" "${msg}" 33 else 34 ret=1 35 nfail=$((nfail+1)) 36 printf "\n TEST: %-50s [FAIL]\n" "${msg}" 37 if [ "${PAUSE_ON_FAIL}" = "yes" ]; then 38 echo 39 echo "hit enter to continue, 'q' to quit" 40 read a 41 [ "$a" = "q" ] && exit 1 42 fi 43 fi 44} 45 46log_section() 47{ 48 echo 49 echo "######################################################################" 50 echo "TEST SECTION: $*" 51 echo "######################################################################" 52} 53 54setup() 55{ 56 set -e 57 ip netns add testns 58 $IP link set dev lo up 59 60 $IP link add dummy0 type dummy 61 $IP link set dev dummy0 up 62 $IP address add $DEV_ADDR/24 dev dummy0 63 $IP -6 address add $DEV_ADDR6/64 dev dummy0 64 65 set +e 66} 67 68cleanup() 69{ 70 $IP link del dev dummy0 &> /dev/null 71 ip netns del testns 72} 73 74fib_check_iproute_support() 75{ 76 ip rule help 2>&1 | grep -q $1 77 if [ $? -ne 0 ]; then 78 echo "SKIP: iproute2 iprule too old, missing $1 match" 79 return 1 80 fi 81 82 ip route get help 2>&1 | grep -q $2 83 if [ $? -ne 0 ]; then 84 echo "SKIP: iproute2 get route too old, missing $2 match" 85 return 1 86 fi 87 88 return 0 89} 90 91fib_rule6_del() 92{ 93 $IP -6 rule del $1 94 log_test $? 0 "rule6 del $1" 95} 96 97fib_rule6_del_by_pref() 98{ 99 pref=$($IP -6 rule show | grep "$1 lookup $TABLE" | cut -d ":" -f 1) 100 $IP -6 rule del pref $pref 101} 102 103fib_rule6_test_match_n_redirect() 104{ 105 local match="$1" 106 local getmatch="$2" 107 108 $IP -6 rule add $match table $RTABLE 109 $IP -6 route get $GW_IP6 $getmatch | grep -q "table $RTABLE" 110 log_test $? 0 "rule6 check: $1" 111 112 fib_rule6_del_by_pref "$match" 113 log_test $? 0 "rule6 del by pref: $match" 114} 115 116fib_rule6_test() 117{ 118 # setup the fib rule redirect route 119 $IP -6 route add table $RTABLE default via $GW_IP6 dev $DEV onlink 120 121 match="oif $DEV" 122 fib_rule6_test_match_n_redirect "$match" "$match" "oif redirect to table" 123 124 match="from $SRC_IP6 iif $DEV" 125 fib_rule6_test_match_n_redirect "$match" "$match" "iif redirect to table" 126 127 match="tos 0x10" 128 fib_rule6_test_match_n_redirect "$match" "$match" "tos redirect to table" 129 130 match="fwmark 0x64" 131 getmatch="mark 0x64" 132 fib_rule6_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table" 133 134 fib_check_iproute_support "uidrange" "uid" 135 if [ $? -eq 0 ]; then 136 match="uidrange 100-100" 137 getmatch="uid 100" 138 fib_rule6_test_match_n_redirect "$match" "$getmatch" "uid redirect to table" 139 fi 140 141 fib_check_iproute_support "sport" "sport" 142 if [ $? -eq 0 ]; then 143 match="sport 666 dport 777" 144 fib_rule6_test_match_n_redirect "$match" "$match" "sport and dport redirect to table" 145 fi 146 147 fib_check_iproute_support "ipproto" "ipproto" 148 if [ $? -eq 0 ]; then 149 match="ipproto tcp" 150 fib_rule6_test_match_n_redirect "$match" "$match" "ipproto match" 151 fi 152 153 fib_check_iproute_support "ipproto" "ipproto" 154 if [ $? -eq 0 ]; then 155 match="ipproto ipv6-icmp" 156 fib_rule6_test_match_n_redirect "$match" "$match" "ipproto ipv6-icmp match" 157 fi 158} 159 160fib_rule4_del() 161{ 162 $IP rule del $1 163 log_test $? 0 "del $1" 164} 165 166fib_rule4_del_by_pref() 167{ 168 pref=$($IP rule show | grep "$1 lookup $TABLE" | cut -d ":" -f 1) 169 $IP rule del pref $pref 170} 171 172fib_rule4_test_match_n_redirect() 173{ 174 local match="$1" 175 local getmatch="$2" 176 177 $IP rule add $match table $RTABLE 178 $IP route get $GW_IP4 $getmatch | grep -q "table $RTABLE" 179 log_test $? 0 "rule4 check: $1" 180 181 fib_rule4_del_by_pref "$match" 182 log_test $? 0 "rule4 del by pref: $match" 183} 184 185fib_rule4_test() 186{ 187 # setup the fib rule redirect route 188 $IP route add table $RTABLE default via $GW_IP4 dev $DEV onlink 189 190 match="oif $DEV" 191 fib_rule4_test_match_n_redirect "$match" "$match" "oif redirect to table" 192 193 # need enable forwarding and disable rp_filter temporarily as all the 194 # addresses are in the same subnet and egress device == ingress device. 195 ip netns exec testns sysctl -w net.ipv4.ip_forward=1 196 ip netns exec testns sysctl -w net.ipv4.conf.$DEV.rp_filter=0 197 match="from $SRC_IP iif $DEV" 198 fib_rule4_test_match_n_redirect "$match" "$match" "iif redirect to table" 199 ip netns exec testns sysctl -w net.ipv4.ip_forward=0 200 201 match="tos 0x10" 202 fib_rule4_test_match_n_redirect "$match" "$match" "tos redirect to table" 203 204 match="fwmark 0x64" 205 getmatch="mark 0x64" 206 fib_rule4_test_match_n_redirect "$match" "$getmatch" "fwmark redirect to table" 207 208 fib_check_iproute_support "uidrange" "uid" 209 if [ $? -eq 0 ]; then 210 match="uidrange 100-100" 211 getmatch="uid 100" 212 fib_rule4_test_match_n_redirect "$match" "$getmatch" "uid redirect to table" 213 fi 214 215 fib_check_iproute_support "sport" "sport" 216 if [ $? -eq 0 ]; then 217 match="sport 666 dport 777" 218 fib_rule4_test_match_n_redirect "$match" "$match" "sport and dport redirect to table" 219 fi 220 221 fib_check_iproute_support "ipproto" "ipproto" 222 if [ $? -eq 0 ]; then 223 match="ipproto tcp" 224 fib_rule4_test_match_n_redirect "$match" "$match" "ipproto tcp match" 225 fi 226 227 fib_check_iproute_support "ipproto" "ipproto" 228 if [ $? -eq 0 ]; then 229 match="ipproto icmp" 230 fib_rule4_test_match_n_redirect "$match" "$match" "ipproto icmp match" 231 fi 232} 233 234run_fibrule_tests() 235{ 236 log_section "IPv4 fib rule" 237 fib_rule4_test 238 log_section "IPv6 fib rule" 239 fib_rule6_test 240} 241 242if [ "$(id -u)" -ne 0 ];then 243 echo "SKIP: Need root privileges" 244 exit $ksft_skip 245fi 246 247if [ ! -x "$(command -v ip)" ]; then 248 echo "SKIP: Could not run test without ip tool" 249 exit $ksft_skip 250fi 251 252# start clean 253cleanup &> /dev/null 254setup 255run_fibrule_tests 256cleanup 257 258if [ "$TESTS" != "none" ]; then 259 printf "\nTests passed: %3d\n" ${nsuccess} 260 printf "Tests failed: %3d\n" ${nfail} 261fi 262 263exit $ret 264