]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
selftests: openvswitch: add tests for tunnel vport refcounting
authorIlya Maximets <i.maximets@ovn.org>
Thu, 30 Apr 2026 23:38:38 +0000 (01:38 +0200)
committerPaolo Abeni <pabeni@redhat.com>
Tue, 5 May 2026 13:19:37 +0000 (15:19 +0200)
There were a few issues found with the tunnel vport types around the
vport destruction code.  Add some basic tests, so at least we know that
they can be properly added and removed without obvious issues.

The test creates OVS datapath, adds a non-LWT tunnel port, makes sure
they are created, and then removes the datapath and waits for all the
ports to be gone.

The dpctl script had a few bugs in the none-lwt tunnel creation code,
so fixing them as well to make the testing possible:
- The type of the --lwt option changed in order to properly disable it.
- Removed byte order conversion for the port numbers, as the value
  supposed to be in the host order.
- Added missing 'gre' choice for the tunnel type.

Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Acked-by: Eelco Chaudron <echaudro@redhat.com>
Acked-by: Aaron Conole <aconole@redhat.com>
Link: https://patch.msgid.link/20260430233848.440994-3-i.maximets@ovn.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
tools/testing/selftests/net/openvswitch/openvswitch.sh
tools/testing/selftests/net/openvswitch/ovs-dpctl.py

index b327d3061ed53ac04fa39df1e7cda21616f10ccd..3cdd953f681324e0f4b6865fdeed41e47f438dcf 100755 (executable)
@@ -26,6 +26,7 @@ tests="
        netlink_checks                          ovsnl: validate netlink attrs and settings
        upcall_interfaces                       ovs: test the upcall interfaces
        tunnel_metadata                         ovs: test extraction of tunnel metadata
+       tunnel_refcount                         ovs: test tunnel vport reference cleanup
        drop_reason                             drop: test drop reasons are emitted
        psample                                 psample: Sampling packets with psample"
 
@@ -830,6 +831,42 @@ test_tunnel_metadata() {
        return 0
 }
 
+test_tunnel_refcount() {
+       sbxname="test_tunnel_refcount"
+       sbx_add "${sbxname}" || return 1
+
+       ovs_sbx "${sbxname}" ip netns add trefns || return 1
+       on_exit "ovs_sbx ${sbxname} ip netns del trefns"
+
+       for tun_type in gre vxlan geneve; do
+               info "testing ${tun_type} tunnel vport refcount"
+
+               ovs_sbx "${sbxname}" ip netns exec trefns \
+                       python3 $ovs_base/ovs-dpctl.py \
+                       add-dp dp-${tun_type} || return 1
+
+               ovs_sbx "${sbxname}" ip netns exec trefns \
+                       python3 $ovs_base/ovs-dpctl.py \
+                       add-if --no-lwt -t ${tun_type} \
+                       dp-${tun_type} ovs-${tun_type}0 || return 1
+
+               ovs_wait ip -netns trefns link show \
+                       ovs-${tun_type}0 >/dev/null 2>&1 || return 1
+
+               info "deleting dp - may hang if reference counting is broken"
+               ovs_sbx "${sbxname}" ip netns exec trefns \
+                       python3 $ovs_base/ovs-dpctl.py \
+                       del-dp dp-${tun_type} &
+
+               dev_removed() {
+                       ! ip -netns trefns link show "$1" >/dev/null 2>&1
+               }
+               ovs_wait dev_removed dp-${tun_type} || return 1
+               ovs_wait dev_removed ovs-${tun_type}0 || return 1
+       done
+       return 0
+}
+
 run_test() {
        (
        tname="$1"
index 848f61fdcee09aee2603ca587de65d3f2c7fadb4..bbe35e2718d2696f31b56edd211139f08953733f 100644 (file)
@@ -11,7 +11,6 @@ import logging
 import math
 import multiprocessing
 import re
-import socket
 import struct
 import sys
 import time
@@ -2069,7 +2068,7 @@ class OvsVport(GenericNetlinkSocket):
         elif vport_type == "internal":
             return OvsVport.OVS_VPORT_TYPE_INTERNAL
         elif vport_type == "gre":
-            return OvsVport.OVS_VPORT_TYPE_INTERNAL
+            return OvsVport.OVS_VPORT_TYPE_GRE
         elif vport_type == "vxlan":
             return OvsVport.OVS_VPORT_TYPE_VXLAN
         elif vport_type == "geneve":
@@ -2121,6 +2120,7 @@ class OvsVport(GenericNetlinkSocket):
         )
 
         TUNNEL_DEFAULTS = [("geneve", 6081),
+                           ("gre", 0),
                            ("vxlan", 4789)]
 
         for tnl in TUNNEL_DEFAULTS:
@@ -2129,9 +2129,13 @@ class OvsVport(GenericNetlinkSocket):
                     dport = tnl[1]
 
                 if not lwt:
+                    if tnl[0] == "gre":
+                        # GRE tunnels have no options.
+                        break
+
                     vportopt = OvsVport.ovs_vport_msg.vportopts()
                     vportopt["attrs"].append(
-                        ["OVS_TUNNEL_ATTR_DST_PORT", socket.htons(dport)]
+                        ["OVS_TUNNEL_ATTR_DST_PORT", dport]
                     )
                     msg["attrs"].append(
                         ["OVS_VPORT_ATTR_OPTIONS", vportopt]
@@ -2145,6 +2149,9 @@ class OvsVport(GenericNetlinkSocket):
                                  geneve_port=dport,
                                  geneve_collect_metadata=True,
                                  geneve_udp_zero_csum6_rx=1)
+                    elif tnl[0] == "gre":
+                        ipr.link("add", ifname=vport_ifname, kind="gretap",
+                                 gre_collect_metadata=True)
                     elif tnl[0] == "vxlan":
                         ipr.link("add", ifname=vport_ifname, kind=tnl[0],
                                  vxlan_learning=0, vxlan_collect_metadata=1,
@@ -2563,7 +2570,7 @@ def print_ovsdp_full(dp_lookup_rep, ifindex, ndb=NDB(), vpl=OvsVport()):
             if vpo:
                 dpo = vpo.get_attr("OVS_TUNNEL_ATTR_DST_PORT")
                 if dpo:
-                    opts += " tnl-dport:%s" % socket.ntohs(dpo)
+                    opts += " tnl-dport:%s" % dpo
             print(
                 "  port %d: %s (%s%s)"
                 % (
@@ -2632,7 +2639,7 @@ def main(argv):
         "--ptype",
         type=str,
         default="netdev",
-        choices=["netdev", "internal", "geneve", "vxlan"],
+        choices=["netdev", "internal", "gre", "geneve", "vxlan"],
         help="Interface type (default netdev)",
     )
     addifcmd.add_argument(
@@ -2645,7 +2652,7 @@ def main(argv):
     addifcmd.add_argument(
         "-l",
         "--lwt",
-        type=bool,
+        action=argparse.BooleanOptionalAction,
         default=True,
         help="Use LWT infrastructure instead of vport (default true)."
     )