Add IPv4 and IPv6 test cases that ensure that we are not leaking a reference on the nexthop device when we are unable to delete its associated route. Without the fix in a previous patch ("netdevsim: fib: Fix reference count leak on route deletion failure") both test cases get stuck, waiting for the reference to be released from the dummy device [1][2]. [1] unregister_netdevice: waiting for dummy1 to become free. Usage count = 5 leaked reference. fib_check_nh+0x275/0x620 fib_create_info+0x237c/0x4d30 fib_table_insert+0x1dd/0x1d20 inet_rtm_newroute+0x11b/0x200 rtnetlink_rcv_msg+0x43b/0xd20 netlink_rcv_skb+0x15e/0x430 netlink_unicast+0x53b/0x800 netlink_sendmsg+0x945/0xe40 ____sys_sendmsg+0x747/0x960 ___sys_sendmsg+0x11d/0x190 __sys_sendmsg+0x118/0x1e0 do_syscall_64+0x34/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd [2] unregister_netdevice: waiting for dummy1 to become free. Usage count = 5 leaked reference. fib6_nh_init+0xc46/0x1ca0 ip6_route_info_create+0x1167/0x19a0 ip6_route_add+0x27/0x150 inet6_rtm_newroute+0x161/0x170 rtnetlink_rcv_msg+0x43b/0xd20 netlink_rcv_skb+0x15e/0x430 netlink_unicast+0x53b/0x800 netlink_sendmsg+0x945/0xe40 ____sys_sendmsg+0x747/0x960 ___sys_sendmsg+0x11d/0x190 __sys_sendmsg+0x118/0x1e0 do_syscall_64+0x34/0x80 entry_SYSCALL_64_after_hwframe+0x63/0xcd Signed-off-by: Ido Schimmel <idosch@nvidia.com> Reviewed-by: Amit Cohen <amcohen@nvidia.com> Reviewed-by: David Ahern <dsahern@kernel.org> Signed-off-by: David S. Miller <davem@davemloft.net>
402 lines
7.5 KiB
Bash
Executable file
402 lines
7.5 KiB
Bash
Executable file
#!/bin/bash
|
|
# SPDX-License-Identifier: GPL-2.0
|
|
#
|
|
# This test is for checking the FIB offload API. It makes use of netdevsim
|
|
# which registers a listener to the FIB notification chain.
|
|
|
|
lib_dir=$(dirname $0)/../../../net/forwarding
|
|
|
|
ALL_TESTS="
|
|
ipv4_identical_routes
|
|
ipv4_tos
|
|
ipv4_metric
|
|
ipv4_replace
|
|
ipv4_delete
|
|
ipv4_plen
|
|
ipv4_replay
|
|
ipv4_flush
|
|
ipv4_error_path
|
|
ipv4_delete_fail
|
|
ipv6_add
|
|
ipv6_metric
|
|
ipv6_append_single
|
|
ipv6_replace_single
|
|
ipv6_metric_multipath
|
|
ipv6_append_multipath
|
|
ipv6_replace_multipath
|
|
ipv6_append_multipath_to_single
|
|
ipv6_delete_single
|
|
ipv6_delete_multipath
|
|
ipv6_replay_single
|
|
ipv6_replay_multipath
|
|
ipv6_error_path
|
|
ipv6_delete_fail
|
|
"
|
|
NETDEVSIM_PATH=/sys/bus/netdevsim/
|
|
DEV_ADDR=1337
|
|
DEV=netdevsim${DEV_ADDR}
|
|
SYSFS_NET_DIR=/sys/bus/netdevsim/devices/$DEV/net/
|
|
DEBUGFS_DIR=/sys/kernel/debug/netdevsim/$DEV/
|
|
NUM_NETIFS=0
|
|
source $lib_dir/lib.sh
|
|
source $lib_dir/fib_offload_lib.sh
|
|
|
|
DEVLINK_DEV=
|
|
source $lib_dir/devlink_lib.sh
|
|
DEVLINK_DEV=netdevsim/${DEV}
|
|
|
|
ipv4_identical_routes()
|
|
{
|
|
fib_ipv4_identical_routes_test "testns1"
|
|
}
|
|
|
|
ipv4_tos()
|
|
{
|
|
fib_ipv4_tos_test "testns1"
|
|
}
|
|
|
|
ipv4_metric()
|
|
{
|
|
fib_ipv4_metric_test "testns1"
|
|
}
|
|
|
|
ipv4_replace()
|
|
{
|
|
fib_ipv4_replace_test "testns1"
|
|
}
|
|
|
|
ipv4_delete()
|
|
{
|
|
fib_ipv4_delete_test "testns1"
|
|
}
|
|
|
|
ipv4_plen()
|
|
{
|
|
fib_ipv4_plen_test "testns1"
|
|
}
|
|
|
|
ipv4_replay_metric()
|
|
{
|
|
fib_ipv4_replay_metric_test "testns1" "$DEVLINK_DEV"
|
|
}
|
|
|
|
ipv4_replay_tos()
|
|
{
|
|
fib_ipv4_replay_tos_test "testns1" "$DEVLINK_DEV"
|
|
}
|
|
|
|
ipv4_replay_plen()
|
|
{
|
|
fib_ipv4_replay_plen_test "testns1" "$DEVLINK_DEV"
|
|
}
|
|
|
|
ipv4_replay()
|
|
{
|
|
ipv4_replay_metric
|
|
ipv4_replay_tos
|
|
ipv4_replay_plen
|
|
}
|
|
|
|
ipv4_flush()
|
|
{
|
|
fib_ipv4_flush_test "testns1"
|
|
}
|
|
|
|
ipv4_error_path_add()
|
|
{
|
|
local lsb
|
|
|
|
RET=0
|
|
|
|
ip -n testns1 link add name dummy1 type dummy
|
|
ip -n testns1 link set dev dummy1 up
|
|
|
|
devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 10
|
|
devlink -N testns1 dev reload $DEVLINK_DEV
|
|
|
|
for lsb in $(seq 1 20); do
|
|
ip -n testns1 route add 192.0.2.${lsb}/32 dev dummy1 \
|
|
&> /dev/null
|
|
done
|
|
|
|
log_test "IPv4 error path - add"
|
|
|
|
ip -n testns1 link del dev dummy1
|
|
}
|
|
|
|
ipv4_error_path_replay()
|
|
{
|
|
local lsb
|
|
|
|
RET=0
|
|
|
|
ip -n testns1 link add name dummy1 type dummy
|
|
ip -n testns1 link set dev dummy1 up
|
|
|
|
devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 100
|
|
devlink -N testns1 dev reload $DEVLINK_DEV
|
|
|
|
for lsb in $(seq 1 20); do
|
|
ip -n testns1 route add 192.0.2.${lsb}/32 dev dummy1
|
|
done
|
|
|
|
devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 10
|
|
devlink -N testns1 dev reload $DEVLINK_DEV &> /dev/null
|
|
|
|
log_test "IPv4 error path - replay"
|
|
|
|
ip -n testns1 link del dev dummy1
|
|
|
|
# Successfully reload after deleting all the routes.
|
|
devlink -N testns1 resource set $DEVLINK_DEV path IPv4/fib size 100
|
|
devlink -N testns1 dev reload $DEVLINK_DEV
|
|
}
|
|
|
|
ipv4_error_path()
|
|
{
|
|
# Test the different error paths of the notifiers by limiting the size
|
|
# of the "IPv4/fib" resource.
|
|
ipv4_error_path_add
|
|
ipv4_error_path_replay
|
|
}
|
|
|
|
ipv4_delete_fail()
|
|
{
|
|
RET=0
|
|
|
|
echo "y" > $DEBUGFS_DIR/fib/fail_route_delete
|
|
|
|
ip -n testns1 link add name dummy1 type dummy
|
|
ip -n testns1 link set dev dummy1 up
|
|
|
|
ip -n testns1 route add 192.0.2.0/24 dev dummy1
|
|
ip -n testns1 route del 192.0.2.0/24 dev dummy1 &> /dev/null
|
|
|
|
# We should not be able to delete the netdev if we are leaking a
|
|
# reference.
|
|
ip -n testns1 link del dev dummy1
|
|
|
|
log_test "IPv4 route delete failure"
|
|
|
|
echo "n" > $DEBUGFS_DIR/fib/fail_route_delete
|
|
}
|
|
|
|
ipv6_add()
|
|
{
|
|
fib_ipv6_add_test "testns1"
|
|
}
|
|
|
|
ipv6_metric()
|
|
{
|
|
fib_ipv6_metric_test "testns1"
|
|
}
|
|
|
|
ipv6_append_single()
|
|
{
|
|
fib_ipv6_append_single_test "testns1"
|
|
}
|
|
|
|
ipv6_replace_single()
|
|
{
|
|
fib_ipv6_replace_single_test "testns1"
|
|
}
|
|
|
|
ipv6_metric_multipath()
|
|
{
|
|
fib_ipv6_metric_multipath_test "testns1"
|
|
}
|
|
|
|
ipv6_append_multipath()
|
|
{
|
|
fib_ipv6_append_multipath_test "testns1"
|
|
}
|
|
|
|
ipv6_replace_multipath()
|
|
{
|
|
fib_ipv6_replace_multipath_test "testns1"
|
|
}
|
|
|
|
ipv6_append_multipath_to_single()
|
|
{
|
|
fib_ipv6_append_multipath_to_single_test "testns1"
|
|
}
|
|
|
|
ipv6_delete_single()
|
|
{
|
|
fib_ipv6_delete_single_test "testns1"
|
|
}
|
|
|
|
ipv6_delete_multipath()
|
|
{
|
|
fib_ipv6_delete_multipath_test "testns1"
|
|
}
|
|
|
|
ipv6_replay_single()
|
|
{
|
|
fib_ipv6_replay_single_test "testns1" "$DEVLINK_DEV"
|
|
}
|
|
|
|
ipv6_replay_multipath()
|
|
{
|
|
fib_ipv6_replay_multipath_test "testns1" "$DEVLINK_DEV"
|
|
}
|
|
|
|
ipv6_error_path_add_single()
|
|
{
|
|
local lsb
|
|
|
|
RET=0
|
|
|
|
ip -n testns1 link add name dummy1 type dummy
|
|
ip -n testns1 link set dev dummy1 up
|
|
|
|
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 10
|
|
devlink -N testns1 dev reload $DEVLINK_DEV
|
|
|
|
for lsb in $(seq 1 20); do
|
|
ip -n testns1 route add 2001:db8:1::${lsb}/128 dev dummy1 \
|
|
&> /dev/null
|
|
done
|
|
|
|
log_test "IPv6 error path - add single"
|
|
|
|
ip -n testns1 link del dev dummy1
|
|
}
|
|
|
|
ipv6_error_path_add_multipath()
|
|
{
|
|
local lsb
|
|
|
|
RET=0
|
|
|
|
for i in $(seq 1 2); do
|
|
ip -n testns1 link add name dummy$i type dummy
|
|
ip -n testns1 link set dev dummy$i up
|
|
ip -n testns1 address add 2001:db8:$i::1/64 dev dummy$i
|
|
done
|
|
|
|
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 10
|
|
devlink -N testns1 dev reload $DEVLINK_DEV
|
|
|
|
for lsb in $(seq 1 20); do
|
|
ip -n testns1 route add 2001:db8:10::${lsb}/128 \
|
|
nexthop via 2001:db8:1::2 dev dummy1 \
|
|
nexthop via 2001:db8:2::2 dev dummy2 &> /dev/null
|
|
done
|
|
|
|
log_test "IPv6 error path - add multipath"
|
|
|
|
for i in $(seq 1 2); do
|
|
ip -n testns1 link del dev dummy$i
|
|
done
|
|
}
|
|
|
|
ipv6_error_path_replay()
|
|
{
|
|
local lsb
|
|
|
|
RET=0
|
|
|
|
ip -n testns1 link add name dummy1 type dummy
|
|
ip -n testns1 link set dev dummy1 up
|
|
|
|
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 100
|
|
devlink -N testns1 dev reload $DEVLINK_DEV
|
|
|
|
for lsb in $(seq 1 20); do
|
|
ip -n testns1 route add 2001:db8:1::${lsb}/128 dev dummy1
|
|
done
|
|
|
|
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 10
|
|
devlink -N testns1 dev reload $DEVLINK_DEV &> /dev/null
|
|
|
|
log_test "IPv6 error path - replay"
|
|
|
|
ip -n testns1 link del dev dummy1
|
|
|
|
# Successfully reload after deleting all the routes.
|
|
devlink -N testns1 resource set $DEVLINK_DEV path IPv6/fib size 100
|
|
devlink -N testns1 dev reload $DEVLINK_DEV
|
|
}
|
|
|
|
ipv6_error_path()
|
|
{
|
|
# Test the different error paths of the notifiers by limiting the size
|
|
# of the "IPv6/fib" resource.
|
|
ipv6_error_path_add_single
|
|
ipv6_error_path_add_multipath
|
|
ipv6_error_path_replay
|
|
}
|
|
|
|
ipv6_delete_fail()
|
|
{
|
|
RET=0
|
|
|
|
echo "y" > $DEBUGFS_DIR/fib/fail_route_delete
|
|
|
|
ip -n testns1 link add name dummy1 type dummy
|
|
ip -n testns1 link set dev dummy1 up
|
|
|
|
ip -n testns1 route add 2001:db8:1::/64 dev dummy1
|
|
ip -n testns1 route del 2001:db8:1::/64 dev dummy1 &> /dev/null
|
|
|
|
# We should not be able to delete the netdev if we are leaking a
|
|
# reference.
|
|
ip -n testns1 link del dev dummy1
|
|
|
|
log_test "IPv6 route delete failure"
|
|
|
|
echo "n" > $DEBUGFS_DIR/fib/fail_route_delete
|
|
}
|
|
|
|
fib_notify_on_flag_change_set()
|
|
{
|
|
local notify=$1; shift
|
|
|
|
ip netns exec testns1 sysctl -qw net.ipv4.fib_notify_on_flag_change=$notify
|
|
ip netns exec testns1 sysctl -qw net.ipv6.fib_notify_on_flag_change=$notify
|
|
|
|
log_info "Set fib_notify_on_flag_change to $notify"
|
|
}
|
|
|
|
setup_prepare()
|
|
{
|
|
local netdev
|
|
|
|
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
|
|
}
|
|
|
|
cleanup()
|
|
{
|
|
pre_cleanup
|
|
ip netns del testns1
|
|
echo "$DEV_ADDR" > ${NETDEVSIM_PATH}/del_device
|
|
modprobe -r netdevsim &> /dev/null
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
|
|
setup_prepare
|
|
|
|
fib_notify_on_flag_change_set 1
|
|
tests_run
|
|
|
|
fib_notify_on_flag_change_set 0
|
|
tests_run
|
|
|
|
exit $EXIT_STATUS
|