routing: Add tests for metric
Add tests to make sure: * Default metric is enforced. * Lowest metric wins. * Deleting routes by specifying gateway/metric works. Reviewed by: markj Differential Revision: https://reviews.freebsd.org/D57016
This commit is contained in:
@@ -8,6 +8,7 @@ ATF_TESTS_C += test_rtsock_lladdr
|
||||
ATF_TESTS_C += test_rtsock_ops
|
||||
ATF_TESTS_PYTEST += test_routing_l3.py
|
||||
ATF_TESTS_PYTEST += test_rtsock_multipath.py
|
||||
ATF_TESTS_SH+= test_routing
|
||||
|
||||
${PACKAGE}FILES+= generic_cleanup.sh
|
||||
${PACKAGE}FILESMODE_generic_cleanup.sh=0555
|
||||
@@ -15,6 +16,8 @@ ${PACKAGE}FILESMODE_generic_cleanup.sh=0555
|
||||
# Most of the tests operates on a common IPv4/IPv6 prefix,
|
||||
# so running them in parallel will lead to weird results.
|
||||
TEST_METADATA+= is_exclusive=true
|
||||
TEST_METADATA.test_routing+= execenv="jail" \
|
||||
execenv_jail_params="vnet"
|
||||
|
||||
CFLAGS+= -I${.CURDIR:H:H:H}
|
||||
|
||||
|
||||
Executable
+231
@@ -0,0 +1,231 @@
|
||||
#
|
||||
# Copyright (c) 2026 Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
|
||||
#
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
#
|
||||
|
||||
. $(atf_get_srcdir)/../../common/vnet.subr
|
||||
|
||||
jq_rtentry()
|
||||
{
|
||||
local route="$1"
|
||||
|
||||
jq -r '.statistics."route-information"."route-table"."rt-family".[]."rt-entry".[] |
|
||||
select(.destination == "'${route}'")'
|
||||
}
|
||||
|
||||
jq_nhop_filter()
|
||||
{
|
||||
local nhop="$1"
|
||||
local weight="$2"
|
||||
local metric="$3"
|
||||
|
||||
jq -r 'select(.gateway == "'${nhop}'") |
|
||||
select(.weight == '${weight}') |
|
||||
select(.metric == '${metric}') |
|
||||
.gateway'
|
||||
}
|
||||
|
||||
|
||||
atf_test_case "add_lowest_metric" "cleanup"
|
||||
add_lowest_metric_head()
|
||||
{
|
||||
atf_set descr 'Create 4 routes to same dst and verify the lowest metric wins'
|
||||
atf_set require.user root
|
||||
atf_set require.progs jq
|
||||
}
|
||||
|
||||
add_lowest_metric_body()
|
||||
{
|
||||
local epair laddr route nhop1 nhop2 nhop3
|
||||
|
||||
laddr="3fff::1"
|
||||
route="3fff:a::"
|
||||
nhop1="3fff::1"
|
||||
nhop2="3fff::2"
|
||||
nhop3="3fff::3"
|
||||
|
||||
vnet_init
|
||||
epair=$(vnet_mkepair)
|
||||
|
||||
atf_check -o ignore \
|
||||
ifconfig ${epair}a inet6 ${laddr} up
|
||||
|
||||
# Create an ECMP route with metric 2
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop2} -weight 10 -metric 2
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop3} -weight 10 -metric 2
|
||||
|
||||
# Validate routes
|
||||
atf_check -o save:netstat \
|
||||
netstat -rn6 --libxo json
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 10 2)
|
||||
atf_check_equal "$output" "$nhop2"
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop3} 10 2)
|
||||
atf_check_equal "$output" "$nhop3"
|
||||
|
||||
# Create a route with metric 3
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop1} -metric 3
|
||||
# Verify that nhop1 is not the best route
|
||||
atf_check -o not-match:".*gateway: ${nhop1}.*" \
|
||||
route -n6 get -net ${route}/64
|
||||
|
||||
# Create a route to the same nhop with same metric 3 and verify it fails
|
||||
atf_check -s exit:1 -o ignore -e match:".*exists.*" \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop1} -metric 3
|
||||
|
||||
# Create a route to an existing nhop with lower metric
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop1} -metric 1
|
||||
# Verify that nhop1 is now the best route
|
||||
atf_check -o match:".*gateway: ${nhop1}.*" \
|
||||
route -n6 get -net ${route}/64
|
||||
}
|
||||
|
||||
add_lowest_metric_cleanup()
|
||||
{
|
||||
vnet_cleanup
|
||||
}
|
||||
|
||||
atf_test_case "add_default_metric" "cleanup"
|
||||
add_default_metric_head()
|
||||
{
|
||||
atf_set descr 'Create a route and verify the default metric is set'
|
||||
atf_set require.user root
|
||||
atf_set require.progs jq
|
||||
}
|
||||
|
||||
add_default_metric_body()
|
||||
{
|
||||
local epair laddr route nhop1
|
||||
|
||||
laddr="3fff::1"
|
||||
route="3fff:a::"
|
||||
nhop1="3fff::1"
|
||||
|
||||
vnet_init
|
||||
epair=$(vnet_mkepair)
|
||||
|
||||
atf_check -o ignore \
|
||||
ifconfig ${epair}a inet6 ${laddr} up
|
||||
|
||||
# Create a route without specifying its metric
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop1}
|
||||
|
||||
# Verify the route has the default metric of 1
|
||||
atf_check -o save:netstat \
|
||||
netstat -rn6 --libxo json
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop1} 1 1)
|
||||
atf_check_equal "$output" "$nhop1"
|
||||
}
|
||||
|
||||
add_default_metric_cleanup()
|
||||
{
|
||||
vnet_cleanup
|
||||
}
|
||||
|
||||
atf_test_case "delete_route_with_metric" "cleanup"
|
||||
delete_route_with_metric_head()
|
||||
{
|
||||
atf_set descr 'Create multiple routes to same dst and delete routes with specific metric'
|
||||
atf_set require.user root
|
||||
atf_set require.progs jq
|
||||
}
|
||||
|
||||
delete_route_with_metric_body()
|
||||
{
|
||||
local epair laddr route nhop1 nhop2
|
||||
|
||||
laddr="3fff::1"
|
||||
route="3fff:a::"
|
||||
nhop1="3fff::1"
|
||||
nhop2="3fff::2"
|
||||
|
||||
vnet_init
|
||||
epair=$(vnet_mkepair)
|
||||
|
||||
atf_check -o ignore \
|
||||
ifconfig ${epair}a inet6 ${laddr} up
|
||||
|
||||
# Create two groups of ECMP routes with metric 2 and 3, and
|
||||
# another route with metric 4.
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop1} -metric 3
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop1} -weight 10 -metric 2
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop2} -weight 10 -metric 2
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop2} -metric 3
|
||||
atf_check -o ignore \
|
||||
route -6 add -net ${route}/64 -gateway ${nhop2} -metric 4
|
||||
|
||||
# Validate we have 5 routes
|
||||
atf_check -o save:netstat \
|
||||
netstat -rn6 --libxo json
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop1} 1 3)
|
||||
atf_check_equal "$output" "$nhop1"
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop1} 10 2)
|
||||
atf_check_equal "$output" "$nhop1"
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 10 2)
|
||||
atf_check_equal "$output" "$nhop2"
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 3)
|
||||
atf_check_equal "$output" "$nhop2"
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 4)
|
||||
atf_check_equal "$output" "$nhop2"
|
||||
|
||||
# Delete one of the nexthops of them best ECMP route
|
||||
# Test that deleting a route by specifying gateway + metric works.
|
||||
atf_check -o ignore \
|
||||
route -n6 delete -net ${route}/64 -gateway ${nhop2} -metric 2
|
||||
|
||||
# Verify that nhop1 is the best route now
|
||||
atf_check -o match:".*gateway: ${nhop1}.*" \
|
||||
route -n6 get -net ${route}/64
|
||||
|
||||
# But other route with nhops2 should exists.
|
||||
atf_check -o save:netstat \
|
||||
netstat -rn6 --libxo json
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 3)
|
||||
atf_check_equal "$output" "$nhop2"
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 4)
|
||||
atf_check_equal "$output" "$nhop2"
|
||||
|
||||
# Delete routes with nhop1 as nexthop without specifying metric.
|
||||
# Test that deleting a route by gateway removes all routes with
|
||||
# that gateway, regardless of metric value.
|
||||
atf_check -o ignore \
|
||||
route -n6 delete -net ${route}/64 -gateway ${nhop1}
|
||||
|
||||
# Verify that nhop2 is the best route now
|
||||
atf_check -o match:".*gateway: ${nhop2}.*" \
|
||||
route -n6 get -net ${route}/64
|
||||
|
||||
# Delete routes with metric 3 without specifying their gateway.
|
||||
# Test that deleting a route by metric removes all routes with
|
||||
# that metric, regardless of gateway value.
|
||||
atf_check -o ignore \
|
||||
route -n6 delete -net ${route}/64 -metric 3
|
||||
|
||||
# Verify that nhop2 is still the best route with metric of 4
|
||||
atf_check -o match:".*gateway: ${nhop2}.*" \
|
||||
route -n6 get -net ${route}/64
|
||||
output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 4)
|
||||
atf_check_equal "$output" "$nhop2"
|
||||
}
|
||||
|
||||
delete_route_with_metric_cleanup()
|
||||
{
|
||||
vnet_cleanup
|
||||
}
|
||||
|
||||
|
||||
atf_init_test_cases()
|
||||
{
|
||||
atf_add_test_case "add_lowest_metric"
|
||||
atf_add_test_case "add_default_metric"
|
||||
atf_add_test_case "delete_route_with_metric"
|
||||
}
|
||||
Reference in New Issue
Block a user