Skip to content

Commit

Permalink
selftests: netdevsim: Add fib_notifications test
Browse files Browse the repository at this point in the history
Add test to check fib notifications behavior.

The test checks route addition, route deletion and route replacement for
both IPv4 and IPv6.

When fib_notify_on_flag_change=0, expect single notification for route
addition/deletion/replacement.

When fib_notify_on_flag_change=1, expect:
- two notification for route addition/replacement, first without RTM_F_TRAP
  and second with RTM_F_TRAP.
- single notification for route deletion.

$ ./fib_notifications.sh
TEST: IPv4 route addition                                           [ OK ]
TEST: IPv4 route deletion                                           [ OK ]
TEST: IPv4 route replacement                                        [ OK ]
TEST: IPv6 route addition                                           [ OK ]
TEST: IPv6 route deletion                                           [ OK ]
TEST: IPv6 route replacement                                        [ OK ]

Signed-off-by: Amit Cohen <amcohen@nvidia.com>
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
  • Loading branch information
Amit Cohen authored and Jakub Kicinski committed Feb 3, 2021
1 parent d1a7a48 commit 19d36d2
Showing 1 changed file with 300 additions and 0 deletions.
300 changes: 300 additions & 0 deletions tools/testing/selftests/drivers/net/netdevsim/fib_notifications.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,300 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0

lib_dir=$(dirname $0)/../../../net/forwarding

ALL_TESTS="
ipv4_route_addition_test
ipv4_route_deletion_test
ipv4_route_replacement_test
ipv6_route_addition_test
ipv6_route_deletion_test
ipv6_route_replacement_test
"

NETDEVSIM_PATH=/sys/bus/netdevsim/
DEV_ADDR=1337
DEV=netdevsim${DEV_ADDR}
DEVLINK_DEV=netdevsim/${DEV}
SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
NUM_NETIFS=0
source $lib_dir/lib.sh

check_rt_trap()
{
local outfile=$1; shift
local line

# Make sure that the first notification was emitted without RTM_F_TRAP
# flag and the second with RTM_F_TRAP flag
head -n 1 $outfile | grep -q "rt_trap"
if [[ $? -eq 0 ]]; then
return 1
fi

head -n 2 $outfile | tail -n 1 | grep -q "rt_trap"
}

route_notify_check()
{
local outfile=$1; shift
local expected_num_lines=$1; shift

# check the monitor results
lines=`wc -l $outfile | cut "-d " -f1`
test $lines -eq $expected_num_lines
check_err $? "$expected_num_lines notifications were expected but $lines were received"

if [[ $expected_num_lines -eq 2 ]]; then
check_rt_trap $outfile
check_err $? "Wrong RTM_F_TRAP flags in notifications"
fi
}

route_addition_check()
{
local ip=$1; shift
local notify=$1; shift
local route=$1; shift
local expected_num_notifications=$1; shift

ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify

local outfile=$(mktemp)

$IP monitor route &> $outfile &
sleep 1
$IP route add $route dev dummy1
sleep 1
kill %% && wait %% &> /dev/null

route_notify_check $outfile $expected_num_notifications
rm -f $outfile

$IP route del $route dev dummy1
}

ipv4_route_addition_test()
{
RET=0

local ip="ipv4"
local route=192.0.2.0/24

# Make sure a single notification will be emitted for the programmed
# route.
local notify=0
local expected_num_notifications=1
# route_addition_check will assign value to RET.
route_addition_check $ip $notify $route $expected_num_notifications

# Make sure two notifications will be emitted for the programmed route.
notify=1
expected_num_notifications=2
route_addition_check $ip $notify $route $expected_num_notifications

log_test "IPv4 route addition"
}

route_deletion_check()
{
local ip=$1; shift
local notify=$1; shift
local route=$1; shift
local expected_num_notifications=$1; shift

ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify
$IP route add $route dev dummy1
sleep 1

local outfile=$(mktemp)

$IP monitor route &> $outfile &
sleep 1
$IP route del $route dev dummy1
sleep 1
kill %% && wait %% &> /dev/null

route_notify_check $outfile $expected_num_notifications
rm -f $outfile
}

