xref: /freebsd/tests/sys/net/routing/test_routing.sh (revision bc301fee4cb2c3e9ce220dc3e0cbb9d7d5a83d6f)
1*bc301feeSPouria Mousavizadeh Tehrani#
2*bc301feeSPouria Mousavizadeh Tehrani# Copyright (c) 2026 Pouria Mousavizadeh Tehrani <pouria@FreeBSD.org>
3*bc301feeSPouria Mousavizadeh Tehrani#
4*bc301feeSPouria Mousavizadeh Tehrani# SPDX-License-Identifier: BSD-2-Clause
5*bc301feeSPouria Mousavizadeh Tehrani#
6*bc301feeSPouria Mousavizadeh Tehrani
7*bc301feeSPouria Mousavizadeh Tehrani. $(atf_get_srcdir)/../../common/vnet.subr
8*bc301feeSPouria Mousavizadeh Tehrani
9*bc301feeSPouria Mousavizadeh Tehranijq_rtentry()
10*bc301feeSPouria Mousavizadeh Tehrani{
11*bc301feeSPouria Mousavizadeh Tehrani	local route="$1"
12*bc301feeSPouria Mousavizadeh Tehrani
13*bc301feeSPouria Mousavizadeh Tehrani	jq -r '.statistics."route-information"."route-table"."rt-family".[]."rt-entry".[] |
14*bc301feeSPouria Mousavizadeh Tehrani	    select(.destination == "'${route}'")'
15*bc301feeSPouria Mousavizadeh Tehrani}
16*bc301feeSPouria Mousavizadeh Tehrani
17*bc301feeSPouria Mousavizadeh Tehranijq_nhop_filter()
18*bc301feeSPouria Mousavizadeh Tehrani{
19*bc301feeSPouria Mousavizadeh Tehrani	local nhop="$1"
20*bc301feeSPouria Mousavizadeh Tehrani	local weight="$2"
21*bc301feeSPouria Mousavizadeh Tehrani	local metric="$3"
22*bc301feeSPouria Mousavizadeh Tehrani
23*bc301feeSPouria Mousavizadeh Tehrani	jq -r 'select(.gateway == "'${nhop}'") |
24*bc301feeSPouria Mousavizadeh Tehrani	    select(.weight == '${weight}') |
25*bc301feeSPouria Mousavizadeh Tehrani	    select(.metric == '${metric}') |
26*bc301feeSPouria Mousavizadeh Tehrani	    .gateway'
27*bc301feeSPouria Mousavizadeh Tehrani}
28*bc301feeSPouria Mousavizadeh Tehrani
29*bc301feeSPouria Mousavizadeh Tehrani
30*bc301feeSPouria Mousavizadeh Tehraniatf_test_case "add_lowest_metric" "cleanup"
31*bc301feeSPouria Mousavizadeh Tehraniadd_lowest_metric_head()
32*bc301feeSPouria Mousavizadeh Tehrani{
33*bc301feeSPouria Mousavizadeh Tehrani	atf_set descr 'Create 4 routes to same dst and verify the lowest metric wins'
34*bc301feeSPouria Mousavizadeh Tehrani	atf_set require.user root
35*bc301feeSPouria Mousavizadeh Tehrani	atf_set require.progs jq
36*bc301feeSPouria Mousavizadeh Tehrani}
37*bc301feeSPouria Mousavizadeh Tehrani
38*bc301feeSPouria Mousavizadeh Tehraniadd_lowest_metric_body()
39*bc301feeSPouria Mousavizadeh Tehrani{
40*bc301feeSPouria Mousavizadeh Tehrani	local epair laddr route nhop1 nhop2 nhop3
41*bc301feeSPouria Mousavizadeh Tehrani
42*bc301feeSPouria Mousavizadeh Tehrani	laddr="3fff::1"
43*bc301feeSPouria Mousavizadeh Tehrani	route="3fff:a::"
44*bc301feeSPouria Mousavizadeh Tehrani	nhop1="3fff::1"
45*bc301feeSPouria Mousavizadeh Tehrani	nhop2="3fff::2"
46*bc301feeSPouria Mousavizadeh Tehrani	nhop3="3fff::3"
47*bc301feeSPouria Mousavizadeh Tehrani
48*bc301feeSPouria Mousavizadeh Tehrani	vnet_init
49*bc301feeSPouria Mousavizadeh Tehrani	epair=$(vnet_mkepair)
50*bc301feeSPouria Mousavizadeh Tehrani
51*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
52*bc301feeSPouria Mousavizadeh Tehrani	    ifconfig ${epair}a inet6 ${laddr} up
53*bc301feeSPouria Mousavizadeh Tehrani
54*bc301feeSPouria Mousavizadeh Tehrani	# Create an ECMP route with metric 2
55*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
56*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop2} -weight 10 -metric 2
57*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
58*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop3} -weight 10 -metric 2
59*bc301feeSPouria Mousavizadeh Tehrani
60*bc301feeSPouria Mousavizadeh Tehrani	# Validate routes
61*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o save:netstat \
62*bc301feeSPouria Mousavizadeh Tehrani	    netstat -rn6 --libxo json
63*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 10 2)
64*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop2"
65*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop3} 10 2)
66*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop3"
67*bc301feeSPouria Mousavizadeh Tehrani
68*bc301feeSPouria Mousavizadeh Tehrani	# Create a route with metric 3
69*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
70*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop1} -metric 3
71*bc301feeSPouria Mousavizadeh Tehrani	# Verify that nhop1 is not the best route
72*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o not-match:".*gateway: ${nhop1}.*" \
73*bc301feeSPouria Mousavizadeh Tehrani	    route -n6 get -net ${route}/64
74*bc301feeSPouria Mousavizadeh Tehrani
75*bc301feeSPouria Mousavizadeh Tehrani	# Create a route to the same nhop with same metric 3 and verify it fails
76*bc301feeSPouria Mousavizadeh Tehrani	atf_check -s exit:1 -o ignore -e match:".*exists.*" \
77*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop1} -metric 3
78*bc301feeSPouria Mousavizadeh Tehrani
79*bc301feeSPouria Mousavizadeh Tehrani	# Create a route to an existing nhop with lower metric
80*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
81*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop1} -metric 1
82*bc301feeSPouria Mousavizadeh Tehrani	# Verify that nhop1 is now the best route
83*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o match:".*gateway: ${nhop1}.*" \
84*bc301feeSPouria Mousavizadeh Tehrani	    route -n6 get -net ${route}/64
85*bc301feeSPouria Mousavizadeh Tehrani}
86*bc301feeSPouria Mousavizadeh Tehrani
87*bc301feeSPouria Mousavizadeh Tehraniadd_lowest_metric_cleanup()
88*bc301feeSPouria Mousavizadeh Tehrani{
89*bc301feeSPouria Mousavizadeh Tehrani	vnet_cleanup
90*bc301feeSPouria Mousavizadeh Tehrani}
91*bc301feeSPouria Mousavizadeh Tehrani
92*bc301feeSPouria Mousavizadeh Tehraniatf_test_case "add_default_metric" "cleanup"
93*bc301feeSPouria Mousavizadeh Tehraniadd_default_metric_head()
94*bc301feeSPouria Mousavizadeh Tehrani{
95*bc301feeSPouria Mousavizadeh Tehrani	atf_set descr 'Create a route and verify the default metric is set'
96*bc301feeSPouria Mousavizadeh Tehrani	atf_set require.user root
97*bc301feeSPouria Mousavizadeh Tehrani	atf_set require.progs jq
98*bc301feeSPouria Mousavizadeh Tehrani}
99*bc301feeSPouria Mousavizadeh Tehrani
100*bc301feeSPouria Mousavizadeh Tehraniadd_default_metric_body()
101*bc301feeSPouria Mousavizadeh Tehrani{
102*bc301feeSPouria Mousavizadeh Tehrani	local epair laddr route nhop1
103*bc301feeSPouria Mousavizadeh Tehrani
104*bc301feeSPouria Mousavizadeh Tehrani	laddr="3fff::1"
105*bc301feeSPouria Mousavizadeh Tehrani	route="3fff:a::"
106*bc301feeSPouria Mousavizadeh Tehrani	nhop1="3fff::1"
107*bc301feeSPouria Mousavizadeh Tehrani
108*bc301feeSPouria Mousavizadeh Tehrani	vnet_init
109*bc301feeSPouria Mousavizadeh Tehrani	epair=$(vnet_mkepair)
110*bc301feeSPouria Mousavizadeh Tehrani
111*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
112*bc301feeSPouria Mousavizadeh Tehrani	    ifconfig ${epair}a inet6 ${laddr} up
113*bc301feeSPouria Mousavizadeh Tehrani
114*bc301feeSPouria Mousavizadeh Tehrani	# Create a route without specifying its metric
115*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
116*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop1}
117*bc301feeSPouria Mousavizadeh Tehrani
118*bc301feeSPouria Mousavizadeh Tehrani	# Verify the route has the default metric of 1
119*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o save:netstat \
120*bc301feeSPouria Mousavizadeh Tehrani	    netstat -rn6 --libxo json
121*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop1} 1 1)
122*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop1"
123*bc301feeSPouria Mousavizadeh Tehrani}
124*bc301feeSPouria Mousavizadeh Tehrani
125*bc301feeSPouria Mousavizadeh Tehraniadd_default_metric_cleanup()
126*bc301feeSPouria Mousavizadeh Tehrani{
127*bc301feeSPouria Mousavizadeh Tehrani	vnet_cleanup
128*bc301feeSPouria Mousavizadeh Tehrani}
129*bc301feeSPouria Mousavizadeh Tehrani
130*bc301feeSPouria Mousavizadeh Tehraniatf_test_case "delete_route_with_metric" "cleanup"
131*bc301feeSPouria Mousavizadeh Tehranidelete_route_with_metric_head()
132*bc301feeSPouria Mousavizadeh Tehrani{
133*bc301feeSPouria Mousavizadeh Tehrani	atf_set descr 'Create multiple routes to same dst and delete routes with specific metric'
134*bc301feeSPouria Mousavizadeh Tehrani	atf_set require.user root
135*bc301feeSPouria Mousavizadeh Tehrani	atf_set require.progs jq
136*bc301feeSPouria Mousavizadeh Tehrani}
137*bc301feeSPouria Mousavizadeh Tehrani
138*bc301feeSPouria Mousavizadeh Tehranidelete_route_with_metric_body()
139*bc301feeSPouria Mousavizadeh Tehrani{
140*bc301feeSPouria Mousavizadeh Tehrani	local epair laddr route nhop1 nhop2
141*bc301feeSPouria Mousavizadeh Tehrani
142*bc301feeSPouria Mousavizadeh Tehrani	laddr="3fff::1"
143*bc301feeSPouria Mousavizadeh Tehrani	route="3fff:a::"
144*bc301feeSPouria Mousavizadeh Tehrani	nhop1="3fff::1"
145*bc301feeSPouria Mousavizadeh Tehrani	nhop2="3fff::2"
146*bc301feeSPouria Mousavizadeh Tehrani
147*bc301feeSPouria Mousavizadeh Tehrani	vnet_init
148*bc301feeSPouria Mousavizadeh Tehrani	epair=$(vnet_mkepair)
149*bc301feeSPouria Mousavizadeh Tehrani
150*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
151*bc301feeSPouria Mousavizadeh Tehrani	    ifconfig ${epair}a inet6 ${laddr} up
152*bc301feeSPouria Mousavizadeh Tehrani
153*bc301feeSPouria Mousavizadeh Tehrani	# Create two groups of ECMP routes with metric 2 and 3, and
154*bc301feeSPouria Mousavizadeh Tehrani	# another route with metric 4.
155*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
156*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop1} -metric 3
157*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
158*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop1} -weight 10 -metric 2
159*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
160*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop2} -weight 10 -metric 2
161*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
162*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop2} -metric 3
163*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
164*bc301feeSPouria Mousavizadeh Tehrani	    route -6 add -net ${route}/64 -gateway ${nhop2} -metric 4
165*bc301feeSPouria Mousavizadeh Tehrani
166*bc301feeSPouria Mousavizadeh Tehrani	# Validate we have 5 routes
167*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o save:netstat \
168*bc301feeSPouria Mousavizadeh Tehrani	    netstat -rn6 --libxo json
169*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop1} 1 3)
170*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop1"
171*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop1} 10 2)
172*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop1"
173*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 10 2)
174*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop2"
175*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 3)
176*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop2"
177*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 4)
178*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop2"
179*bc301feeSPouria Mousavizadeh Tehrani
180*bc301feeSPouria Mousavizadeh Tehrani	# Delete one of the nexthops of them best ECMP route
181*bc301feeSPouria Mousavizadeh Tehrani	# Test that deleting a route by specifying gateway + metric works.
182*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
183*bc301feeSPouria Mousavizadeh Tehrani	    route -n6 delete -net ${route}/64 -gateway ${nhop2} -metric 2
184*bc301feeSPouria Mousavizadeh Tehrani
185*bc301feeSPouria Mousavizadeh Tehrani	# Verify that nhop1 is the best route now
186*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o match:".*gateway: ${nhop1}.*" \
187*bc301feeSPouria Mousavizadeh Tehrani	    route -n6 get -net ${route}/64
188*bc301feeSPouria Mousavizadeh Tehrani
189*bc301feeSPouria Mousavizadeh Tehrani	# But other route with nhops2 should exists.
190*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o save:netstat \
191*bc301feeSPouria Mousavizadeh Tehrani	    netstat -rn6 --libxo json
192*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 3)
193*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop2"
194*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 4)
195*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop2"
196*bc301feeSPouria Mousavizadeh Tehrani
197*bc301feeSPouria Mousavizadeh Tehrani	# Delete routes with nhop1 as nexthop without specifying metric.
198*bc301feeSPouria Mousavizadeh Tehrani	# Test that deleting a route by gateway removes all routes with
199*bc301feeSPouria Mousavizadeh Tehrani	# that gateway, regardless of metric value.
200*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
201*bc301feeSPouria Mousavizadeh Tehrani	    route -n6 delete -net ${route}/64 -gateway ${nhop1}
202*bc301feeSPouria Mousavizadeh Tehrani
203*bc301feeSPouria Mousavizadeh Tehrani	# Verify that nhop2 is the best route now
204*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o match:".*gateway: ${nhop2}.*" \
205*bc301feeSPouria Mousavizadeh Tehrani	    route -n6 get -net ${route}/64
206*bc301feeSPouria Mousavizadeh Tehrani
207*bc301feeSPouria Mousavizadeh Tehrani	# Delete routes with metric 3 without specifying their gateway.
208*bc301feeSPouria Mousavizadeh Tehrani	# Test that deleting a route by metric removes all routes with
209*bc301feeSPouria Mousavizadeh Tehrani	# that metric, regardless of gateway value.
210*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o ignore \
211*bc301feeSPouria Mousavizadeh Tehrani	    route -n6 delete -net ${route}/64 -metric 3
212*bc301feeSPouria Mousavizadeh Tehrani
213*bc301feeSPouria Mousavizadeh Tehrani	# Verify that nhop2 is still the best route with metric of 4
214*bc301feeSPouria Mousavizadeh Tehrani	atf_check -o match:".*gateway: ${nhop2}.*" \
215*bc301feeSPouria Mousavizadeh Tehrani	    route -n6 get -net ${route}/64
216*bc301feeSPouria Mousavizadeh Tehrani	output=$(cat netstat | jq_rtentry ${route}/64 | jq_nhop_filter ${nhop2} 1 4)
217*bc301feeSPouria Mousavizadeh Tehrani	atf_check_equal "$output" "$nhop2"
218*bc301feeSPouria Mousavizadeh Tehrani}
219*bc301feeSPouria Mousavizadeh Tehrani
220*bc301feeSPouria Mousavizadeh Tehranidelete_route_with_metric_cleanup()
221*bc301feeSPouria Mousavizadeh Tehrani{
222*bc301feeSPouria Mousavizadeh Tehrani	vnet_cleanup
223*bc301feeSPouria Mousavizadeh Tehrani}
224*bc301feeSPouria Mousavizadeh Tehrani
225*bc301feeSPouria Mousavizadeh Tehrani
226*bc301feeSPouria Mousavizadeh Tehraniatf_init_test_cases()
227*bc301feeSPouria Mousavizadeh Tehrani{
228*bc301feeSPouria Mousavizadeh Tehrani	atf_add_test_case "add_lowest_metric"
229*bc301feeSPouria Mousavizadeh Tehrani	atf_add_test_case "add_default_metric"
230*bc301feeSPouria Mousavizadeh Tehrani	atf_add_test_case "delete_route_with_metric"
231*bc301feeSPouria Mousavizadeh Tehrani}
232