diff --git a/SOURCES/openvswitch-2.15.0.patch b/SOURCES/openvswitch-2.15.0.patch
index d08504a..fde06bd 100644
--- a/SOURCES/openvswitch-2.15.0.patch
+++ b/SOURCES/openvswitch-2.15.0.patch
@@ -21167,6 +21167,28 @@ index e2e829772a..6fb3da5074 100644
encap->n_props = n_props;
out->header = &encap->ofpact;
ofpact_finish_ENCAP(out, &encap);
+diff --git a/lib/ofp-flow.c b/lib/ofp-flow.c
+index ff0396845a..3bc744f78f 100644
+--- a/lib/ofp-flow.c
++++ b/lib/ofp-flow.c
+@@ -1254,7 +1254,16 @@ ofputil_append_flow_stats_reply(const struct ofputil_flow_stats *fs,
+ OVS_NOT_REACHED();
+ }
+
+- ofpmp_postappend(replies, start_ofs);
++ if ((reply->size - start_ofs) > (UINT16_MAX - ofpbuf_headersize(reply))) {
++ /* When this happens, the reply will not fit in a single OFP message,
++ * and we should not append it to the queue. We will log a warning
++ * and continue with the next flow stat entry. */
++ reply->size = start_ofs;
++ VLOG_WARN_RL(&rl, "Flow exceeded the maximum flow statistics reply "
++ "size and was excluded from the response set");
++ } else {
++ ofpmp_postappend(replies, start_ofs);
++ }
+ fs_->match.flow.tunnel.metadata.tab = orig_tun_table;
+ }
+
diff --git a/lib/ofp-group.c b/lib/ofp-group.c
index bf0f8af544..737f48047b 100644
--- a/lib/ofp-group.c
@@ -21211,7 +21233,7 @@ index a2778de4bc..3894cb3c33 100644
Open vSwitch 2.6 introduced nat
. Linux 4.6 was the
earliest upstream kernel that implemented ct
support for
diff --git a/lib/ovsdb-cs.c b/lib/ovsdb-cs.c
-index ff8adaefb5..7c78056956 100644
+index ff8adaefb5..249cff0512 100644
--- a/lib/ovsdb-cs.c
+++ b/lib/ovsdb-cs.c
@@ -712,6 +712,16 @@ void
@@ -21261,7 +21283,31 @@ index ff8adaefb5..7c78056956 100644
}
/* Sets the replication condition for 'tc' in 'cs' to 'condition' and arranges
-@@ -1367,7 +1396,7 @@ ovsdb_cs_send_transaction(struct ovsdb_cs *cs, struct json *operations)
+@@ -1063,6 +1092,23 @@ ovsdb_cs_db_sync_condition(struct ovsdb_cs_db *db)
+ }
+ table->req_cond = NULL;
+ db->cond_changed = true;
++
++ /* There are two cases:
++ * a. either the server already processed the requested monitor
++ * condition change but the FSM was restarted before the
++ * client was notified. In this case the client should
++ * clear its local cache because it's out of sync with the
++ * monitor view on the server side.
++ *
++ * b. OR the server hasn't processed the requested monitor
++ * condition change yet.
++ *
++ * As there's no easy way to differentiate between the two,
++ * and given that this condition should be rare, reset the
++ * 'last_id', essentially flushing the local cached DB
++ * contents.
++ */
++ db->last_id = UUID_ZERO;
+ }
+ }
+ }
+@@ -1367,7 +1413,7 @@ ovsdb_cs_send_transaction(struct ovsdb_cs *cs, struct json *operations)
sizeof *cs->txns);
}
cs->txns[cs->n_txns++] = request_id;
@@ -21270,7 +21316,7 @@ index ff8adaefb5..7c78056956 100644
}
/* Makes 'cs' drop its record of transaction 'request_id'. If a reply arrives
-@@ -1380,6 +1409,7 @@ ovsdb_cs_forget_transaction(struct ovsdb_cs *cs, const struct json *request_id)
+@@ -1380,6 +1426,7 @@ ovsdb_cs_forget_transaction(struct ovsdb_cs *cs, const struct json *request_id)
{
for (size_t i = 0; i < cs->n_txns; i++) {
if (json_equal(request_id, cs->txns[i])) {
@@ -21278,8 +21324,22 @@ index ff8adaefb5..7c78056956 100644
cs->txns[i] = cs->txns[--cs->n_txns];
return true;
}
+@@ -1492,12 +1539,11 @@ ovsdb_cs_db_parse_monitor_reply(struct ovsdb_cs_db *db,
+ const struct json *table_updates;
+ bool clear;
+ if (version == 3) {
+- struct uuid last_id;
+ if (result->type != JSON_ARRAY || result->array.n != 3
+ || (result->array.elems[0]->type != JSON_TRUE &&
+ result->array.elems[0]->type != JSON_FALSE)
+ || result->array.elems[1]->type != JSON_STRING
+- || !uuid_from_string(&last_id,
++ || !uuid_from_string(&db->last_id,
+ json_string(result->array.elems[1]))) {
+ struct ovsdb_error *error = ovsdb_syntax_error(
+ result, NULL, "bad monitor_cond_since reply format");
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
-index 2c8a0c9cfe..2198c69c60 100644
+index 2c8a0c9cfe..601a806c3a 100644
--- a/lib/ovsdb-idl.c
+++ b/lib/ovsdb-idl.c
@@ -92,6 +92,9 @@ struct ovsdb_idl {
@@ -21574,6 +21634,17 @@ index 2c8a0c9cfe..2198c69c60 100644
}
/* Returns true if a column with mode OVSDB_IDL_MODE_RW changed, false
+@@ -4035,6 +4112,10 @@ void
+ ovsdb_idl_loop_destroy(struct ovsdb_idl_loop *loop)
+ {
+ if (loop) {
++ if (loop->committing_txn) {
++ ovsdb_idl_txn_abort(loop->committing_txn);
++ ovsdb_idl_txn_destroy(loop->committing_txn);
++ }
+ ovsdb_idl_destroy(loop->idl);
+ }
+ }
diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h
index 05bb48d66c..d93483245e 100644
--- a/lib/ovsdb-idl.h
@@ -24034,7 +24105,7 @@ index 31064ed95e..2a7c1bbb55 100644
AT_CLEANUP
diff --git a/tests/ovs-ofctl.at b/tests/ovs-ofctl.at
-index 5ddca67e71..604f15c2d1 100644
+index 5ddca67e71..c93cb9f16c 100644
--- a/tests/ovs-ofctl.at
+++ b/tests/ovs-ofctl.at
@@ -449,6 +449,16 @@ actions=output(max_len=100,port=123)
@@ -24071,6 +24142,29 @@ index 5ddca67e71..604f15c2d1 100644
]])
AT_CLEANUP
+@@ -3226,3 +3246,22 @@ dnl because we need ovs-vswitchd to have the controller config before starting
+ dnl the controller to 'snoop' the OpenFlow messages from beginning
+ OVS_VSWITCHD_STOP(["/connection failed (No such file or directory)/d"])
+ AT_CLEANUP
++
++
++AT_SETUP([ovs-ofctl show-flows - Oversized flow])
++OVS_VSWITCHD_START
++
++printf " priority=90,icmp,reg15=0x8005,metadata=0x1,nw_dst=11.0.0.1,icmp_type=8,icmp_code=0 actions=" > flow.txt
++for i in `seq 1 1022`; do printf "set_field:0x399->reg13,set_field:0x$i->reg15,resubmit(,39),"; done >> flow.txt
++printf "resubmit(,39)\n" >> flow.txt
++
++AT_CHECK([ovs-ofctl -O OpenFlow15 add-flows br0 flow.txt])
++
++AT_CHECK([ovs-ofctl -O OpenFlow10 dump-flows br0 | ofctl_strip | sed '/NXST_FLOW/d' | sort], [0], [])
++OVS_WAIT_UNTIL([grep -q "ofp_flow|WARN|Flow exceeded the maximum flow statistics reply size and was excluded from the response set" ovs-vswitchd.log])
++
++cat flow.txt > expout
++AT_CHECK([ovs-ofctl -O OpenFlow15 dump-flows br0 | ofctl_strip | sed '/OFPST_FLOW/d' | sort], [0], [expout])
++
++OVS_VSWITCHD_STOP(["/Flow exceeded the maximum flow statistics reply size and was excluded from the response set/d"])
++AT_CLEANUP
diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at
index c8babe3612..1f1fc3c79a 100644
--- a/tests/ovs-vsctl.at
@@ -24151,7 +24245,7 @@ index 92aa427093..cf43e9cf86 100644
# Start collecting raft_is_connected logs for $target before shutting down
# any servers.
diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at
-index 4b4791a7da..d5cdf7e8b0 100644
+index 4b4791a7da..dd7b0df755 100644
--- a/tests/ovsdb-idl.at
+++ b/tests/ovsdb-idl.at
@@ -141,7 +141,7 @@ m4_define([OVSDB_CHECK_IDL_REGISTER_COLUMNS_PY],
@@ -25300,11 +25394,11 @@ index 4b4791a7da..d5cdf7e8b0 100644
AT_CHECK([test-ovsdb '-vPATTERN:console:test-ovsdb|%c|%m' -vjsonrpc -t10 idl tcp:LPBK:$TCP_PORT_1 $4],
- [0], [stdout], [ignore])
+ [0], [stdout], [stderr])
-+ AT_CHECK([sort stdout | uuidfilt]m4_if([$7],,, [[| $7]]),
-+ [0], [$5])
+ AT_CHECK([sort stdout | uuidfilt]m4_if([$7],,, [[| $7]]),
+ [0], [$5])
+ m4_ifval([$8], [AT_CHECK([grep '$8' stderr], [1])], [], [])
-+ AT_CLEANUP])
-+
+ AT_CLEANUP])
+
+# Same as OVSDB_CHECK_CLUSTER_IDL_C but uses the Python IDL implementation.
+m4_define([OVSDB_CHECK_CLUSTER_IDL_PY],
+ [AT_SETUP([$1 - Python3 - tcp])
@@ -25320,11 +25414,11 @@ index 4b4791a7da..d5cdf7e8b0 100644
+ [AT_CHECK([ovsdb-client transact $remotes $3], [0], [ignore], [ignore])])
+ AT_CHECK([$PYTHON3 $srcdir/test-ovsdb.py -t10 idl $srcdir/idltest.ovsschema tcp:LPBK:$TCP_PORT_1 $4],
+ [0], [stdout], [stderr])
- AT_CHECK([sort stdout | uuidfilt]m4_if([$7],,, [[| $7]]),
- [0], [$5])
++ AT_CHECK([sort stdout | uuidfilt]m4_if([$7],,, [[| $7]]),
++ [0], [$5])
+ m4_if([$8], [AT_CHECK([grep '$8' stderr], [1])], [], [])
- AT_CLEANUP])
-
++ AT_CLEANUP])
++
+m4_define([OVSDB_CHECK_CLUSTER_IDL],
+ [OVSDB_CHECK_CLUSTER_IDL_C($@)
+ OVSDB_CHECK_CLUSTER_IDL_PY($@)])
@@ -25332,6 +25426,15 @@ index 4b4791a7da..d5cdf7e8b0 100644
# Checks that monitor_cond_since works fine when disconnects happen
# with cond_change requests in flight (i.e., IDL is properly updated).
OVSDB_CHECK_CLUSTER_IDL_C([simple idl, monitor_cond_since, cluster disconnect],
+@@ -1981,7 +2309,7 @@ OVSDB_CHECK_CLUSTER_IDL_C([simple idl, monitor_cond_since, cluster disconnect],
+ 'condition simple [["i","==",2]]' \
+ 'condition simple [["i","==",1]]' \
+ '+reconnect' \
+- '["idltest",
++ '?["idltest",
+ {"op": "update",
+ "table": "simple",
+ "where": [["i", "==", 1]],
@@ -1989,11 +2317,34 @@ OVSDB_CHECK_CLUSTER_IDL_C([simple idl, monitor_cond_since, cluster disconnect],
[[000: change conditions
001: empty
@@ -25341,7 +25444,7 @@ index 4b4791a7da..d5cdf7e8b0 100644
004: change conditions
005: reconnect
-006: i=2 r=1 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
-+006: table simple: i=2 r=1 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
++006: table simple
007: {"error":null,"result":[{"count":1}]}
-008: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
+008: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
@@ -25804,15 +25907,16 @@ index 3eabcd78d5..1df5afa221 100644
import errno
import os
diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c
-index 15433e3472..a886f971e7 100644
+index 15433e3472..c4845956ca 100644
--- a/tests/test-ovsdb.c
+++ b/tests/test-ovsdb.c
-@@ -1861,6 +1861,23 @@ print_and_log(const char *format, ...)
+@@ -1861,6 +1861,28 @@ print_and_log(const char *format, ...)
free(message);
}
+static char *
-+format_idl_row(const struct ovsdb_idl_row *row, int step, const char *contents)
++format_idl_row(const struct ovsdb_idl_row *row, int step, const char *contents,
++ bool terse)
+{
+ const char *change_str =
+ !ovsdb_idl_track_is_set(row->table)
@@ -25823,15 +25927,19 @@ index 15433e3472..a886f971e7 100644
+ ? "deleted row: "
+ : "";
+
-+ return xasprintf("%03d: table %s: %s%s uuid=" UUID_FMT,
-+ step, row->table->class_->name, change_str, contents,
-+ UUID_ARGS(&row->uuid));
++ if (terse) {
++ return xasprintf("%03d: table %s", step, row->table->class_->name);
++ } else {
++ return xasprintf("%03d: table %s: %s%s uuid=" UUID_FMT,
++ step, row->table->class_->name, change_str,
++ contents, UUID_ARGS(&row->uuid));
++ }
+}
+
static void
print_idl_row_updated_simple(const struct idltest_simple *s, int step)
{
-@@ -1871,7 +1888,9 @@ print_idl_row_updated_simple(const struct idltest_simple *s, int step)
+@@ -1871,7 +1893,9 @@ print_idl_row_updated_simple(const struct idltest_simple *s, int step)
}
}
if (updates.length) {
@@ -25842,7 +25950,7 @@ index 15433e3472..a886f971e7 100644
ds_destroy(&updates);
}
}
-@@ -1886,7 +1905,9 @@ print_idl_row_updated_link1(const struct idltest_link1 *l1, int step)
+@@ -1886,7 +1910,9 @@ print_idl_row_updated_link1(const struct idltest_link1 *l1, int step)
}
}
if (updates.length) {
@@ -25853,7 +25961,7 @@ index 15433e3472..a886f971e7 100644
ds_destroy(&updates);
}
}
-@@ -1901,7 +1922,43 @@ print_idl_row_updated_link2(const struct idltest_link2 *l2, int step)
+@@ -1901,7 +1927,43 @@ print_idl_row_updated_link2(const struct idltest_link2 *l2, int step)
}
}
if (updates.length) {
@@ -25898,7 +26006,7 @@ index 15433e3472..a886f971e7 100644
ds_destroy(&updates);
}
}
-@@ -1916,7 +1973,9 @@ print_idl_row_updated_simple6(const struct idltest_simple6 *s6, int step)
+@@ -1916,7 +1978,9 @@ print_idl_row_updated_simple6(const struct idltest_simple6 *s6, int step)
}
}
if (updates.length) {
@@ -25909,7 +26017,7 @@ index 15433e3472..a886f971e7 100644
ds_destroy(&updates);
}
}
-@@ -1931,7 +1990,9 @@ print_idl_row_updated_singleton(const struct idltest_singleton *sng, int step)
+@@ -1931,17 +1995,19 @@ print_idl_row_updated_singleton(const struct idltest_singleton *sng, int step)
}
}
if (updates.length) {
@@ -25920,8 +26028,10 @@ index 15433e3472..a886f971e7 100644
ds_destroy(&updates);
}
}
-@@ -1940,8 +2001,8 @@ static void
- print_idl_row_simple(const struct idltest_simple *s, int step)
+
+ static void
+-print_idl_row_simple(const struct idltest_simple *s, int step)
++print_idl_row_simple(const struct idltest_simple *s, int step, bool terse)
{
struct ds msg = DS_EMPTY_INITIALIZER;
- ds_put_format(&msg, "%03d: i=%"PRId64" r=%g b=%s s=%s u="UUID_FMT" ia=[",
@@ -25931,7 +26041,7 @@ index 15433e3472..a886f971e7 100644
s->s, UUID_ARGS(&s->u));
for (size_t i = 0; i < s->n_ia; i++) {
ds_put_format(&msg, "%s%"PRId64, i ? " " : "", s->ia[i]);
-@@ -1962,9 +2023,12 @@ print_idl_row_simple(const struct idltest_simple *s, int step)
+@@ -1962,18 +2028,21 @@ print_idl_row_simple(const struct idltest_simple *s, int step)
for (size_t i = 0; i < s->n_ua; i++) {
ds_put_format(&msg, "%s"UUID_FMT, i ? " " : "", UUID_ARGS(&s->ua[i]));
}
@@ -25939,15 +26049,17 @@ index 15433e3472..a886f971e7 100644
- print_and_log("%s", ds_cstr(&msg));
+ ds_put_cstr(&msg, "]");
+
-+ char *row_msg = format_idl_row(&s->header_, step, ds_cstr(&msg));
++ char *row_msg = format_idl_row(&s->header_, step, ds_cstr(&msg), terse);
+ print_and_log("%s", row_msg);
ds_destroy(&msg);
+ free(row_msg);
print_idl_row_updated_simple(s, step);
}
-@@ -1973,7 +2037,7 @@ static void
- print_idl_row_link1(const struct idltest_link1 *l1, int step)
+
+ static void
+-print_idl_row_link1(const struct idltest_link1 *l1, int step)
++print_idl_row_link1(const struct idltest_link1 *l1, int step, bool terse)
{
struct ds msg = DS_EMPTY_INITIALIZER;
- ds_put_format(&msg, "%03d: i=%"PRId64" k=", step, l1->i);
@@ -25955,22 +26067,24 @@ index 15433e3472..a886f971e7 100644
if (l1->k) {
ds_put_format(&msg, "%"PRId64, l1->k->i);
}
-@@ -1988,9 +2052,11 @@ print_idl_row_link1(const struct idltest_link1 *l1, int step)
+@@ -1988,56 +2057,115 @@ print_idl_row_link1(const struct idltest_link1 *l1, int step)
if (l1->l2) {
ds_put_format(&msg, "%"PRId64, l1->l2->i);
}
- ds_put_format(&msg, " uuid="UUID_FMT, UUID_ARGS(&l1->header_.uuid));
- print_and_log("%s", ds_cstr(&msg));
+
-+ char *row_msg = format_idl_row(&l1->header_, step, ds_cstr(&msg));
++ char *row_msg = format_idl_row(&l1->header_, step, ds_cstr(&msg), terse);
+ print_and_log("%s", row_msg);
ds_destroy(&msg);
+ free(row_msg);
print_idl_row_updated_link1(l1, step);
}
-@@ -1999,30 +2065,77 @@ static void
- print_idl_row_link2(const struct idltest_link2 *l2, int step)
+
+ static void
+-print_idl_row_link2(const struct idltest_link2 *l2, int step)
++print_idl_row_link2(const struct idltest_link2 *l2, int step, bool terse)
{
struct ds msg = DS_EMPTY_INITIALIZER;
- ds_put_format(&msg, "%03d: i=%"PRId64" l1=", step, l2->i);
@@ -25981,7 +26095,7 @@ index 15433e3472..a886f971e7 100644
- ds_put_format(&msg, " uuid="UUID_FMT, UUID_ARGS(&l2->header_.uuid));
- print_and_log("%s", ds_cstr(&msg));
+
-+ char *row_msg = format_idl_row(&l2->header_, step, ds_cstr(&msg));
++ char *row_msg = format_idl_row(&l2->header_, step, ds_cstr(&msg), terse);
+ print_and_log("%s", row_msg);
ds_destroy(&msg);
+ free(row_msg);
@@ -25989,10 +26103,12 @@ index 15433e3472..a886f971e7 100644
print_idl_row_updated_link2(l2, step);
}
-+static void
-+print_idl_row_simple3(const struct idltest_simple3 *s3, int step)
-+{
-+ struct ds msg = DS_EMPTY_INITIALIZER;
+ static void
+-print_idl_row_simple6(const struct idltest_simple6 *s6, int step)
++print_idl_row_simple3(const struct idltest_simple3 *s3, int step, bool terse)
+ {
+ struct ds msg = DS_EMPTY_INITIALIZER;
+- ds_put_format(&msg, "%03d: name=%s ", step, s6->name);
+ size_t i;
+
+ ds_put_format(&msg, "name=%s uset=[", s3->name);
@@ -26009,7 +26125,7 @@ index 15433e3472..a886f971e7 100644
+ }
+ ds_put_cstr(&msg, "]");
+
-+ char *row_msg = format_idl_row(&s3->header_, step, ds_cstr(&msg));
++ char *row_msg = format_idl_row(&s3->header_, step, ds_cstr(&msg), terse);
+ print_and_log("%s", row_msg);
+ ds_destroy(&msg);
+ free(row_msg);
@@ -26018,12 +26134,12 @@ index 15433e3472..a886f971e7 100644
+}
+
+static void
-+print_idl_row_simple4(const struct idltest_simple4 *s4, int step)
++print_idl_row_simple4(const struct idltest_simple4 *s4, int step, bool terse)
+{
+ struct ds msg = DS_EMPTY_INITIALIZER;
+ ds_put_format(&msg, "name=%s", s4->name);
+
-+ char *row_msg = format_idl_row(&s4->header_, step, ds_cstr(&msg));
++ char *row_msg = format_idl_row(&s4->header_, step, ds_cstr(&msg), terse);
+ print_and_log("%s", row_msg);
+ ds_destroy(&msg);
+ free(row_msg);
@@ -26031,11 +26147,10 @@ index 15433e3472..a886f971e7 100644
+ print_idl_row_updated_simple4(s4, step);
+}
+
- static void
- print_idl_row_simple6(const struct idltest_simple6 *s6, int step)
- {
- struct ds msg = DS_EMPTY_INITIALIZER;
-- ds_put_format(&msg, "%03d: name=%s ", step, s6->name);
++static void
++print_idl_row_simple6(const struct idltest_simple6 *s6, int step, bool terse)
++{
++ struct ds msg = DS_EMPTY_INITIALIZER;
+ ds_put_format(&msg, "name=%s ", s6->name);
ds_put_cstr(&msg, "weak_ref=[");
for (size_t i = 0; i < s6->n_weak_ref; i++) {
@@ -26046,23 +26161,25 @@ index 15433e3472..a886f971e7 100644
- print_and_log("%s", ds_cstr(&msg));
+ ds_put_cstr(&msg, "]");
+
-+ char *row_msg = format_idl_row(&s6->header_, step, ds_cstr(&msg));
++ char *row_msg = format_idl_row(&s6->header_, step, ds_cstr(&msg), terse);
+ print_and_log("%s", row_msg);
ds_destroy(&msg);
+ free(row_msg);
print_idl_row_updated_simple6(s6, step);
}
-@@ -2030,14 +2143,23 @@ print_idl_row_simple6(const struct idltest_simple6 *s6, int step)
+
static void
- print_idl_row_singleton(const struct idltest_singleton *sng, int step)
+-print_idl_row_singleton(const struct idltest_singleton *sng, int step)
++print_idl_row_singleton(const struct idltest_singleton *sng, int step,
++ bool terse)
{
- print_and_log("%03d: name=%s uuid="UUID_FMT, step, sng->name,
- UUID_ARGS(&sng->header_.uuid));
+ struct ds msg = DS_EMPTY_INITIALIZER;
+ ds_put_format(&msg, "name=%s", sng->name);
+
-+ char *row_msg = format_idl_row(&sng->header_, step, ds_cstr(&msg));
++ char *row_msg = format_idl_row(&sng->header_, step, ds_cstr(&msg), terse);
+ print_and_log("%s", row_msg);
+ ds_destroy(&msg);
+ free(row_msg);
@@ -26071,7 +26188,8 @@ index 15433e3472..a886f971e7 100644
}
static void
- print_idl(struct ovsdb_idl *idl, int step)
+-print_idl(struct ovsdb_idl *idl, int step)
++print_idl(struct ovsdb_idl *idl, int step, bool terse)
{
+ const struct idltest_simple3 *s3;
+ const struct idltest_simple4 *s4;
@@ -26079,38 +26197,59 @@ index 15433e3472..a886f971e7 100644
const struct idltest_simple *s;
const struct idltest_link1 *l1;
const struct idltest_link2 *l2;
-@@ -2056,6 +2178,18 @@ print_idl(struct ovsdb_idl *idl, int step)
- print_idl_row_link2(l2, step);
+@@ -2045,19 +2173,31 @@ print_idl(struct ovsdb_idl *idl, int step)
+ int n = 0;
+
+ IDLTEST_SIMPLE_FOR_EACH (s, idl) {
+- print_idl_row_simple(s, step);
++ print_idl_row_simple(s, step, terse);
+ n++;
+ }
+ IDLTEST_LINK1_FOR_EACH (l1, idl) {
+- print_idl_row_link1(l1, step);
++ print_idl_row_link1(l1, step, terse);
n++;
}
+ IDLTEST_LINK2_FOR_EACH (l2, idl) {
+- print_idl_row_link2(l2, step);
++ print_idl_row_link2(l2, step, terse);
++ n++;
++ }
+ IDLTEST_SIMPLE3_FOR_EACH (s3, idl) {
-+ print_idl_row_simple3(s3, step);
++ print_idl_row_simple3(s3, step, terse);
+ n++;
+ }
+ IDLTEST_SIMPLE4_FOR_EACH (s4, idl) {
-+ print_idl_row_simple4(s4, step);
++ print_idl_row_simple4(s4, step, terse);
+ n++;
+ }
+ IDLTEST_SIMPLE6_FOR_EACH (s6, idl) {
-+ print_idl_row_simple6(s6, step);
-+ n++;
-+ }
++ print_idl_row_simple6(s6, step, terse);
+ n++;
+ }
IDLTEST_SINGLETON_FOR_EACH (sng, idl) {
- print_idl_row_singleton(sng, step);
+- print_idl_row_singleton(sng, step);
++ print_idl_row_singleton(sng, step, terse);
n++;
-@@ -2068,6 +2202,8 @@ print_idl(struct ovsdb_idl *idl, int step)
+ }
+ if (!n) {
+@@ -2066,8 +2206,10 @@ print_idl(struct ovsdb_idl *idl, int step)
+ }
+
static void
- print_idl_track(struct ovsdb_idl *idl, int step)
+-print_idl_track(struct ovsdb_idl *idl, int step)
++print_idl_track(struct ovsdb_idl *idl, int step, bool terse)
{
+ const struct idltest_simple3 *s3;
+ const struct idltest_simple4 *s4;
const struct idltest_simple6 *s6;
const struct idltest_simple *s;
const struct idltest_link1 *l1;
-@@ -2076,51 +2212,26 @@ print_idl_track(struct ovsdb_idl *idl, int step)
+@@ -2075,52 +2217,27 @@ print_idl_track(struct ovsdb_idl *idl, int step)
+ int n = 0;
IDLTEST_SIMPLE_FOR_EACH_TRACKED (s, idl) {
- print_idl_row_simple(s, step);
+- print_idl_row_simple(s, step);
- if (idltest_simple_is_deleted(s)) {
- print_and_log("%03d: deleted row: uuid="UUID_FMT, step,
- UUID_ARGS(&s->header_.uuid));
@@ -26118,6 +26257,7 @@ index 15433e3472..a886f971e7 100644
- print_and_log("%03d: inserted row: uuid="UUID_FMT, step,
- UUID_ARGS(&s->header_.uuid));
- }
++ print_idl_row_simple(s, step, terse);
n++;
}
IDLTEST_LINK1_FOR_EACH_TRACKED (l1, idl) {
@@ -26131,7 +26271,7 @@ index 15433e3472..a886f971e7 100644
- UUID_ARGS(&l1->header_.uuid));
- }
- }
-+ print_idl_row_link1(l1, step);
++ print_idl_row_link1(l1, step, terse);
n++;
}
IDLTEST_LINK2_FOR_EACH_TRACKED (l2, idl) {
@@ -26146,19 +26286,19 @@ index 15433e3472..a886f971e7 100644
- }
-
- }
-+ print_idl_row_link2(l2, step);
++ print_idl_row_link2(l2, step, terse);
+ n++;
+ }
+ IDLTEST_SIMPLE3_FOR_EACH_TRACKED (s3, idl) {
-+ print_idl_row_simple3(s3, step);
++ print_idl_row_simple3(s3, step, terse);
+ n++;
+ }
+ IDLTEST_SIMPLE4_FOR_EACH_TRACKED (s4, idl) {
-+ print_idl_row_simple4(s4, step);
++ print_idl_row_simple4(s4, step, terse);
n++;
}
IDLTEST_SIMPLE6_FOR_EACH_TRACKED (s6, idl) {
- print_idl_row_simple6(s6, step);
+- print_idl_row_simple6(s6, step);
- if (idltest_simple6_is_deleted(s6)) {
- print_and_log("%03d: deleted row: uuid="UUID_FMT, step,
- UUID_ARGS(&s6->header_.uuid));
@@ -26166,10 +26306,11 @@ index 15433e3472..a886f971e7 100644
- print_and_log("%03d: inserted row: uuid="UUID_FMT, step,
- UUID_ARGS(&s6->header_.uuid));
- }
++ print_idl_row_simple6(s6, step, terse);
n++;
}
-@@ -2349,6 +2460,10 @@ find_table_class(const char *name)
+@@ -2349,6 +2466,10 @@ find_table_class(const char *name)
return &idltest_table_link1;
} else if (!strcmp(name, "link2")) {
return &idltest_table_link2;
@@ -26180,7 +26321,43 @@ index 15433e3472..a886f971e7 100644
} else if (!strcmp(name, "simple6")) {
return &idltest_table_simple6;
}
-@@ -2702,27 +2817,6 @@ do_idl_partial_update_map_column(struct ovs_cmdl_context *ctx)
+@@ -2518,6 +2639,13 @@ do_idl(struct ovs_cmdl_context *ctx)
+ char *arg = ctx->argv[i];
+ struct jsonrpc_msg *request, *reply;
+
++ bool terse = false;
++ if (*arg == '?') {
++ /* We're only interested in terse table contents. */
++ terse = true;
++ arg++;
++ }
++
+ if (*arg == '+') {
+ /* The previous transaction didn't change anything. */
+ arg++;
+@@ -2538,10 +2666,10 @@ do_idl(struct ovs_cmdl_context *ctx)
+
+ /* Print update. */
+ if (track) {
+- print_idl_track(idl, step++);
++ print_idl_track(idl, step++, terse);
+ ovsdb_idl_track_clear(idl);
+ } else {
+- print_idl(idl, step++);
++ print_idl(idl, step++, terse);
+ }
+ }
+ seqno = ovsdb_idl_get_seqno(idl);
+@@ -2589,7 +2717,7 @@ do_idl(struct ovs_cmdl_context *ctx)
+ ovsdb_idl_wait(idl);
+ poll_block();
+ }
+- print_idl(idl, step++);
++ print_idl(idl, step++, false);
+ ovsdb_idl_track_clear(idl);
+ ovsdb_idl_destroy(idl);
+ print_and_log("%03d: done", step);
+@@ -2702,34 +2830,13 @@ do_idl_partial_update_map_column(struct ovs_cmdl_context *ctx)
printf("%03d: End test\n", step);
}
@@ -26208,8 +26385,25 @@ index 15433e3472..a886f971e7 100644
static void
dump_simple3(struct ovsdb_idl *idl,
const struct idltest_simple3 *myRow,
+ int step)
+ {
+ IDLTEST_SIMPLE3_FOR_EACH(myRow, idl) {
+- print_idl_row_simple3(myRow, step);
++ print_idl_row_simple3(myRow, step, false);
+ }
+ }
+
+@@ -2871,7 +2978,7 @@ do_idl_compound_index_with_ref(struct ovs_cmdl_context *ctx)
+ idltest_simple3_index_set_uref(equal, &myRow2, 1);
+ printf("%03d: Query using index with reference\n", step++);
+ IDLTEST_SIMPLE3_FOR_EACH_EQUAL (myRow, equal, index) {
+- print_idl_row_simple3(myRow, step++);
++ print_idl_row_simple3(myRow, step++, false);
+ }
+ idltest_simple3_index_destroy_row(equal);
+
diff --git a/tests/test-ovsdb.py b/tests/test-ovsdb.py
-index a196802743..72a319123e 100644
+index a196802743..123f89f081 100644
--- a/tests/test-ovsdb.py
+++ b/tests/test-ovsdb.py
@@ -162,6 +162,10 @@ def get_simple_printable_row_string(row, columns):
@@ -26236,7 +26430,7 @@ index a196802743..72a319123e 100644
return get_simple_printable_row_string(row, simple_columns)
-@@ -184,81 +189,118 @@ def get_simple2_table_printable_row(row):
+@@ -184,81 +189,130 @@ def get_simple2_table_printable_row(row):
def get_simple3_table_printable_row(row):
@@ -26245,6 +26439,7 @@ index a196802743..72a319123e 100644
return get_simple_printable_row_string(row, simple3_columns)
+-def print_idl(idl, step):
+def get_simple4_table_printable_row(row):
+ simple4_columns = ["name"]
+ return get_simple_printable_row_string(row, simple4_columns)
@@ -26284,13 +26479,16 @@ index a196802743..72a319123e 100644
+ return "name=%s" % row.name
+
+
-+def print_row(table, row, step, contents):
-+ s = "%03d: table %s: %s " % (step, table, contents)
-+ s += get_simple_printable_row_string(row, ["uuid"])
++def print_row(table, row, step, contents, terse):
++ if terse:
++ s = "%03d: table %s" % (step, table)
++ else:
++ s = "%03d: table %s: %s " % (step, table, contents)
++ s += get_simple_printable_row_string(row, ["uuid"])
+ print(s)
+
+
- def print_idl(idl, step):
++def print_idl(idl, step, terse=False):
n = 0
if "simple" in idl.tables:
simple = idl.tables["simple"].rows
@@ -26299,7 +26497,8 @@ index a196802743..72a319123e 100644
- s += get_simple_table_printable_row(row)
- print(s)
+ print_row("simple", row, step,
-+ get_simple_table_printable_row(row))
++ get_simple_table_printable_row(row),
++ terse)
n += 1
if "simple2" in idl.tables:
@@ -26309,7 +26508,8 @@ index a196802743..72a319123e 100644
- s += get_simple2_table_printable_row(row)
- print(s)
+ print_row("simple2", row, step,
-+ get_simple2_table_printable_row(row))
++ get_simple2_table_printable_row(row),
++ terse)
n += 1
if "simple3" in idl.tables:
@@ -26319,14 +26519,16 @@ index a196802743..72a319123e 100644
- s += get_simple3_table_printable_row(row)
- print(s)
+ print_row("simple3", row, step,
-+ get_simple3_table_printable_row(row))
++ get_simple3_table_printable_row(row),
++ terse)
+ n += 1
+
+ if "simple4" in idl.tables:
+ simple4 = idl.tables["simple4"].rows
+ for row in simple4.values():
+ print_row("simple4", row, step,
-+ get_simple4_table_printable_row(row))
++ get_simple4_table_printable_row(row),
++ terse)
n += 1
if "simple5" in idl.tables:
@@ -26336,14 +26538,16 @@ index a196802743..72a319123e 100644
- s += get_simple_printable_row_string(row, ["name", "irefmap"])
- print(s)
+ print_row("simple5", row, step,
-+ get_simple5_table_printable_row(row))
++ get_simple5_table_printable_row(row),
++ terse)
+ n += 1
+
+ if "simple6" in idl.tables:
+ simple6 = idl.tables["simple6"].rows
+ for row in simple6.values():
+ print_row("simple6", row, step,
-+ get_simple6_table_printable_row(row))
++ get_simple6_table_printable_row(row),
++ terse)
n += 1
if "link1" in idl.tables:
@@ -26362,7 +26566,8 @@ index a196802743..72a319123e 100644
- s.append(" uuid=%s" % row.uuid)
- print(''.join(s))
+ print_row("link1", row, step,
-+ get_link1_table_printable_row(row))
++ get_link1_table_printable_row(row),
++ terse)
n += 1
if "link2" in idl.tables:
@@ -26376,7 +26581,8 @@ index a196802743..72a319123e 100644
- s.append(" uuid=%s" % row.uuid)
- print(''.join(s))
+ print_row("link2", row, step,
-+ get_link2_table_printable_row(row))
++ get_link2_table_printable_row(row),
++ terse)
n += 1
if "singleton" in idl.tables:
@@ -26388,11 +26594,12 @@ index a196802743..72a319123e 100644
- s.append(" uuid=%s" % row.uuid)
- print(''.join(s))
+ print_row("singleton", row, step,
-+ get_singleton_table_printable_row(row))
++ get_singleton_table_printable_row(row),
++ terse)
n += 1
if not n:
-@@ -637,7 +679,8 @@ def do_idl(schema_file, remote, *commands):
+@@ -637,7 +691,8 @@ def do_idl(schema_file, remote, *commands):
def mock_notify(event, row, updates=None):
output = "%03d: " % step
output += "event:" + str(event) + ", row={"
@@ -26402,6 +26609,28 @@ index a196802743..72a319123e 100644
if updates is None:
output += "None"
else:
+@@ -658,6 +713,12 @@ def do_idl(schema_file, remote, *commands):
+ step += 1
+
+ for command in commands:
++ terse = False
++ if command.startswith("?"):
++ # We're only interested in terse table contents.
++ terse = True
++ command = command[1:]
++
+ if command.startswith("+"):
+ # The previous transaction didn't change anything.
+ command = command[1:]
+@@ -671,7 +732,7 @@ def do_idl(schema_file, remote, *commands):
+ rpc.wait(poller)
+ poller.block()
+
+- print_idl(idl, step)
++ print_idl(idl, step, terse)
+ step += 1
+
+ seqno = idl.change_seqno
diff --git a/tests/test-reconnect.py b/tests/test-reconnect.py
index f0ad9f9793..cea48eb527 100644
--- a/tests/test-reconnect.py
diff --git a/SPECS/openvswitch2.15.spec b/SPECS/openvswitch2.15.spec
index 4d74cd5..b5adbba 100644
--- a/SPECS/openvswitch2.15.spec
+++ b/SPECS/openvswitch2.15.spec
@@ -57,7 +57,7 @@ Summary: Open vSwitch
Group: System Environment/Daemons daemon/database/utilities
URL: http://www.openvswitch.org/
Version: 2.15.0
-Release: 67%{?dist}
+Release: 68%{?dist}
# Nearly all of openvswitch is ASL 2.0. The bugtool is LGPLv2+, and the
# lib/sflow*.[ch] files are SISSL
@@ -702,6 +702,15 @@ exit 0
%endif
%changelog
+* Mon Jan 31 2022 Open vSwitch CI - 2.15.0-68
+- Merging upstream branch-2.15 [RH git: df7561a258]
+ Commit list:
+ 02dd680dc5 ovsdb-idl: ovsdb_idl_loop_destroy must also destroy the committing txn.
+ b664877079 ovsdb-cs: Clear last_id on reconnect if condition changes in-flight.
+ dec99de837 ofp-flow: Skip flow reply if it exceeds the maximum message size.
+ 2a92aac033 ovsdb-cs: Fix ignoring of the last id from the initial monitor reply. (#2044624)
+
+
* Wed Jan 26 2022 Open vSwitch CI - 2.15.0-67
- Merging upstream branch-2.15 [RH git: 0ec5c70e5a]
Commit list: