2018-05-23 00:03:29 +03:00
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# This test is for checking IPv4 and IPv6 FIB rules API
2021-08-23 11:58:54 +03:00
# Kselftest framework requirement - SKIP code is 4.
ksft_skip = 4
2018-05-23 00:03:29 +03:00
ret = 0
PAUSE_ON_FAIL = ${ PAUSE_ON_FAIL : =no }
IP = "ip -netns testns"
RTABLE = 100
GW_IP4 = 192.51.100.2
SRC_IP = 192.51.100.3
GW_IP6 = 2001:db8:1::2
SRC_IP6 = 2001:db8:1::3
DEV_ADDR = 192.51.100.1
2019-05-21 09:40:47 +03:00
DEV_ADDR6 = 2001:db8:1::1
2018-05-23 00:03:29 +03:00
DEV = dummy0
2022-04-12 05:04:31 +03:00
TESTS = "fib_rule6 fib_rule4"
2018-05-23 00:03:29 +03:00
log_test( )
{
local rc = $1
local expected = $2
local msg = " $3 "
if [ ${ rc } -eq ${ expected } ] ; then
nsuccess = $(( nsuccess+1))
printf "\n TEST: %-50s [ OK ]\n" " ${ msg } "
else
2019-04-30 05:46:10 +03:00
ret = 1
2018-05-23 00:03:29 +03:00
nfail = $(( nfail+1))
printf "\n TEST: %-50s [FAIL]\n" " ${ msg } "
if [ " ${ PAUSE_ON_FAIL } " = "yes" ] ; then
echo
echo "hit enter to continue, 'q' to quit"
read a
[ " $a " = "q" ] && exit 1
fi
fi
}
log_section( )
{
echo
echo "######################################################################"
echo " TEST SECTION: $* "
echo "######################################################################"
}
setup( )
{
set -e
ip netns add testns
$IP link set dev lo up
$IP link add dummy0 type dummy
$IP link set dev dummy0 up
2019-05-21 09:40:47 +03:00
$IP address add $DEV_ADDR /24 dev dummy0
$IP -6 address add $DEV_ADDR6 /64 dev dummy0
2018-05-23 00:03:29 +03:00
set +e
}
cleanup( )
{
$IP link del dev dummy0 & > /dev/null
ip netns del testns
}
fib_check_iproute_support( )
{
ip rule help 2>& 1 | grep -q $1
if [ $? -ne 0 ] ; then
echo " SKIP: iproute2 iprule too old, missing $1 match "
return 1
fi
ip route get help 2>& 1 | grep -q $2
if [ $? -ne 0 ] ; then
echo " SKIP: iproute2 get route too old, missing $2 match "
return 1
fi
return 0
}
fib_rule6_del( )
{
$IP -6 rule del $1
log_test $? 0 " rule6 del $1 "
}
fib_rule6_del_by_pref( )
{
2022-01-31 18:42:04 +03:00
pref = $( $IP -6 rule show $1 table $RTABLE | cut -d ":" -f 1)
2018-05-23 00:03:29 +03:00
$IP -6 rule del pref $pref
}
fib_rule6_test_match_n_redirect( )
{
local match = " $1 "
local getmatch = " $2 "
2022-01-31 18:42:06 +03:00
local description = " $3 "
2018-05-23 00:03:29 +03:00
$IP -6 rule add $match table $RTABLE
$IP -6 route get $GW_IP6 $getmatch | grep -q " table $RTABLE "
2022-01-31 18:42:06 +03:00
log_test $? 0 " rule6 check: $description "
2018-05-23 00:03:29 +03:00
fib_rule6_del_by_pref " $match "
2022-01-31 18:42:06 +03:00
log_test $? 0 " rule6 del by pref: $description "
2018-05-23 00:03:29 +03:00
}
2022-02-04 16:58:11 +03:00
fib_rule6_test_reject( )
{
local match = " $1 "
local rc
$IP -6 rule add $match table $RTABLE 2>/dev/null
rc = $?
log_test $rc 2 " rule6 check: $match "
if [ $rc -eq 0 ] ; then
$IP -6 rule del $match table $RTABLE
fi
}
2018-05-23 00:03:29 +03:00
fib_rule6_test( )
{
2022-01-31 18:42:01 +03:00
local getmatch
local match
2022-02-04 16:58:11 +03:00
local cnt
2022-01-31 18:42:01 +03:00
2018-05-23 00:03:29 +03:00
# setup the fib rule redirect route
$IP -6 route add table $RTABLE default via $GW_IP6 dev $DEV onlink
match = " oif $DEV "
fib_rule6_test_match_n_redirect " $match " " $match " "oif redirect to table"
match = " from $SRC_IP6 iif $DEV "
fib_rule6_test_match_n_redirect " $match " " $match " "iif redirect to table"
2022-02-04 16:58:11 +03:00
# Reject dsfield (tos) options which have ECN bits set
for cnt in $( seq 1 3) ; do
match = " dsfield $cnt "
fib_rule6_test_reject " $match "
done
# Don't take ECN bits into account when matching on dsfield
2018-05-23 00:03:29 +03:00
match = "tos 0x10"
2022-02-04 16:58:11 +03:00
for cnt in "0x10" "0x11" "0x12" "0x13" ; do
# Using option 'tos' instead of 'dsfield' as old iproute2
# versions don't support 'dsfield' in ip rule show.
getmatch = " tos $cnt "
fib_rule6_test_match_n_redirect " $match " " $getmatch " \
" $getmatch redirect to table "
done
2018-05-23 00:03:29 +03:00
match = "fwmark 0x64"
getmatch = "mark 0x64"
fib_rule6_test_match_n_redirect " $match " " $getmatch " "fwmark redirect to table"
fib_check_iproute_support "uidrange" "uid"
if [ $? -eq 0 ] ; then
match = "uidrange 100-100"
getmatch = "uid 100"
fib_rule6_test_match_n_redirect " $match " " $getmatch " "uid redirect to table"
fi
fib_check_iproute_support "sport" "sport"
if [ $? -eq 0 ] ; then
match = "sport 666 dport 777"
fib_rule6_test_match_n_redirect " $match " " $match " "sport and dport redirect to table"
fi
fib_check_iproute_support "ipproto" "ipproto"
if [ $? -eq 0 ] ; then
match = "ipproto tcp"
fib_rule6_test_match_n_redirect " $match " " $match " "ipproto match"
fi
fib_check_iproute_support "ipproto" "ipproto"
if [ $? -eq 0 ] ; then
2019-04-29 20:30:09 +03:00
match = "ipproto ipv6-icmp"
fib_rule6_test_match_n_redirect " $match " " $match " "ipproto ipv6-icmp match"
2018-05-23 00:03:29 +03:00
fi
}
fib_rule4_del( )
{
$IP rule del $1
log_test $? 0 " del $1 "
}
fib_rule4_del_by_pref( )
{
2022-01-31 18:42:04 +03:00
pref = $( $IP rule show $1 table $RTABLE | cut -d ":" -f 1)
2018-05-23 00:03:29 +03:00
$IP rule del pref $pref
}
fib_rule4_test_match_n_redirect( )
{
local match = " $1 "
local getmatch = " $2 "
2022-01-31 18:42:06 +03:00
local description = " $3 "
2018-05-23 00:03:29 +03:00
$IP rule add $match table $RTABLE
$IP route get $GW_IP4 $getmatch | grep -q " table $RTABLE "
2022-01-31 18:42:06 +03:00
log_test $? 0 " rule4 check: $description "
2018-05-23 00:03:29 +03:00
fib_rule4_del_by_pref " $match "
2022-01-31 18:42:06 +03:00
log_test $? 0 " rule4 del by pref: $description "
2018-05-23 00:03:29 +03:00
}
2022-02-04 16:58:14 +03:00
fib_rule4_test_reject( )
{
local match = " $1 "
local rc
$IP rule add $match table $RTABLE 2>/dev/null
rc = $?
log_test $rc 2 " rule4 check: $match "
if [ $rc -eq 0 ] ; then
$IP rule del $match table $RTABLE
fi
}
2018-05-23 00:03:29 +03:00
fib_rule4_test( )
{
2022-01-31 18:42:01 +03:00
local getmatch
local match
2022-02-04 16:58:14 +03:00
local cnt
2022-01-31 18:42:01 +03:00
2018-05-23 00:03:29 +03:00
# setup the fib rule redirect route
$IP route add table $RTABLE default via $GW_IP4 dev $DEV onlink
match = " oif $DEV "
fib_rule4_test_match_n_redirect " $match " " $match " "oif redirect to table"
2019-05-20 07:36:55 +03:00
# need enable forwarding and disable rp_filter temporarily as all the
# addresses are in the same subnet and egress device == ingress device.
2022-01-31 18:42:09 +03:00
ip netns exec testns sysctl -qw net.ipv4.ip_forward= 1
ip netns exec testns sysctl -qw net.ipv4.conf.$DEV .rp_filter= 0
2018-05-23 00:03:29 +03:00
match = " from $SRC_IP iif $DEV "
fib_rule4_test_match_n_redirect " $match " " $match " "iif redirect to table"
2022-01-31 18:42:09 +03:00
ip netns exec testns sysctl -qw net.ipv4.ip_forward= 0
2018-05-23 00:03:29 +03:00
2022-02-04 16:58:14 +03:00
# Reject dsfield (tos) options which have ECN bits set
for cnt in $( seq 1 3) ; do
match = " dsfield $cnt "
fib_rule4_test_reject " $match "
done
# Don't take ECN bits into account when matching on dsfield
2018-05-23 00:03:29 +03:00
match = "tos 0x10"
2022-02-04 16:58:14 +03:00
for cnt in "0x10" "0x11" "0x12" "0x13" ; do
# Using option 'tos' instead of 'dsfield' as old iproute2
# versions don't support 'dsfield' in ip rule show.
getmatch = " tos $cnt "
fib_rule4_test_match_n_redirect " $match " " $getmatch " \
" $getmatch redirect to table "
done
2018-05-23 00:03:29 +03:00
match = "fwmark 0x64"
getmatch = "mark 0x64"
fib_rule4_test_match_n_redirect " $match " " $getmatch " "fwmark redirect to table"
fib_check_iproute_support "uidrange" "uid"
if [ $? -eq 0 ] ; then
match = "uidrange 100-100"
getmatch = "uid 100"
fib_rule4_test_match_n_redirect " $match " " $getmatch " "uid redirect to table"
fi
fib_check_iproute_support "sport" "sport"
if [ $? -eq 0 ] ; then
match = "sport 666 dport 777"
fib_rule4_test_match_n_redirect " $match " " $match " "sport and dport redirect to table"
fi
fib_check_iproute_support "ipproto" "ipproto"
if [ $? -eq 0 ] ; then
match = "ipproto tcp"
fib_rule4_test_match_n_redirect " $match " " $match " "ipproto tcp match"
fi
fib_check_iproute_support "ipproto" "ipproto"
if [ $? -eq 0 ] ; then
match = "ipproto icmp"
fib_rule4_test_match_n_redirect " $match " " $match " "ipproto icmp match"
fi
}
run_fibrule_tests( )
{
log_section "IPv4 fib rule"
fib_rule4_test
log_section "IPv6 fib rule"
fib_rule6_test
}
2022-06-30 13:24:49 +03:00
################################################################################
# usage
usage( )
{
cat <<EOF
usage: ${ 0 ##*/ } OPTS
-t <test> Test( s) to run ( default: all)
( options: $TESTS )
EOF
}
################################################################################
# main
while getopts ":t:h" opt; do
case $opt in
t) TESTS = $OPTARG ; ;
h) usage; exit 0; ;
*) usage; exit 1; ;
esac
done
2018-05-23 00:03:29 +03:00
if [ " $( id -u) " -ne 0 ] ; then
echo "SKIP: Need root privileges"
2021-08-23 11:58:54 +03:00
exit $ksft_skip
2018-05-23 00:03:29 +03:00
fi
if [ ! -x " $( command -v ip) " ] ; then
echo "SKIP: Could not run test without ip tool"
2021-08-23 11:58:54 +03:00
exit $ksft_skip
2018-05-23 00:03:29 +03:00
fi
# start clean
cleanup & > /dev/null
setup
2022-04-12 05:04:31 +03:00
for t in $TESTS
do
case $t in
fib_rule6_test| fib_rule6) fib_rule6_test; ;
fib_rule4_test| fib_rule4) fib_rule4_test; ;
help ) echo " Test names: $TESTS " ; exit 0; ;
esac
done
2018-05-23 00:03:29 +03:00
cleanup
2019-04-30 05:46:10 +03:00
if [ " $TESTS " != "none" ] ; then
printf "\nTests passed: %3d\n" ${ nsuccess }
printf "Tests failed: %3d\n" ${ nfail }
fi
2018-05-23 00:03:29 +03:00
exit $ret