diff --git a/SOURCES/openvswitch-3.1.0.patch b/SOURCES/openvswitch-3.1.0.patch
index 6c4f263..a599243 100644
--- a/SOURCES/openvswitch-3.1.0.patch
+++ b/SOURCES/openvswitch-3.1.0.patch
@@ -677,10 +677,81 @@ index d12d9b8a5..41b23d8ae 100644
      free(argcopy);
      return 0;
 diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
-index c9f7179c3..aed2c8fbb 100644
+index c9f7179c3..a0878086e 100644
 --- a/lib/dpif-netdev.c
 +++ b/lib/dpif-netdev.c
-@@ -9616,6 +9616,7 @@ dpif_netdev_bond_stats_get(struct dpif *dpif, uint32_t bond_id,
+@@ -4191,7 +4191,7 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd,
+                 const struct dpif_flow_put *put,
+                 struct dpif_flow_stats *stats)
+ {
+-    struct dp_netdev_flow *netdev_flow;
++    struct dp_netdev_flow *netdev_flow = NULL;
+     int error = 0;
+ 
+     if (stats) {
+@@ -4199,16 +4199,35 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd,
+     }
+ 
+     ovs_mutex_lock(&pmd->flow_mutex);
+-    netdev_flow = dp_netdev_pmd_lookup_flow(pmd, key, NULL);
+-    if (!netdev_flow) {
+-        if (put->flags & DPIF_FP_CREATE) {
+-            dp_netdev_flow_add(pmd, match, ufid, put->actions,
+-                               put->actions_len, ODPP_NONE);
++    if (put->ufid) {
++        netdev_flow = dp_netdev_pmd_find_flow(pmd, put->ufid,
++                                              put->key, put->key_len);
++    } else {
++        /* Use key instead of the locally generated ufid
++         * to search netdev_flow. */
++        netdev_flow = dp_netdev_pmd_lookup_flow(pmd, key, NULL);
++    }
++
++    if (put->flags & DPIF_FP_CREATE) {
++        if (!netdev_flow) {
++            dp_netdev_flow_add(pmd, match, ufid,
++                               put->actions, put->actions_len, ODPP_NONE);
+         } else {
+-            error = ENOENT;
++            error = EEXIST;
+         }
+-    } else {
+-        if (put->flags & DPIF_FP_MODIFY) {
++        goto exit;
++    }
++
++    if (put->flags & DPIF_FP_MODIFY) {
++        if (!netdev_flow) {
++            error = ENOENT;
++        } else {
++            if (!put->ufid && !flow_equal(&match->flow, &netdev_flow->flow)) {
++                /* Overlapping flow. */
++                error = EINVAL;
++                goto exit;
++            }
++
+             struct dp_netdev_actions *new_actions;
+             struct dp_netdev_actions *old_actions;
+ 
+@@ -4239,15 +4258,11 @@ flow_put_on_pmd(struct dp_netdev_pmd_thread *pmd,
+                  *   counter, and subtracting it before outputting the stats */
+                 error = EOPNOTSUPP;
+             }
+-
+             ovsrcu_postpone(dp_netdev_actions_free, old_actions);
+-        } else if (put->flags & DPIF_FP_CREATE) {
+-            error = EEXIST;
+-        } else {
+-            /* Overlapping flow. */
+-            error = EINVAL;
+         }
+     }
++
++exit:
+     ovs_mutex_unlock(&pmd->flow_mutex);
+     return error;
+ }
+@@ -9616,6 +9631,7 @@ dpif_netdev_bond_stats_get(struct dpif *dpif, uint32_t bond_id,
  const struct dpif_class dpif_netdev_class = {
      "netdev",
      true,                       /* cleanup_required */
@@ -5369,6 +5440,61 @@ index 3b5c66fe5..d63528e69 100644
  ])
  
  ovs-appctl time/warp 1000
+diff --git a/tests/pmd.at b/tests/pmd.at
+index c707f762c..1cc9fed3d 100644
+--- a/tests/pmd.at
++++ b/tests/pmd.at
+@@ -1300,3 +1300,50 @@ OVS_WAIT_UNTIL([tail -n +$LINENUM ovs-vswitchd.log | grep "PMD load based sleeps
+ 
+ OVS_VSWITCHD_STOP
+ AT_CLEANUP
++
++AT_SETUP([PMD - revalidator modify overlapping flows])
++
++OVS_VSWITCHD_START(
++[add-port br0 p1 \
++   -- set bridge br0 datapath-type=dummy \
++   -- set interface p1 type=dummy-pmd \
++   -- add-port br0 p2 \
++   -- set interface p2 type=dummy-pmd
++], [], [], [DUMMY_NUMA])
++
++dnl Add one OpenFlow rule and generate a megaflow.
++AT_CHECK([ovs-ofctl add-flow br0 'table=0,in_port=p1,ip,nw_dst=10.1.2.0/24,actions=p2'])
++AT_CHECK([ovs-appctl netdev-dummy/receive p1 'ipv4(src=10.0.0.1,dst=10.1.2.2,proto=6),tcp(src=1,dst=2)'])
++
++OVS_WAIT_UNTIL_EQUAL([ovs-appctl dpctl/dump-flows | sed 's/.*core: [[0-9]]*//'], [
++recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=10.1.2.2/255.255.255.0,frag=no), packets:0, bytes:0, used:never, actions:2])
++
++AT_CHECK([ovs-appctl netdev-dummy/receive p1 'ipv4(src=10.0.0.1,dst=10.1.2.2,proto=6),tcp(src=1,dst=2)'])
++dnl Replace OpenFlow rules, trigger the revalidation.
++AT_CHECK([echo 'table=0,in_port=p1,ip,nw_dst=10.1.0.0/16 actions=ct(commit)' | dnl
++          ovs-ofctl --bundle replace-flows br0 -])
++AT_CHECK([ovs-appctl revalidator/wait])
++
++AT_CHECK([ovs-appctl netdev-dummy/receive p1 'ipv4(src=10.0.0.1,dst=10.1.0.2,proto=6),tcp(src=1,dst=2)'])
++OVS_WAIT_UNTIL_EQUAL([ovs-appctl dpctl/dump-flows | sed 's/.*core: [[0-9]]*//' | strip_xout_keep_actions], [
++recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=10.1.0.2/255.255.0.0,frag=no), packets:0, bytes:0, used:never, actions:ct(commit)
++recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=10.1.2.2/255.255.255.0,frag=no), packets:0, bytes:0, used:0.0s, actions:ct(commit)])
++
++dnl Hold the prefix 10.1.2.2/24 by another 10s.
++AT_CHECK([ovs-appctl netdev-dummy/receive p1 'ipv4(src=10.0.0.1,dst=10.1.2.2,proto=6),tcp(src=1,dst=2)'])
++dnl Send more 10.1.0.2 to make 10.1.0.0/16 tuple prepend 10.1.2.0/24 tuple in the pvector of subtables.
++for i in $(seq 0 256); do
++  AT_CHECK([ovs-appctl netdev-dummy/receive p1 'ipv4(src=10.0.0.1,dst=10.1.0.2,proto=6),tcp(src=1,dst=2)'])
++done
++
++AT_CHECK([echo 'table=0,in_port=p1,ip,nw_dst=10.1.0.0/16 actions=p2' | dnl
++          ovs-ofctl --bundle replace-flows br0 -])
++
++AT_CHECK([ovs-appctl revalidator/wait])
++AT_CHECK([ovs-appctl dpctl/dump-flows | sed 's/.*core: [[0-9]]*//' | strip_xout_keep_actions], [0], [
++recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=10.1.0.2/255.255.0.0,frag=no), packets:0, bytes:0, used:0.0s, actions:2
++recirc_id(0),in_port(1),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(dst=10.1.2.2/255.255.255.0,frag=no), packets:0, bytes:0, used:0.0s, actions:2
++])
++
++OVS_VSWITCHD_STOP
++AT_CLEANUP
 diff --git a/tests/system-dpdk-macros.at b/tests/system-dpdk-macros.at
 index 53fbc1320..3920f08a5 100644
 --- a/tests/system-dpdk-macros.at
diff --git a/SPECS/openvswitch3.1.spec b/SPECS/openvswitch3.1.spec
index 2687053..a8a181b 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: 43%{?dist}
+Release: 44%{?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
+* Mon Aug 14 2023 Open vSwitch CI <ovs-ci@redhat.com> - 3.1.0-44
+- Merging upstream branch-3.1 [RH git: 5c394656fd]
+    Commit list:
+    9c600710bf dpif-netdev: Fix dpif_netdev_flow_put.
+
+
 * Wed Aug 09 2023 Open vSwitch CI <ovs-ci@redhat.com> - 3.1.0-43
 - Merging upstream branch-3.1 [RH git: 2719628c57]
     Commit list: