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