diff --git a/SOURCES/openvswitch-3.1.0.patch b/SOURCES/openvswitch-3.1.0.patch
index 084fbeb..646c736 100644
--- a/SOURCES/openvswitch-3.1.0.patch
+++ b/SOURCES/openvswitch-3.1.0.patch
@@ -591,9 +591,18 @@ index 134496ef3..5d2635946 100644
      invalidate_cache(ctx);
  }
 diff --git a/lib/dpctl.c b/lib/dpctl.c
-index d12d9b8a5..bfc397329 100644
+index d12d9b8a5..41b23d8ae 100644
 --- a/lib/dpctl.c
 +++ b/lib/dpctl.c
+@@ -673,7 +673,7 @@ show_dpif(struct dpif *dpif, struct dpctl_params *dpctl_p)
+     }
+ 
+     for (int i = 0; i < n_port_nos; i++) {
+-        if (dpif_port_query_by_number(dpif, port_nos[i], &dpif_port)) {
++        if (dpif_port_query_by_number(dpif, port_nos[i], &dpif_port, true)) {
+             continue;
+         }
+ 
 @@ -1713,10 +1713,16 @@ dpctl_flush_conntrack(int argc, const char *argv[],
      uint16_t zone, *pzone = NULL;
      int error;
@@ -703,10 +712,52 @@ index 12477a24f..b8ead8a02 100644
       * startup.  Returning an error from this function will prevent any
       * datapath with this class from being created.
 diff --git a/lib/dpif.c b/lib/dpif.c
-index fe4db83fb..3305401fe 100644
+index fe4db83fb..4397aeaf4 100644
 --- a/lib/dpif.c
 +++ b/lib/dpif.c
-@@ -2109,3 +2109,9 @@ dpif_cache_set_size(struct dpif *dpif, uint32_t level, uint32_t size)
+@@ -701,13 +701,14 @@ dpif_port_set_config(struct dpif *dpif, odp_port_t port_no,
+  * initializes '*port' appropriately; on failure, returns a positive errno
+  * value.
+  *
+- * Retuns ENODEV if the port doesn't exist.
++ * Retuns ENODEV if the port doesn't exist.  Will not log a warning in this
++ * case unless 'warn_if_not_found' is true.
+  *
+  * The caller owns the data in 'port' and must free it with
+  * dpif_port_destroy() when it is no longer needed. */
+ int
+ dpif_port_query_by_number(const struct dpif *dpif, odp_port_t port_no,
+-                          struct dpif_port *port)
++                          struct dpif_port *port, bool warn_if_not_found)
+ {
+     int error = dpif->dpif_class->port_query_by_number(dpif, port_no, port);
+     if (!error) {
+@@ -715,8 +716,13 @@ dpif_port_query_by_number(const struct dpif *dpif, odp_port_t port_no,
+                     dpif_name(dpif), port_no, port->name);
+     } else {
+         memset(port, 0, sizeof *port);
+-        VLOG_WARN_RL(&error_rl, "%s: failed to query port %"PRIu32": %s",
+-                     dpif_name(dpif), port_no, ovs_strerror(error));
++        if (error == ENODEV && !warn_if_not_found) {
++            VLOG_DBG_RL(&dpmsg_rl, "%s: failed to query port %"PRIu32": %s",
++                        dpif_name(dpif), port_no, ovs_strerror(error));
++        } else {
++            VLOG_WARN_RL(&error_rl, "%s: failed to query port %"PRIu32": %s",
++                         dpif_name(dpif), port_no, ovs_strerror(error));
++        }
+     }
+     return error;
+ }
+@@ -784,7 +790,7 @@ dpif_port_get_name(struct dpif *dpif, odp_port_t port_no,
+ 
+     ovs_assert(name_size > 0);
+ 
+-    error = dpif_port_query_by_number(dpif, port_no, &port);
++    error = dpif_port_query_by_number(dpif, port_no, &port, true);
+     if (!error) {
+         ovs_strlcpy(name, port.name, name_size);
+         dpif_port_destroy(&port);
+@@ -2109,3 +2115,9 @@ dpif_cache_set_size(struct dpif *dpif, uint32_t level, uint32_t size)
             ? dpif->dpif_class->cache_set_size(dpif, level, size)
             : EOPNOTSUPP;
  }
@@ -717,9 +768,18 @@ index fe4db83fb..3305401fe 100644
 +    return dpif->dpif_class->synced_dp_layers;
 +}
 diff --git a/lib/dpif.h b/lib/dpif.h
-index 6cb4dae6d..129cbf6a1 100644
+index 6cb4dae6d..2a3649720 100644
 --- a/lib/dpif.h
 +++ b/lib/dpif.h
+@@ -461,7 +461,7 @@ void dpif_port_clone(struct dpif_port *, const struct dpif_port *);
+ void dpif_port_destroy(struct dpif_port *);
+ bool dpif_port_exists(const struct dpif *dpif, const char *devname);
+ int dpif_port_query_by_number(const struct dpif *, odp_port_t port_no,
+-                              struct dpif_port *);
++                              struct dpif_port *, bool warn_if_not_found);
+ int dpif_port_query_by_name(const struct dpif *, const char *devname,
+                             struct dpif_port *);
+ int dpif_port_get_name(struct dpif *, odp_port_t port_no,
 @@ -939,6 +939,7 @@ int dpif_get_pmds_for_port(const struct dpif * dpif, odp_port_t port_no,
  char *dpif_get_dp_version(const struct dpif *);
  bool dpif_supports_tnl_push_pop(const struct dpif *);
@@ -3201,7 +3261,7 @@ index a9cf3cbee..78b6df409 100644
                  return;
              }
 diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
-index f87e27a8c..fad7342b0 100644
+index f87e27a8c..e22ca757a 100644
 --- a/ofproto/ofproto-dpif.c
 +++ b/ofproto/ofproto-dpif.c
 @@ -714,12 +714,6 @@ close_dpif_backer(struct dpif_backer *backer, bool del)
@@ -3261,6 +3321,41 @@ index f87e27a8c..fad7342b0 100644
      shash_add(&all_dpif_backers, type, backer);
  
      check_support(backer);
+@@ -2171,8 +2161,7 @@ port_destruct(struct ofport *port_, bool del)
+     struct ofproto_dpif *ofproto = ofproto_dpif_cast(port->up.ofproto);
+     const char *devname = netdev_get_name(port->up.netdev);
+     const char *netdev_type = netdev_get_type(port->up.netdev);
+-    char namebuf[NETDEV_VPORT_NAME_BUFSIZE];
+-    const char *dp_port_name;
++    struct dpif_port dpif_port;
+ 
+     ofproto->backer->need_revalidate = REV_RECONFIGURE;
+     xlate_txn_start();
+@@ -2186,9 +2175,13 @@ port_destruct(struct ofport *port_, bool del)
+         del = dpif_cleanup_required(ofproto->backer->dpif);
+     }
+ 
+-    dp_port_name = netdev_vport_get_dpif_port(port->up.netdev, namebuf,
+-                                              sizeof namebuf);
+-    if (del && dpif_port_exists(ofproto->backer->dpif, dp_port_name)) {
++    /* Don't try to delete ports that are not part of the datapath. */
++    if (del && port->odp_port == ODPP_NONE) {
++        del = false;
++    }
++
++    if (del && !dpif_port_query_by_number(ofproto->backer->dpif,
++                                          port->odp_port, &dpif_port, false)) {
+         /* The underlying device is still there, so delete it.  This
+          * happens when the ofproto is being destroyed, since the caller
+          * assumes that removal of attached ports will happen as part of
+@@ -2196,6 +2189,7 @@ port_destruct(struct ofport *port_, bool del)
+         if (!port->is_tunnel) {
+             dpif_port_del(ofproto->backer->dpif, port->odp_port, false);
+         }
++        dpif_port_destroy(&dpif_port);
+     } else if (del) {
+         /* The underlying device is already deleted (e.g. tunctl -d).
+          * Calling dpif_port_remove to do local cleanup for the netdev */
 diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
 index a84ddc1d0..143ded690 100644
 --- a/ofproto/ofproto-provider.h
@@ -4684,10 +4779,10 @@ index cb6c6d590..0f58e8574 100644
  AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:shared-mempool-config=8000,6000,1500])
  AT_CHECK([ovs-vsctl --no-wait set Open_vSwitch . other_config:dpdk-init=true])
 diff --git a/tests/system-interface.at b/tests/system-interface.at
-index 784bada12..3bf339582 100644
+index 784bada12..15e789a24 100644
 --- a/tests/system-interface.at
 +++ b/tests/system-interface.at
-@@ -63,3 +63,62 @@ AT_CHECK([
+@@ -63,3 +63,119 @@ AT_CHECK([
      [stdout], [Device "br-p1" does not exist.]
  )
  AT_CLEANUP
@@ -4750,6 +4845,63 @@ index 784bada12..3bf339582 100644
 +
 +OVS_TRAFFIC_VSWITCHD_STOP
 +AT_CLEANUP
++
++AT_SETUP([interface - datapath port rename])
++OVS_TRAFFIC_VSWITCHD_START()
++
++dnl Not relevant for userspace datapath.
++AT_SKIP_IF([! ovs-appctl dpctl/show | grep -q ovs-system])
++
++AT_CHECK([ip link add ovs-veth0 type veth peer name ovs-veth1])
++dnl We will rename ovs-veth0, so removing the peer on exit.
++on_exit 'ip link del ovs-veth1'
++
++AT_CHECK([ovs-vsctl add-port br0 ovs-veth0])
++
++OVS_WAIT_UNTIL([ip link show | grep -q "ovs-veth0.* ovs-system "])
++
++AT_CHECK([ovs-appctl dpctl/show | grep port], [0], [dnl
++  port 0: ovs-system (internal)
++  port 1: br0 (internal)
++  port 2: ovs-veth0
++])
++
++dnl Rename the interface while attached to OVS.
++AT_CHECK([ip l set ovs-veth0 name ovs-new-port])
++
++dnl Wait for the port to be detached from the OVS datapath.
++OVS_WAIT_UNTIL([ip link show | grep "ovs-new-port" | grep -v "ovs-system"])
++
++dnl Check that database indicates the error.
++AT_CHECK([ovs-vsctl get interface ovs-veth0 error], [0], [dnl
++"could not open network device ovs-veth0 (No such device)"
++])
++
++dnl Check that the port is no longer in the datapath.
++AT_CHECK([ovs-appctl dpctl/show | grep port], [0], [dnl
++  port 0: ovs-system (internal)
++  port 1: br0 (internal)
++])
++
++dnl Rename the interface back and check that it is in use again.
++AT_CHECK([ip l set ovs-new-port name ovs-veth0])
++
++OVS_WAIT_UNTIL([ip link show | grep -q "ovs-veth0.* ovs-system "])
++
++AT_CHECK([ovs-vsctl get interface ovs-veth0 error], [0], [dnl
++[[]]
++])
++
++AT_CHECK([ovs-appctl dpctl/show | grep port], [0], [dnl
++  port 0: ovs-system (internal)
++  port 1: br0 (internal)
++  port 2: ovs-veth0
++])
++
++OVS_TRAFFIC_VSWITCHD_STOP(["
++  /could not open network device ovs-veth0 (No such device)/d
++"])
++AT_CLEANUP
 diff --git a/tests/system-kmod-macros.at b/tests/system-kmod-macros.at
 index 11920e60b..1f9950f83 100644
 --- a/tests/system-kmod-macros.at
diff --git a/SPECS/openvswitch3.1.spec b/SPECS/openvswitch3.1.spec
index 318f1b5..2e7a437 100644
--- a/SPECS/openvswitch3.1.spec
+++ b/SPECS/openvswitch3.1.spec
@@ -57,7 +57,7 @@ Summary: Open vSwitch
 Group: System Environment/Daemons daemon/database/utilities
 URL: http://www.openvswitch.org/
 Version: 3.1.0
-Release: 38%{?dist}
+Release: 39%{?dist}
 
 # Nearly all of openvswitch is ASL 2.0.  The bugtool is LGPLv2+, and the
 # lib/sflow*.[ch] files are SISSL
@@ -754,6 +754,12 @@ exit 0
 %endif
 
 %changelog
+* Tue Aug 01 2023 Open vSwitch CI <ovs-ci@redhat.com> - 3.1.0-39
+- Merging upstream branch-3.1 [RH git: 9dbd076546]
+    Commit list:
+    618d3bdbb5 ofproto-dpif: Fix removal of renamed datapath ports.
+
+
 * Tue Jul 25 2023 Open vSwitch CI <ovs-ci@redhat.com> - 3.1.0-38
 - Merging upstream branch-3.1 [RH git: 63dcdf1a37]
     Commit list: