[PATCH net-next 5/5] selftests: seg6: add End.X PSP selftest

From: Hangbin Liu

Date: Tue Sep 22 2026 - 05:04:00 EST


From: Hangbin Liu <liuhangbin@xxxxxxxxxx>

The current selftest only exercises End with PSP. Add a new test that
uses End.X on the PSP path so the kernel's End.X flavor handling is
validated end to end.

Extend __setup_rt_policy() to parse End.X action field from the
router description, allowing entries like:
4:psp:End.X,4,2
3:psp:End.X,3,1

Since SETUP_ERR is not set in one setup function, and the middle test may
set ret to 1, we also need to check ret before setting the result as SKIP.

Signed-off-by: Hangbin Liu <liuhangbin@xxxxxxxxxx>
---
.../testing/selftests/net/srv6_end_flavors_test.sh | 83 ++++++++++++++++++++--
1 file changed, 78 insertions(+), 5 deletions(-)

diff --git a/tools/testing/selftests/net/srv6_end_flavors_test.sh b/tools/testing/selftests/net/srv6_end_flavors_test.sh
index 52731983b4cc..e130d0d71b3d 100755
--- a/tools/testing/selftests/net/srv6_end_flavors_test.sh
+++ b/tools/testing/selftests/net/srv6_end_flavors_test.sh
@@ -194,8 +194,8 @@
# after the IPv6 header. At this point, the packet with IPv6 DA=cafe::1 is sent
# to the destination, i.e. hs-1.

-# Kselftest framework requirement - SKIP code is 4.
-readonly ksft_skip=4
+# shellcheck source=lib.sh
+source lib.sh

readonly RDMSUFF="$(mktemp -u XXXXXXXX)"
readonly DUMMY_DEVNAME="dum0"
@@ -345,7 +345,7 @@ cleanup()
# check whether the setup phase was completed successfully or not. In
# case of an error during the setup phase of the testing environment,
# the selftest is considered as "skipped".
- if [ "${SETUP_ERR}" -ne 0 ]; then
+ if [ "${SETUP_ERR}" -ne 0 ] && [ "$ret" -ne "$ksft_fail" ]; then
echo "SKIP: Setting up the testing environment failed"
exit "${ksft_skip}"
fi
@@ -414,6 +414,36 @@ __get_srv6_rtcfg_op()
xargs | sed 's/ /,/g'
}

+# Given the description of a router <id:op:act> as an input, the function
+# returns the <act> token which represents the action (e.g. End, End.X,
+# End.T behavior with or without route table, out interface) configured
+# for the node.
+#
+# Support End, End.X at present. When omit, return default End behavior.
+# i.e. input: "1:psp:End.X,1,3"
+# output: "End.X nh6 fcf0:0:1:3::3 oif veth-rt-1-3"
+__get_srv6_rtcfg_act()
+{
+ local element="$1"
+ local net_prefix
+ local acts
+ local out
+
+ acts="$(echo "${element}" | cut -d':' -f3)"
+ act="$(echo "${acts}" | cut -d',' -f1)"
+ act="${act:-"End"}"
+
+ rt="$(echo "${acts}" | cut -d',' -f2)"
+ neigh="$(echo "${acts}" | cut -d',' -f3)"
+
+ if [ "$act" == "End" ]; then
+ echo "End"
+ elif [ "$act" == "End.X" ]; then
+ net_prefix="$(get_network_prefix "${rt}" "${neigh}")"
+ echo "End.X nh6 ${net_prefix}::${neigh} oif veth-rt-${rt}-${neigh}"
+ fi
+}
+
# Setup the basic networking for the routers
setup_rt_networking()
{
@@ -514,6 +544,7 @@ __setup_rt_policy()
local function
local fullsid
local op_type
+ local action
local node
local n

@@ -522,19 +553,20 @@ __setup_rt_policy()
for n in ${policy_rts}; do
node="$(__get_srv6_rtcfg_id "${n}")"
op_type="$(__get_srv6_rtcfg_op "${n}")"
+ action="$(__get_srv6_rtcfg_act "${n}")"
rt_nsname="$(get_rtname "${node}")"

case "${op_type}" in
"noflv")
policy="${policy}${LOCATOR_SERVICE}:${node}::${END_FUNC},"
function="${END_FUNC}"
- behavior_cfg="End"
+ behavior_cfg="${action}"
;;

"psp")
policy="${policy}${LOCATOR_SERVICE}:${node}::${END_PSP_FUNC},"
function="${END_PSP_FUNC}"
- behavior_cfg="End flavors psp"
+ behavior_cfg="${action} flavors psp"
;;

*)
@@ -729,6 +761,30 @@ cleanup_end_flv_psp()
cleanup_rt_policy_ipv6 1 2 "1:psp"
}

+setup_endx_flv_psp()
+{
+ # Direction hs-1 -> hs-2 (End.X PSP flavor)
+ # SID List=fcff:3::e,fcff:4::ef1,cafe::2
+ # - rt-1 (SRv6 H.Insert policy)
+ # - rt-3 (SRv6 End behavior)
+ # - rt-4 (SRv6 End.X flavor PSP with SL=1)
+ # - rt-2 (Route to hs-2 via nh and oif)
+ #
+ # Direction hs-2 -> hs-1 (End.X PSP flavor)
+ # SID List=fcff:3::ef1,cafe::1
+ # - rt-2 (SRv6 H.Insert policy)
+ # - rt-3 (SRv6 End.X flavor PSP with SL=1)
+ # - rt-1 (Route to hs-1 via nh and oif)
+ setup_rt_policy_ipv6 2 1 "3:noflv:End 4:psp:End.X,4,2"
+ setup_rt_policy_ipv6 1 2 "3:psp:End.X,3,1"
+}
+
+cleanup_endx_flv_psp()
+{
+ cleanup_rt_policy_ipv6 2 1 "3:noflv 4:psp"
+ cleanup_rt_policy_ipv6 1 2 "3:psp"
+}
+
check_rt_connectivity()
{
local rtsrc="$1"
@@ -835,6 +891,22 @@ host_srv6_end_flv_psp_tests()
cleanup_end_flv_psp
}

+host_srv6_endx_flv_psp_tests()
+{
+ set -e
+ SETUP_ERR=1
+ setup_endx_flv_psp
+ SETUP_ERR=0
+ set +e
+
+ log_section "SRv6 connectivity test hosts (h1 <-> h2, End.X flavor PSP)"
+
+ check_and_log_hs_connectivity 1 2
+ check_and_log_hs_connectivity 2 1
+
+ cleanup_endx_flv_psp
+}
+
test_iproute2_supp_or_ksft_skip()
{
local flavor="$1"
@@ -936,5 +1008,6 @@ set +e
router_tests
host2gateway_tests
host_srv6_end_flv_psp_tests
+host_srv6_endx_flv_psp_tests

print_log_test_results

--
2.55.0