diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch
index 0dd25e2..caa6ae8 100644
--- a/SOURCES/openvswitch-2.17.0.patch
+++ b/SOURCES/openvswitch-2.17.0.patch
@@ -65505,7 +65505,7 @@ index ef7bb4b8ee..c36a140a8e 100644
 -#endif
  }
 diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py
-index 4ecdcaa197..08846b0d51 100644
+index 4ecdcaa197..1aa0c33d13 100644
 --- a/python/ovs/db/idl.py
 +++ b/python/ovs/db/idl.py
 @@ -85,9 +85,9 @@ class Monitor(enum.IntEnum):
@@ -65624,7 +65624,15 @@ index 4ecdcaa197..08846b0d51 100644
  
      def restart_fsm(self):
          # Resync data DB table conditions to avoid missing updated due to
-@@ -482,7 +517,7 @@ class Idl(object):
+@@ -459,6 +494,7 @@ class Idl(object):
+                         if not msg.result[0]:
+                             self.__clear()
+                         self.__parse_update(msg.result[2], OVSDB_UPDATE3)
++                        self.last_id = msg.result[1]
+                     elif self.state == self.IDL_S_DATA_MONITOR_COND_REQUESTED:
+                         self.__clear()
+                         self.__parse_update(msg.result, OVSDB_UPDATE2)
+@@ -482,7 +518,7 @@ class Idl(object):
                      sh.register_table(self._server_db_table)
                      schema = sh.get_idl_schema()
                      self._server_db = schema
