diff --git a/SOURCES/openvswitch-2.17.0.patch b/SOURCES/openvswitch-2.17.0.patch
index 62493c2..a7f52d9 100644
--- a/SOURCES/openvswitch-2.17.0.patch
+++ b/SOURCES/openvswitch-2.17.0.patch
@@ -62101,11 +62101,66 @@ index 388dd54a16..9aa3788dbb 100644
               hmap_remove(&o_column->o_clauses, &c->hmap_node);
               free(c);
           }
+diff --git a/ovsdb/execution.c b/ovsdb/execution.c
+index f9b8067d02..5587ef96fe 100644
+--- a/ovsdb/execution.c
++++ b/ovsdb/execution.c
+@@ -320,7 +320,7 @@ parse_row(const struct json *json, const struct ovsdb_table *table,
+     }
+ 
+     row = ovsdb_row_create(table);
+-    error = ovsdb_row_from_json(row, json, symtab, columns);
++    error = ovsdb_row_from_json(row, json, symtab, columns, false);
+     if (error) {
+         ovsdb_row_destroy(row);
+         return error;
+@@ -764,7 +764,7 @@ ovsdb_execute_wait(struct ovsdb_execution *x, struct ovsdb_parser *parser,
+ 
+             row = ovsdb_row_create(table);
+             error = ovsdb_row_from_json(row, rows->array.elems[i], x->symtab,
+-                                        NULL);
++                                        NULL, false);
+             if (error) {
+                 ovsdb_row_destroy(row);
+                 break;
 diff --git a/ovsdb/file.c b/ovsdb/file.c
-index 9f44007d97..ca80c28235 100644
+index 9f44007d97..b1ef2774ea 100644
 --- a/ovsdb/file.c
 +++ b/ovsdb/file.c
-@@ -524,6 +524,7 @@ ovsdb_file_read__(const char *filename, bool rw,
+@@ -106,13 +106,18 @@ ovsdb_file_update_row_from_json(struct ovsdb_row *row, bool converting,
+                                       column_name, schema->name);
+         }
+ 
+-        error = ovsdb_datum_from_json(&datum, &column->type, node->data, NULL);
++        if (row_contains_diff) {
++            /* Diff may violate the type size rules. */
++            error = ovsdb_transient_datum_from_json(&datum, &column->type,
++                                                    node->data);
++        } else {
++            error = ovsdb_datum_from_json(&datum, &column->type,
++                                          node->data, NULL);
++        }
+         if (error) {
+             return error;
+         }
+-        if (row_contains_diff
+-            && !ovsdb_datum_is_default(&row->fields[column->index],
+-                                       &column->type)) {
++        if (row_contains_diff) {
+             error = ovsdb_datum_apply_diff_in_place(
+                                            &row->fields[column->index],
+                                            &datum, &column->type);
+@@ -153,8 +158,7 @@ ovsdb_file_txn_row_from_json(struct ovsdb_txn *txn, struct ovsdb_table *table,
+ 
+         new = ovsdb_row_create(table);
+         *ovsdb_row_get_uuid_rw(new) = *row_uuid;
+-        error = ovsdb_file_update_row_from_json(new, converting,
+-                                                row_contains_diff, json);
++        error = ovsdb_file_update_row_from_json(new, converting, false, json);
+         if (error) {
+             ovsdb_row_destroy(new);
+         } else {
+@@ -524,6 +528,7 @@ ovsdb_file_read__(const char *filename, bool rw,
  
          error = ovsdb_txn_replay_commit(txn);
          if (error) {
@@ -62836,7 +62891,7 @@ index 10a70ae26f..13c5359395 100755
  unsigned int %(s)s_get_seqno(const struct ovsdb_idl *);
  unsigned int %(s)s_row_get_seqno(const struct %(s)s *row, enum ovsdb_idl_change change);
 diff --git a/ovsdb/ovsdb-server.c b/ovsdb/ovsdb-server.c
-index 9fe90592ea..ddb623dc1a 100644
+index 9fe90592ea..36997e8480 100644
 --- a/ovsdb/ovsdb-server.c
 +++ b/ovsdb/ovsdb-server.c
 @@ -26,6 +26,7 @@
@@ -62847,7 +62902,7 @@ index 9fe90592ea..ddb623dc1a 100644
  #include "openvswitch/dynamic-string.h"
  #include "fatal-signal.h"
  #include "file.h"
-@@ -228,8 +229,7 @@ main_loop(struct server_config *config,
+@@ -228,10 +229,9 @@ main_loop(struct server_config *config,
  
          ovsdb_relay_run();
  
@@ -62855,8 +62910,11 @@ index 9fe90592ea..ddb623dc1a 100644
 -        SHASH_FOR_EACH_SAFE (node, next, all_dbs) {
 +        SHASH_FOR_EACH_SAFE (node, all_dbs) {
              struct db *db = node->data;
-             ovsdb_txn_history_run(db->db);
+-            ovsdb_txn_history_run(db->db);
++
              ovsdb_storage_run(db->db->storage);
+             read_db(config, db);
+             /* Run triggers after storage_run and read_db to make sure new raft
 @@ -321,7 +321,7 @@ main(int argc, char *argv[])
      FILE *config_tmpfile;
      struct server_config server_config;
@@ -62970,7 +63028,7 @@ index 9fe90592ea..ddb623dc1a 100644
      }
  
      if (txn_json) {
-@@ -613,24 +637,25 @@ parse_txn(struct server_config *config, struct db *db,
+@@ -613,24 +637,26 @@ parse_txn(struct server_config *config, struct db *db,
              return ovsdb_error(NULL, "%s: data without schema", db->filename);
          }
  
@@ -63002,12 +63060,13 @@ index 9fe90592ea..ddb623dc1a 100644
 +        if (!error && !uuid_is_zero(txnid)) {
 +            db->db->prereq = *txnid;
 +        }
++        ovsdb_txn_history_run(db->db);
 +    }
 +    return error;
  }
  
  static void
-@@ -1240,8 +1265,8 @@ update_server_status(struct shash *all_dbs)
+@@ -1240,8 +1266,8 @@ update_server_status(struct shash *all_dbs)
  
      /* Update rows for databases that still exist.
       * Delete rows for databases that no longer exist. */
@@ -63019,7 +63078,7 @@ index 9fe90592ea..ddb623dc1a 100644
          ovsdb_util_read_string_column(row, "name", &name);
          struct db *db = shash_find_data(all_dbs, name);
 diff --git a/ovsdb/ovsdb-tool.c b/ovsdb/ovsdb-tool.c
-index d4a9e34cc4..f9a423fba2 100644
+index d4a9e34cc4..4e5be14dcc 100644
 --- a/ovsdb/ovsdb-tool.c
 +++ b/ovsdb/ovsdb-tool.c
 @@ -1005,7 +1005,8 @@ raft_header_to_standalone_log(const struct raft_header *h,
@@ -63073,7 +63132,15 @@ index d4a9e34cc4..f9a423fba2 100644
          if (data_json->type != JSON_NULL) {
              check_ovsdb_error(ovsdb_log_write(db_log_data, data_json));
          }
-@@ -1579,15 +1613,14 @@ do_check_cluster(struct ovs_cmdl_context *ctx)
+@@ -1059,6 +1093,7 @@ do_show_log_cluster(struct ovsdb_log *log)
+             free(s);
+         }
+ 
++        json_destroy(json);
+         putchar('\n');
+     }
+ 
+@@ -1579,15 +1614,14 @@ do_check_cluster(struct ovs_cmdl_context *ctx)
      }
      free(c.servers);
  
@@ -63092,7 +63159,7 @@ index d4a9e34cc4..f9a423fba2 100644
          hmap_remove(&c.leaders, &leader->hmap_node);
          free(leader);
      }
-@@ -1636,7 +1669,8 @@ do_compare_versions(struct ovs_cmdl_context *ctx)
+@@ -1636,7 +1670,8 @@ do_compare_versions(struct ovs_cmdl_context *ctx)
  }
  
  static void
@@ -63102,7 +63169,7 @@ index d4a9e34cc4..f9a423fba2 100644
  {
      for (unsigned int i = 0; ; i++) {
          struct json *json;
-@@ -1653,7 +1687,7 @@ do_convert_to_standalone(struct ovsdb_log *log, struct ovsdb_log *db_log_data)
+@@ -1653,7 +1688,7 @@ do_convert_to_standalone(struct ovsdb_log *log, struct ovsdb_log *db_log_data)
          } else {
              struct raft_record r;
              check_ovsdb_error(raft_record_from_json(&r, json));
@@ -63111,7 +63178,7 @@ index d4a9e34cc4..f9a423fba2 100644
              raft_record_uninit(&r);
          }
          json_destroy(json);
-@@ -1676,7 +1710,7 @@ do_cluster_standalone(struct ovs_cmdl_context *ctx)
+@@ -1676,7 +1711,7 @@ do_cluster_standalone(struct ovs_cmdl_context *ctx)
      if (strcmp(ovsdb_log_get_magic(log), RAFT_MAGIC) != 0) {
          ovs_fatal(0, "Database is not clustered db.\n");
      }
@@ -63578,7 +63645,7 @@ index 1a3447a8dd..cf9edf35c6 100644
          failure_test = FT_NO_TEST;
          unixctl_command_reply(conn, "test dismissed");
 diff --git a/ovsdb/relay.c b/ovsdb/relay.c
-index ef0e44d340..423b98ee7c 100644
+index ef0e44d340..f898de25c0 100644
 --- a/ovsdb/relay.c
 +++ b/ovsdb/relay.c
 @@ -269,9 +269,9 @@ ovsdb_relay_clear(struct ovsdb *db)
@@ -63634,6 +63701,14 @@ index ef0e44d340..423b98ee7c 100644
      if (!error) {
          if (update->clear) {
              error = ovsdb_relay_clear(ctx->db);
+@@ -368,6 +382,7 @@ ovsdb_relay_run(void)
+             }
+             ovsdb_cs_event_destroy(event);
+         }
++        ovsdb_txn_history_run(ctx->db);
+     }
+ }
+ 
 diff --git a/ovsdb/relay.h b/ovsdb/relay.h
 index 390ea70c82..2d66b5e5fa 100644
 --- a/ovsdb/relay.h
@@ -63679,6 +63754,56 @@ index d8b56d8131..477c69d701 100644
          hmap_remove(&replication_dbs->map, &node->node);
          struct replication_db *rdb = node->data;
          if (rdb->active_db_schema) {
+diff --git a/ovsdb/row.c b/ovsdb/row.c
+index e83c60a218..f82d4b84f4 100644
+--- a/ovsdb/row.c
++++ b/ovsdb/row.c
+@@ -290,12 +290,14 @@ ovsdb_row_columns_to_string(const struct ovsdb_row *row,
+ struct ovsdb_error *
+ ovsdb_row_from_json(struct ovsdb_row *row, const struct json *json,
+                     struct ovsdb_symbol_table *symtab,
+-                    struct ovsdb_column_set *included)
++                    struct ovsdb_column_set *included, bool is_diff)
+ {
+     struct ovsdb_table_schema *schema = row->table->schema;
+     struct ovsdb_error *error;
+     struct shash_node *node;
+ 
++    ovs_assert(!is_diff || !symtab);
++
+     if (json->type != JSON_OBJECT) {
+         return ovsdb_syntax_error(json, NULL, "row must be JSON object");
+     }
+@@ -312,8 +314,13 @@ ovsdb_row_from_json(struct ovsdb_row *row, const struct json *json,
+                                       column_name, schema->name);
+         }
+ 
+-        error = ovsdb_datum_from_json(&datum, &column->type, node->data,
+-                                      symtab);
++        if (is_diff) {
++            error = ovsdb_transient_datum_from_json(&datum, &column->type,
++                                                    node->data);
++        } else {
++            error = ovsdb_datum_from_json(&datum, &column->type, node->data,
++                                          symtab);
++        }
+         if (error) {
+             return error;
+         }
+diff --git a/ovsdb/row.h b/ovsdb/row.h
+index fe04555d0c..736c0026d7 100644
+--- a/ovsdb/row.h
++++ b/ovsdb/row.h
+@@ -113,7 +113,8 @@ void ovsdb_row_columns_to_string(const struct ovsdb_row *,
+ struct ovsdb_error *ovsdb_row_from_json(struct ovsdb_row *,
+                                         const struct json *,
+                                         struct ovsdb_symbol_table *,
+-                                        struct ovsdb_column_set *included)
++                                        struct ovsdb_column_set *included,
++                                        bool is_diff)
+     OVS_WARN_UNUSED_RESULT;
+ struct json *ovsdb_row_to_json(const struct ovsdb_row *,
+                                const struct ovsdb_column_set *include);
 diff --git a/ovsdb/storage.c b/ovsdb/storage.c
 index d4984be250..6069c4f102 100644
 --- a/ovsdb/storage.c
@@ -63735,7 +63860,7 @@ index ff026b77fa..6c69e53134 100644
      OVS_WARN_UNUSED_RESULT;
  
 diff --git a/ovsdb/table.c b/ovsdb/table.c
-index 455a3663fe..2184701ec1 100644
+index 455a3663fe..6f48375569 100644
 --- a/ovsdb/table.c
 +++ b/ovsdb/table.c
 @@ -309,10 +309,10 @@ void
@@ -63751,6 +63876,25 @@ index 455a3663fe..2184701ec1 100644
              ovsdb_row_destroy(row);
          }
          hmap_destroy(&table->rows);
+@@ -355,7 +355,8 @@ ovsdb_table_execute_insert(struct ovsdb_txn *txn, const struct uuid *row_uuid,
+ 
+     struct ovsdb_row *row = ovsdb_row_create(table);
+ 
+-    struct ovsdb_error *error = ovsdb_row_from_json(row, json_row, NULL, NULL);
++    struct ovsdb_error *error = ovsdb_row_from_json(row, json_row,
++                                                    NULL, NULL, false);
+     if (!error) {
+         *ovsdb_row_get_uuid_rw(row) = *row_uuid;
+         ovsdb_txn_row_insert(txn, row);
+@@ -398,7 +399,7 @@ ovsdb_table_execute_update(struct ovsdb_txn *txn, const struct uuid *row_uuid,
+     struct ovsdb_column_set columns = OVSDB_COLUMN_SET_INITIALIZER;
+     struct ovsdb_row *update = ovsdb_row_create(table);
+     struct ovsdb_error *error = ovsdb_row_from_json(update, json_row,
+-                                                    NULL, &columns);
++                                                    NULL, &columns, xor);
+ 
+     if (!error && (xor || !ovsdb_row_equal_columns(row, update, &columns))) {
+         error = ovsdb_row_update_columns(ovsdb_txn_row_modify(txn, row),
 diff --git a/ovsdb/transaction-forward.c b/ovsdb/transaction-forward.c
 index d15f2f1d6d..963e937957 100644
 --- a/ovsdb/transaction-forward.c
@@ -68298,6 +68442,85 @@ index fc6253cfe9..9fbf5dc897 100644
  
      join_cluster() {
          local i=$1
+diff --git a/tests/ovsdb-execution.at b/tests/ovsdb-execution.at
+index e72bf06069..fd1c7a2395 100644
+--- a/tests/ovsdb-execution.at
++++ b/tests/ovsdb-execution.at
+@@ -728,6 +728,53 @@ dnl collide (only) with their previous values (succeeds).
+ [{"count":2},{"uuid":["uuid","<6>"]},{"uuid":["uuid","<7>"]},{"rows":[{"name":"new one","number":1},{"name":"new two","number":2},{"name":"old one","number":10},{"name":"old two","number":20}]}]
+ ]])
+ 
++OVSDB_CHECK_EXECUTION([size constraints on sets],
++  [constraint_schema],
++  [
++   [[["constraints",
++      {"op": "insert",
++       "table": "b",
++       "row": {"b": 1}
++      }]]],
++   [[["constraints",
++      {"op": "mutate",
++       "table": "b",
++       "where": [],
++       "mutations": [["x", "delete", 0]]
++      }]]],
++   [[["constraints",
++      {"op": "mutate",
++       "table": "b",
++       "where": [],
++       "mutations": [["x", "insert", 1]]
++      }]]],
++   [[["constraints",
++      {"op": "update",
++       "table": "b",
++       "where": [],
++       "row": {"x": ["set", [3, 4]]}
++      }]]],
++   [[["constraints",
++      {"op": "mutate",
++       "table": "b",
++       "where": [],
++       "mutations": [["x", "insert", 5]]
++      }]]],
++   [[["constraints",
++      {"op": "mutate",
++       "table": "b",
++       "where": [],
++       "mutations": [["x", "delete", 4], ["x", "insert", 5]]
++      }]]]
++  ],
++  [[[{"uuid":["uuid","<0>"]}]
++[{"details":"Attempted to store 0 elements in set of 1 to 2 integers.","error":"constraint violation"}]
++[{"count":1}]
++[{"count":1}]
++[{"details":"Attempted to store 3 elements in set of 1 to 2 integers.","error":"constraint violation"}]
++[{"count":1}]
++]])
++
+ OVSDB_CHECK_EXECUTION([referential integrity -- simple],
+   [constraint_schema],
+   [[[["constraints",
+@@ -751,12 +798,6 @@ OVSDB_CHECK_EXECUTION([referential integrity -- simple],
+       {"op": "delete",
+        "table": "b",
+        "where": []}]]],
+-dnl Check that "mutate" honors number-of-elements constraints on sets and maps.
+-   [[["constraints",
+-      {"op": "mutate",
+-       "table": "b",
+-       "where": [],
+-       "mutations": [["x", "delete", 0]]}]]],
+    [[["constraints",
+       {"op": "delete",
+        "table": "a",
+@@ -783,7 +824,6 @@ dnl Check that "mutate" honors number-of-elements constraints on sets and maps.
+        "where": []}]]]],
+   [[[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]
+ [{"count":1},{"details":"cannot delete b row <0> because of 3 remaining reference(s)","error":"referential integrity violation"}]
+-[{"details":"Attempted to store 0 elements in set of 1 to 2 integers.","error":"constraint violation"}]
+ [{"count":1}]
+ [{"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
 --- a/tests/ovsdb-idl.at
@@ -68644,7 +68867,7 @@ index 62e2b63832..092d9f81a2 100644
 +006: done
 +]])
 diff --git a/tests/ovsdb-server.at b/tests/ovsdb-server.at
-index 876cb836cd..4a183bf186 100644
+index 876cb836cd..a20d7a926d 100644
 --- a/tests/ovsdb-server.at
 +++ b/tests/ovsdb-server.at
 @@ -4,7 +4,7 @@ m4_define([OVSDB_SERVER_SHUTDOWN],
@@ -68656,12 +68879,23 @@ index 876cb836cd..4a183bf186 100644
     AT_CHECK([ovs-appctl -t "`pwd`"/unixctl$1 -e exit], [0], [ignore], [ignore])
     OVS_WAIT_WHILE([kill -0 `cat savepid$1`], [kill `cat savepid$1`])])
  
-@@ -30,14 +30,13 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -24,20 +24,32 @@ m4_define([OVSDB_SERVER_SHUTDOWN2],
+ # If a given UUID appears more than once it is always replaced by the
+ # same marker.
+ #
++# Additionally, checks that records written to a database file can be
++# read back producing the same in-memory database content.
++#
+ # TITLE is provided to AT_SETUP and KEYWORDS to AT_KEYWORDS.
+ m4_define([OVSDB_CHECK_EXECUTION], 
+   [AT_SETUP([$1])
     AT_KEYWORDS([ovsdb server positive unix $5])
     $2 > schema
     AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
+-   AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db], [0], [ignore], [ignore])
 +   on_exit 'kill `cat *.pid`'
-    AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db], [0], [ignore], [ignore])
++   AT_CHECK([ovsdb-server --detach --no-chdir --log-file --pidfile \
++                          --remote=punix:socket db], [0], [ignore], [ignore])
     m4_foreach([txn], [$3], 
 -     [AT_CHECK([ovsdb-client transact unix:socket 'txn'], [0], [stdout], [ignore],
 -     [test ! -e pid || kill `cat pid`])
@@ -68671,10 +68905,19 @@ index 876cb836cd..4a183bf186 100644
 -   AT_CHECK([uuidfilt output], [0], [$4], [ignore],
 -            [test ! -e pid || kill `cat pid`])
 +   AT_CHECK([uuidfilt output], [0], [$4], [ignore])
++
++   AT_CHECK([ovsdb-client dump unix:socket], [0], [stdout], [ignore])
++
++   OVSDB_SERVER_SHUTDOWN
++
++   AT_CHECK([ovsdb-server --detach --no-chdir --log-file --pidfile \
++                          --remote=punix:socket db], [0], [ignore], [ignore])
++   OVS_WAIT_UNTIL([ovsdb-client dump unix:socket > dump2; diff stdout dump2])
++
     OVSDB_SERVER_SHUTDOWN
     AT_CLEANUP])
  
-@@ -88,8 +87,7 @@ AT_CHECK([uuidfilt output], [0],
+@@ -88,8 +100,7 @@ AT_CHECK([uuidfilt output], [0],
    [[[{"uuid":["uuid","<0>"]}]
  [{"uuid":["uuid","<1>"]}]
  [{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<2>"],"name":"zero","number":0},{"_uuid":["uuid","<1>"],"_version":["uuid","<3>"],"name":"one","number":1}]}]
@@ -68684,7 +68927,7 @@ index 876cb836cd..4a183bf186 100644
  AT_CLEANUP
  
  AT_SETUP([truncating database log with bad transaction])
-@@ -136,8 +134,7 @@ AT_CHECK([uuidfilt output], [0],
+@@ -136,8 +147,7 @@ AT_CHECK([uuidfilt output], [0],
    [[[{"uuid":["uuid","<0>"]}]
  [{"uuid":["uuid","<1>"]}]
  [{"rows":[{"_uuid":["uuid","<0>"],"_version":["uuid","<2>"],"name":"zero","number":0},{"_uuid":["uuid","<1>"],"_version":["uuid","<3>"],"name":"one","number":1}]}]
@@ -68694,7 +68937,7 @@ index 876cb836cd..4a183bf186 100644
  AT_CLEANUP
  
  dnl CHECK_DBS([databases])
-@@ -159,6 +156,7 @@ ordinal_schema > schema1
+@@ -159,6 +169,7 @@ ordinal_schema > schema1
  constraint_schema > schema2
  AT_CHECK([ovsdb-tool create db1 schema1], [0], [ignore], [ignore])
  AT_CHECK([ovsdb-tool create db2 schema2], [0], [ignore], [ignore])
@@ -68702,7 +68945,7 @@ index 876cb836cd..4a183bf186 100644
  AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:db.sock db1 db2], [0], [ignore], [ignore])
  CHECK_DBS([constraints
  ordinals
-@@ -166,7 +164,7 @@ ordinals
+@@ -166,7 +177,7 @@ ordinals
  AT_CHECK(
    [[ovstest test-jsonrpc request unix:db.sock get_schema [\"nonexistent\"]]], [0],
    [[{"error":{"details":"get_schema request specifies unknown database nonexistent","error":"unknown database","syntax":"[\"nonexistent\"]"},"id":0,"result":null}
@@ -68711,7 +68954,7 @@ index 876cb836cd..4a183bf186 100644
  OVSDB_SERVER_SHUTDOWN
  AT_CLEANUP
  
-@@ -393,7 +391,7 @@ AT_CHECK(
+@@ -393,7 +404,7 @@ AT_CHECK(
          "table": "Manager",
          "uuid-name": "x",
          "row": {"target": "punix:socket2"}}]']], [0], [ignore], [ignore])
@@ -68720,7 +68963,7 @@ index 876cb836cd..4a183bf186 100644
  AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=db:mydb,Root,managers --remote=db:mydb,Root,manager_options --log-file db], [0], [ignore], [ignore])
  ovs-appctl -t ovsdb-server time/warp 6000 1000
  AT_CHECK(
-@@ -686,6 +684,7 @@ ovsdb_check_online_compaction() {
+@@ -686,6 +697,7 @@ ovsdb_check_online_compaction() {
                    ovsdb-tool create-cluster db schema unix:s1.raft
                fi])
      dnl Start ovsdb-server.
@@ -68728,7 +68971,7 @@ index 876cb836cd..4a183bf186 100644
      AT_CHECK([ovsdb-server -vvlog:off -vconsole:off --detach --no-chdir --pidfile --remote=punix:socket --log-file db], [0])
      AT_CHECK([ovsdb_client_wait unix:socket ordinals connected])
      AT_CAPTURE_FILE([ovsdb-server.log])
-@@ -832,7 +831,7 @@ _uuid                                name  number
+@@ -832,7 +844,7 @@ _uuid                                name  number
  <0> five  5
  <1> four  4
  <2> three 3
@@ -68737,7 +68980,7 @@ index 876cb836cd..4a183bf186 100644
      OVSDB_SERVER_SHUTDOWN
  }
  OVS_END_SHELL_HELPERS
-@@ -1255,7 +1254,7 @@ dnl a case where there is only one transaction in a history.
+@@ -1255,7 +1267,7 @@ dnl a case where there is only one transaction in a history.
  get_memory_value () {
      n=$(ovs-appctl -t ovsdb-server memory/show dnl
              | tr ' ' '\n' | grep "^$1:" | cut -d ':' -f 2)
@@ -68746,7 +68989,7 @@ index 876cb836cd..4a183bf186 100644
          n=0
      fi
      echo $n
-@@ -1293,6 +1292,24 @@ dnl After removing all the bridges, the number of atoms in the database
+@@ -1293,6 +1305,24 @@ dnl After removing all the bridges, the number of atoms in the database
  dnl should return to its initial value.
  AT_CHECK([test $(get_memory_value atoms) -eq $initial_db_atoms])
  
@@ -68771,7 +69014,7 @@ index 876cb836cd..4a183bf186 100644
  OVS_APP_EXIT_AND_WAIT([ovsdb-server])
  AT_CLEANUP
  
-@@ -1319,15 +1336,14 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1319,15 +1349,14 @@ m4_define([OVSDB_CHECK_EXECUTION],
     $2 > schema
     PKIDIR=$abs_top_builddir/tests
     AT_CHECK([ovsdb-tool create db schema], [0], [stdout], [ignore])
@@ -68790,7 +69033,7 @@ index 876cb836cd..4a183bf186 100644
     OVSDB_SERVER_SHUTDOWN
     AT_CLEANUP])
  
-@@ -1356,16 +1372,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1356,16 +1385,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
     AT_SKIP_IF([test $HAVE_IPV6 = no])
     $2 > schema
     PKIDIR=$abs_top_builddir/tests
@@ -68810,7 +69053,7 @@ index 876cb836cd..4a183bf186 100644
     OVSDB_SERVER_SHUTDOWN
     AT_CLEANUP])
  
-@@ -1392,16 +1407,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1392,16 +1420,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
     AT_KEYWORDS([ovsdb server positive tcp $5])
     $2 > schema
     PKIDIR=$abs_top_builddir/tests
@@ -68830,7 +69073,7 @@ index 876cb836cd..4a183bf186 100644
     OVSDB_SERVER_SHUTDOWN
     AT_CLEANUP])
  
-@@ -1429,16 +1443,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1429,16 +1456,15 @@ m4_define([OVSDB_CHECK_EXECUTION],
     AT_SKIP_IF([test $HAVE_IPV6 = no])
     $2 > schema
     PKIDIR=$abs_top_builddir/tests
@@ -68850,7 +69093,7 @@ index 876cb836cd..4a183bf186 100644
     OVSDB_SERVER_SHUTDOWN
     AT_CLEANUP])
  
-@@ -1518,9 +1531,9 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1518,9 +1544,9 @@ m4_define([OVSDB_CHECK_EXECUTION],
     target=4
     $2 > schema
     schema_name=`ovsdb-tool schema-name schema`
@@ -68861,7 +69104,7 @@ index 876cb836cd..4a183bf186 100644
     AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log dnl
                            --pidfile --remote=punix:db1.sock db1
              ], [0], [ignore], [ignore])
-@@ -1576,12 +1589,11 @@ m4_define([OVSDB_CHECK_EXECUTION],
+@@ -1576,12 +1602,11 @@ m4_define([OVSDB_CHECK_EXECUTION],
     AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
     AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
  
@@ -68876,7 +69119,7 @@ index 876cb836cd..4a183bf186 100644
  
     m4_foreach([txn], [$3],
       [AT_CHECK([ovsdb-client transact 'txn'], [0], [stdout], [ignore])
-@@ -1622,11 +1634,10 @@ m4_define([OVSDB_CHECK_REPLICATION],
+@@ -1622,11 +1647,10 @@ m4_define([OVSDB_CHECK_REPLICATION],
     AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
     AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
  
@@ -68890,7 +69133,7 @@ index 876cb836cd..4a183bf186 100644
  
     m4_foreach([txn], [$3],
       [AT_CHECK([ ovsdb-client transact 'txn' ], [0], [stdout], [ignore])
-@@ -1694,6 +1705,7 @@ AT_CLEANUP
+@@ -1694,6 +1718,7 @@ AT_CLEANUP
  
  #ovsdb-server/set-sync-exclude-tables command
  AT_SETUP([ovsdb-server/set-sync-exclude-tables])
@@ -68898,7 +69141,7 @@ index 876cb836cd..4a183bf186 100644
  AT_KEYWORDS([ovsdb server replication set-exclude-tables])
  AT_SKIP_IF([test $DIFF_SUPPORTS_NORMAL_FORMAT = no])
  
-@@ -1702,12 +1714,10 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
+@@ -1702,12 +1727,10 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
  AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
  
  AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore])
@@ -68913,7 +69156,7 @@ index 876cb836cd..4a183bf186 100644
  
  AT_CHECK([ovsdb-client transact unix:db.sock \
   '[["mydb",
-@@ -1716,11 +1726,9 @@ AT_CHECK([ovsdb-client transact unix:db.sock \
+@@ -1716,11 +1739,9 @@ AT_CHECK([ovsdb-client transact unix:db.sock \
        "row": {"number": 0, "name": "zero"}},
      {"op": "insert",
        "table": "b",
@@ -68927,7 +69170,7 @@ index 876cb836cd..4a183bf186 100644
  cat stdout > dump1
  OVS_WAIT_UNTIL([ ovsdb-client dump unix:db2.sock | grep zero ])
  AT_CHECK([ovsdb-client dump unix:db2.sock], [0], [stdout], [ignore])
-@@ -1744,16 +1752,15 @@ AT_CLEANUP
+@@ -1744,16 +1765,15 @@ AT_CLEANUP
  
  #ovsdb-server/connect-active-ovsdb-server
  AT_SETUP([ovsdb-server/connect-active-server])
@@ -68946,7 +69189,7 @@ index 876cb836cd..4a183bf186 100644
  
  dnl Try to connect without specifying the active server.
  AT_CHECK([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/connect-active-ovsdb-server], [0],
-@@ -1783,6 +1790,7 @@ AT_CLEANUP
+@@ -1783,6 +1803,7 @@ AT_CLEANUP
  
  #ovsdb-server/disconnect-active-server command
  AT_SETUP([ovsdb-server/disconnect-active-server])
@@ -68954,7 +69197,7 @@ index 876cb836cd..4a183bf186 100644
  AT_KEYWORDS([ovsdb server replication disconnect-active-server])
  AT_SKIP_IF([test $DIFF_SUPPORTS_NORMAL_FORMAT = no])
  
-@@ -1791,10 +1799,8 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
+@@ -1791,10 +1812,8 @@ AT_CHECK([ovsdb-tool create db1 schema], [0], [stdout], [ignore])
  AT_CHECK([ovsdb-tool create db2 schema], [0], [stdout], [ignore])
  
  AT_CHECK([ovsdb-server --detach --no-chdir --log-file=ovsdb-server1.log --pidfile --remote=punix:db.sock db1], [0], [ignore], [ignore])
@@ -68966,7 +69209,7 @@ index 876cb836cd..4a183bf186 100644
  
  AT_CHECK([ovsdb-client transact unix:db.sock \
  '[["mydb",
-@@ -1840,7 +1846,7 @@ AT_CHECK([uuidfilt output], [0], [7,9c7,8
+@@ -1840,7 +1859,7 @@ AT_CHECK([uuidfilt output], [0], [7,9c7,8
  ---
  > _uuid name number
  > ----- ---- ------
@@ -68975,7 +69218,7 @@ index 876cb836cd..4a183bf186 100644
  
  dnl The backup server now become active, and can accept write transactions.
  AT_CHECK([ovsdb-client transact unix:db2.sock \
-@@ -1891,13 +1897,12 @@ dnl Start both 'db1' and 'db2' in backup mode. Let them backup from each
+@@ -1891,13 +1910,12 @@ dnl Start both 'db1' and 'db2' in backup mode. Let them backup from each
  dnl other. This is not an supported operation state, but to simulate a start
  dnl up condition where an HA manger can select which one to be an active
  dnl server soon after.
@@ -68992,7 +69235,7 @@ index 876cb836cd..4a183bf186 100644
  
  dnl
  dnl make sure both servers reached the replication state
-@@ -1965,8 +1970,8 @@ AT_CHECK([ovsdb-tool transact db \
+@@ -1965,8 +1983,8 @@ AT_CHECK([ovsdb-tool transact db \
     "row": {"number": 9, "name": "nine"}}]]'], [0], [ignore], [ignore])
  
  dnl Start 'db', then try to be a back up server of itself.
@@ -69003,7 +69246,7 @@ index 876cb836cd..4a183bf186 100644
  
  dnl Save the current content
  AT_CHECK([ovsdb-client dump unix:db.sock], [0], [stdout])
-@@ -1984,6 +1989,7 @@ AT_CHECK([diff dump1 dump2])
+@@ -1984,6 +2002,7 @@ AT_CHECK([diff dump1 dump2])
  AT_CLEANUP
  
  AT_SETUP([ovsdb-server/read-only db:ptcp connection])
@@ -69011,7 +69254,7 @@ index 876cb836cd..4a183bf186 100644
  AT_KEYWORDS([ovsdb server read-only])
  AT_DATA([schema],
    [[{"name": "mydb",
-@@ -2072,12 +2078,10 @@ AT_CHECK([ovsdb-tool transact db2 \
+@@ -2072,12 +2091,10 @@ AT_CHECK([ovsdb-tool transact db2 \
     "row": {"number": 10, "name": "ten"}}]]'], [0], [ignore], [ignore])
  
  dnl Start both 'db1' and 'db2'.
@@ -69027,7 +69270,7 @@ index 876cb836cd..4a183bf186 100644
  
  OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl ovsdb-server/sync-status |grep active])
  OVS_WAIT_UNTIL([ovs-appctl -t "`pwd`"/unixctl2 ovsdb-server/sync-status |grep active])
-@@ -2177,7 +2181,7 @@ dnl Starting a dummy server only to reserve some tcp port.
+@@ -2177,7 +2194,7 @@ dnl Starting a dummy server only to reserve some tcp port.
  AT_CHECK([cp db db.tmp])
  AT_CHECK([ovsdb-server -vfile -vvlog:off --log-file=listener.log  dnl
              --detach --no-chdir                                   dnl
@@ -71625,7 +71868,7 @@ index 6f1fb059bc..ac82f2048e 100644
      }
  }
 diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c
-index ca4e87b811..e725cd4983 100644
+index ca4e87b811..cd1c31a6c2 100644
 --- a/tests/test-ovsdb.c
 +++ b/tests/test-ovsdb.c
 @@ -294,11 +294,24 @@ print_and_free_ovsdb_error(struct ovsdb_error *error)
@@ -71761,7 +72004,17 @@ index ca4e87b811..e725cd4983 100644
      json = unbox_json(parse_json(ctx->argv[1]));
      check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
      json_destroy(json);
-@@ -870,6 +907,8 @@ do_compare_rows(struct ovs_cmdl_context *ctx)
+@@ -827,7 +864,8 @@ do_parse_rows(struct ovs_cmdl_context *ctx)
+         row = ovsdb_row_create(table);
+ 
+         json = unbox_json(parse_json(ctx->argv[i]));
+-        check_ovsdb_error(ovsdb_row_from_json(row, json, NULL, &columns));
++        check_ovsdb_error(ovsdb_row_from_json(row, json, NULL,
++                                              &columns, false));
+         json_destroy(json);
+ 
+         print_and_free_json(ovsdb_row_to_json(row, &all_columns));
+@@ -870,6 +908,8 @@ do_compare_rows(struct ovs_cmdl_context *ctx)
      int n_rows;
      int i, j;
  
@@ -71770,7 +72023,16 @@ index ca4e87b811..e725cd4983 100644
      json = unbox_json(parse_json(ctx->argv[1]));
      check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
      json_destroy(json);
-@@ -929,6 +968,8 @@ do_parse_conditions(struct ovs_cmdl_context *ctx)
+@@ -892,7 +932,7 @@ do_compare_rows(struct ovs_cmdl_context *ctx)
+         }
+         names[i] = xstrdup(json->array.elems[0]->string);
+         check_ovsdb_error(ovsdb_row_from_json(rows[i], json->array.elems[1],
+-                                              NULL, NULL));
++                                              NULL, NULL, false));
+         json_destroy(json);
+     }
+     for (i = 0; i < n_rows; i++) {
+@@ -929,6 +969,8 @@ do_parse_conditions(struct ovs_cmdl_context *ctx)
      int exit_code = 0;
      int i;
  
@@ -71779,7 +72041,7 @@ index ca4e87b811..e725cd4983 100644
      json = unbox_json(parse_json(ctx->argv[1]));
      check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
      json_destroy(json);
-@@ -971,6 +1012,8 @@ do_evaluate_condition__(struct ovs_cmdl_context *ctx, int mode)
+@@ -971,6 +1013,8 @@ do_evaluate_condition__(struct ovs_cmdl_context *ctx, int mode)
      struct json *json;
      size_t i, j;
  
@@ -71788,7 +72050,16 @@ index ca4e87b811..e725cd4983 100644
      /* Parse table schema, create table. */
      json = unbox_json(parse_json(ctx->argv[1]));
      check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
-@@ -1058,6 +1101,8 @@ do_compare_conditions(struct ovs_cmdl_context *ctx)
+@@ -1001,7 +1045,7 @@ do_evaluate_condition__(struct ovs_cmdl_context *ctx, int mode)
+     for (i = 0; i < n_rows; i++) {
+         rows[i] = ovsdb_row_create(table);
+         check_ovsdb_error(ovsdb_row_from_json(rows[i], json->array.elems[i],
+-                                              NULL, NULL));
++                                              NULL, NULL, false));
+     }
+     json_destroy(json);
+ 
+@@ -1058,6 +1102,8 @@ do_compare_conditions(struct ovs_cmdl_context *ctx)
      struct json *json;
      size_t i;
  
@@ -71797,7 +72068,7 @@ index ca4e87b811..e725cd4983 100644
      /* Parse table schema, create table. */
      json = unbox_json(parse_json(ctx->argv[1]));
      check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
-@@ -1099,6 +1144,8 @@ do_parse_mutations(struct ovs_cmdl_context *ctx)
+@@ -1099,6 +1145,8 @@ do_parse_mutations(struct ovs_cmdl_context *ctx)
      int exit_code = 0;
      int i;
  
@@ -71806,7 +72077,7 @@ index ca4e87b811..e725cd4983 100644
      json = unbox_json(parse_json(ctx->argv[1]));
      check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
      json_destroy(json);
-@@ -1138,6 +1185,8 @@ do_execute_mutations(struct ovs_cmdl_context *ctx)
+@@ -1138,6 +1186,8 @@ do_execute_mutations(struct ovs_cmdl_context *ctx)
      struct json *json;
      size_t i, j;
  
@@ -71815,7 +72086,16 @@ index ca4e87b811..e725cd4983 100644
      /* Parse table schema, create table. */
      json = unbox_json(parse_json(ctx->argv[1]));
      check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
-@@ -1262,6 +1311,8 @@ do_query(struct ovs_cmdl_context *ctx)
+@@ -1169,7 +1219,7 @@ do_execute_mutations(struct ovs_cmdl_context *ctx)
+     for (i = 0; i < n_rows; i++) {
+         rows[i] = ovsdb_row_create(table);
+         check_ovsdb_error(ovsdb_row_from_json(rows[i], json->array.elems[i],
+-                                              NULL, NULL));
++                                              NULL, NULL, false));
+     }
+     json_destroy(json);
+ 
+@@ -1262,6 +1312,8 @@ do_query(struct ovs_cmdl_context *ctx)
      int exit_code = 0;
      size_t i;
  
@@ -71824,7 +72104,16 @@ index ca4e87b811..e725cd4983 100644
      /* Parse table schema, create table. */
      json = unbox_json(parse_json(ctx->argv[1]));
      check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
-@@ -1356,6 +1407,8 @@ do_query_distinct(struct ovs_cmdl_context *ctx)
+@@ -1281,7 +1333,7 @@ do_query(struct ovs_cmdl_context *ctx)
+         struct ovsdb_row *row = ovsdb_row_create(table);
+         uuid_generate(ovsdb_row_get_uuid_rw(row));
+         check_ovsdb_error(ovsdb_row_from_json(row, json->array.elems[i],
+-                                              NULL, NULL));
++                                              NULL, NULL, false));
+         if (ovsdb_table_get_row(table, ovsdb_row_get_uuid(row))) {
+             ovs_fatal(0, "duplicate UUID "UUID_FMT" in table",
+                       UUID_ARGS(ovsdb_row_get_uuid(row)));
+@@ -1356,6 +1408,8 @@ do_query_distinct(struct ovs_cmdl_context *ctx)
      int exit_code = 0;
      size_t i;
  
@@ -71833,7 +72122,16 @@ index ca4e87b811..e725cd4983 100644
      /* Parse table schema, create table. */
      json = unbox_json(parse_json(ctx->argv[1]));
      check_ovsdb_error(ovsdb_table_schema_from_json(json, "mytable", &ts));
-@@ -1483,6 +1536,8 @@ do_parse_schema(struct ovs_cmdl_context *ctx)
+@@ -1386,7 +1440,7 @@ do_query_distinct(struct ovs_cmdl_context *ctx)
+         row = ovsdb_row_create(table);
+         uuid_generate(ovsdb_row_get_uuid_rw(row));
+         check_ovsdb_error(ovsdb_row_from_json(row, json->array.elems[i],
+-                                              NULL, NULL));
++                                              NULL, NULL, false));
+ 
+         /* Initialize row and find equivalence class. */
+         rows[i].uuid = *ovsdb_row_get_uuid(row);
+@@ -1483,6 +1537,8 @@ do_parse_schema(struct ovs_cmdl_context *ctx)
      struct ovsdb_schema *schema;
      struct json *json;
  
@@ -71842,7 +72140,7 @@ index ca4e87b811..e725cd4983 100644
      json = parse_json(ctx->argv[1]);
      check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
      json_destroy(json);
-@@ -1498,6 +1553,8 @@ do_execute__(struct ovs_cmdl_context *ctx, bool ro)
+@@ -1498,6 +1554,8 @@ do_execute__(struct ovs_cmdl_context *ctx, bool ro)
      struct ovsdb *db;
      int i;
  
@@ -71851,7 +72149,7 @@ index ca4e87b811..e725cd4983 100644
      /* Create database. */
      json = parse_json(ctx->argv[1]);
      check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
-@@ -1564,6 +1621,8 @@ do_trigger(struct ovs_cmdl_context *ctx)
+@@ -1564,6 +1622,8 @@ do_trigger(struct ovs_cmdl_context *ctx)
      int number;
      int i;
  
@@ -71860,7 +72158,7 @@ index ca4e87b811..e725cd4983 100644
      /* Create database. */
      json = parse_json(ctx->argv[1]);
      check_ovsdb_error(ovsdb_schema_from_json(json, &schema));
-@@ -1789,6 +1848,8 @@ do_transact(struct ovs_cmdl_context *ctx)
+@@ -1789,6 +1849,8 @@ do_transact(struct ovs_cmdl_context *ctx)
      struct json *json;
      int i;
  
@@ -71869,7 +72167,7 @@ index ca4e87b811..e725cd4983 100644
      /* Create table. */
      json = parse_json("{\"name\": \"testdb\", "
                        " \"tables\": "
-@@ -1885,11 +1946,14 @@ format_idl_row(const struct ovsdb_idl_row *row, int step, const char *contents,
+@@ -1885,11 +1947,14 @@ format_idl_row(const struct ovsdb_idl_row *row, int step, const char *contents,
      const char *change_str =
          !ovsdb_idl_track_is_set(row->table)
          ? ""
@@ -71889,7 +72187,7 @@ index ca4e87b811..e725cd4983 100644
  
      if (terse) {
          return xasprintf("%03d: table %s", step, row->table->class_->name);
-@@ -2541,11 +2605,12 @@ parse_link2_json_clause(struct ovsdb_idl_condition *cond,
+@@ -2541,11 +2606,12 @@ parse_link2_json_clause(struct ovsdb_idl_condition *cond,
      }
  }
  
@@ -71905,7 +72203,7 @@ index ca4e87b811..e725cd4983 100644
  
      for (cmd = strtok_r(commands, ";", &save_ptr1); cmd;
           cmd = strtok_r(NULL, ";", &save_ptr1)) {
-@@ -2596,15 +2661,20 @@ update_conditions(struct ovsdb_idl *idl, char *commands)
+@@ -2596,15 +2662,20 @@ update_conditions(struct ovsdb_idl *idl, char *commands)
          unsigned int seqno = ovsdb_idl_get_condition_seqno(idl);
          unsigned int next_seqno = ovsdb_idl_set_condition(idl, tc, &cond);
          if (seqno == next_seqno ) {
@@ -71927,7 +72225,7 @@ index ca4e87b811..e725cd4983 100644
  }
  
  static void
-@@ -2612,6 +2682,7 @@ do_idl(struct ovs_cmdl_context *ctx)
+@@ -2612,6 +2683,7 @@ do_idl(struct ovs_cmdl_context *ctx)
  {
      struct jsonrpc *rpc;
      struct ovsdb_idl *idl;
@@ -71935,7 +72233,7 @@ index ca4e87b811..e725cd4983 100644
      unsigned int seqno = 0;
      struct ovsdb_symbol_table *symtab;
      size_t n_uuids = 0;
-@@ -2647,8 +2718,8 @@ do_idl(struct ovs_cmdl_context *ctx)
+@@ -2647,8 +2719,8 @@ do_idl(struct ovs_cmdl_context *ctx)
      const char remote_s[] = "set-remote ";
      const char cond_s[] = "condition ";
      if (ctx->argc > 2 && strstr(ctx->argv[2], cond_s)) {
@@ -71946,7 +72244,7 @@ index ca4e87b811..e725cd4983 100644
          i = 3;
      } else {
          i = 2;
-@@ -2667,6 +2738,21 @@ do_idl(struct ovs_cmdl_context *ctx)
+@@ -2667,6 +2739,21 @@ do_idl(struct ovs_cmdl_context *ctx)
          if (*arg == '+') {
              /* The previous transaction didn't change anything. */
              arg++;
@@ -71968,7 +72266,7 @@ index ca4e87b811..e725cd4983 100644
          } else {
              /* Wait for update. */
              for (;;) {
-@@ -2701,8 +2787,8 @@ do_idl(struct ovs_cmdl_context *ctx)
+@@ -2701,8 +2788,8 @@ do_idl(struct ovs_cmdl_context *ctx)
                            arg + strlen(remote_s),
                            ovsdb_idl_is_connected(idl) ? "true" : "false");
          }  else if (!strncmp(arg, cond_s, strlen(cond_s))) {
@@ -72741,7 +73039,7 @@ index 08957bdf46..779ea60aee 100755
  $FUNCNAME: attach the default sandbox to an interconnection network
  usage: $FUNCNAME NETWORK BRIDGE
 diff --git a/utilities/ovs-tcpdump.in b/utilities/ovs-tcpdump.in
-index 82d1bedfa6..420c11eb8a 100755
+index 82d1bedfa6..4cbd9a5d31 100755
 --- a/utilities/ovs-tcpdump.in
 +++ b/utilities/ovs-tcpdump.in
 @@ -44,6 +44,7 @@ try:
@@ -72752,7 +73050,18 @@ index 82d1bedfa6..420c11eb8a 100755
  except Exception:
      print("ERROR: Please install the correct Open vSwitch python support")
      print("       libraries (version @VERSION@).")
-@@ -165,6 +166,9 @@ class OVSDB(object):
+@@ -95,6 +96,10 @@ def _install_dst_if_linux(tap_name, mtu_value=None):
+         *(['ip', 'link', 'set', 'dev', str(tap_name), 'up']))
+     pipe.wait()
+ 
++    pipe = _doexec(
++        *(['ip', '-6', 'addr', 'flush', 'dev', str(tap_name)]))
++    pipe.wait()
++
+ 
+ def _remove_dst_if_linux(tap_name):
+     _doexec(
+@@ -165,6 +170,9 @@ class OVSDB(object):
          self._idl_conn = idl.Idl(db_sock, schema)
          OVSDB.wait_for_db_change(self._idl_conn)  # Initial Sync with DB
  
@@ -72762,7 +73071,7 @@ index 82d1bedfa6..420c11eb8a 100755
      def _get_schema(self):
          error, strm = Stream.open_block(Stream.open(self._db_sock))
          if error:
-@@ -222,6 +226,13 @@ class OVSDB(object):
+@@ -222,6 +230,13 @@ class OVSDB(object):
      def interface_mtu(self, intf_name):
          try:
              intf = self._find_row_by_name('Interface', intf_name)
@@ -72776,7 +73085,7 @@ index 82d1bedfa6..420c11eb8a 100755
              return intf.mtu[0]
          except Exception:
              return None
-@@ -402,8 +413,27 @@ def py_which(executable):
+@@ -402,8 +417,27 @@ def py_which(executable):
                 for path in os.environ["PATH"].split(os.pathsep))
  
  
@@ -72805,7 +73114,7 @@ index 82d1bedfa6..420c11eb8a 100755
      interface = None
      tcpdargs = []
  
-@@ -485,6 +515,9 @@ def main():
+@@ -485,6 +519,9 @@ def main():
          print("ERROR: Mirror port (%s) exists for port %s." %
                (mirror_interface, interface))
          sys.exit(1)
@@ -72815,7 +73124,7 @@ index 82d1bedfa6..420c11eb8a 100755
      try:
          ovsdb.make_port(mirror_interface, ovsdb.port_bridge(interface))
          ovsdb.bridge_mirror(interface, mirror_interface,
-@@ -492,14 +525,10 @@ def main():
+@@ -492,14 +529,10 @@ def main():
                              mirror_select_all)
      except OVSDBException as oe:
          print("ERROR: Unable to properly setup the mirror: %s." % str(oe))
@@ -72832,7 +73141,7 @@ index 82d1bedfa6..420c11eb8a 100755
      pipes = _doexec(*([dump_cmd, '-i', mirror_interface] + tcpdargs))
      try:
          while pipes.poll() is None:
-@@ -509,20 +538,20 @@ def main():
+@@ -509,20 +542,20 @@ def main():
              print(data.decode('utf-8'))
          raise KeyboardInterrupt
      except KeyboardInterrupt:
diff --git a/SPECS/openvswitch2.17.spec b/SPECS/openvswitch2.17.spec
index ec35b8d..e68fdee 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: 96%{?dist}
+Release: 97%{?dist}
 
 # Nearly all of openvswitch is ASL 2.0.  The bugtool is LGPLv2+, and the
 # lib/sflow*.[ch] files are SISSL
@@ -751,6 +751,18 @@ exit 0
 %endif
 
 %changelog
+* Thu Aug 03 2023 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-97
+- Merging upstream branch-2.17 [RH git: 22854be7fc]
+    Commit list:
+    fe98b0c1f9 ovsdb-tool: Fix json leak while showing clustered log.
+    44722bbda3 ovsdb-server: Fix excessive memory usage on DB open. (#2228464)
+    9db221fcd8 tests: Add ovsdb execution cases for set size constraints.
+    3cfe388cb8 ovsdb: relay: Fix handling of XOR updates with size constraints.
+    f4d15497f8 ovsdb: file: Fix diff application to a default column value.
+    7864ed557e ovsdb: file: Fix inability to read diffs that violate type size.
+    97d91ad2d6 ovs-tcpdump: Clear auto-assigned ipv6 address of mirror port.
+
+
 * Wed Aug 02 2023 Open vSwitch CI <ovs-ci@redhat.com> - 2.17.0-96
 - Merging upstream branch-2.17 [RH git: 507c546250]
     Commit list: