From: Minxi Hou <houminxi@gmail.com>
To: netdev@vger.kernel.org
Cc: davem@davemloft.net, edumazet@google.com, kuba@kernel.org,
pabeni@redhat.com, aconole@redhat.com, echaudro@redhat.com,
i.maximets@ovn.org, i.maximets@redhat.com, dev@openvswitch.org,
linux-kselftest@vger.kernel.org, shuah@kernel.org,
horms@kernel.org, linux-kernel@vger.kernel.org,
Minxi Hou <houminxi@gmail.com>
Subject: [PATCH net-next v6 2/2] selftests/net/openvswitch: add SCTP flow key test
Date: Fri, 24 Jul 2026 11:06:24 -0400 [thread overview]
Message-ID: <20260724150624.3457427-3-houminxi@gmail.com> (raw)
In-Reply-To: <20260724150624.3457427-1-houminxi@gmail.com>
Add test_sctp_connect_v4() to verify OVS can match on SCTP flow keys
(sctp src/dst port).
The test sets up client and server namespaces connected through an
OVS bridge, installs port-keyed flows, and verifies:
- sctp(dst=4443) matches client-to-server INIT
- sctp(src=4443) matches server-to-client INIT-ACK
- removing flows drops the connection
- reinstalling flows restores connectivity
The listener readiness probe reads /proc/net/sctp/eps instead of ss:
ss requires the sctp_diag interface, which is not enabled on all
kernels, while /proc/net/sctp/eps exists whenever SCTP is loaded.
Signed-off-by: Minxi Hou <houminxi@gmail.com>
---
.../selftests/net/openvswitch/openvswitch.sh | 121 ++++++++++++++++++
1 file changed, 121 insertions(+)
diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh b/tools/testing/selftests/net/openvswitch/openvswitch.sh
index 853dbc1b00d7..b448324527d8 100755
--- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
+++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
@@ -34,6 +34,7 @@ tests="
action_set set: SET action rewrites fields
trunc trunc: output truncation
icmpv6 icmpv6: ICMPv6 echo type match
+ sctp_connect_v4 sctp: SCTP flow key matching
psample psample: Sampling packets with psample"
info() {
@@ -611,6 +612,126 @@ test_icmpv6() {
return 0
}
+# Check for an SCTP endpoint via /proc, which works without sctp_diag.
+sctp_eps_has() {
+ ip netns exec "$1" awk -v p="$2" '$6==p' /proc/net/sctp/eps | grep -q .
+}
+
+# sctp_connect_v4 test
+# - sctp(dst=4443) matches client-to-server INIT
+# - sctp(src=4443) matches server-to-client INIT-ACK
+# - remove flows and verify connection fails, reinstall and recover
+test_sctp_connect_v4() {
+ local t="test_sctp_connect_v4"
+ local srv_ip=172.31.110.20
+
+ modprobe -q sctp 2>/dev/null || return "$ksft_skip"
+ socat -V 2>&1 | grep -q "define WITH_SCTP" || return "$ksft_skip"
+
+ sbx_add "$t" || return $?
+ ovs_add_dp "$t" sctp4 || return 1
+
+ info "create namespaces"
+ for ns in client server; do
+ ovs_add_netns_and_veths "$t" "sctp4" "$ns" \
+ "${ns:0:1}0" "${ns:0:1}1" || return 1
+ done
+
+ ip netns exec client ip addr add 172.31.110.10/24 dev c1
+ ip netns exec client ip link set c1 up
+ ip netns exec server ip addr add "${srv_ip}/24" dev s1
+ ip netns exec server ip link set s1 up
+
+ # Probe: check if kernel supports sctp flow key.
+ ovs_add_flow "$t" sctp4 \
+ 'in_port(1),eth(),eth_type(0x0800),ipv4(proto=132),sctp(dst=4443)' \
+ '2' &>/dev/null
+ if [ $? -ne 0 ]; then
+ info "no support for sctp key - skipping"
+ ovs_exit_sig
+ return $ksft_skip
+ fi
+ ovs_del_flows "$t" sctp4
+
+ # ARP forwarding
+ ovs_add_flow "$t" sctp4 \
+ 'in_port(1),eth(),eth_type(0x0806),arp()' \
+ '2' || return 1
+ ovs_add_flow "$t" sctp4 \
+ 'in_port(2),eth(),eth_type(0x0806),arp()' \
+ '1' || return 1
+
+ # SCTP port matching: dst for request, src for reply
+ ovs_add_flow "$t" sctp4 \
+ 'in_port(1),eth(),eth_type(0x0800),ipv4(proto=132),sctp(dst=4443)' \
+ '2' || return 1
+ ovs_add_flow "$t" sctp4 \
+ 'in_port(2),eth(),eth_type(0x0800),ipv4(proto=132),sctp(src=4443)' \
+ '1' || return 1
+
+ ovs_netns_spawn_daemon "$t" "server" \
+ socat -u SCTP4-LISTEN:4443 STDOUT
+ local server_pid="$pid"
+ ovs_wait sctp_eps_has server 4443 || return 1
+
+ info "verify SCTP association with port-keyed flows"
+ ovs_sbx "$t" ip netns exec client \
+ timeout 3 socat -u STDIN "SCTP4-CONNECT:${srv_ip}:4443" </dev/null \
+ || return 1
+
+ ovs_del_flows "$t" sctp4
+
+ info "verify connection fails without flows"
+ ovs_add_flow "$t" sctp4 \
+ 'in_port(1),eth(),eth_type(0x0806),arp()' \
+ '2' || return 1
+ ovs_add_flow "$t" sctp4 \
+ 'in_port(2),eth(),eth_type(0x0806),arp()' \
+ '1' || return 1
+
+ kill -TERM "$server_pid" 2>/dev/null
+ local i=0
+ while kill -0 "$server_pid" 2>/dev/null && [ "$i" -lt 5 ]; do
+ sleep 0.2
+ i=$((i + 1))
+ done
+ ovs_netns_spawn_daemon "$t" "server" \
+ socat -u SCTP4-LISTEN:4443 STDOUT
+ server_pid="$pid"
+ ovs_wait sctp_eps_has server 4443 || return 1
+
+ ovs_sbx "$t" ip netns exec client \
+ timeout 3 socat -u STDIN "SCTP4-CONNECT:${srv_ip}:4443" </dev/null \
+ >/dev/null 2>&1 \
+ && { info "connection should fail without flows"
+ return 1; }
+
+ info "reinstall flows and verify recovery"
+ ovs_add_flow "$t" sctp4 \
+ 'in_port(1),eth(),eth_type(0x0800),ipv4(proto=132),sctp(dst=4443)' \
+ '2' || return 1
+ ovs_add_flow "$t" sctp4 \
+ 'in_port(2),eth(),eth_type(0x0800),ipv4(proto=132),sctp(src=4443)' \
+ '1' || return 1
+
+ kill -TERM "$server_pid" 2>/dev/null
+ i=0
+ while kill -0 "$server_pid" 2>/dev/null && [ "$i" -lt 5 ]; do
+ sleep 0.2
+ i=$((i + 1))
+ done
+ ovs_netns_spawn_daemon "$t" "server" \
+ socat -u SCTP4-LISTEN:4443 STDOUT
+ server_pid="$pid"
+ ovs_wait sctp_eps_has server 4443 || return 1
+
+ ovs_sbx "$t" ip netns exec client \
+ timeout 3 socat -u STDIN "SCTP4-CONNECT:${srv_ip}:4443" </dev/null \
+ || return 1
+
+ return 0
+}
+
# psample test
# - use psample to observe packets
test_psample() {
--
2.55.0
prev parent reply other threads:[~2026-07-24 15:06 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-07-24 15:06 [PATCH net-next v6 0/2] selftests/net/openvswitch: add SCTP flow key test Minxi Hou
2026-07-24 15:06 ` [PATCH net-next v6 1/2] selftests/net/openvswitch: add SCTP flow key parsing to ovs-dpctl.py Minxi Hou
2026-07-24 19:02 ` [net-next,v6,1/2] " Aaron Conole
2026-07-24 15:06 ` Minxi Hou [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260724150624.3457427-3-houminxi@gmail.com \
--to=houminxi@gmail.com \
--cc=aconole@redhat.com \
--cc=davem@davemloft.net \
--cc=dev@openvswitch.org \
--cc=echaudro@redhat.com \
--cc=edumazet@google.com \
--cc=horms@kernel.org \
--cc=i.maximets@ovn.org \
--cc=i.maximets@redhat.com \
--cc=kuba@kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=shuah@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.