@@ -65633,7 +65641,7 @@ index 4ecdcaa197..08846b0d51 100644
                      self.__send_server_monitor_request()
                  except error.Error as e:
                      vlog.err("%s: error receiving server schema: %s"
-@@ -588,10 +623,10 @@ class Idl(object):
+@@ -588,10 +624,10 @@ class Idl(object):
          for table in self.tables.values():
              # Always use the most recent conditions set by the IDL client when
              # requesting monitor_cond_change
@@ -65647,7 +65655,7 @@ index 4ecdcaa197..08846b0d51 100644
  
          if not change_requests:
              return
-@@ -627,19 +662,20 @@ class Idl(object):
+@@ -627,19 +663,20 @@ class Idl(object):
              cond = [False]
  
          # Compare the new condition to the last known condition
@@ -65673,7 +65681,7 @@ index 4ecdcaa197..08846b0d51 100644
  
      def wait(self, poller):
          """Arranges for poller.block() to wake up when self.run() has something
-@@ -811,8 +847,8 @@ class Idl(object):
+@@ -811,8 +848,8 @@ class Idl(object):
                      columns.append(column)
              monitor_request = {"columns": columns}
              if method in ("monitor_cond", "monitor_cond_since") and (
@@ -65684,7 +65692,7 @@ index 4ecdcaa197..08846b0d51 100644
              monitor_requests[table.name] = [monitor_request]
  
          args = [self._db.name, str(self.uuid), monitor_requests]
-@@ -1148,13 +1184,6 @@ class Idl(object):
+@@ -1148,13 +1185,6 @@ class Idl(object):
              return True
  
  
@@ -65698,7 +65706,7 @@ index 4ecdcaa197..08846b0d51 100644
  def _row_to_uuid(value):
      if isinstance(value, Row):
          return value.uuid
-@@ -1266,7 +1295,19 @@ class Row(object):
+@@ -1266,7 +1296,19 @@ class Row(object):
          return "{table}({data})".format(
              table=self._table.name,
              data=", ".join("{col}={val}".format(col=c, val=getattr(self, c))
@@ -65719,7 +65727,7 @@ index 4ecdcaa197..08846b0d51 100644
  
      def __getattr__(self, column_name):
          assert self._changes is not None
-@@ -1309,7 +1350,7 @@ class Row(object):
+@@ -1309,7 +1351,7 @@ class Row(object):
                      datum = data.Datum.from_python(column.type, dlist,
                                                     _row_to_uuid)
                  elif column.type.is_map():
@@ -65728,7 +65736,7 @@ index 4ecdcaa197..08846b0d51 100644
                      if inserts is not None:
                          dmap.update(inserts)
                      if removes is not None:
-@@ -1326,7 +1367,7 @@ class Row(object):
+@@ -1326,7 +1368,7 @@ class Row(object):
                  else:
                      datum = inserts
  
@@ -65737,7 +65745,7 @@ index 4ecdcaa197..08846b0d51 100644
  
      def __setattr__(self, column_name, value):
          assert self._changes is not None
-@@ -1410,7 +1451,7 @@ class Row(object):
+@@ -1410,7 +1452,7 @@ class Row(object):
          if value:
              try:
                  old_value = data.Datum.to_python(self._data[column_name],
@@ -69756,7 +69764,7 @@ index e72bf06069..fd1c7a2395 100644
  [{"count":1},{"details":"cannot delete b row <0> because of 2 remaining reference(s)","error":"referential integrity violation"}]
  [{"count":1}]
 diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at
-index 62e2b63832..092d9f81a2 100644
+index 62e2b63832..bacb7f161a 100644
 --- a/tests/ovsdb-idl.at
 +++ b/tests/ovsdb-idl.at
 @@ -561,9 +561,9 @@ OVSDB_CHECK_IDL([simple idl, conditional, false condition],
@@ -69992,7 +70000,60 @@ index 62e2b63832..092d9f81a2 100644
  003: table simple3: name=row0_s3 uset=[] uref=[] uuid=<1>
  004: {"error":null,"result":[{"uuid":["uuid","<2>"]}]}
  005: table simple3: name=row0_s3 uset=[] uref=[] uuid=<1>
-@@ -2341,11 +2378,11 @@ OVSDB_CHECK_CLUSTER_IDL([simple idl, monitor_cond_since, cluster disconnect],
+@@ -2230,6 +2267,23 @@ CHECK_STREAM_OPEN_BLOCK([Python3], [$PYTHON3 $srcdir/test-stream.py],
+ CHECK_STREAM_OPEN_BLOCK([Python3], [$PYTHON3 $srcdir/test-stream.py],
+                         [tcp6], [[[::1]]])
+ 
++dnl OVSDB_CLUSTER_CHECK_MONITOR_COND_SINCE_TXN_IDS(LOG)
++dnl
++dnl Looks up transaction IDs in the log of OVSDB client application.
++dnl All-zero UUID should not be sent within a monitor request more than once,
++dnl unless some database requests were lost (not replied).
++m4_define([OVSDB_CLUSTER_CHECK_MONITOR_COND_SINCE_TXN_IDS],
++[
++   requests=$(grep -c 'send request' $1)
++   replies=$(grep -c 'received reply' $1)
++
++   if test "$requests" -eq "$replies"; then
++     AT_CHECK([grep 'monitor_cond_since' $1 \
++                | grep -c "00000000-0000-0000-0000-000000000000" | tr -d '\n'],
++              [0], [1])
++   fi
++])
++
+ # same as OVSDB_CHECK_IDL but uses Python IDL implementation with tcp
+ # with multiple remotes to assert the idl connects to the leader of the Raft cluster
+ m4_define([OVSDB_CHECK_IDL_LEADER_ONLY_PY],
+@@ -2245,10 +2299,11 @@ m4_define([OVSDB_CHECK_IDL_LEADER_ONLY_PY],
+    pids=$(cat s2.pid s3.pid s1.pid | tr '\n' ',')
+    echo $pids
+    AT_CHECK([$PYTHON3 $srcdir/test-ovsdb.py  -t30 idl-cluster $srcdir/idltest.ovsschema $remotes $pids $3],
+-        [0], [stdout], [ignore])
++        [0], [stdout], [stderr])
+    remote=$(ovsdb_cluster_leader $remotes "idltest")
+    leader=$(echo $remote | cut -d'|' -f 1)
+    AT_CHECK([grep -F -- "${leader}" stdout], [0], [ignore])
++   OVSDB_CLUSTER_CHECK_MONITOR_COND_SINCE_TXN_IDS([stderr])
+    AT_CLEANUP])
+ 
+ OVSDB_CHECK_IDL_LEADER_ONLY_PY([Check Python IDL connects to leader], 3, ['remote'])
+@@ -2291,6 +2346,7 @@ m4_define([OVSDB_CHECK_CLUSTER_IDL_C],
+    AT_CHECK([sort stdout | uuidfilt]m4_if([$7],,, [[| $7]]),
+             [0], [$5])
+    m4_ifval([$8], [AT_CHECK([grep '$8' stderr], [1])], [], [])
++   OVSDB_CLUSTER_CHECK_MONITOR_COND_SINCE_TXN_IDS([stderr])
+    AT_CLEANUP])
+ 
+ # Same as OVSDB_CHECK_CLUSTER_IDL_C but uses the Python IDL implementation.
+@@ -2311,6 +2367,7 @@ m4_define([OVSDB_CHECK_CLUSTER_IDL_PY],
+    AT_CHECK([sort stdout | uuidfilt]m4_if([$7],,, [[| $7]]),
+             [0], [$5])
+    m4_if([$8], [AT_CHECK([grep '$8' stderr], [1])], [], [])
++   OVSDB_CLUSTER_CHECK_MONITOR_COND_SINCE_TXN_IDS([stderr])
+    AT_CLEANUP])
+ 
+ m4_define([OVSDB_CHECK_CLUSTER_IDL],
+@@ -2341,11 +2398,11 @@ OVSDB_CHECK_CLUSTER_IDL([simple idl, monitor_cond_since, cluster disconnect],
         "table": "simple",
         "where": [["i", "==", 1]],
         "row": {"r": 2.0 }}]']],
@@ -70007,7 +70068,7 @@ index 62e2b63832..092d9f81a2 100644
  005: reconnect
  006: table simple
  007: {"error":null,"result":[{"count":1}]}
-@@ -2437,3 +2474,92 @@ unix:socket2 remote has col id in table simple7
+@@ -2437,3 +2494,92 @@ unix:socket2 remote has col id in table simple7
  
  OVSDB_SERVER_SHUTDOWN
  AT_CLEANUP
diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec
index ea0211d..082b109 100644
--- a/SPECS/openvswitch2.17.spec
+++ b/SPECS/openvswitch2.17.spec
@@ -57,7 +57,7 @@ Summary: Open vSwitch
 Group: System Environment/Daemons daemon/database/utilities
 URL: http://www.openvswitch.org/
 Version: 2.17.0
-Release: 108%{?dist}
+Release: 109%{?dist}
 
 # Nearly all of openvswitch is ASL 2.0.  The bugtool is LGPLv2+, and the
 # lib/sflow*.[ch] files are SISSL
@@ -751,6 +751,12 @@ exit 0
 %endif
 
 %changelog
+* Mon Sep 18 2023 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-109
+- Merging upstream branch-2.17 [RH git: 03e330a147]
+    Commit list:
+    3c39cfe031 python: idl: Fix last-id update from a monitor reply.
+
+
 * Thu Sep 07 2023 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-108
 - Merging upstream branch-2.17 [RH git: 2636d56cb6]
     Commit list: