The merged SCTP test covers only IPv4. The SCTP branch of the IPv6
extractor (the proto=132 walk after parse_ipv6hdr) and the v6 side of
the SCTP netlink validation (match_validate() requires the sctp() key
whenever ipv6(proto=132) is matched) have no selftest coverage.

Add test_sctp_connect_v6 mirroring the v4 test: bare icmpv6() flows
forward NS/NA, and ipv6(proto=132),sctp(dst=4443)/sctp(src=4443)
flows gate the association in the same three phases (flows installed,
removed, reinstalled). A keyless ipv6(proto=132) install must be
refused with EINVAL, pinning the reject side of the match_validate()
rule; without it a regression dropping the requirement would pass
unnoticed. The refusal is asserted to be EINVAL specifically, not a
parse error of the flow string. After the association succeeds the
test also pushes a known payload across and waits for the listener
to log it, proving the datapath carries the association's traffic
end to end, not only its handshake. Skips when the sctp module is
missing, socat lacks SCTP or IPv6 support, or IPv6 is unavailable;
an association or payload failure with the flows installed fails
the test.

Signed-off-by: Minxi Hou <[email protected]>
---
 .../selftests/net/openvswitch/openvswitch.sh  | 109 ++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh 
b/tools/testing/selftests/net/openvswitch/openvswitch.sh
index a31f7fb6882d..aa84fafc3201 100755
--- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
+++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
@@ -34,6 +34,7 @@ tests="
        trunc                                   trunc: output truncation
        icmpv6                                  icmpv6: ICMPv6 echo type match
        sctp_connect_v4                         sctp: SCTP flow key matching
+       sctp_connect_v6                         sctp6: SCTP flow keys over IPv6
        psample                                 psample: Sampling packets with 
psample"
 
 info() {
@@ -700,6 +701,114 @@ test_sctp_connect_v4() {
        return 0
 }
 
+# sctp_connect_v6 test
+# - sctp(dst=4443) matches client-to-server INIT
+# - sctp(src=4443) matches server-to-client INIT-ACK
+# - icmpv6 NS/NA flows forward neighbour discovery
+# - remove flows and verify connection fails, reinstall and recover
+test_sctp_connect_v6() {
+       local t="test_sctp_connect_v6"
+       local v6="eth_type(0x86dd),ipv6(proto=132)"
+       local payload="SCTP6_DATA_OK"
+       local rxfile="${ovs_base}/${t}/sctp-rx.txt"
+
+       modprobe -q sctp 2>/dev/null || return "$ksft_skip"
+       socat -V 2>&1 | grep -q "define WITH_SCTP" || return "$ksft_skip"
+       socat -V 2>&1 | grep -q "define WITH_IP6" || return "$ksft_skip"
+       [ -e /proc/sys/net/ipv6 ] || return "$ksft_skip"
+
+       sbx_add "$t" || return $?
+       ovs_add_dp "$t" sctp6 || return 1
+
+       info "create namespaces"
+       for ns in client server; do
+               ovs_add_netns_and_veths "$t" "sctp6" "$ns" \
+                   "${ns:0:1}0" "${ns:0:1}1" || return 1
+       done
+
+       ip netns exec client ip addr add fd00::1/64 dev c1 nodad
+       ip netns exec client ip link set c1 up
+       ip netns exec server ip addr add fd00::2/64 dev s1 nodad
+       ip netns exec server ip link set s1 up
+
+       # NS/NA forwarding
+       ovs_add_flow "$t" sctp6 \
+           'in_port(1),eth(),eth_type(0x86dd),ipv6(proto=58),icmpv6()' \
+           '2' || return 1
+       ovs_add_flow "$t" sctp6 \
+           'in_port(2),eth(),eth_type(0x86dd),ipv6(proto=58),icmpv6()' \
+           '1' || return 1
+
+       # SCTP port matching: dst for request, src for reply
+       ovs_add_flow "$t" sctp6 \
+           "in_port(1),eth(),$v6,sctp(dst=4443)" \
+           '2' || return 1
+       ovs_add_flow "$t" sctp6 \
+           "in_port(2),eth(),$v6,sctp(src=4443)" \
+           '1' || return 1
+
+       # A keyless ipv6(proto=132) install must be refused (EINVAL):
+       # match_validate() requires the sctp() key. Pin the reject side
+       # of that rule; the keyed installs above cover the accept side.
+       # Verify the refusal is EINVAL (missing key), not a parse error.
+       err=$(ovs_sbx "$t" python3 $ovs_base/ovs-dpctl.py add-flow sctp6 \
+           "in_port(1),eth(),$v6" '2' 2>&1 >/dev/null) \
+           && { info "keyless SCTP flow should be refused"
+                return 1; }
+       echo "$err" | grep -q "(22," || {
+               info "keyless SCTP flow refused for wrong reason: $err"
+               return 1
+       }
+
+       ovs_netns_spawn_daemon "$t" "server" \
+           socat -u -t 1 SCTP6-LISTEN:4443,fork \
+           OPEN:"$rxfile",creat,append
+       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 "SCTP6-CONNECT:[fd00::2]:4443" </dev/null \
+           || return 1
+
+       info "verify SCTP DATA chunk crosses the datapath"
+       ovs_sbx "$t" ip netns exec client \
+           timeout 3 socat -u STDIN "SCTP6-CONNECT:[fd00::2]:4443" \
+           <<< "$payload" || return 1
+       ovs_wait grep -q "$payload" "$rxfile" \
+           || { info "server did not receive SCTP DATA payload"
+                return 1; }
+
+       ovs_del_flows "$t" sctp6
+
+       info "verify connection fails without flows"
+       ovs_add_flow "$t" sctp6 \
+           'in_port(1),eth(),eth_type(0x86dd),ipv6(proto=58),icmpv6()' \
+           '2' || return 1
+       ovs_add_flow "$t" sctp6 \
+           'in_port(2),eth(),eth_type(0x86dd),ipv6(proto=58),icmpv6()' \
+           '1' || return 1
+
+       ovs_sbx "$t" ip netns exec client \
+           timeout 3 socat -u STDIN "SCTP6-CONNECT:[fd00::2]: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" sctp6 \
+           "in_port(1),eth(),$v6,sctp(dst=4443)" \
+           '2' || return 1
+       ovs_add_flow "$t" sctp6 \
+           "in_port(2),eth(),$v6,sctp(src=4443)" \
+           '1' || return 1
+
+       ovs_sbx "$t" ip netns exec client \
+           timeout 3 socat -u STDIN "SCTP6-CONNECT:[fd00::2]:4443" </dev/null \
+           || return 1
+
+       return 0
+}
+
 # psample test
 # - use psample to observe packets
 test_psample() {
-- 
2.55.0


Reply via email to