ipv4_route_deletion_test()
{
RET=0

local ip="ipv4"
local route=192.0.2.0/24
local expected_num_notifications=1

# Make sure a single notification will be emitted for the deleted route,
# regardless of fib_notify_on_flag_change value.
local notify=0
# route_deletion_check will assign value to RET.
route_deletion_check $ip $notify $route $expected_num_notifications

notify=1
route_deletion_check $ip $notify $route $expected_num_notifications

log_test "IPv4 route deletion"
}

route_replacement_check()
{
local ip=$1; shift
local notify=$1; shift
local route=$1; shift
local expected_num_notifications=$1; shift

ip netns exec testns1 sysctl -qw net.$ip.fib_notify_on_flag_change=$notify
$IP route add $route dev dummy1
sleep 1

local outfile=$(mktemp)

$IP monitor route &> $outfile &
sleep 1
$IP route replace $route dev dummy2
sleep 1
kill %% && wait %% &> /dev/null

route_notify_check $outfile $expected_num_notifications
rm -f $outfile

$IP route del $route dev dummy2
}

ipv4_route_replacement_test()
{
RET=0

local ip="ipv4"
local route=192.0.2.0/24

$IP link add name dummy2 type dummy
$IP link set dev dummy2 up

# Make sure a single notification will be emitted for the new route.
local notify=0
local expected_num_notifications=1
# route_replacement_check will assign value to RET.
route_replacement_check $ip $notify $route $expected_num_notifications

# Make sure two notifications will be emitted for the new route.
notify=1
expected_num_notifications=2
route_replacement_check $ip $notify $route $expected_num_notifications

$IP link del name dummy2

log_test "IPv4 route replacement"
}

ipv6_route_addition_test()
{
RET=0

local ip="ipv6"
local route=2001:db8:1::/64

# Make sure a single notification will be emitted for the programmed
# route.
local notify=0
local expected_num_notifications=1
route_addition_check $ip $notify $route $expected_num_notifications

# Make sure two notifications will be emitted for the programmed route.
notify=1
expected_num_notifications=2
route_addition_check $ip $notify $route $expected_num_notifications

log_test "IPv6 route addition"
}

ipv6_route_deletion_test()
{
RET=0

local ip="ipv6"
local route=2001:db8:1::/64
local expected_num_notifications=1

# Make sure a single notification will be emitted for the deleted route,
# regardless of fib_notify_on_flag_change value.
local notify=0
route_deletion_check $ip $notify $route $expected_num_notifications

notify=1
route_deletion_check $ip $notify $route $expected_num_notifications

log_test "IPv6 route deletion"
}

ipv6_route_replacement_test()
{
RET=0

local ip="ipv6"
local route=2001:db8:1::/64

$IP link add name dummy2 type dummy
$IP link set dev dummy2 up

# Make sure a single notification will be emitted for the new route.
local notify=0
local expected_num_notifications=1
route_replacement_check $ip $notify $route $expected_num_notifications

# Make sure two notifications will be emitted for the new route.
notify=1
expected_num_notifications=2
route_replacement_check $ip $notify $route $expected_num_notifications

$IP link del name dummy2

log_test "IPv6 route replacement"
}

setup_prepare()
{
modprobe netdevsim &> /dev/null
echo "$DEV_ADDR 1" > ${NETDEVSIM_PATH}/new_device
while [ ! -d $SYSFS_NET_DIR ] ; do :; done

ip netns add testns1

if [ $? -ne 0 ]; then
echo "Failed to add netns \"testns1\""
exit 1
fi

devlink dev reload $DEVLINK_DEV netns testns1

if [ $? -ne 0 ]; then
echo "Failed to reload into netns \"testns1\""
exit 1
fi

IP="ip -n testns1"

$IP link add name dummy1 type dummy
$IP link set dev dummy1 up
}

cleanup()
{
pre_cleanup

$IP link del name dummy1
ip netns del testns1
echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
modprobe -r netdevsim &> /dev/null
}

trap cleanup EXIT

setup_prepare

tests_run

exit $EXIT_STATUS

0 comments on commit 19d36d2

Please sign in to comment.