Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F167681695
D57016.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
7 KB
Referenced Files
None
Subscribers
None
D57016.diff
View Options
diff --git a/tests/sys/net/routing/Makefile b/tests/sys/net/routing/Makefile
--- a/tests/sys/net/routing/Makefile
+++ b/tests/sys/net/routing/Makefile
@@ -8,6 +8,7 @@
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 @@
# 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}
diff --git a/tests/sys/net/routing/test_routing.sh b/tests/sys/net/routing/test_routing.sh
new file mode 100755
--- /dev/null
+++ b/tests/sys/net/routing/test_routing.sh
@@ -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"
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Mon, Aug 24, 6:05 PM (11 h, 39 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
37197953
Default Alt Text
D57016.diff (7 KB)
Attached To
Mode
D57016: routing: Add tests for metric
Attached
Detach File
Event Timeline
Log In to Comment