Add regression coverage for OVS IPv6 SET actions on later IPv6
fragments. A later fragment has no transport header, so the test sends
a crafted noninitial fragment through a source-address SET flow, checks
that the flow counter advances, and looks for a set_ipv6_addr warning.

This covers the later-fragment case handled by the upstream fix.

Signed-off-by: Sahaj Chaudhari <[email protected]>

---
 tools/testing/selftests/net/openvswitch/Makefile   |  2 +-
 tools/testing/selftests/net/openvswitch/config     |  1 +
 .../selftests/net/openvswitch/openvswitch.sh       | 43 +++++++++++++++++++
 .../selftests/net/openvswitch/ovs-ipv6-frag.py     | 48 ++++++++++++++++++++++
 4 files changed, 93 insertions(+), 1 deletion(-)

diff --git a/tools/testing/selftests/net/openvswitch/Makefile 
b/tools/testing/selftests/net/openvswitch/Makefile
index 3fd1da2ec07d5..b3260cd354419 100644
--- a/tools/testing/selftests/net/openvswitch/Makefile
+++ b/tools/testing/selftests/net/openvswitch/Makefile
@@ -6,7 +6,7 @@ CFLAGS += -Wall -Wl,--no-as-needed -O2 -g 
-I$(top_srcdir)/usr/include $(KHDR_INC
 
 TEST_PROGS := openvswitch.sh
 
-TEST_FILES := ovs-dpctl.py
+TEST_FILES := ovs-dpctl.py ovs-ipv6-frag.py
 
 EXTRA_CLEAN := test_netlink_checks
 
diff --git a/tools/testing/selftests/net/openvswitch/config 
b/tools/testing/selftests/net/openvswitch/config
index a825e0b5c88e5..b062ebbce0f00 100644
--- a/tools/testing/selftests/net/openvswitch/config
+++ b/tools/testing/selftests/net/openvswitch/config
@@ -3,6 +3,7 @@ CONFIG_INET_DIAG=y
 CONFIG_IP_SCTP=y
 CONFIG_IPV6=y
 CONFIG_NETFILTER=y
+CONFIG_DEBUG_NET=y
 CONFIG_NET_IPGRE=m
 CONFIG_NET_IPGRE_DEMUX=m
 CONFIG_NF_CONNTRACK=m
diff --git a/tools/testing/selftests/net/openvswitch/openvswitch.sh 
b/tools/testing/selftests/net/openvswitch/openvswitch.sh
index a31f7fb6882dc..b9a4c4bf40672 100755
--- a/tools/testing/selftests/net/openvswitch/openvswitch.sh
+++ b/tools/testing/selftests/net/openvswitch/openvswitch.sh
@@ -31,6 +31,7 @@ tests="
        dec_ttl                                 ttl: dec_ttl decrements IP TTL
        flow_set                                flow-set: Flow modify
        action_set                              set: SET action rewrites fields
+       ipv6_later_frag                         ipv6-frag: SET on a later IPv6 
fragment
        trunc                                   trunc: output truncation
        icmpv6                                  icmpv6: ICMPv6 echo type match
        sctp_connect_v4                         sctp: SCTP flow key matching
@@ -66,6 +67,11 @@ ovs_wait() {
        return 1
 }
 
+ovs_flow_has_packets() {
+       python3 "$ovs_base/ovs-dpctl.py" dump-flows "$1" |
+               grep -Eq 'packets:[1-9][0-9]*,'
+}
+
 ovs_base=`pwd`
 sbxs=
 sbx_add () {
@@ -445,6 +451,43 @@ test_action_set() {
        return 0
 }
 
+test_ipv6_later_frag() {
+       local t="test_ipv6_later_frag"
+       local warning="WARNING:.*set_ipv6_addr"
+       local before after
+
+       if ! dmesg >/dev/null 2>&1; then
+               info "dmesg unavailable - cannot check for kernel warning"
+               return $ksft_skip
+       fi
+
+       before=$(dmesg | grep -c "$warning" || true)
+       if [ "$before" -ne 0 ]; then
+               info "set_ipv6_addr warning already present - skipping"
+               return $ksft_skip
+       fi
+
+       sbx_add "$t" || return 1
+       ovs_add_dp "$t" fragtest || return 1
+       ovs_add_netns_and_veths "$t" fragtest client c0 c1 || return 1
+
+       ovs_add_flow "$t" fragtest \
+               'in_port(1),eth(),eth_type(0x86dd),ipv6(proto=44)' \
+               'set(ipv6(src=2001:db8::99,proto=44)),drop' || return 1
+
+       ip netns exec client python3 "$ovs_base/ovs-ipv6-frag.py" c1 || \
+               return 1
+       ovs_wait ovs_flow_has_packets fragtest || return 1
+
+       after=$(dmesg | grep -c "$warning" || true)
+       if [ "$after" -ne "$before" ]; then
+               info "set_ipv6_addr warning emitted for later IPv6 fragment"
+               return 1
+       fi
+
+       return 0
+}
+
 # trunc test
 # - trunc(14): truncate to ETH_HLEN, strips IP payload, ping fails
 # - trunc(1) and trunc(13): kernel rejects below ETH_HLEN (EINVAL)
diff --git a/tools/testing/selftests/net/openvswitch/ovs-ipv6-frag.py 
b/tools/testing/selftests/net/openvswitch/ovs-ipv6-frag.py
new file mode 100644
index 0000000000000..869f9d6503ef4
--- /dev/null
+++ b/tools/testing/selftests/net/openvswitch/ovs-ipv6-frag.py
@@ -0,0 +1,48 @@
+#!/usr/bin/env python3
+# SPDX-License-Identifier: GPL-2.0
+
+import ipaddress
+import socket
+import struct
+import sys
+
+
+def main():
+    if len(sys.argv) != 2:
+        print(f"Usage: {sys.argv[0]} INTERFACE", file=sys.stderr)
+        return 2
+
+    interface = sys.argv[1]
+    payload = bytes(range(8))
+    # Offset 1 and M=1 make this a noninitial fragment.
+    fragment = struct.pack("!BBHI", socket.IPPROTO_TCP, 0, 0x0009, 1)
+    ipv6 = struct.pack(
+        "!IHBB16s16s",
+        6 << 28,
+        len(fragment) + len(payload),
+        socket.IPPROTO_FRAGMENT,
+        64,
+        ipaddress.IPv6Address("2001:db8::1").packed,
+        ipaddress.IPv6Address("2001:db8::2").packed,
+    )
+    ethernet = struct.pack(
+        "!6s6sH",
+        b"\xff" * 6,
+        bytes.fromhex("020000000001"),
+        0x86DD,
+    )
+    packet = ethernet + ipv6 + fragment + payload
+
+    with socket.socket(
+        socket.AF_PACKET, socket.SOCK_RAW, socket.htons(0x0003)
+    ) as sock:
+        sock.bind((interface, 0))
+        sent = sock.send(packet)
+
+    if sent != len(packet):
+        raise OSError(f"short packet send: {sent} of {len(packet)} bytes")
+    return 0
+
+
+if __name__ == "__main__":
+    sys.exit(main())
_______________________________________________
dev mailing list
[email protected]
https://mail.openvswitch.org/mailman/listinfo/ovs-dev

Reply via email to