Open vSwitch CI fe1a04
diff --git a/.ci/linux-build.sh b/.ci/linux-build.sh
Open vSwitch CI fe1a04
index 3e5136fd4e..dd29a4182d 100755
Open vSwitch CI fe1a04
--- a/.ci/linux-build.sh
Open vSwitch CI fe1a04
+++ b/.ci/linux-build.sh
Open vSwitch CI fe1a04
@@ -235,7 +235,7 @@ if [ "$TESTSUITE" ]; then
Open vSwitch CI fe1a04
     configure_ovs
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     export DISTCHECK_CONFIGURE_FLAGS="$OPTS"
Open vSwitch CI fe1a04
-    if ! make distcheck CFLAGS="${CFLAGS_FOR_OVS}" \
Open vSwitch CI fe1a04
+    if ! make distcheck -j4 CFLAGS="${CFLAGS_FOR_OVS}" \
Open vSwitch CI fe1a04
          TESTSUITEFLAGS=-j4 RECHECK=yes; then
Open vSwitch CI fe1a04
         # testsuite.log is necessary for debugging.
Open vSwitch CI fe1a04
         cat */_build/sub/tests/testsuite.log
Open vSwitch CI daaf06
diff --git a/Documentation/topics/dpdk/pmd.rst b/Documentation/topics/dpdk/pmd.rst
Open vSwitch CI daaf06
index caa7d97bef..e481e79414 100644
Open vSwitch CI daaf06
--- a/Documentation/topics/dpdk/pmd.rst
Open vSwitch CI daaf06
+++ b/Documentation/topics/dpdk/pmd.rst
Open vSwitch CI daaf06
@@ -239,7 +239,9 @@ If not set, the default variance improvement threshold is 25%.
Open vSwitch CI daaf06
 
Open vSwitch CI daaf06
     PMD Auto Load Balancing doesn't currently work if queues are assigned
Open vSwitch CI daaf06
     cross NUMA as actual processing load could get worse after assignment
Open vSwitch CI daaf06
-    as compared to what dry run predicts.
Open vSwitch CI daaf06
+    as compared to what dry run predicts. The only exception is when all
Open vSwitch CI daaf06
+    PMD threads are running on cores from a single NUMA node.  In this case
Open vSwitch CI daaf06
+    Auto Load Balancing is still possible.
Open vSwitch CI daaf06
 
Open vSwitch CI daaf06
 The minimum time between 2 consecutive PMD auto load balancing iterations can
Open vSwitch CI daaf06
 also be configured by::
Open vSwitch CI fe1a04
diff --git a/Documentation/topics/dpdk/qos.rst b/Documentation/topics/dpdk/qos.rst
Open vSwitch CI fe1a04
index 103495415a..a98ec672fc 100644
Open vSwitch CI fe1a04
--- a/Documentation/topics/dpdk/qos.rst
Open vSwitch CI fe1a04
+++ b/Documentation/topics/dpdk/qos.rst
Open vSwitch CI fe1a04
@@ -69,22 +69,24 @@ to prioritize certain traffic over others at a port level.
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 For example, the following configuration will limit the traffic rate at a
Open vSwitch CI fe1a04
 port level to a maximum of 2000 packets a second (64 bytes IPv4 packets).
Open vSwitch CI fe1a04
-100pps as CIR (Committed Information Rate) and 1000pps as EIR (Excess
Open vSwitch CI fe1a04
-Information Rate). High priority traffic is routed to queue 10, which marks
Open vSwitch CI fe1a04
+1000pps as CIR (Committed Information Rate) and 1000pps as EIR (Excess
Open vSwitch CI fe1a04
+Information Rate). CIR and EIR are measured in bytes without Ethernet header.
Open vSwitch CI fe1a04
+As a result, 1000pps means (64-byte - 14-byte) * 1000 = 50,000 in the
Open vSwitch CI fe1a04
+configuration below. High priority traffic is routed to queue 10, which marks
Open vSwitch CI fe1a04
 all traffic as CIR, i.e. Green. All low priority traffic, queue 20, is
Open vSwitch CI fe1a04
 marked as EIR, i.e. Yellow::
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     $ ovs-vsctl --timeout=5 set port dpdk1 qos=@myqos -- \
Open vSwitch CI fe1a04
         --id=@myqos create qos type=trtcm-policer \
Open vSwitch CI fe1a04
-        other-config:cir=52000 other-config:cbs=2048 \
Open vSwitch CI fe1a04
-        other-config:eir=52000 other-config:ebs=2048  \
Open vSwitch CI fe1a04
+        other-config:cir=50000 other-config:cbs=2048 \
Open vSwitch CI fe1a04
+        other-config:eir=50000 other-config:ebs=2048  \
Open vSwitch CI fe1a04
         queues:10=@dpdk1Q10 queues:20=@dpdk1Q20 -- \
Open vSwitch CI fe1a04
          --id=@dpdk1Q10 create queue \
Open vSwitch CI fe1a04
-          other-config:cir=41600000 other-config:cbs=2048 \
Open vSwitch CI fe1a04
+          other-config:cir=100000 other-config:cbs=2048 \
Open vSwitch CI fe1a04
           other-config:eir=0 other-config:ebs=0 -- \
Open vSwitch CI fe1a04
          --id=@dpdk1Q20 create queue \
Open vSwitch CI fe1a04
            other-config:cir=0 other-config:cbs=0 \
Open vSwitch CI fe1a04
-           other-config:eir=41600000 other-config:ebs=2048 \
Open vSwitch CI fe1a04
+           other-config:eir=50000 other-config:ebs=2048
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 This configuration accomplishes that the high priority traffic has a
Open vSwitch CI fe1a04
 guaranteed bandwidth egressing the ports at CIR (1000pps), but it can also
Open vSwitch CI fe1a04
diff --git a/NEWS b/NEWS
Open vSwitch CI fe1a04
index bc901efdb1..036d4032c4 100644
Open vSwitch CI fe1a04
--- a/NEWS
Open vSwitch CI fe1a04
+++ b/NEWS
Open vSwitch CI fe1a04
@@ -1,3 +1,11 @@
Open vSwitch CI fe1a04
+v2.15.1 - xx xxx xxxx
Open vSwitch CI fe1a04
+---------------------
Open vSwitch CI fe1a04
+   - ovs-ctl:
Open vSwitch CI fe1a04
+     * New option '--no-record-hostname' to disable hostname configuration
Open vSwitch CI fe1a04
+       in ovsdb on startup.
Open vSwitch CI fe1a04
+     * New command 'record-hostname-if-not-set' to update hostname in ovsdb.
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
 v2.15.0 - 15 Feb 2021
Open vSwitch CI fe1a04
 ---------------------
Open vSwitch CI fe1a04
    - OVSDB:
Open vSwitch CI d251a9
diff --git a/acinclude.m4 b/acinclude.m4
Open vSwitch CI d251a9
index 435685c93d..15a54d636f 100644
Open vSwitch CI d251a9
--- a/acinclude.m4
Open vSwitch CI d251a9
+++ b/acinclude.m4
Open vSwitch CI d251a9
@@ -209,10 +209,10 @@ dnl Configure Linux tc compat.
Open vSwitch CI d251a9
 AC_DEFUN([OVS_CHECK_LINUX_TC], [
Open vSwitch CI d251a9
   AC_COMPILE_IFELSE([
Open vSwitch CI d251a9
     AC_LANG_PROGRAM([#include <linux/pkt_cls.h>], [
Open vSwitch CI d251a9
-        int x = TCA_ACT_FLAGS;
Open vSwitch CI d251a9
+        int x = TCA_FLOWER_KEY_CT_FLAGS_REPLY;
Open vSwitch CI d251a9
     ])],
Open vSwitch CI d251a9
-    [AC_DEFINE([HAVE_TCA_ACT_FLAGS], [1],
Open vSwitch CI d251a9
-               [Define to 1 if TCA_ACT_FLAGS is available.])])
Open vSwitch CI d251a9
+    [AC_DEFINE([HAVE_TCA_FLOWER_KEY_CT_FLAGS_REPLY], [1],
Open vSwitch CI d251a9
+               [Define to 1 if TCA_FLOWER_KEY_CT_FLAGS_REPLY is available.])])
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
   AC_CHECK_MEMBERS([struct tcf_t.firstuse], [], [], [#include <linux/pkt_cls.h>])
Open vSwitch CI d251a9
 
Open vSwitch CI fe1a04
diff --git a/configure.ac b/configure.ac
Open vSwitch CI fe1a04
index fd82d7d270..9299342960 100644
Open vSwitch CI fe1a04
--- a/configure.ac
Open vSwitch CI fe1a04
+++ b/configure.ac
Open vSwitch CI fe1a04
@@ -13,7 +13,7 @@
Open vSwitch CI fe1a04
 # limitations under the License.
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 AC_PREREQ(2.63)
Open vSwitch CI fe1a04
-AC_INIT(openvswitch, 2.15.0, bugs@openvswitch.org)
Open vSwitch CI fe1a04
+AC_INIT(openvswitch, 2.15.1, bugs@openvswitch.org)
Open vSwitch CI fe1a04
 AC_CONFIG_SRCDIR([datapath/datapath.c])
Open vSwitch CI fe1a04
 AC_CONFIG_MACRO_DIR([m4])
Open vSwitch CI fe1a04
 AC_CONFIG_AUX_DIR([build-aux])
Open vSwitch CI fe1a04
diff --git a/debian/changelog b/debian/changelog
Open vSwitch CI fe1a04
index 1f2b7a3668..8b5d075840 100644
Open vSwitch CI fe1a04
--- a/debian/changelog
Open vSwitch CI fe1a04
+++ b/debian/changelog
Open vSwitch CI fe1a04
@@ -1,3 +1,9 @@
Open vSwitch CI fe1a04
+openvswitch (2.15.1-1) unstable; urgency=low
Open vSwitch CI fe1a04
+   [ Open vSwitch team ]
Open vSwitch CI fe1a04
+   * New upstream version
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+ -- Open vSwitch team <dev@openvswitch.org>  Mon, 15 Feb 2021 17:35:33 +0100
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
 openvswitch (2.15.0-1) unstable; urgency=low
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
    * New upstream version
Open vSwitch CI d251a9
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
Open vSwitch CI d251a9
index b0a5ce8bec..bc51a5767f 100644
Open vSwitch CI d251a9
--- a/include/linux/pkt_cls.h
Open vSwitch CI d251a9
+++ b/include/linux/pkt_cls.h
Open vSwitch CI d251a9
@@ -1,7 +1,7 @@
Open vSwitch CI d251a9
 #ifndef __LINUX_PKT_CLS_WRAPPER_H
Open vSwitch CI d251a9
 #define __LINUX_PKT_CLS_WRAPPER_H 1
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
-#if defined(__KERNEL__) || defined(HAVE_TCA_ACT_FLAGS)
Open vSwitch CI d251a9
+#if defined(__KERNEL__) || defined(HAVE_TCA_FLOWER_KEY_CT_FLAGS_REPLY)
Open vSwitch CI d251a9
 #include_next <linux/pkt_cls.h>
Open vSwitch CI d251a9
 #else
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
@@ -255,6 +255,9 @@ enum {
Open vSwitch CI d251a9
 	TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED = 1 << 1, /* Part of an existing connection. */
Open vSwitch CI d251a9
 	TCA_FLOWER_KEY_CT_FLAGS_RELATED = 1 << 2, /* Related to an established connection. */
Open vSwitch CI d251a9
 	TCA_FLOWER_KEY_CT_FLAGS_TRACKED = 1 << 3, /* Conntrack has occurred. */
Open vSwitch CI d251a9
+	TCA_FLOWER_KEY_CT_FLAGS_INVALID = 1 << 4, /* Conntrack is invalid. */
Open vSwitch CI d251a9
+	TCA_FLOWER_KEY_CT_FLAGS_REPLY = 1 << 5, /* Packet is in the reply direction. */
Open vSwitch CI d251a9
+	__TCA_FLOWER_KEY_CT_FLAGS_MAX,
Open vSwitch CI d251a9
 };
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
 enum {
Open vSwitch CI 91e748
diff --git a/ipsec/ovs-monitor-ipsec.in b/ipsec/ovs-monitor-ipsec.in
Open vSwitch CI 91e748
index 64111768b3..668507fd37 100755
Open vSwitch CI 91e748
--- a/ipsec/ovs-monitor-ipsec.in
Open vSwitch CI 91e748
+++ b/ipsec/ovs-monitor-ipsec.in
Open vSwitch CI 91e748
@@ -14,6 +14,7 @@
Open vSwitch CI 91e748
 # limitations under the License.
Open vSwitch CI 91e748
 
Open vSwitch CI 91e748
 import argparse
Open vSwitch CI 91e748
+import ipaddress
Open vSwitch CI 91e748
 import re
Open vSwitch CI 91e748
 import subprocess
Open vSwitch CI 91e748
 import sys
Open vSwitch CI 91e748
@@ -413,6 +414,11 @@ conn prevent_unencrypted_vxlan
Open vSwitch CI 91e748
     leftprotoport=udp/4789
Open vSwitch CI 91e748
     mark={0}
Open vSwitch CI 91e748
 
Open vSwitch CI 91e748
+"""
Open vSwitch CI 91e748
+
Open vSwitch CI 91e748
+    IPV6_CONN = """\
Open vSwitch CI 91e748
+    hostaddrfamily=ipv6
Open vSwitch CI 91e748
+    clientaddrfamily=ipv6
Open vSwitch CI 91e748
 """
Open vSwitch CI 91e748
 
Open vSwitch CI 91e748
     auth_tmpl = {"psk": Template("""\
Open vSwitch CI 91e748
@@ -520,6 +526,9 @@ conn prevent_unencrypted_vxlan
Open vSwitch CI 91e748
         else:
Open vSwitch CI 91e748
             auth_section = self.auth_tmpl["pki_ca"].substitute(tunnel.conf)
Open vSwitch CI 91e748
 
Open vSwitch CI 91e748
+        if tunnel.conf["address_family"] == "IPv6":
Open vSwitch CI 91e748
+            auth_section = self.IPV6_CONN + auth_section
Open vSwitch CI 91e748
+
Open vSwitch CI 91e748
         vals = tunnel.conf.copy()
Open vSwitch CI 91e748
         vals["auth_section"] = auth_section
Open vSwitch CI 91e748
         vals["version"] = tunnel.version
Open vSwitch CI 91e748
@@ -756,6 +765,7 @@ class IPsecTunnel(object):
Open vSwitch CI 91e748
   Tunnel Type:    $tunnel_type
Open vSwitch CI 91e748
   Local IP:       $local_ip
Open vSwitch CI 91e748
   Remote IP:      $remote_ip
Open vSwitch CI 91e748
+  Address Family: $address_family
Open vSwitch CI 91e748
   SKB mark:       $skb_mark
Open vSwitch CI 91e748
   Local cert:     $certificate
Open vSwitch CI 91e748
   Local name:     $local_name
Open vSwitch CI 91e748
@@ -797,6 +807,9 @@ class IPsecTunnel(object):
Open vSwitch CI 91e748
             "tunnel_type": row.type,
Open vSwitch CI 91e748
             "local_ip": options.get("local_ip", "%defaultroute"),
Open vSwitch CI 91e748
             "remote_ip": options.get("remote_ip"),
Open vSwitch CI 91e748
+            "address_family": self._get_conn_address_family(
Open vSwitch CI 91e748
+                                                   options.get("remote_ip"),
Open vSwitch CI 91e748
+                                                   options.get("local_ip")),
Open vSwitch CI 91e748
             "skb_mark": monitor.conf["skb_mark"],
Open vSwitch CI 91e748
             "certificate": monitor.conf["pki"]["certificate"],
Open vSwitch CI 91e748
             "private_key": monitor.conf["pki"]["private_key"],
Open vSwitch CI 91e748
@@ -865,6 +878,17 @@ class IPsecTunnel(object):
Open vSwitch CI 91e748
 
Open vSwitch CI 91e748
         return header + conf + status + spds + sas + cons + "\n"
Open vSwitch CI 91e748
 
Open vSwitch CI 91e748
+    def _get_conn_address_family(self, remote_ip, local_ip):
Open vSwitch CI 91e748
+        remote = address_family(remote_ip)
Open vSwitch CI 91e748
+        local = address_family(local_ip)
Open vSwitch CI 91e748
+
Open vSwitch CI 91e748
+        if local is None:
Open vSwitch CI 91e748
+            return remote
Open vSwitch CI 91e748
+        elif local != remote:
Open vSwitch CI 91e748
+            return None
Open vSwitch CI 91e748
+        else:
Open vSwitch CI 91e748
+            return remote
Open vSwitch CI 91e748
+
Open vSwitch CI 91e748
     def _is_valid_tunnel_conf(self):
Open vSwitch CI 91e748
         """This function verifies if IPsec tunnel has valid configuration
Open vSwitch CI 91e748
         set in 'conf'.  If it is valid, then it returns True.  Otherwise,
Open vSwitch CI 91e748
@@ -1120,6 +1144,19 @@ class IPsecMonitor(object):
Open vSwitch CI 91e748
         return m.group(1)
Open vSwitch CI 91e748
 
Open vSwitch CI 91e748
 
Open vSwitch CI 91e748
+def address_family(address):
Open vSwitch CI 91e748
+    try:
Open vSwitch CI 91e748
+        ip = ipaddress.ip_address(address)
Open vSwitch CI 91e748
+        ipstr = str(type(ip))
Open vSwitch CI 91e748
+    # ipaddress has inconsistencies with what exceptions are raised:
Open vSwitch CI 91e748
+    # https://mail.openvswitch.org/pipermail/ovs-dev/2021-April/381696.html
Open vSwitch CI 91e748
+    except (ValueError, ipaddress.AddressValueError):
Open vSwitch CI 91e748
+        return None
Open vSwitch CI 91e748
+    if ipstr.find('v6') != -1:
Open vSwitch CI 91e748
+        return "IPv6"
Open vSwitch CI 91e748
+    return "IPv4"
Open vSwitch CI 91e748
+
Open vSwitch CI 91e748
+
Open vSwitch CI 91e748
 def unixctl_xfrm_policies(conn, unused_argv, unused_aux):
Open vSwitch CI 91e748
     global xfrm
Open vSwitch CI 91e748
     policies = xfrm.get_policies()
Open vSwitch CI fe1a04
diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
Open vSwitch CI 0aa018
index 4381c618f1..251788b049 100644
Open vSwitch CI fe1a04
--- a/lib/dpif-netdev.c
Open vSwitch CI fe1a04
+++ b/lib/dpif-netdev.c
Open vSwitch CI 0aa018
@@ -279,8 +279,9 @@ static bool dpcls_lookup(struct dpcls *cls,
Open vSwitch CI 0aa018
     ( 1 << OFPMBT13_DROP )
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
 struct dp_meter_band {
Open vSwitch CI 0aa018
-    struct ofputil_meter_band up; /* type, prec_level, pad, rate, burst_size */
Open vSwitch CI 0aa018
-    uint32_t bucket; /* In 1/1000 packets (for PKTPS), or in bits (for KBPS) */
Open vSwitch CI 0aa018
+    uint32_t rate;
Open vSwitch CI 0aa018
+    uint32_t burst_size;
Open vSwitch CI 0aa018
+    uint64_t bucket; /* In 1/1000 packets (for PKTPS), or in bits (for KBPS) */
Open vSwitch CI 0aa018
     uint64_t packet_count;
Open vSwitch CI 0aa018
     uint64_t byte_count;
Open vSwitch CI 0aa018
 };
Open vSwitch CI 0aa018
@@ -3834,6 +3835,15 @@ dpif_netdev_flow_put(struct dpif *dpif, const struct dpif_flow_put *put)
Open vSwitch CI fe1a04
         return error;
Open vSwitch CI fe1a04
     }
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
+    if (match.wc.masks.in_port.odp_port != ODPP_NONE) {
Open vSwitch CI fe1a04
+        static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(1, 5);
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+        VLOG_ERR_RL(&rl, "failed to put%s flow: in_port is not an exact match",
Open vSwitch CI fe1a04
+                    (put->flags & DPIF_FP_CREATE) ? "[create]"
Open vSwitch CI fe1a04
+                    : (put->flags & DPIF_FP_MODIFY) ? "[modify]" : "[zero]");
Open vSwitch CI fe1a04
+        return EINVAL;
Open vSwitch CI fe1a04
+    }
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
     if (put->ufid) {
Open vSwitch CI fe1a04
         ufid = *put->ufid;
Open vSwitch CI fe1a04
     } else {
Open vSwitch CI 0aa018
@@ -4878,6 +4888,12 @@ struct rr_numa {
Open vSwitch CI daaf06
     bool idx_inc;
Open vSwitch CI daaf06
 };
Open vSwitch CI daaf06
 
Open vSwitch CI daaf06
+static size_t
Open vSwitch CI daaf06
+rr_numa_list_count(struct rr_numa_list *rr)
Open vSwitch CI daaf06
+{
Open vSwitch CI daaf06
+    return hmap_count(&rr->numas);
Open vSwitch CI daaf06
+}
Open vSwitch CI daaf06
+
Open vSwitch CI daaf06
 static struct rr_numa *
Open vSwitch CI daaf06
 rr_numa_list_lookup(struct rr_numa_list *rr, int numa_id)
Open vSwitch CI daaf06
 {
Open vSwitch CI 0aa018
@@ -5590,10 +5606,17 @@ get_dry_run_variance(struct dp_netdev *dp, uint32_t *core_list,
Open vSwitch CI daaf06
     for (int i = 0; i < n_rxqs; i++) {
Open vSwitch CI daaf06
         int numa_id = netdev_get_numa_id(rxqs[i]->port->netdev);
Open vSwitch CI daaf06
         numa = rr_numa_list_lookup(&rr, numa_id);
Open vSwitch CI daaf06
+        /* If there is no available pmd on the local numa but there is only one
Open vSwitch CI daaf06
+         * numa for cross-numa polling, we can estimate the dry run. */
Open vSwitch CI daaf06
+        if (!numa && rr_numa_list_count(&rr) == 1) {
Open vSwitch CI daaf06
+            numa = rr_numa_list_next(&rr, NULL);
Open vSwitch CI daaf06
+        }
Open vSwitch CI daaf06
         if (!numa) {
Open vSwitch CI daaf06
-            /* Abort if cross NUMA polling. */
Open vSwitch CI daaf06
-            VLOG_DBG("PMD auto lb dry run."
Open vSwitch CI daaf06
-                     " Aborting due to cross-numa polling.");
Open vSwitch CI daaf06
+            VLOG_DBG("PMD auto lb dry run: "
Open vSwitch CI daaf06
+                     "There's no available (non-isolated) PMD thread on NUMA "
Open vSwitch CI daaf06
+                     "node %d for port '%s' and there are PMD threads on more "
Open vSwitch CI daaf06
+                     "than one NUMA node available for cross-NUMA polling. "
Open vSwitch CI daaf06
+                     "Aborting.", numa_id, netdev_rxq_get_name(rxqs[i]->rx));
Open vSwitch CI daaf06
             goto cleanup;
Open vSwitch CI daaf06
         }
Open vSwitch CI daaf06
 
Open vSwitch CI 0aa018
@@ -6203,12 +6226,14 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_,
Open vSwitch CI 0aa018
     /* Update all bands and find the one hit with the highest rate for each
Open vSwitch CI 0aa018
      * packet (if any). */
Open vSwitch CI 0aa018
     for (int m = 0; m < meter->n_bands; ++m) {
Open vSwitch CI 0aa018
-        band = &meter->bands[m];
Open vSwitch CI 0aa018
+        uint64_t max_bucket_size;
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
+        band = &meter->bands[m];
Open vSwitch CI 0aa018
+        max_bucket_size = (band->rate + band->burst_size) * 1000ULL;
Open vSwitch CI 0aa018
         /* Update band's bucket. */
Open vSwitch CI 0aa018
-        band->bucket += delta_t * band->up.rate;
Open vSwitch CI 0aa018
-        if (band->bucket > band->up.burst_size) {
Open vSwitch CI 0aa018
-            band->bucket = band->up.burst_size;
Open vSwitch CI 0aa018
+        band->bucket += (uint64_t) delta_t * band->rate;
Open vSwitch CI 0aa018
+        if (band->bucket > max_bucket_size) {
Open vSwitch CI 0aa018
+            band->bucket = max_bucket_size;
Open vSwitch CI 0aa018
         }
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
         /* Drain the bucket for all the packets, if possible. */
Open vSwitch CI 0aa018
@@ -6226,8 +6251,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_,
Open vSwitch CI 0aa018
                  * (Only one band will be fired by a packet, and that
Open vSwitch CI 0aa018
                  * can be different for each packet.) */
Open vSwitch CI 0aa018
                 for (int i = band_exceeded_pkt; i < cnt; i++) {
Open vSwitch CI 0aa018
-                    if (band->up.rate > exceeded_rate[i]) {
Open vSwitch CI 0aa018
-                        exceeded_rate[i] = band->up.rate;
Open vSwitch CI 0aa018
+                    if (band->rate > exceeded_rate[i]) {
Open vSwitch CI 0aa018
+                        exceeded_rate[i] = band->rate;
Open vSwitch CI 0aa018
                         exceeded_band[i] = m;
Open vSwitch CI 0aa018
                     }
Open vSwitch CI 0aa018
                 }
Open vSwitch CI 0aa018
@@ -6246,8 +6271,8 @@ dp_netdev_run_meter(struct dp_netdev *dp, struct dp_packet_batch *packets_,
Open vSwitch CI 0aa018
                         /* Update the exceeding band for the exceeding packet.
Open vSwitch CI 0aa018
                          * (Only one band will be fired by a packet, and that
Open vSwitch CI 0aa018
                          * can be different for each packet.) */
Open vSwitch CI 0aa018
-                        if (band->up.rate > exceeded_rate[i]) {
Open vSwitch CI 0aa018
-                            exceeded_rate[i] = band->up.rate;
Open vSwitch CI 0aa018
+                        if (band->rate > exceeded_rate[i]) {
Open vSwitch CI 0aa018
+                            exceeded_rate[i] = band->rate;
Open vSwitch CI 0aa018
                             exceeded_band[i] = m;
Open vSwitch CI 0aa018
                         }
Open vSwitch CI 0aa018
                     }
Open vSwitch CI 0aa018
@@ -6329,16 +6354,15 @@ dpif_netdev_meter_set(struct dpif *dpif, ofproto_meter_id meter_id,
Open vSwitch CI 0aa018
             config->bands[i].burst_size = config->bands[i].rate;
Open vSwitch CI 0aa018
         }
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
-        meter->bands[i].up = config->bands[i];
Open vSwitch CI 0aa018
-        /* Convert burst size to the bucket units: */
Open vSwitch CI 0aa018
-        /* pkts => 1/1000 packets, kilobits => bits. */
Open vSwitch CI 0aa018
-        meter->bands[i].up.burst_size *= 1000;
Open vSwitch CI 0aa018
-        /* Initialize bucket to empty. */
Open vSwitch CI 0aa018
-        meter->bands[i].bucket = 0;
Open vSwitch CI 0aa018
+        meter->bands[i].rate = config->bands[i].rate;
Open vSwitch CI 0aa018
+        meter->bands[i].burst_size = config->bands[i].burst_size;
Open vSwitch CI 0aa018
+        /* Start with a full bucket. */
Open vSwitch CI 0aa018
+        meter->bands[i].bucket =
Open vSwitch CI 0aa018
+            (meter->bands[i].burst_size + meter->bands[i].rate) * 1000ULL;
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
         /* Figure out max delta_t that is enough to fill any bucket. */
Open vSwitch CI 0aa018
         band_max_delta_t
Open vSwitch CI 0aa018
-            = meter->bands[i].up.burst_size / meter->bands[i].up.rate;
Open vSwitch CI 0aa018
+            = meter->bands[i].bucket / meter->bands[i].rate;
Open vSwitch CI 0aa018
         if (band_max_delta_t > meter->max_delta_t) {
Open vSwitch CI 0aa018
             meter->max_delta_t = band_max_delta_t;
Open vSwitch CI 0aa018
         }
Open vSwitch CI d251a9
diff --git a/lib/dpif-netlink.c b/lib/dpif-netlink.c
Open vSwitch CI d251a9
index ceb56c6851..50520f8c06 100644
Open vSwitch CI d251a9
--- a/lib/dpif-netlink.c
Open vSwitch CI d251a9
+++ b/lib/dpif-netlink.c
Open vSwitch CI d251a9
@@ -2061,6 +2061,7 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
Open vSwitch CI d251a9
     uint8_t csum_on = false;
Open vSwitch CI d251a9
     int err;
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
+    info.tc_modify_flow_deleted = false;
Open vSwitch CI d251a9
     if (put->flags & DPIF_FP_PROBE) {
Open vSwitch CI d251a9
         return EOPNOTSUPP;
Open vSwitch CI d251a9
     }
Open vSwitch CI d251a9
@@ -2105,7 +2106,6 @@ parse_flow_put(struct dpif_netlink *dpif, struct dpif_flow_put *put)
Open vSwitch CI d251a9
     info.tunnel_csum_on = csum_on;
Open vSwitch CI d251a9
     info.recirc_id_shared_with_tc = (dpif->user_features
Open vSwitch CI d251a9
                                      & OVS_DP_F_TC_RECIRC_SHARING);
Open vSwitch CI d251a9
-    info.tc_modify_flow_deleted = false;
Open vSwitch CI d251a9
     err = netdev_flow_put(dev, &match,
Open vSwitch CI d251a9
                           CONST_CAST(struct nlattr *, put->actions),
Open vSwitch CI d251a9
                           put->actions_len,
Open vSwitch CI d251a9
diff --git a/lib/dpif.c b/lib/dpif.c
Open vSwitch CI d251a9
index 56d0b4a654..26e8bfb7db 100644
Open vSwitch CI d251a9
--- a/lib/dpif.c
Open vSwitch CI d251a9
+++ b/lib/dpif.c
Open vSwitch CI d251a9
@@ -1240,6 +1240,7 @@ dpif_execute_helper_cb(void *aux_, struct dp_packet_batch *packets_,
Open vSwitch CI d251a9
         execute.needs_help = false;
Open vSwitch CI d251a9
         execute.probe = false;
Open vSwitch CI d251a9
         execute.mtu = 0;
Open vSwitch CI d251a9
+        execute.hash = 0;
Open vSwitch CI d251a9
         aux->error = dpif_execute(aux->dpif, &execute);
Open vSwitch CI d251a9
         log_execute_message(aux->dpif, &this_module, &execute,
Open vSwitch CI d251a9
                             true, aux->error);
Open vSwitch CI d251a9
diff --git a/lib/dpif.h b/lib/dpif.h
Open vSwitch CI d251a9
index ecda896c78..f9728e6739 100644
Open vSwitch CI d251a9
--- a/lib/dpif.h
Open vSwitch CI d251a9
+++ b/lib/dpif.h
Open vSwitch CI d251a9
@@ -727,7 +727,7 @@ struct dpif_execute {
Open vSwitch CI d251a9
     bool probe;                     /* Suppress error messages. */
Open vSwitch CI d251a9
     unsigned int mtu;               /* Maximum transmission unit to fragment.
Open vSwitch CI d251a9
                                        0 if not a fragmented packet */
Open vSwitch CI d251a9
-    uint64_t hash;
Open vSwitch CI d251a9
+    uint64_t hash;                  /* Packet flow hash. 0 if not specified. */
Open vSwitch CI d251a9
     const struct flow *flow;         /* Flow extracted from 'packet'. */
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
     /* Input, but possibly modified as a side effect of execution. */
Open vSwitch CI fe1a04
diff --git a/lib/netdev-linux.c b/lib/netdev-linux.c
Open vSwitch CI b3acf0
index 6be23dbeed..f87a200756 100644
Open vSwitch CI fe1a04
--- a/lib/netdev-linux.c
Open vSwitch CI fe1a04
+++ b/lib/netdev-linux.c
Open vSwitch CI fe1a04
@@ -1255,21 +1255,21 @@ netdev_linux_batch_rxq_recv_sock(struct netdev_rxq_linux *rx, int mtu,
Open vSwitch CI fe1a04
      * aux_buf is allocated so that it can be prepended to TSO buffer. */
Open vSwitch CI fe1a04
     std_len = virtio_net_hdr_size + VLAN_ETH_HEADER_LEN + mtu;
Open vSwitch CI fe1a04
     for (i = 0; i < NETDEV_MAX_BURST; i++) {
Open vSwitch CI fe1a04
-         buffers[i] = dp_packet_new_with_headroom(std_len, DP_NETDEV_HEADROOM);
Open vSwitch CI fe1a04
-         iovs[i][IOV_PACKET].iov_base = dp_packet_data(buffers[i]);
Open vSwitch CI fe1a04
-         iovs[i][IOV_PACKET].iov_len = std_len;
Open vSwitch CI fe1a04
-         if (iovlen == IOV_TSO_SIZE) {
Open vSwitch CI fe1a04
-             iovs[i][IOV_AUXBUF].iov_base = dp_packet_data(rx->aux_bufs[i]);
Open vSwitch CI fe1a04
-             iovs[i][IOV_AUXBUF].iov_len = dp_packet_tailroom(rx->aux_bufs[i]);
Open vSwitch CI fe1a04
-         }
Open vSwitch CI fe1a04
+        buffers[i] = dp_packet_new_with_headroom(std_len, DP_NETDEV_HEADROOM);
Open vSwitch CI fe1a04
+        iovs[i][IOV_PACKET].iov_base = dp_packet_data(buffers[i]);
Open vSwitch CI fe1a04
+        iovs[i][IOV_PACKET].iov_len = std_len;
Open vSwitch CI fe1a04
+        if (iovlen == IOV_TSO_SIZE) {
Open vSwitch CI fe1a04
+            iovs[i][IOV_AUXBUF].iov_base = dp_packet_data(rx->aux_bufs[i]);
Open vSwitch CI fe1a04
+            iovs[i][IOV_AUXBUF].iov_len = dp_packet_tailroom(rx->aux_bufs[i]);
Open vSwitch CI fe1a04
+        }
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
-         mmsgs[i].msg_hdr.msg_name = NULL;
Open vSwitch CI fe1a04
-         mmsgs[i].msg_hdr.msg_namelen = 0;
Open vSwitch CI fe1a04
-         mmsgs[i].msg_hdr.msg_iov = iovs[i];
Open vSwitch CI fe1a04
-         mmsgs[i].msg_hdr.msg_iovlen = iovlen;
Open vSwitch CI fe1a04
-         mmsgs[i].msg_hdr.msg_control = &cmsg_buffers[i];
Open vSwitch CI fe1a04
-         mmsgs[i].msg_hdr.msg_controllen = sizeof cmsg_buffers[i];
Open vSwitch CI fe1a04
-         mmsgs[i].msg_hdr.msg_flags = 0;
Open vSwitch CI fe1a04
+        mmsgs[i].msg_hdr.msg_name = NULL;
Open vSwitch CI fe1a04
+        mmsgs[i].msg_hdr.msg_namelen = 0;
Open vSwitch CI fe1a04
+        mmsgs[i].msg_hdr.msg_iov = iovs[i];
Open vSwitch CI fe1a04
+        mmsgs[i].msg_hdr.msg_iovlen = iovlen;
Open vSwitch CI fe1a04
+        mmsgs[i].msg_hdr.msg_control = &cmsg_buffers[i];
Open vSwitch CI fe1a04
+        mmsgs[i].msg_hdr.msg_controllen = sizeof cmsg_buffers[i];
Open vSwitch CI fe1a04
+        mmsgs[i].msg_hdr.msg_flags = 0;
Open vSwitch CI fe1a04
     }
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     do {
Open vSwitch CI b3acf0
@@ -2572,7 +2572,7 @@ exit:
Open vSwitch CI b3acf0
 static struct tc_police
Open vSwitch CI b3acf0
 tc_matchall_fill_police(uint32_t kbits_rate, uint32_t kbits_burst)
Open vSwitch CI b3acf0
 {
Open vSwitch CI b3acf0
-    unsigned int bsize = MIN(UINT32_MAX / 1024, kbits_burst) * 1024 / 64;
Open vSwitch CI b3acf0
+    unsigned int bsize = MIN(UINT32_MAX / 1024, kbits_burst) * 1024 / 8;
Open vSwitch CI b3acf0
     unsigned int bps = ((uint64_t) kbits_rate * 1000) / 8;
Open vSwitch CI b3acf0
     struct tc_police police;
Open vSwitch CI b3acf0
     struct tc_ratespec rate;
Open vSwitch CI d251a9
diff --git a/lib/netdev-offload-tc.c b/lib/netdev-offload-tc.c
Open vSwitch CI d251a9
index 72b7915052..7656427845 100644
Open vSwitch CI d251a9
--- a/lib/netdev-offload-tc.c
Open vSwitch CI d251a9
+++ b/lib/netdev-offload-tc.c
Open vSwitch CI d251a9
@@ -48,6 +48,7 @@ static struct hmap ufid_to_tc = HMAP_INITIALIZER(&ufid_to_tc);
Open vSwitch CI d251a9
 static struct hmap tc_to_ufid = HMAP_INITIALIZER(&tc_to_ufid);
Open vSwitch CI d251a9
 static bool multi_mask_per_prio = false;
Open vSwitch CI d251a9
 static bool block_support = false;
Open vSwitch CI d251a9
+static uint16_t ct_state_support;
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
 struct netlink_field {
Open vSwitch CI d251a9
     int offset;
Open vSwitch CI d251a9
@@ -676,6 +677,27 @@ parse_tc_flower_to_match(struct tc_flower *flower,
Open vSwitch CI d251a9
                 ct_statem |= OVS_CS_F_TRACKED;
Open vSwitch CI d251a9
             }
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
+            if (mask->ct_state & TCA_FLOWER_KEY_CT_FLAGS_REPLY) {
Open vSwitch CI d251a9
+                if (key->ct_state & TCA_FLOWER_KEY_CT_FLAGS_REPLY) {
Open vSwitch CI d251a9
+                    ct_statev |= OVS_CS_F_REPLY_DIR;
Open vSwitch CI d251a9
+                }
Open vSwitch CI d251a9
+                ct_statem |= OVS_CS_F_REPLY_DIR;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+            if (mask->ct_state & TCA_FLOWER_KEY_CT_FLAGS_INVALID) {
Open vSwitch CI d251a9
+                if (key->ct_state & TCA_FLOWER_KEY_CT_FLAGS_INVALID) {
Open vSwitch CI d251a9
+                    ct_statev |= OVS_CS_F_INVALID;
Open vSwitch CI d251a9
+                }
Open vSwitch CI d251a9
+                ct_statem |= OVS_CS_F_INVALID;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+            if (mask->ct_state & TCA_FLOWER_KEY_CT_FLAGS_RELATED) {
Open vSwitch CI d251a9
+                if (key->ct_state & TCA_FLOWER_KEY_CT_FLAGS_RELATED) {
Open vSwitch CI d251a9
+                    ct_statev |= OVS_CS_F_RELATED;
Open vSwitch CI d251a9
+                }
Open vSwitch CI d251a9
+                ct_statem |= OVS_CS_F_RELATED;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
             match_set_ct_state_masked(match, ct_statev, ct_statem);
Open vSwitch CI d251a9
         }
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
@@ -1406,6 +1428,90 @@ flower_match_to_tun_opt(struct tc_flower *flower, const struct flow_tnl *tnl,
Open vSwitch CI d251a9
     flower->mask.tunnel.metadata.present.len = tnl->metadata.present.len;
Open vSwitch CI d251a9
 }
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
+static void
Open vSwitch CI d251a9
+parse_match_ct_state_to_flower(struct tc_flower *flower, struct match *match)
Open vSwitch CI d251a9
+{
Open vSwitch CI d251a9
+    const struct flow *key = &match->flow;
Open vSwitch CI d251a9
+    struct flow *mask = &match->wc.masks;
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    if (!ct_state_support) {
Open vSwitch CI d251a9
+        return;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    if ((ct_state_support & mask->ct_state) == mask->ct_state) {
Open vSwitch CI d251a9
+        if (mask->ct_state & OVS_CS_F_NEW) {
Open vSwitch CI d251a9
+            if (key->ct_state & OVS_CS_F_NEW) {
Open vSwitch CI d251a9
+                flower->key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+            flower->mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW;
Open vSwitch CI d251a9
+            mask->ct_state &= ~OVS_CS_F_NEW;
Open vSwitch CI d251a9
+        }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+        if (mask->ct_state & OVS_CS_F_ESTABLISHED) {
Open vSwitch CI d251a9
+            if (key->ct_state & OVS_CS_F_ESTABLISHED) {
Open vSwitch CI d251a9
+                flower->key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+            flower->mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED;
Open vSwitch CI d251a9
+            mask->ct_state &= ~OVS_CS_F_ESTABLISHED;
Open vSwitch CI d251a9
+        }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+        if (mask->ct_state & OVS_CS_F_TRACKED) {
Open vSwitch CI d251a9
+            if (key->ct_state & OVS_CS_F_TRACKED) {
Open vSwitch CI d251a9
+                flower->key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+            flower->mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED;
Open vSwitch CI d251a9
+            mask->ct_state &= ~OVS_CS_F_TRACKED;
Open vSwitch CI d251a9
+        }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+        if (mask->ct_state & OVS_CS_F_REPLY_DIR) {
Open vSwitch CI d251a9
+            if (key->ct_state & OVS_CS_F_REPLY_DIR) {
Open vSwitch CI d251a9
+                flower->key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_REPLY;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+            flower->mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_REPLY;
Open vSwitch CI d251a9
+            mask->ct_state &= ~OVS_CS_F_REPLY_DIR;
Open vSwitch CI d251a9
+        }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+        if (mask->ct_state & OVS_CS_F_INVALID) {
Open vSwitch CI d251a9
+            if (key->ct_state & OVS_CS_F_INVALID) {
Open vSwitch CI d251a9
+                flower->key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_INVALID;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+            flower->mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_INVALID;
Open vSwitch CI d251a9
+            mask->ct_state &= ~OVS_CS_F_INVALID;
Open vSwitch CI d251a9
+        }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+        if (mask->ct_state & OVS_CS_F_RELATED) {
Open vSwitch CI d251a9
+            if (key->ct_state & OVS_CS_F_RELATED) {
Open vSwitch CI d251a9
+                flower->key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_RELATED;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+            flower->mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_RELATED;
Open vSwitch CI d251a9
+            mask->ct_state &= ~OVS_CS_F_RELATED;
Open vSwitch CI d251a9
+        }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+        if (flower->key.ct_state & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED) {
Open vSwitch CI d251a9
+            flower->key.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW);
Open vSwitch CI d251a9
+            flower->mask.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW);
Open vSwitch CI d251a9
+        }
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    if (mask->ct_zone) {
Open vSwitch CI d251a9
+        flower->key.ct_zone = key->ct_zone;
Open vSwitch CI d251a9
+        flower->mask.ct_zone = mask->ct_zone;
Open vSwitch CI d251a9
+        mask->ct_zone = 0;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    if (mask->ct_mark) {
Open vSwitch CI d251a9
+        flower->key.ct_mark = key->ct_mark;
Open vSwitch CI d251a9
+        flower->mask.ct_mark = mask->ct_mark;
Open vSwitch CI d251a9
+        mask->ct_mark = 0;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    if (!ovs_u128_is_zero(mask->ct_label)) {
Open vSwitch CI d251a9
+        flower->key.ct_label = key->ct_label;
Open vSwitch CI d251a9
+        flower->mask.ct_label = mask->ct_label;
Open vSwitch CI d251a9
+        mask->ct_label = OVS_U128_ZERO;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+}
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
 static int
Open vSwitch CI d251a9
 netdev_tc_flow_put(struct netdev *netdev, struct match *match,
Open vSwitch CI d251a9
                    struct nlattr *actions, size_t actions_len,
Open vSwitch CI d251a9
@@ -1650,54 +1756,7 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
Open vSwitch CI d251a9
         }
Open vSwitch CI d251a9
     }
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
-    if (mask->ct_state) {
Open vSwitch CI d251a9
-        if (mask->ct_state & OVS_CS_F_NEW) {
Open vSwitch CI d251a9
-            if (key->ct_state & OVS_CS_F_NEW) {
Open vSwitch CI d251a9
-                flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW;
Open vSwitch CI d251a9
-            }
Open vSwitch CI d251a9
-            flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_NEW;
Open vSwitch CI d251a9
-            mask->ct_state &= ~OVS_CS_F_NEW;
Open vSwitch CI d251a9
-        }
Open vSwitch CI d251a9
-
Open vSwitch CI d251a9
-        if (mask->ct_state & OVS_CS_F_ESTABLISHED) {
Open vSwitch CI d251a9
-            if (key->ct_state & OVS_CS_F_ESTABLISHED) {
Open vSwitch CI d251a9
-                flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED;
Open vSwitch CI d251a9
-            }
Open vSwitch CI d251a9
-            flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED;
Open vSwitch CI d251a9
-            mask->ct_state &= ~OVS_CS_F_ESTABLISHED;
Open vSwitch CI d251a9
-        }
Open vSwitch CI d251a9
-
Open vSwitch CI d251a9
-        if (mask->ct_state & OVS_CS_F_TRACKED) {
Open vSwitch CI d251a9
-            if (key->ct_state & OVS_CS_F_TRACKED) {
Open vSwitch CI d251a9
-                flower.key.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED;
Open vSwitch CI d251a9
-            }
Open vSwitch CI d251a9
-            flower.mask.ct_state |= TCA_FLOWER_KEY_CT_FLAGS_TRACKED;
Open vSwitch CI d251a9
-            mask->ct_state &= ~OVS_CS_F_TRACKED;
Open vSwitch CI d251a9
-        }
Open vSwitch CI d251a9
-
Open vSwitch CI d251a9
-        if (flower.key.ct_state & TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED) {
Open vSwitch CI d251a9
-            flower.key.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW);
Open vSwitch CI d251a9
-            flower.mask.ct_state &= ~(TCA_FLOWER_KEY_CT_FLAGS_NEW);
Open vSwitch CI d251a9
-        }
Open vSwitch CI d251a9
-    }
Open vSwitch CI d251a9
-
Open vSwitch CI d251a9
-    if (mask->ct_zone) {
Open vSwitch CI d251a9
-        flower.key.ct_zone = key->ct_zone;
Open vSwitch CI d251a9
-        flower.mask.ct_zone = mask->ct_zone;
Open vSwitch CI d251a9
-        mask->ct_zone = 0;
Open vSwitch CI d251a9
-    }
Open vSwitch CI d251a9
-
Open vSwitch CI d251a9
-    if (mask->ct_mark) {
Open vSwitch CI d251a9
-        flower.key.ct_mark = key->ct_mark;
Open vSwitch CI d251a9
-        flower.mask.ct_mark = mask->ct_mark;
Open vSwitch CI d251a9
-        mask->ct_mark = 0;
Open vSwitch CI d251a9
-    }
Open vSwitch CI d251a9
-
Open vSwitch CI d251a9
-    if (!ovs_u128_is_zero(mask->ct_label)) {
Open vSwitch CI d251a9
-        flower.key.ct_label = key->ct_label;
Open vSwitch CI d251a9
-        flower.mask.ct_label = mask->ct_label;
Open vSwitch CI d251a9
-        mask->ct_label = OVS_U128_ZERO;
Open vSwitch CI d251a9
-    }
Open vSwitch CI d251a9
+    parse_match_ct_state_to_flower(&flower, match);
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
     /* ignore exact match on skb_mark of 0. */
Open vSwitch CI d251a9
     if (mask->pkt_mark == UINT32_MAX && !key->pkt_mark) {
Open vSwitch CI d251a9
@@ -1779,6 +1838,10 @@ netdev_tc_flow_put(struct netdev *netdev, struct match *match,
Open vSwitch CI d251a9
             const struct nlattr *ct = nl_attr_get(nla);
Open vSwitch CI d251a9
             const size_t ct_len = nl_attr_get_size(nla);
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
+            if (!ct_state_support) {
Open vSwitch CI d251a9
+                return -EOPNOTSUPP;
Open vSwitch CI d251a9
+            }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
             err = parse_put_flow_ct_action(&flower, action, ct, ct_len);
Open vSwitch CI d251a9
             if (err) {
Open vSwitch CI d251a9
                 return err;
Open vSwitch CI d251a9
@@ -1971,6 +2034,96 @@ out:
Open vSwitch CI d251a9
     tc_add_del_qdisc(ifindex, false, block_id, TC_INGRESS);
Open vSwitch CI d251a9
 }
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+static int
Open vSwitch CI d251a9
+probe_insert_ct_state_rule(int ifindex, uint16_t ct_state, struct tcf_id *id)
Open vSwitch CI d251a9
+{
Open vSwitch CI d251a9
+    int prio = TC_RESERVED_PRIORITY_MAX + 1;
Open vSwitch CI d251a9
+    struct tc_flower flower;
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    memset(&flower, 0, sizeof flower);
Open vSwitch CI d251a9
+    flower.key.ct_state = ct_state;
Open vSwitch CI d251a9
+    flower.mask.ct_state = ct_state;
Open vSwitch CI d251a9
+    flower.tc_policy = TC_POLICY_SKIP_HW;
Open vSwitch CI d251a9
+    flower.key.eth_type = htons(ETH_P_IP);
Open vSwitch CI d251a9
+    flower.mask.eth_type = OVS_BE16_MAX;
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    *id = tc_make_tcf_id(ifindex, 0, prio, TC_INGRESS);
Open vSwitch CI d251a9
+    return tc_replace_flower(id, &flower);
Open vSwitch CI d251a9
+}
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+static void
Open vSwitch CI d251a9
+probe_ct_state_support(int ifindex)
Open vSwitch CI d251a9
+{
Open vSwitch CI d251a9
+    struct tc_flower flower;
Open vSwitch CI d251a9
+    uint16_t ct_state;
Open vSwitch CI d251a9
+    struct tcf_id id;
Open vSwitch CI d251a9
+    int error;
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    error = tc_add_del_qdisc(ifindex, true, 0, TC_INGRESS);
Open vSwitch CI d251a9
+    if (error) {
Open vSwitch CI d251a9
+        return;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    /* Test for base ct_state match support */
Open vSwitch CI d251a9
+    ct_state = TCA_FLOWER_KEY_CT_FLAGS_NEW | TCA_FLOWER_KEY_CT_FLAGS_TRACKED;
Open vSwitch CI d251a9
+    error = probe_insert_ct_state_rule(ifindex, ct_state, &id;;
Open vSwitch CI d251a9
+    if (error) {
Open vSwitch CI d251a9
+        goto out;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    error = tc_get_flower(&id, &flower);
Open vSwitch CI d251a9
+    if (error || flower.mask.ct_state != ct_state) {
Open vSwitch CI d251a9
+        goto out_del;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    tc_del_filter(&id;;
Open vSwitch CI d251a9
+    ct_state_support = OVS_CS_F_NEW |
Open vSwitch CI d251a9
+                       OVS_CS_F_ESTABLISHED |
Open vSwitch CI d251a9
+                       OVS_CS_F_TRACKED |
Open vSwitch CI d251a9
+                       OVS_CS_F_RELATED;
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    /* Test for reject, ct_state >= MAX */
Open vSwitch CI d251a9
+    ct_state = ~0;
Open vSwitch CI d251a9
+    error = probe_insert_ct_state_rule(ifindex, ct_state, &id;;
Open vSwitch CI d251a9
+    if (!error) {
Open vSwitch CI d251a9
+        /* No reject, can't continue probing other flags */
Open vSwitch CI d251a9
+        goto out_del;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    tc_del_filter(&id;;
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    /* Test for ct_state INVALID support */
Open vSwitch CI d251a9
+    memset(&flower, 0, sizeof flower);
Open vSwitch CI d251a9
+    ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
Open vSwitch CI d251a9
+               TCA_FLOWER_KEY_CT_FLAGS_INVALID;
Open vSwitch CI d251a9
+    error = probe_insert_ct_state_rule(ifindex, ct_state, &id;;
Open vSwitch CI d251a9
+    if (error) {
Open vSwitch CI d251a9
+        goto out;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    tc_del_filter(&id;;
Open vSwitch CI d251a9
+    ct_state_support |= OVS_CS_F_INVALID;
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    /* Test for ct_state REPLY support */
Open vSwitch CI d251a9
+    memset(&flower, 0, sizeof flower);
Open vSwitch CI d251a9
+    ct_state = TCA_FLOWER_KEY_CT_FLAGS_TRACKED |
Open vSwitch CI d251a9
+               TCA_FLOWER_KEY_CT_FLAGS_ESTABLISHED |
Open vSwitch CI d251a9
+               TCA_FLOWER_KEY_CT_FLAGS_REPLY;
Open vSwitch CI d251a9
+    error = probe_insert_ct_state_rule(ifindex, ct_state, &id;;
Open vSwitch CI d251a9
+    if (error) {
Open vSwitch CI d251a9
+        goto out;
Open vSwitch CI d251a9
+    }
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+    ct_state_support |= OVS_CS_F_REPLY_DIR;
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
+out_del:
Open vSwitch CI d251a9
+    tc_del_filter(&id;;
Open vSwitch CI d251a9
+out:
Open vSwitch CI d251a9
+    tc_add_del_qdisc(ifindex, false, 0, TC_INGRESS);
Open vSwitch CI d251a9
+    VLOG_INFO("probe tc: supported ovs ct_state bits: 0x%x", ct_state_support);
Open vSwitch CI d251a9
+}
Open vSwitch CI d251a9
+
Open vSwitch CI d251a9
 static void
Open vSwitch CI d251a9
 probe_tc_block_support(int ifindex)
Open vSwitch CI d251a9
 {
Open vSwitch CI d251a9
@@ -2038,6 +2191,7 @@ netdev_tc_init_flow_api(struct netdev *netdev)
Open vSwitch CI d251a9
         block_id = get_block_id_from_netdev(netdev);
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
         probe_multi_mask_per_prio(ifindex);
Open vSwitch CI d251a9
+        probe_ct_state_support(ifindex);
Open vSwitch CI d251a9
         ovsthread_once_done(&once);
Open vSwitch CI d251a9
     }
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
diff --git a/lib/odp-util.c b/lib/odp-util.c
Open vSwitch CI d251a9
index a8598d52af..e1199d1da6 100644
Open vSwitch CI d251a9
--- a/lib/odp-util.c
Open vSwitch CI d251a9
+++ b/lib/odp-util.c
Open vSwitch CI d251a9
@@ -3189,17 +3189,17 @@ tun_key_to_attr(struct ofpbuf *a, const struct flow_tnl *tun_key,
Open vSwitch CI d251a9
     if ((!tnl_type || !strcmp(tnl_type, "erspan") ||
Open vSwitch CI d251a9
         !strcmp(tnl_type, "ip6erspan")) &&
Open vSwitch CI d251a9
         (tun_key->erspan_ver == 1 || tun_key->erspan_ver == 2)) {
Open vSwitch CI d251a9
-        struct erspan_metadata opts;
Open vSwitch CI d251a9
+        struct erspan_metadata *opts;
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
-        opts.version = tun_key->erspan_ver;
Open vSwitch CI d251a9
-        if (opts.version == 1) {
Open vSwitch CI d251a9
-            opts.u.index = htonl(tun_key->erspan_idx);
Open vSwitch CI d251a9
+        opts = nl_msg_put_unspec_zero(a, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS,
Open vSwitch CI d251a9
+                                      sizeof *opts);
Open vSwitch CI d251a9
+        opts->version = tun_key->erspan_ver;
Open vSwitch CI d251a9
+        if (opts->version == 1) {
Open vSwitch CI d251a9
+            opts->u.index = htonl(tun_key->erspan_idx);
Open vSwitch CI d251a9
         } else {
Open vSwitch CI d251a9
-            opts.u.md2.dir = tun_key->erspan_dir;
Open vSwitch CI d251a9
-            set_hwid(&opts.u.md2, tun_key->erspan_hwid);
Open vSwitch CI d251a9
+            opts->u.md2.dir = tun_key->erspan_dir;
Open vSwitch CI d251a9
+            set_hwid(&opts->u.md2, tun_key->erspan_hwid);
Open vSwitch CI d251a9
         }
Open vSwitch CI d251a9
-        nl_msg_put_unspec(a, OVS_TUNNEL_KEY_ATTR_ERSPAN_OPTS,
Open vSwitch CI d251a9
-                          &opts, sizeof(opts));
Open vSwitch CI d251a9
     }
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
     if ((!tnl_type || !strcmp(tnl_type, "gtpu")) &&
Open vSwitch CI fe1a04
diff --git a/lib/ofp-actions.c b/lib/ofp-actions.c
Open vSwitch CI fe1a04
index e2e829772a..0342a228b7 100644
Open vSwitch CI fe1a04
--- a/lib/ofp-actions.c
Open vSwitch CI fe1a04
+++ b/lib/ofp-actions.c
Open vSwitch CI fe1a04
@@ -4431,6 +4431,7 @@ decode_NXAST_RAW_ENCAP(const struct nx_action_encap *nae,
Open vSwitch CI fe1a04
 {
Open vSwitch CI fe1a04
     struct ofpact_encap *encap;
Open vSwitch CI fe1a04
     const struct ofp_ed_prop_header *ofp_prop;
Open vSwitch CI fe1a04
+    const size_t encap_ofs = out->size;
Open vSwitch CI fe1a04
     size_t props_len;
Open vSwitch CI fe1a04
     uint16_t n_props = 0;
Open vSwitch CI fe1a04
     int err;
Open vSwitch CI fe1a04
@@ -4458,6 +4459,7 @@ decode_NXAST_RAW_ENCAP(const struct nx_action_encap *nae,
Open vSwitch CI fe1a04
         }
Open vSwitch CI fe1a04
         n_props++;
Open vSwitch CI fe1a04
     }
Open vSwitch CI fe1a04
+    encap = ofpbuf_at_assert(out, encap_ofs, sizeof *encap);
Open vSwitch CI fe1a04
     encap->n_props = n_props;
Open vSwitch CI fe1a04
     out->header = &encap->ofpact;
Open vSwitch CI fe1a04
     ofpact_finish_ENCAP(out, &encap);
Open vSwitch CI fe1a04
diff --git a/lib/ovsdb-cs.c b/lib/ovsdb-cs.c
Open vSwitch CI fe1a04
index ff8adaefb5..6f9f912ac4 100644
Open vSwitch CI fe1a04
--- a/lib/ovsdb-cs.c
Open vSwitch CI fe1a04
+++ b/lib/ovsdb-cs.c
Open vSwitch CI fe1a04
@@ -1367,7 +1367,7 @@ ovsdb_cs_send_transaction(struct ovsdb_cs *cs, struct json *operations)
Open vSwitch CI fe1a04
                               sizeof *cs->txns);
Open vSwitch CI fe1a04
     }
Open vSwitch CI fe1a04
     cs->txns[cs->n_txns++] = request_id;
Open vSwitch CI fe1a04
-    return request_id;
Open vSwitch CI fe1a04
+    return json_clone(request_id);
Open vSwitch CI fe1a04
 }
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 /* Makes 'cs' drop its record of transaction 'request_id'.  If a reply arrives
Open vSwitch CI fe1a04
@@ -1380,6 +1380,7 @@ ovsdb_cs_forget_transaction(struct ovsdb_cs *cs, const struct json *request_id)
Open vSwitch CI fe1a04
 {
Open vSwitch CI fe1a04
     for (size_t i = 0; i < cs->n_txns; i++) {
Open vSwitch CI fe1a04
         if (json_equal(request_id, cs->txns[i])) {
Open vSwitch CI fe1a04
+            json_destroy(cs->txns[i]);
Open vSwitch CI fe1a04
             cs->txns[i] = cs->txns[--cs->n_txns];
Open vSwitch CI fe1a04
             return true;
Open vSwitch CI fe1a04
         }
Open vSwitch CI 78f366
diff --git a/lib/ovsdb-idl.c b/lib/ovsdb-idl.c
Open vSwitch CI 78f366
index 2c8a0c9cfe..1d385ca2fe 100644
Open vSwitch CI 78f366
--- a/lib/ovsdb-idl.c
Open vSwitch CI 78f366
+++ b/lib/ovsdb-idl.c
Open vSwitch CI 78f366
@@ -92,6 +92,9 @@ struct ovsdb_idl {
Open vSwitch CI 78f366
     struct ovsdb_idl_txn *txn;
Open vSwitch CI 78f366
     struct hmap outstanding_txns;
Open vSwitch CI 78f366
     bool verify_write_only;
Open vSwitch CI 78f366
+    struct ovs_list deleted_untracked_rows; /* Stores rows deleted in the
Open vSwitch CI 78f366
+                                             * current run, that are not yet
Open vSwitch CI 78f366
+                                             * added to the track_list. */
Open vSwitch CI 78f366
 };
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 static struct ovsdb_cs_ops ovsdb_idl_cs_ops;
Open vSwitch CI 78f366
@@ -144,6 +147,7 @@ static bool ovsdb_idl_modify_row(struct ovsdb_idl_row *,
Open vSwitch CI 78f366
                                  const struct shash *values, bool xor);
Open vSwitch CI 78f366
 static void ovsdb_idl_parse_update(struct ovsdb_idl *,
Open vSwitch CI 78f366
                                    const struct ovsdb_cs_update_event *);
Open vSwitch CI 78f366
+static void ovsdb_idl_reparse_deleted(struct ovsdb_idl *);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 static void ovsdb_idl_txn_process_reply(struct ovsdb_idl *,
Open vSwitch CI 78f366
                                         const struct jsonrpc_msg *);
Open vSwitch CI 78f366
@@ -163,6 +167,10 @@ static void ovsdb_idl_row_unparse(struct ovsdb_idl_row *);
Open vSwitch CI 78f366
 static void ovsdb_idl_row_clear_old(struct ovsdb_idl_row *);
Open vSwitch CI 78f366
 static void ovsdb_idl_row_clear_new(struct ovsdb_idl_row *);
Open vSwitch CI 78f366
 static void ovsdb_idl_row_clear_arcs(struct ovsdb_idl_row *, bool destroy_dsts);
Open vSwitch CI 78f366
+static void ovsdb_idl_row_reparse_backrefs(struct ovsdb_idl_row *);
Open vSwitch CI 78f366
+static void ovsdb_idl_row_track_change(struct ovsdb_idl_row *,
Open vSwitch CI 78f366
+                                       enum ovsdb_idl_change);
Open vSwitch CI 78f366
+static void ovsdb_idl_row_untrack_change(struct ovsdb_idl_row *);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 static void ovsdb_idl_txn_abort_all(struct ovsdb_idl *);
Open vSwitch CI 78f366
 static bool ovsdb_idl_txn_extract_mutations(struct ovsdb_idl_row *,
Open vSwitch CI 78f366
@@ -182,7 +190,6 @@ ovsdb_idl_table_from_class(const struct ovsdb_idl *,
Open vSwitch CI 78f366
 static struct ovsdb_idl_table *
Open vSwitch CI 78f366
 ovsdb_idl_table_from_class(const struct ovsdb_idl *,
Open vSwitch CI 78f366
                            const struct ovsdb_idl_table_class *);
Open vSwitch CI 78f366
-static bool ovsdb_idl_track_is_set(struct ovsdb_idl_table *table);
Open vSwitch CI 78f366
 static void ovsdb_idl_track_clear__(struct ovsdb_idl *, bool flush_all);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 static void ovsdb_idl_destroy_indexes(struct ovsdb_idl_table *);
Open vSwitch CI 78f366
@@ -191,6 +198,8 @@ static void ovsdb_idl_remove_from_indexes(const struct ovsdb_idl_row *);
Open vSwitch CI 78f366
 static int ovsdb_idl_try_commit_loop_txn(struct ovsdb_idl_loop *loop,
Open vSwitch CI 78f366
                                          bool *may_need_wakeup);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+static void add_tracked_change_for_references(struct ovsdb_idl_row *);
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
 /* Creates and returns a connection to database 'remote', which should be in a
Open vSwitch CI 78f366
  * form acceptable to jsonrpc_session_open().  The connection will maintain an
Open vSwitch CI 78f366
  * in-memory replica of the remote database whose schema is described by
Open vSwitch CI 78f366
@@ -249,6 +258,8 @@ ovsdb_idl_create_unconnected(const struct ovsdb_idl_class *class,
Open vSwitch CI 78f366
         .txn = NULL,
Open vSwitch CI 78f366
         .outstanding_txns = HMAP_INITIALIZER(&idl->outstanding_txns),
Open vSwitch CI 78f366
         .verify_write_only = false,
Open vSwitch CI 78f366
+        .deleted_untracked_rows
Open vSwitch CI 78f366
+            = OVS_LIST_INITIALIZER(&idl->deleted_untracked_rows),
Open vSwitch CI 78f366
     };
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     uint8_t default_mode = (monitor_everything_by_default
Open vSwitch CI 78f366
@@ -352,6 +363,14 @@ ovsdb_idl_set_leader_only(struct ovsdb_idl *idl, bool leader_only)
Open vSwitch CI 78f366
 static void
Open vSwitch CI 78f366
 ovsdb_idl_clear(struct ovsdb_idl *db)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
+    /* Process deleted rows, removing them from the 'deleted_untracked_rows'
Open vSwitch CI 78f366
+     * list and reparsing their backrefs.
Open vSwitch CI 78f366
+     */
Open vSwitch CI 78f366
+    ovsdb_idl_reparse_deleted(db);
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    /* Cleanup all rows; each row gets added to its own table's
Open vSwitch CI 78f366
+     * 'track_list'.
Open vSwitch CI 78f366
+     */
Open vSwitch CI 78f366
     for (size_t i = 0; i < db->class_->n_tables; i++) {
Open vSwitch CI 78f366
         struct ovsdb_idl_table *table = &db->tables[i];
Open vSwitch CI 78f366
         struct ovsdb_idl_row *row, *next_row;
Open vSwitch CI 78f366
@@ -368,17 +387,26 @@ ovsdb_idl_clear(struct ovsdb_idl *db)
Open vSwitch CI 78f366
                 ovsdb_idl_row_unparse(row);
Open vSwitch CI 78f366
             }
Open vSwitch CI 78f366
             LIST_FOR_EACH_SAFE (arc, next_arc, src_node, &row->src_arcs) {
Open vSwitch CI 78f366
+                ovs_list_remove(&arc->src_node);
Open vSwitch CI 78f366
+                ovs_list_remove(&arc->dst_node);
Open vSwitch CI 78f366
+                free(arc);
Open vSwitch CI 78f366
+            }
Open vSwitch CI 78f366
+            LIST_FOR_EACH_SAFE (arc, next_arc, dst_node, &row->dst_arcs) {
Open vSwitch CI 78f366
+                ovs_list_remove(&arc->src_node);
Open vSwitch CI 78f366
+                ovs_list_remove(&arc->dst_node);
Open vSwitch CI 78f366
                 free(arc);
Open vSwitch CI 78f366
             }
Open vSwitch CI 78f366
-            /* No need to do anything with dst_arcs: some node has those arcs
Open vSwitch CI 78f366
-             * as forward arcs and will destroy them itself. */
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
             ovsdb_idl_row_destroy(row);
Open vSwitch CI 78f366
         }
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    /* Free rows deleted from tables with change tracking disabled. */
Open vSwitch CI 78f366
     ovsdb_idl_row_destroy_postprocess(db);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+    /* Free rows deleted from tables with change tracking enabled. */
Open vSwitch CI 78f366
     ovsdb_idl_track_clear__(db, true);
Open vSwitch CI 78f366
+    ovs_assert(ovs_list_is_empty(&db->deleted_untracked_rows));
Open vSwitch CI 78f366
     db->change_seqno++;
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -416,7 +444,7 @@ ovsdb_idl_run(struct ovsdb_idl *idl)
Open vSwitch CI 78f366
         }
Open vSwitch CI 78f366
         ovsdb_cs_event_destroy(event);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
-
Open vSwitch CI 78f366
+    ovsdb_idl_reparse_deleted(idl);
Open vSwitch CI 78f366
     ovsdb_idl_row_destroy_postprocess(idl);
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1140,7 +1168,7 @@ ovsdb_idl_track_add_all(struct ovsdb_idl *idl)
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 /* Returns true if 'table' has any tracked column. */
Open vSwitch CI 78f366
-static bool
Open vSwitch CI 78f366
+bool
Open vSwitch CI 78f366
 ovsdb_idl_track_is_set(struct ovsdb_idl_table *table)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
     size_t i;
Open vSwitch CI 78f366
@@ -1227,13 +1255,8 @@ ovsdb_idl_track_clear__(struct ovsdb_idl *idl, bool flush_all)
Open vSwitch CI 78f366
                     free(row->updated);
Open vSwitch CI 78f366
                     row->updated = NULL;
Open vSwitch CI 78f366
                 }
Open vSwitch CI 78f366
+                ovsdb_idl_row_untrack_change(row);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
-                row->change_seqno[OVSDB_IDL_CHANGE_INSERT] =
Open vSwitch CI 78f366
-                    row->change_seqno[OVSDB_IDL_CHANGE_MODIFY] =
Open vSwitch CI 78f366
-                    row->change_seqno[OVSDB_IDL_CHANGE_DELETE] = 0;
Open vSwitch CI 78f366
-
Open vSwitch CI 78f366
-                ovs_list_remove(&row->track_node);
Open vSwitch CI 78f366
-                ovs_list_init(&row->track_node);
Open vSwitch CI 78f366
                 if (ovsdb_idl_row_is_orphan(row)) {
Open vSwitch CI 78f366
                     ovsdb_idl_row_unparse(row);
Open vSwitch CI 78f366
                     if (row->tracked_old_datum) {
Open vSwitch CI 78f366
@@ -1351,6 +1374,33 @@ ovsdb_idl_parse_update(struct ovsdb_idl *idl,
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+/* Reparses references to rows that have been deleted in the current IDL run.
Open vSwitch CI 78f366
+ *
Open vSwitch CI 78f366
+ * To ensure that reference sources that are deleted are not reparsed,
Open vSwitch CI 78f366
+ * this function must be called after all updates have been processed in
Open vSwitch CI 78f366
+ * the current IDL run, i.e., after all calls to ovsdb_idl_parse_update().
Open vSwitch CI 78f366
+ */
Open vSwitch CI 78f366
+static void
Open vSwitch CI 78f366
+ovsdb_idl_reparse_deleted(struct ovsdb_idl *db)
Open vSwitch CI 78f366
+{
Open vSwitch CI 78f366
+    struct ovsdb_idl_row *row, *next;
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    LIST_FOR_EACH_SAFE (row, next, track_node, &db->deleted_untracked_rows) {
Open vSwitch CI 78f366
+        ovsdb_idl_row_untrack_change(row);
Open vSwitch CI 78f366
+        add_tracked_change_for_references(row);
Open vSwitch CI 78f366
+        ovsdb_idl_row_reparse_backrefs(row);
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+        /* Orphan rows that are still unreferenced or are part of tables that
Open vSwitch CI 78f366
+         * have change tracking enabled should be added to their table's
Open vSwitch CI 78f366
+         * 'track_list'.
Open vSwitch CI 78f366
+         */
Open vSwitch CI 78f366
+        if (ovs_list_is_empty(&row->dst_arcs)
Open vSwitch CI 78f366
+                || ovsdb_idl_track_is_set(row->table)) {
Open vSwitch CI 78f366
+            ovsdb_idl_row_track_change(row, OVSDB_IDL_CHANGE_DELETE);
Open vSwitch CI 78f366
+        }
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+}
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
 static struct ovsdb_idl_row *
Open vSwitch CI 78f366
 ovsdb_idl_get_row(struct ovsdb_idl_table *table, const struct uuid *uuid)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
@@ -1404,6 +1454,7 @@ ovsdb_idl_process_update(struct ovsdb_idl_table *table,
Open vSwitch CI 78f366
             ovsdb_idl_insert_row(ovsdb_idl_row_create(table, uuid),
Open vSwitch CI 78f366
                                  ru->columns);
Open vSwitch CI 78f366
         } else if (ovsdb_idl_row_is_orphan(row)) {
Open vSwitch CI 78f366
+            ovsdb_idl_row_untrack_change(row);
Open vSwitch CI 78f366
             ovsdb_idl_insert_row(row, ru->columns);
Open vSwitch CI 78f366
         } else {
Open vSwitch CI 78f366
             VLOG_ERR_RL(&semantic_rl, "cannot add existing row "UUID_FMT" to "
Open vSwitch CI 78f366
@@ -1451,13 +1502,8 @@ add_tracked_change_for_references(struct ovsdb_idl_row *row)
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
         if (ovs_list_is_empty(&ref->track_node) &&
Open vSwitch CI 78f366
             ovsdb_idl_track_is_set(ref->table)) {
Open vSwitch CI 78f366
-                ovs_list_push_back(&ref->table->track_list,
Open vSwitch CI 78f366
-                                   &ref->track_node);
Open vSwitch CI 78f366
-
Open vSwitch CI 78f366
-            ref->change_seqno[OVSDB_IDL_CHANGE_MODIFY]
Open vSwitch CI 78f366
-                = ref->table->change_seqno[OVSDB_IDL_CHANGE_MODIFY]
Open vSwitch CI 78f366
-                = ref->table->idl->change_seqno + 1;
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+            ovsdb_idl_row_track_change(ref, OVSDB_IDL_CHANGE_MODIFY);
Open vSwitch CI 78f366
             add_tracked_change_for_references(ref);
Open vSwitch CI 78f366
         }
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
@@ -2023,6 +2069,32 @@ ovsdb_idl_row_reparse_backrefs(struct ovsdb_idl_row *row)
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+static void
Open vSwitch CI 78f366
+ovsdb_idl_row_track_change(struct ovsdb_idl_row *row,
Open vSwitch CI 78f366
+                           enum ovsdb_idl_change change)
Open vSwitch CI 78f366
+{
Open vSwitch CI 78f366
+    row->change_seqno[change]
Open vSwitch CI 78f366
+        = row->table->change_seqno[change]
Open vSwitch CI 78f366
+        = row->table->idl->change_seqno + 1;
Open vSwitch CI 78f366
+    if (ovs_list_is_empty(&row->track_node)) {
Open vSwitch CI 78f366
+        ovs_list_push_back(&row->table->track_list, &row->track_node);
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+}
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+static void
Open vSwitch CI 78f366
+ovsdb_idl_row_untrack_change(struct ovsdb_idl_row *row)
Open vSwitch CI 78f366
+{
Open vSwitch CI 78f366
+    if (ovs_list_is_empty(&row->track_node)) {
Open vSwitch CI 78f366
+        return;
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    row->change_seqno[OVSDB_IDL_CHANGE_INSERT] =
Open vSwitch CI 78f366
+        row->change_seqno[OVSDB_IDL_CHANGE_MODIFY] =
Open vSwitch CI 78f366
+        row->change_seqno[OVSDB_IDL_CHANGE_DELETE] = 0;
Open vSwitch CI 78f366
+    ovs_list_remove(&row->track_node);
Open vSwitch CI 78f366
+    ovs_list_init(&row->track_node);
Open vSwitch CI 78f366
+}
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
 static struct ovsdb_idl_row *
Open vSwitch CI 78f366
 ovsdb_idl_row_create__(const struct ovsdb_idl_table_class *class)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
@@ -2049,22 +2121,26 @@ ovsdb_idl_row_create(struct ovsdb_idl_table *table, const struct uuid *uuid)
Open vSwitch CI 78f366
     return row;
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+/* If 'row' is not referenced anymore, removes 'row' from the table hmap,
Open vSwitch CI 78f366
+ * clears the old datum and adds 'row' to the table's track_list.
Open vSwitch CI 78f366
+ *
Open vSwitch CI 78f366
+ * If 'row' is still referenced, i.e., became "orphan", queues 'row' for
Open vSwitch CI 78f366
+ * reparsing after all updates have been processed by adding it to the
Open vSwitch CI 78f366
+ * 'deleted_untracked_rows' list.
Open vSwitch CI 78f366
+ */
Open vSwitch CI 78f366
 static void
Open vSwitch CI 78f366
 ovsdb_idl_row_destroy(struct ovsdb_idl_row *row)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
-    if (row) {
Open vSwitch CI 78f366
-        ovsdb_idl_row_clear_old(row);
Open vSwitch CI 78f366
+    ovsdb_idl_row_clear_old(row);
Open vSwitch CI 78f366
+    if (ovs_list_is_empty(&row->dst_arcs)) {
Open vSwitch CI 78f366
         hmap_remove(&row->table->rows, &row->hmap_node);
Open vSwitch CI 78f366
         ovsdb_idl_destroy_all_map_op_lists(row);
Open vSwitch CI 78f366
         ovsdb_idl_destroy_all_set_op_lists(row);
Open vSwitch CI 78f366
-        if (ovsdb_idl_track_is_set(row->table)) {
Open vSwitch CI 78f366
-            row->change_seqno[OVSDB_IDL_CHANGE_DELETE]
Open vSwitch CI 78f366
-                = row->table->change_seqno[OVSDB_IDL_CHANGE_DELETE]
Open vSwitch CI 78f366
-                = row->table->idl->change_seqno + 1;
Open vSwitch CI 78f366
-        }
Open vSwitch CI 78f366
-        if (ovs_list_is_empty(&row->track_node)) {
Open vSwitch CI 78f366
-            ovs_list_push_back(&row->table->track_list, &row->track_node);
Open vSwitch CI 78f366
-        }
Open vSwitch CI 78f366
+        ovsdb_idl_row_track_change(row, OVSDB_IDL_CHANGE_DELETE);
Open vSwitch CI 78f366
+    } else {
Open vSwitch CI 78f366
+        ovsdb_idl_row_untrack_change(row);
Open vSwitch CI 78f366
+        ovs_list_push_back(&row->table->idl->deleted_untracked_rows,
Open vSwitch CI 78f366
+                           &row->track_node);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -2154,12 +2230,7 @@ ovsdb_idl_delete_row(struct ovsdb_idl_row *row)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
     ovsdb_idl_remove_from_indexes(row);
Open vSwitch CI 78f366
     ovsdb_idl_row_clear_arcs(row, true);
Open vSwitch CI 78f366
-    ovsdb_idl_row_clear_old(row);
Open vSwitch CI 78f366
-    if (ovs_list_is_empty(&row->dst_arcs)) {
Open vSwitch CI 78f366
-        ovsdb_idl_row_destroy(row);
Open vSwitch CI 78f366
-    } else {
Open vSwitch CI 78f366
-        ovsdb_idl_row_reparse_backrefs(row);
Open vSwitch CI 78f366
-    }
Open vSwitch CI 78f366
+    ovsdb_idl_row_destroy(row);
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 /* Returns true if a column with mode OVSDB_IDL_MODE_RW changed, false
Open vSwitch CI 78f366
diff --git a/lib/ovsdb-idl.h b/lib/ovsdb-idl.h
Open vSwitch CI 78f366
index 05bb48d66c..d93483245e 100644
Open vSwitch CI 78f366
--- a/lib/ovsdb-idl.h
Open vSwitch CI 78f366
+++ b/lib/ovsdb-idl.h
Open vSwitch CI 78f366
@@ -53,6 +53,7 @@ struct ovsdb_datum;
Open vSwitch CI 78f366
 struct ovsdb_idl_class;
Open vSwitch CI 78f366
 struct ovsdb_idl_row;
Open vSwitch CI 78f366
 struct ovsdb_idl_column;
Open vSwitch CI 78f366
+struct ovsdb_idl_table;
Open vSwitch CI 78f366
 struct ovsdb_idl_table_class;
Open vSwitch CI 78f366
 struct uuid;
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -217,6 +218,7 @@ unsigned int ovsdb_idl_row_get_seqno(
Open vSwitch CI 78f366
 void ovsdb_idl_track_add_column(struct ovsdb_idl *idl,
Open vSwitch CI 78f366
                                 const struct ovsdb_idl_column *column);
Open vSwitch CI 78f366
 void ovsdb_idl_track_add_all(struct ovsdb_idl *idl);
Open vSwitch CI 78f366
+bool ovsdb_idl_track_is_set(struct ovsdb_idl_table *table);
Open vSwitch CI 78f366
 const struct ovsdb_idl_row *ovsdb_idl_track_get_first(
Open vSwitch CI 78f366
     const struct ovsdb_idl *, const struct ovsdb_idl_table_class *);
Open vSwitch CI 78f366
 const struct ovsdb_idl_row *ovsdb_idl_track_get_next(const struct ovsdb_idl_row *);
Open vSwitch CI fe1a04
diff --git a/ofproto/connmgr.c b/ofproto/connmgr.c
Open vSwitch CI fe1a04
index 9c5c633b41..fa8f6cd0e8 100644
Open vSwitch CI fe1a04
--- a/ofproto/connmgr.c
Open vSwitch CI fe1a04
+++ b/ofproto/connmgr.c
Open vSwitch CI fe1a04
@@ -2140,7 +2140,7 @@ ofmonitor_report(struct connmgr *mgr, struct rule *rule,
Open vSwitch CI fe1a04
                  const struct rule_actions *old_actions)
Open vSwitch CI fe1a04
     OVS_REQUIRES(ofproto_mutex)
Open vSwitch CI fe1a04
 {
Open vSwitch CI fe1a04
-    if (rule_is_hidden(rule)) {
Open vSwitch CI fe1a04
+    if (!mgr || rule_is_hidden(rule)) {
Open vSwitch CI fe1a04
         return;
Open vSwitch CI fe1a04
     }
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
@@ -2244,6 +2244,10 @@ ofmonitor_flush(struct connmgr *mgr)
Open vSwitch CI fe1a04
 {
Open vSwitch CI fe1a04
     struct ofconn *ofconn;
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
+    if (!mgr) {
Open vSwitch CI fe1a04
+        return;
Open vSwitch CI fe1a04
+    }
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
     LIST_FOR_EACH (ofconn, connmgr_node, &mgr->conns) {
Open vSwitch CI fe1a04
         struct rconn_packet_counter *counter = ofconn->monitor_counter;
Open vSwitch CI fe1a04
 
Open vSwitch CI d251a9
diff --git a/ofproto/ofproto-dpif-sflow.c b/ofproto/ofproto-dpif-sflow.c
Open vSwitch CI d251a9
index fdcb9eabbf..864c136b5d 100644
Open vSwitch CI d251a9
--- a/ofproto/ofproto-dpif-sflow.c
Open vSwitch CI d251a9
+++ b/ofproto/ofproto-dpif-sflow.c
Open vSwitch CI d251a9
@@ -1292,10 +1292,10 @@ dpif_sflow_received(struct dpif_sflow *ds, const struct dp_packet *packet,
Open vSwitch CI d251a9
     ovs_be16 vlan_tci;
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
     ovs_mutex_lock(&mutex);
Open vSwitch CI d251a9
-    sampler = ds->sflow_agent->samplers;
Open vSwitch CI d251a9
-    if (!sampler) {
Open vSwitch CI d251a9
+    if (!ds->sflow_agent || !ds->sflow_agent->samplers) {
Open vSwitch CI d251a9
         goto out;
Open vSwitch CI d251a9
     }
Open vSwitch CI d251a9
+    sampler = ds->sflow_agent->samplers;
Open vSwitch CI d251a9
 
Open vSwitch CI d251a9
     /* Build a flow sample. */
Open vSwitch CI d251a9
     memset(&fs, 0, sizeof fs);
Open vSwitch CI fe1a04
diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
Open vSwitch CI fe1a04
index 5fae46adfc..ccf97266c0 100644
Open vSwitch CI fe1a04
--- a/ofproto/ofproto-dpif-upcall.c
Open vSwitch CI fe1a04
+++ b/ofproto/ofproto-dpif-upcall.c
Open vSwitch CI fe1a04
@@ -491,6 +491,11 @@ udpif_destroy(struct udpif *udpif)
Open vSwitch CI fe1a04
     dpif_register_upcall_cb(udpif->dpif, NULL, udpif);
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     for (int i = 0; i < N_UMAPS; i++) {
Open vSwitch CI fe1a04
+        struct udpif_key *ukey;
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+        CMAP_FOR_EACH (ukey, cmap_node, &udpif->ukeys[i].cmap) {
Open vSwitch CI fe1a04
+            ukey_delete__(ukey);
Open vSwitch CI fe1a04
+        }
Open vSwitch CI fe1a04
         cmap_destroy(&udpif->ukeys[i].cmap);
Open vSwitch CI fe1a04
         ovs_mutex_destroy(&udpif->ukeys[i].mutex);
Open vSwitch CI fe1a04
     }
Open vSwitch CI fe1a04
diff --git a/ovsdb/ovsdb-client.c b/ovsdb/ovsdb-client.c
Open vSwitch CI fe1a04
index 72756eb1f2..ba28e36d78 100644
Open vSwitch CI fe1a04
--- a/ovsdb/ovsdb-client.c
Open vSwitch CI fe1a04
+++ b/ovsdb/ovsdb-client.c
Open vSwitch CI fe1a04
@@ -1664,14 +1664,15 @@ static void
Open vSwitch CI fe1a04
 do_needs_conversion(struct jsonrpc *rpc, const char *database_ OVS_UNUSED,
Open vSwitch CI fe1a04
                     int argc OVS_UNUSED, char *argv[])
Open vSwitch CI fe1a04
 {
Open vSwitch CI fe1a04
+    const char *schema_file_name = argv[argc - 1];
Open vSwitch CI fe1a04
     struct ovsdb_schema *schema1;
Open vSwitch CI fe1a04
-    check_ovsdb_error(ovsdb_schema_from_file(argv[0], &schema1));
Open vSwitch CI fe1a04
+    check_ovsdb_error(ovsdb_schema_from_file(schema_file_name, &schema1));
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     char *database = schema1->name;
Open vSwitch CI fe1a04
     open_rpc(1, NEED_DATABASE, argc, argv, &rpc, &database);
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     if (is_database_clustered(rpc, database)) {
Open vSwitch CI fe1a04
-        ovsdb_schema_persist_ephemeral_columns(schema1, argv[0]);
Open vSwitch CI fe1a04
+        ovsdb_schema_persist_ephemeral_columns(schema1, schema_file_name);
Open vSwitch CI fe1a04
     }
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     struct ovsdb_schema *schema2 = fetch_schema(rpc, schema1->name);
Open vSwitch CI fe1a04
diff --git a/ovsdb/raft.c b/ovsdb/raft.c
Open vSwitch CI fe1a04
index ea91d1fdba..192f7f0a96 100644
Open vSwitch CI fe1a04
--- a/ovsdb/raft.c
Open vSwitch CI fe1a04
+++ b/ovsdb/raft.c
Open vSwitch CI fe1a04
@@ -940,6 +940,34 @@ raft_reset_ping_timer(struct raft *raft)
Open vSwitch CI fe1a04
     raft->ping_timeout = time_msec() + raft->election_timer / 3;
Open vSwitch CI fe1a04
 }
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
+static void
Open vSwitch CI fe1a04
+raft_conn_update_probe_interval(struct raft *raft, struct raft_conn *r_conn)
Open vSwitch CI fe1a04
+{
Open vSwitch CI fe1a04
+    /* Inactivity probe will be sent if connection will remain idle for the
Open vSwitch CI fe1a04
+     * time of an election timeout.  Connection will be dropped if inactivity
Open vSwitch CI fe1a04
+     * will last twice that time.
Open vSwitch CI fe1a04
+     *
Open vSwitch CI fe1a04
+     * It's not enough to just have heartbeats if connection is still
Open vSwitch CI fe1a04
+     * established, but no packets received from the other side.  Without
Open vSwitch CI fe1a04
+     * inactivity probe follower will just try to initiate election
Open vSwitch CI fe1a04
+     * indefinitely staying in 'candidate' role.  And the leader will continue
Open vSwitch CI fe1a04
+     * to send heartbeats to the dead connection thinking that remote server
Open vSwitch CI fe1a04
+     * is still part of the cluster. */
Open vSwitch CI fe1a04
+    int probe_interval = raft->election_timer + ELECTION_RANGE_MSEC;
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+    jsonrpc_session_set_probe_interval(r_conn->js, probe_interval);
Open vSwitch CI fe1a04
+}
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+static void
Open vSwitch CI fe1a04
+raft_update_probe_intervals(struct raft *raft)
Open vSwitch CI fe1a04
+{
Open vSwitch CI fe1a04
+    struct raft_conn *r_conn;
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+    LIST_FOR_EACH (r_conn, list_node, &raft->conns) {
Open vSwitch CI fe1a04
+        raft_conn_update_probe_interval(raft, r_conn);
Open vSwitch CI fe1a04
+    }
Open vSwitch CI fe1a04
+}
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
 static void
Open vSwitch CI fe1a04
 raft_add_conn(struct raft *raft, struct jsonrpc_session *js,
Open vSwitch CI fe1a04
               const struct uuid *sid, bool incoming)
Open vSwitch CI fe1a04
@@ -954,7 +982,7 @@ raft_add_conn(struct raft *raft, struct jsonrpc_session *js,
Open vSwitch CI fe1a04
                                               &conn->sid);
Open vSwitch CI fe1a04
     conn->incoming = incoming;
Open vSwitch CI fe1a04
     conn->js_seqno = jsonrpc_session_get_seqno(conn->js);
Open vSwitch CI fe1a04
-    jsonrpc_session_set_probe_interval(js, 0);
Open vSwitch CI fe1a04
+    raft_conn_update_probe_interval(raft, conn);
Open vSwitch CI fe1a04
     jsonrpc_session_set_backlog_threshold(js, raft->conn_backlog_max_n_msgs,
Open vSwitch CI fe1a04
                                               raft->conn_backlog_max_n_bytes);
Open vSwitch CI fe1a04
 }
Open vSwitch CI fe1a04
@@ -2804,6 +2832,7 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index)
Open vSwitch CI fe1a04
                           raft->election_timer, e->election_timer);
Open vSwitch CI fe1a04
                 raft->election_timer = e->election_timer;
Open vSwitch CI fe1a04
                 raft->election_timer_new = 0;
Open vSwitch CI fe1a04
+                raft_update_probe_intervals(raft);
Open vSwitch CI fe1a04
             }
Open vSwitch CI fe1a04
             if (e->servers) {
Open vSwitch CI fe1a04
                 /* raft_run_reconfigure() can write a new Raft entry, which can
Open vSwitch CI fe1a04
@@ -2820,6 +2849,7 @@ raft_update_commit_index(struct raft *raft, uint64_t new_commit_index)
Open vSwitch CI fe1a04
                 VLOG_INFO("Election timer changed from %"PRIu64" to %"PRIu64,
Open vSwitch CI fe1a04
                           raft->election_timer, e->election_timer);
Open vSwitch CI fe1a04
                 raft->election_timer = e->election_timer;
Open vSwitch CI fe1a04
+                raft_update_probe_intervals(raft);
Open vSwitch CI fe1a04
             }
Open vSwitch CI fe1a04
         }
Open vSwitch CI fe1a04
         /* Check if any pending command can be completed, and complete it.
Open vSwitch CI fe1a04
@@ -4468,6 +4498,8 @@ raft_unixctl_status(struct unixctl_conn *conn,
Open vSwitch CI fe1a04
                   : raft->leaving ? "leaving cluster"
Open vSwitch CI fe1a04
                   : raft->left ? "left cluster"
Open vSwitch CI fe1a04
                   : raft->failed ? "failed"
Open vSwitch CI fe1a04
+                  : raft->candidate_retrying
Open vSwitch CI fe1a04
+                      ? "disconnected from the cluster (election timeout)"
Open vSwitch CI fe1a04
                   : "cluster member");
Open vSwitch CI fe1a04
     if (raft->joining) {
Open vSwitch CI fe1a04
         ds_put_format(&s, "Remotes for joining:");
Open vSwitch CI fe1a04
diff --git a/python/ovs/db/idl.py b/python/ovs/db/idl.py
Open vSwitch CI fe1a04
index 5850ac7abf..4226d1cb2f 100644
Open vSwitch CI fe1a04
--- a/python/ovs/db/idl.py
Open vSwitch CI fe1a04
+++ b/python/ovs/db/idl.py
Open vSwitch CI fe1a04
@@ -12,6 +12,7 @@
Open vSwitch CI fe1a04
 # See the License for the specific language governing permissions and
Open vSwitch CI fe1a04
 # limitations under the License.
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
+import collections
Open vSwitch CI fe1a04
 import functools
Open vSwitch CI fe1a04
 import uuid
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
@@ -39,6 +40,10 @@ OVSDB_UPDATE2 = 1
Open vSwitch CI fe1a04
 CLUSTERED = "clustered"
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
+Notice = collections.namedtuple('Notice', ('event', 'row', 'updates'))
Open vSwitch CI fe1a04
+Notice.__new__.__defaults__ = (None,)  # default updates=None
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
 class Idl(object):
Open vSwitch CI fe1a04
     """Open vSwitch Database Interface Definition Language (OVSDB IDL).
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
@@ -614,6 +619,7 @@ class Idl(object):
Open vSwitch CI fe1a04
             raise error.Error("<table-updates> is not an object",
Open vSwitch CI fe1a04
                               table_updates)
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
+        notices = []
Open vSwitch CI fe1a04
         for table_name, table_update in table_updates.items():
Open vSwitch CI fe1a04
             table = tables.get(table_name)
Open vSwitch CI fe1a04
             if not table:
Open vSwitch CI fe1a04
@@ -639,7 +645,9 @@ class Idl(object):
Open vSwitch CI fe1a04
                                       % (table_name, uuid_string))
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
                 if version == OVSDB_UPDATE2:
Open vSwitch CI fe1a04
-                    if self.__process_update2(table, uuid, row_update):
Open vSwitch CI fe1a04
+                    changes = self.__process_update2(table, uuid, row_update)
Open vSwitch CI fe1a04
+                    if changes:
Open vSwitch CI fe1a04
+                        notices.append(changes)
Open vSwitch CI fe1a04
                         self.change_seqno += 1
Open vSwitch CI fe1a04
                     continue
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
@@ -652,17 +660,20 @@ class Idl(object):
Open vSwitch CI fe1a04
                     raise error.Error('<row-update> missing "old" and '
Open vSwitch CI fe1a04
                                       '"new" members', row_update)
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
-                if self.__process_update(table, uuid, old, new):
Open vSwitch CI fe1a04
+                changes = self.__process_update(table, uuid, old, new)
Open vSwitch CI fe1a04
+                if changes:
Open vSwitch CI fe1a04
+                    notices.append(changes)
Open vSwitch CI fe1a04
                     self.change_seqno += 1
Open vSwitch CI fe1a04
+        for notice in notices:
Open vSwitch CI fe1a04
+            self.notify(*notice)
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     def __process_update2(self, table, uuid, row_update):
Open vSwitch CI fe1a04
+        """Returns Notice if a column changed, False otherwise."""
Open vSwitch CI fe1a04
         row = table.rows.get(uuid)
Open vSwitch CI fe1a04
-        changed = False
Open vSwitch CI fe1a04
         if "delete" in row_update:
Open vSwitch CI fe1a04
             if row:
Open vSwitch CI fe1a04
                 del table.rows[uuid]
Open vSwitch CI fe1a04
-                self.notify(ROW_DELETE, row)
Open vSwitch CI fe1a04
-                changed = True
Open vSwitch CI fe1a04
+                return Notice(ROW_DELETE, row)
Open vSwitch CI fe1a04
             else:
Open vSwitch CI fe1a04
                 # XXX rate-limit
Open vSwitch CI fe1a04
                 vlog.warn("cannot delete missing row %s from table"
Open vSwitch CI fe1a04
@@ -681,29 +692,27 @@ class Idl(object):
Open vSwitch CI fe1a04
             changed = self.__row_update(table, row, row_update)
Open vSwitch CI fe1a04
             table.rows[uuid] = row
Open vSwitch CI fe1a04
             if changed:
Open vSwitch CI fe1a04
-                self.notify(ROW_CREATE, row)
Open vSwitch CI fe1a04
+                return Notice(ROW_CREATE, row)
Open vSwitch CI fe1a04
         elif "modify" in row_update:
Open vSwitch CI fe1a04
             if not row:
Open vSwitch CI fe1a04
                 raise error.Error('Modify non-existing row')
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
             old_row = self.__apply_diff(table, row, row_update['modify'])
Open vSwitch CI fe1a04
-            self.notify(ROW_UPDATE, row, Row(self, table, uuid, old_row))
Open vSwitch CI fe1a04
-            changed = True
Open vSwitch CI fe1a04
+            return Notice(ROW_UPDATE, row, Row(self, table, uuid, old_row))
Open vSwitch CI fe1a04
         else:
Open vSwitch CI fe1a04
             raise error.Error('<row-update> unknown operation',
Open vSwitch CI fe1a04
                               row_update)
Open vSwitch CI fe1a04
-        return changed
Open vSwitch CI fe1a04
+        return False
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     def __process_update(self, table, uuid, old, new):
Open vSwitch CI fe1a04
-        """Returns True if a column changed, False otherwise."""
Open vSwitch CI fe1a04
+        """Returns Notice if a column changed, False otherwise."""
Open vSwitch CI fe1a04
         row = table.rows.get(uuid)
Open vSwitch CI fe1a04
         changed = False
Open vSwitch CI fe1a04
         if not new:
Open vSwitch CI fe1a04
             # Delete row.
Open vSwitch CI fe1a04
             if row:
Open vSwitch CI fe1a04
                 del table.rows[uuid]
Open vSwitch CI fe1a04
-                changed = True
Open vSwitch CI fe1a04
-                self.notify(ROW_DELETE, row)
Open vSwitch CI fe1a04
+                return Notice(ROW_DELETE, row)
Open vSwitch CI fe1a04
             else:
Open vSwitch CI fe1a04
                 # XXX rate-limit
Open vSwitch CI fe1a04
                 vlog.warn("cannot delete missing row %s from table %s"
Open vSwitch CI fe1a04
@@ -723,7 +732,7 @@ class Idl(object):
Open vSwitch CI fe1a04
             if op == ROW_CREATE:
Open vSwitch CI fe1a04
                 table.rows[uuid] = row
Open vSwitch CI fe1a04
             if changed:
Open vSwitch CI fe1a04
-                self.notify(ROW_CREATE, row)
Open vSwitch CI fe1a04
+                return Notice(ROW_CREATE, row)
Open vSwitch CI fe1a04
         else:
Open vSwitch CI fe1a04
             op = ROW_UPDATE
Open vSwitch CI fe1a04
             if not row:
Open vSwitch CI fe1a04
@@ -737,8 +746,8 @@ class Idl(object):
Open vSwitch CI fe1a04
             if op == ROW_CREATE:
Open vSwitch CI fe1a04
                 table.rows[uuid] = row
Open vSwitch CI fe1a04
             if changed:
Open vSwitch CI fe1a04
-                self.notify(op, row, Row.from_json(self, table, uuid, old))
Open vSwitch CI fe1a04
-        return changed
Open vSwitch CI fe1a04
+                return Notice(op, row, Row.from_json(self, table, uuid, old))
Open vSwitch CI fe1a04
+        return False
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     def __check_server_db(self):
Open vSwitch CI fe1a04
         """Returns True if this is a valid server database, False otherwise."""
Open vSwitch CI b3acf0
diff --git a/tests/atlocal.in b/tests/atlocal.in
Open vSwitch CI b3acf0
index 02e2dc57f2..cfca7e1926 100644
Open vSwitch CI b3acf0
--- a/tests/atlocal.in
Open vSwitch CI b3acf0
+++ b/tests/atlocal.in
Open vSwitch CI b3acf0
@@ -175,6 +175,9 @@ find_command()
Open vSwitch CI b3acf0
 # Set HAVE_NC
Open vSwitch CI b3acf0
 find_command nc
Open vSwitch CI b3acf0
 
Open vSwitch CI b3acf0
+# Set HAVE_TC
Open vSwitch CI b3acf0
+find_command tc
Open vSwitch CI b3acf0
+
Open vSwitch CI b3acf0
 # Determine correct netcat option to quit on stdin EOF
Open vSwitch CI b3acf0
 if nc --version 2>&1 | grep -q nmap.org; then
Open vSwitch CI b3acf0
     # Nmap netcat
Open vSwitch CI fe1a04
diff --git a/tests/automake.mk b/tests/automake.mk
Open vSwitch CI fe1a04
index 677b99a6b4..fc80e027df 100644
Open vSwitch CI fe1a04
--- a/tests/automake.mk
Open vSwitch CI fe1a04
+++ b/tests/automake.mk
Open vSwitch CI fe1a04
@@ -134,7 +134,8 @@ FUZZ_REGRESSION_TESTS = \
Open vSwitch CI fe1a04
 	tests/fuzz-regression/ofp_print_fuzzer-5722747668791296 \
Open vSwitch CI fe1a04
 	tests/fuzz-regression/ofp_print_fuzzer-6285128790704128 \
Open vSwitch CI fe1a04
 	tests/fuzz-regression/ofp_print_fuzzer-6470117922701312 \
Open vSwitch CI fe1a04
-	tests/fuzz-regression/ofp_print_fuzzer-6502620041576448
Open vSwitch CI fe1a04
+	tests/fuzz-regression/ofp_print_fuzzer-6502620041576448 \
Open vSwitch CI fe1a04
+	tests/fuzz-regression/ofp_print_fuzzer-6540965472632832
Open vSwitch CI fe1a04
 $(srcdir)/tests/fuzz-regression-list.at: tests/automake.mk
Open vSwitch CI fe1a04
 	$(AM_V_GEN)for name in $(FUZZ_REGRESSION_TESTS); do \
Open vSwitch CI fe1a04
             basename=`echo $$name | sed 's,^.*/,,'`; \
Open vSwitch CI fe1a04
diff --git a/tests/daemon.at b/tests/daemon.at
Open vSwitch CI fe1a04
index a7982de381..39d9aa391e 100644
Open vSwitch CI fe1a04
--- a/tests/daemon.at
Open vSwitch CI fe1a04
+++ b/tests/daemon.at
Open vSwitch CI fe1a04
@@ -218,11 +218,11 @@ OVS_WAIT_UNTIL([test -s ovsdb-server.pid])
Open vSwitch CI fe1a04
 OVS_WAIT_UNTIL([sc query ovsdb-server | grep STATE | grep RUNNING > /dev/null 2>&1])
Open vSwitch CI fe1a04
 AT_CHECK([kill -0 `cat ovsdb-server.pid`], [0], [ignore])
Open vSwitch CI fe1a04
 AT_CHECK([ovs-appctl -t ovsdb-server ovsdb-server/list-dbs], [0],
Open vSwitch CI fe1a04
-[Open_vSwitch
Open vSwitch CI fe1a04
+[_Server
Open vSwitch CI fe1a04
 ])
Open vSwitch CI fe1a04
 AT_CHECK([sc stop ovsdb-server], [0], [ignore])
Open vSwitch CI fe1a04
 OVS_WAIT_UNTIL([test ! -s ovsdb-server.pid])
Open vSwitch CI fe1a04
-AT_CHECK([sc query ovsdb-server | grep STATE | grep STOPPED], [0], [ignore])
Open vSwitch CI fe1a04
+OVS_WAIT_UNTIL([sc query ovsdb-server | grep STATE | grep STOPPED > /dev/null 2>&1])
Open vSwitch CI fe1a04
 AT_CHECK([sc delete ovsdb-server], [0], [[[SC]] DeleteService SUCCESS
Open vSwitch CI fe1a04
 ])
Open vSwitch CI fe1a04
 AT_CLEANUP
Open vSwitch CI fe1a04
diff --git a/tests/dpif-netdev.at b/tests/dpif-netdev.at
Open vSwitch CI e0c144
index 2862a3c9b9..57cae383fe 100644
Open vSwitch CI fe1a04
--- a/tests/dpif-netdev.at
Open vSwitch CI fe1a04
+++ b/tests/dpif-netdev.at
Open vSwitch CI 0aa018
@@ -299,59 +299,61 @@ type=drop rate=1 burst_size=2
Open vSwitch CI 0aa018
 ])
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
 ovs-appctl time/warp 5000
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
+for i in `seq 1 7`; do
Open vSwitch CI 0aa018
+  AT_CHECK(
Open vSwitch CI 0aa018
+    [ovs-appctl netdev-dummy/receive p7 \
Open vSwitch CI 0aa018
+       'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
+done
Open vSwitch CI 0aa018
+
Open vSwitch CI 0aa018
+for i in `seq 1 5`; do
Open vSwitch CI 0aa018
+  AT_CHECK(
Open vSwitch CI 0aa018
+    [ovs-appctl netdev-dummy/receive p8 \
Open vSwitch CI 0aa018
+       'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
+done
Open vSwitch CI 0aa018
+
Open vSwitch CI 0aa018
 sleep 1  # wait for forwarders process packets
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
 # Meter 1 is measuring packets, allowing one packet per second with
Open vSwitch CI 0aa018
-# bursts of one packet, so 4 out of 5 packets should hit the drop
Open vSwitch CI 0aa018
+# bursts of one packet, so 3 out of 5 packets should hit the drop
Open vSwitch CI 0aa018
 # band.
Open vSwitch CI 0aa018
-# Meter 2 is measuring kbps, with burst size 2 (== 2000 bits). 4 packets
Open vSwitch CI 0aa018
-# (240 bytes == 1920 bits) pass, but the last packet should hit the drop band.
Open vSwitch CI 0aa018
+# Meter 2 is measuring kbps, with burst size 2 (== 3000 bits). 6 packets
Open vSwitch CI 0aa018
+# (360 bytes == 2880 bits) pass, but the last packet should hit the drop band.
Open vSwitch CI 0aa018
 AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | strip_timers], [0], [dnl
Open vSwitch CI 0aa018
 OFPST_METER reply (OF1.3) (xid=0x2):
Open vSwitch CI 0aa018
 meter:1 flow_count:1 packet_in_count:5 byte_in_count:300 duration:0.0s bands:
Open vSwitch CI 0aa018
-0: packet_count:4 byte_count:240
Open vSwitch CI 0aa018
+0: packet_count:3 byte_count:180
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
-meter:2 flow_count:1 packet_in_count:5 byte_in_count:300 duration:0.0s bands:
Open vSwitch CI 0aa018
+meter:2 flow_count:1 packet_in_count:7 byte_in_count:420 duration:0.0s bands:
Open vSwitch CI 0aa018
 0: packet_count:1 byte_count:60
Open vSwitch CI 0aa018
 ])
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
 # Advance time by 1/2 second
Open vSwitch CI 0aa018
 ovs-appctl time/warp 500
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p7 'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
-AT_CHECK([ovs-appctl netdev-dummy/receive p8 'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
+for i in `seq 1 5`; do
Open vSwitch CI 0aa018
+  AT_CHECK(
Open vSwitch CI 0aa018
+    [ovs-appctl netdev-dummy/receive p7 \
Open vSwitch CI 0aa018
+       'in_port(7),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:09,dst=50:54:00:00:00:0a),eth_type(0x0800),ipv4(src=10.0.0.2,dst=10.0.0.1,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
+
Open vSwitch CI 0aa018
+  AT_CHECK(
Open vSwitch CI 0aa018
+    [ovs-appctl netdev-dummy/receive p8 \
Open vSwitch CI 0aa018
+       'in_port(8),packet_type(ns=0,id=0),eth(src=50:54:00:00:00:0b,dst=50:54:00:00:00:0c),eth_type(0x0800),ipv4(src=10.0.0.3,dst=10.0.0.4,proto=1,tos=0,ttl=64,frag=no),icmp(type=8,code=0)' --len 60])
Open vSwitch CI 0aa018
+done
Open vSwitch CI 0aa018
+
Open vSwitch CI 0aa018
 sleep 1  # wait for forwarders process packets
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
 # Meter 1 is measuring packets, allowing one packet per second with
Open vSwitch CI 0aa018
 # bursts of one packet, so all 5 of the new packets should hit the drop
Open vSwitch CI 0aa018
 # band.
Open vSwitch CI 0aa018
-# Meter 2 is measuring kbps, with burst size 2 (== 2000 bits). After 500ms
Open vSwitch CI 0aa018
-# there should be space for 80 + 500 bits, so one new 60 byte (480 bit) packet
Open vSwitch CI 0aa018
+# Meter 2 is measuring kbps, with burst size 2 (== 3000 bits). After 500ms
Open vSwitch CI 0aa018
+# there should be space for 120 + 500 bits, so one new 60 byte (480 bit) packet
Open vSwitch CI 0aa018
 # should pass, remaining 4 should hit the drop band.
Open vSwitch CI 0aa018
 AT_CHECK([ovs-ofctl -O OpenFlow13 meter-stats br0 | strip_timers], [0], [dnl
Open vSwitch CI 0aa018
 OFPST_METER reply (OF1.3) (xid=0x2):
Open vSwitch CI 0aa018
 meter:1 flow_count:1 packet_in_count:10 byte_in_count:600 duration:0.0s bands:
Open vSwitch CI 0aa018
-0: packet_count:9 byte_count:540
Open vSwitch CI 0aa018
+0: packet_count:8 byte_count:480
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
-meter:2 flow_count:1 packet_in_count:10 byte_in_count:600 duration:0.0s bands:
Open vSwitch CI 0aa018
+meter:2 flow_count:1 packet_in_count:12 byte_in_count:720 duration:0.0s bands:
Open vSwitch CI 0aa018
 0: packet_count:5 byte_count:300
Open vSwitch CI 0aa018
 ])
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
@@ -360,7 +362,7 @@ ovs-appctl time/warp 5000
Open vSwitch CI 0aa018
 AT_CHECK([
Open vSwitch CI 0aa018
 ovs-appctl coverage/read-counter datapath_drop_meter
Open vSwitch CI 0aa018
 ], [0], [dnl
Open vSwitch CI 0aa018
-14
Open vSwitch CI 0aa018
+13
Open vSwitch CI 0aa018
 ])
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
 AT_CHECK([cat ovs-vswitchd.log | filter_flow_install | strip_xout_keep_actions], [0], [dnl
Open vSwitch CI e0c144
@@ -370,6 +372,8 @@ recirc_id(0),in_port(7),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), a
Open vSwitch CI e0c144
 recirc_id(0),in_port(8),packet_type(ns=0,id=0),eth_type(0x0800),ipv4(frag=no), actions:2
Open vSwitch CI e0c144
 ])
Open vSwitch CI e0c144
 
Open vSwitch CI e0c144
+AT_CHECK([ovs-ofctl -O OpenFlow13 del-meters br0])
Open vSwitch CI e0c144
+
Open vSwitch CI e0c144
 OVS_VSWITCHD_STOP
Open vSwitch CI e0c144
 AT_CLEANUP
Open vSwitch CI e0c144
 
Open vSwitch CI e0c144
@@ -589,3 +593,20 @@ arp,in_port=ANY,dl_vlan=11,dl_vlan_pcp=7,vlan_tci1=0x0000,dl_src=00:06:07:08:09:
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy])
Open vSwitch CI fe1a04
 DPIF_NETDEV_FLOW_HW_OFFLOAD_OFFSETS_VID_ARP([dummy-pmd])
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+AT_SETUP([dpif-netdev - check dpctl/add-flow in_port exact match])
Open vSwitch CI fe1a04
+OVS_VSWITCHD_START(
Open vSwitch CI fe1a04
+  [add-port br0 p1 \
Open vSwitch CI fe1a04
+   -- set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p0.sock \
Open vSwitch CI fe1a04
+   -- set bridge br0 datapath-type=dummy \
Open vSwitch CI fe1a04
+                     other-config:datapath-id=1234 fail-mode=secure])
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+AT_CHECK([ovs-appctl dpctl/add-flow "eth(),eth_type(0x0800),ipv4()" "3"], [2],
Open vSwitch CI fe1a04
+[], [dnl
Open vSwitch CI fe1a04
+ovs-vswitchd: updating flow table (Invalid argument)
Open vSwitch CI fe1a04
+ovs-appctl: ovs-vswitchd: server returned an error
Open vSwitch CI fe1a04
+])
Open vSwitch CI fe1a04
+OVS_WAIT_UNTIL([grep "flow: in_port is not an exact match" ovs-vswitchd.log])
Open vSwitch CI fe1a04
+OVS_VSWITCHD_STOP(["/flow: in_port is not an exact match/d
Open vSwitch CI fe1a04
+/failed to put/d"])
Open vSwitch CI fe1a04
+AT_CLEANUP
Open vSwitch CI fe1a04
diff --git a/tests/fuzz-regression-list.at b/tests/fuzz-regression-list.at
Open vSwitch CI fe1a04
index e3173fb88f..2347c690ef 100644
Open vSwitch CI fe1a04
--- a/tests/fuzz-regression-list.at
Open vSwitch CI fe1a04
+++ b/tests/fuzz-regression-list.at
Open vSwitch CI fe1a04
@@ -21,3 +21,4 @@ TEST_FUZZ_REGRESSION([ofp_print_fuzzer-5722747668791296])
Open vSwitch CI fe1a04
 TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6285128790704128])
Open vSwitch CI fe1a04
 TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6470117922701312])
Open vSwitch CI fe1a04
 TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6502620041576448])
Open vSwitch CI fe1a04
+TEST_FUZZ_REGRESSION([ofp_print_fuzzer-6540965472632832])
Open vSwitch CI fe1a04
diff --git a/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832 b/tests/fuzz-regression/ofp_print_fuzzer-6540965472632832
Open vSwitch CI fe1a04
new file mode 100644
Open vSwitch CI fe1a04
index 0000000000..e69de29bb2
Open vSwitch CI 0aa018
diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
Open vSwitch CI 0aa018
index 31064ed95e..24bbd884ca 100644
Open vSwitch CI 0aa018
--- a/tests/ofproto-dpif.at
Open vSwitch CI 0aa018
+++ b/tests/ofproto-dpif.at
Open vSwitch CI 0aa018
@@ -2123,7 +2123,7 @@ AT_CHECK([ovs-appctl revalidator/purge])
Open vSwitch CI 0aa018
 AT_CHECK([ovs-ofctl monitor br0 65534 invalid_ttl -P nxt_packet_in --detach --no-chdir --pidfile 2> ofctl_monitor.log])
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
 dnl Add a controller meter.
Open vSwitch CI 0aa018
-AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=controller pktps stats bands=type=drop rate=2'])
Open vSwitch CI 0aa018
+AT_CHECK([ovs-ofctl -O OpenFlow13 add-meter br0 'meter=controller pktps burst stats bands=type=drop rate=1 burst_size=1'])
Open vSwitch CI 0aa018
 
Open vSwitch CI 0aa018
 dnl Advance time by 1 second.
Open vSwitch CI 0aa018
 AT_CHECK([ovs-appctl time/warp 1000], [0], [ignore])
Open vSwitch CI b3acf0
diff --git a/tests/ovs-vsctl.at b/tests/ovs-vsctl.at
Open vSwitch CI b3acf0
index c8babe3612..1f1fc3c79a 100644
Open vSwitch CI b3acf0
--- a/tests/ovs-vsctl.at
Open vSwitch CI b3acf0
+++ b/tests/ovs-vsctl.at
Open vSwitch CI b3acf0
@@ -1639,3 +1639,26 @@ AT_CHECK([grep "server name" ovsdb-server.log], [0],
Open vSwitch CI b3acf0
 
Open vSwitch CI b3acf0
 OVS_VSCTL_CLEANUP
Open vSwitch CI b3acf0
 AT_CLEANUP
Open vSwitch CI b3acf0
+
Open vSwitch CI b3acf0
+dnl ----------------------------------------------------------------------
Open vSwitch CI b3acf0
+AT_BANNER([set ingress policing test])
Open vSwitch CI b3acf0
+
Open vSwitch CI b3acf0
+AT_SETUP([set ingress_policing_rate and ingress_policing_burst])
Open vSwitch CI b3acf0
+AT_KEYWORDS([ingress_policing])
Open vSwitch CI b3acf0
+OVS_VSCTL_SETUP
Open vSwitch CI b3acf0
+AT_CHECK([RUN_OVS_VSCTL_TOGETHER(
Open vSwitch CI b3acf0
+   [add-br a],
Open vSwitch CI b3acf0
+   [add-port a a1],
Open vSwitch CI b3acf0
+   [set interface a1 ingress_policing_rate=100],
Open vSwitch CI b3acf0
+   [set interface a1 ingress_policing_burst=10],
Open vSwitch CI b3acf0
+   [--columns=ingress_policing_burst,ingress_policing_rate list interface a1])],
Open vSwitch CI b3acf0
+   [0],
Open vSwitch CI b3acf0
+   [
Open vSwitch CI b3acf0
+
Open vSwitch CI b3acf0
+
Open vSwitch CI b3acf0
+
Open vSwitch CI b3acf0
+ingress_policing_burst: 10
Open vSwitch CI b3acf0
+ingress_policing_rate: 100
Open vSwitch CI b3acf0
+])
Open vSwitch CI b3acf0
+OVS_VSCTL_CLEANUP
Open vSwitch CI b3acf0
+AT_CLEANUP
Open vSwitch CI fe1a04
diff --git a/tests/ovsdb-client.at b/tests/ovsdb-client.at
Open vSwitch CI fe1a04
index 8d777a0275..5e3b26aea8 100644
Open vSwitch CI fe1a04
--- a/tests/ovsdb-client.at
Open vSwitch CI fe1a04
+++ b/tests/ovsdb-client.at
Open vSwitch CI fe1a04
@@ -12,6 +12,30 @@ AT_CHECK([ovsdb-client get-schema-cksum unix:socket ordinals], [0], [12345678 9
Open vSwitch CI fe1a04
 OVSDB_SERVER_SHUTDOWN
Open vSwitch CI fe1a04
 AT_CLEANUP
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
+AT_SETUP([ovsdb-client needs-conversion (no conversion needed)])
Open vSwitch CI fe1a04
+AT_KEYWORDS([ovsdb client file positive])
Open vSwitch CI fe1a04
+ordinal_schema > schema
Open vSwitch CI fe1a04
+touch .db.~lock~
Open vSwitch CI fe1a04
+AT_CHECK([ovsdb-tool create db schema], [0], [], [ignore])
Open vSwitch CI fe1a04
+AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db], [0], [ignore], [ignore])
Open vSwitch CI fe1a04
+AT_CHECK([ovsdb-client needs-conversion unix:socket schema], [0], [no
Open vSwitch CI fe1a04
+])
Open vSwitch CI fe1a04
+OVSDB_SERVER_SHUTDOWN
Open vSwitch CI fe1a04
+AT_CLEANUP
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
+AT_SETUP([ovsdb-client needs-conversion (conversion needed)])
Open vSwitch CI fe1a04
+AT_KEYWORDS([ovsdb client file positive])
Open vSwitch CI fe1a04
+ordinal_schema > schema
Open vSwitch CI fe1a04
+touch .db.~lock~
Open vSwitch CI fe1a04
+AT_CHECK([ovsdb-tool create db schema], [0], [], [ignore])
Open vSwitch CI fe1a04
+AT_CHECK([ovsdb-server --detach --no-chdir --pidfile --remote=punix:socket db], [0], [ignore], [ignore])
Open vSwitch CI fe1a04
+sed 's/5\.1\.3/5.1.4/' < schema > schema2
Open vSwitch CI fe1a04
+AT_CHECK([diff schema schema2], [1], [ignore])
Open vSwitch CI fe1a04
+AT_CHECK([ovsdb-client needs-conversion unix:socket schema2], [0], [yes
Open vSwitch CI fe1a04
+])
Open vSwitch CI fe1a04
+OVSDB_SERVER_SHUTDOWN
Open vSwitch CI fe1a04
+AT_CLEANUP
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
 AT_SETUP([ovsdb-client backup and restore])
Open vSwitch CI fe1a04
 AT_KEYWORDS([ovsdb client positive])
Open vSwitch CI fe1a04
 
Open vSwitch CI 78f366
diff --git a/tests/ovsdb-cluster.at b/tests/ovsdb-cluster.at
Open vSwitch CI 78f366
index 92aa427093..cf43e9cf86 100644
Open vSwitch CI 78f366
--- a/tests/ovsdb-cluster.at
Open vSwitch CI 78f366
+++ b/tests/ovsdb-cluster.at
Open vSwitch CI 78f366
@@ -128,7 +128,7 @@ ovsdb_test_cluster_disconnect () {
Open vSwitch CI 78f366
            "rows": [{"i": 1}]}]]' > test-ovsdb.log 2>&1 &
Open vSwitch CI 78f366
     echo $! > test-ovsdb.pid
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
-    OVS_WAIT_UNTIL([grep "000: i=1" test-ovsdb.log])
Open vSwitch CI 78f366
+    OVS_WAIT_UNTIL([grep "000: table simple: i=1" test-ovsdb.log])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     # Start collecting raft_is_connected logs for $target before shutting down
Open vSwitch CI 78f366
     # any servers.
Open vSwitch CI fe1a04
diff --git a/tests/ovsdb-idl.at b/tests/ovsdb-idl.at
Open vSwitch CI 78f366
index 4b4791a7da..62181dd4de 100644
Open vSwitch CI fe1a04
--- a/tests/ovsdb-idl.at
Open vSwitch CI fe1a04
+++ b/tests/ovsdb-idl.at
Open vSwitch CI 78f366
@@ -141,7 +141,7 @@ m4_define([OVSDB_CHECK_IDL_REGISTER_COLUMNS_PY],
Open vSwitch CI 78f366
    AT_CHECK([ovsdb_start_idltest])
Open vSwitch CI 78f366
    m4_if([$2], [], [],
Open vSwitch CI 78f366
      [AT_CHECK([ovsdb-client transact unix:socket $2], [0], [ignore], [ignore])])
Open vSwitch CI 78f366
-   AT_CHECK([$PYTHON3 $srcdir/test-ovsdb.py  -t10 idl $srcdir/idltest.ovsschema unix:socket ?simple:b,ba,i,ia,r,ra,s,sa,u,ua?link1:i,k,ka,l2?link2:i,l1?singleton:name $3],
Open vSwitch CI 78f366
+   AT_CHECK([$PYTHON3 $srcdir/test-ovsdb.py  -t10 idl $srcdir/idltest.ovsschema unix:socket ?simple:b,ba,i,ia,r,ra,s,sa,u,ua?simple3:name,uset,uref?simple4:name?simple6:name,weak_ref?link1:i,k,ka,l2?link2:i,l1?singleton:name $3],
Open vSwitch CI 78f366
             [0], [stdout], [ignore])
Open vSwitch CI 78f366
    AT_CHECK([sort stdout | uuidfilt]m4_if([$6],,, [[| $6]]),
Open vSwitch CI 78f366
             [0], [$4])
Open vSwitch CI 78f366
@@ -355,28 +355,28 @@ OVSDB_CHECK_IDL([simple idl, initially empty, various ops],
Open vSwitch CI 78f366
     'reconnect']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]}
Open vSwitch CI 78f366
-002: i=0 r=0 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-002: i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+002: table simple: i=0 r=0 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+002: table simple: i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 003: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-004: i=0 r=0 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-004: i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+004: table simple: i=0 r=0 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+004: table simple: i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 005: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-006: i=0 r=123.5 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-006: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+006: table simple: i=0 r=123.5 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+006: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 007: {"error":null,"result":[{"uuid":["uuid","<6>"]}]}
Open vSwitch CI 78f366
-008: i=-1 r=125 b=false s= u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-008: i=0 r=123.5 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-008: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+008: table simple: i=-1 r=125 b=false s= u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+008: table simple: i=0 r=123.5 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+008: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 009: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-010: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-010: i=0 r=123.5 b=true s=newstring u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-010: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+010: table simple: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+010: table simple: i=0 r=123.5 b=true s=newstring u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+010: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 011: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-012: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-012: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+012: table simple: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+012: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 013: reconnect
Open vSwitch CI 78f366
-014: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-014: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+014: table simple: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+014: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 015: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -403,11 +403,11 @@ OVSDB_CHECK_IDL([simple idl, initially populated],
Open vSwitch CI 78f366
        "table": "simple",
Open vSwitch CI 78f366
        "where": [],
Open vSwitch CI 78f366
        "row": {"b": true}}]']],
Open vSwitch CI 78f366
-  [[000: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-000: i=1 r=2 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<5>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+000: table simple: i=1 r=2 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<5>
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-002: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-002: i=1 r=2 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<5>
Open vSwitch CI 78f366
+002: table simple: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+002: table simple: i=1 r=2 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<5>
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -431,14 +431,14 @@ OVSDB_CHECK_IDL([simple idl, writing via IDL],
Open vSwitch CI 78f366
        "row": {}}]']],
Open vSwitch CI 78f366
   [['verify 0 b, verify 1 r, set 0 b 1, set 1 r 3.5' \
Open vSwitch CI 78f366
     'insert 2, verify 2 i, verify 1 b, delete 1']],
Open vSwitch CI 78f366
-  [[000: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-000: i=1 r=2 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<5>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+000: table simple: i=1 r=2 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<5>
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
-002: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-002: i=1 r=3.5 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<5>
Open vSwitch CI 78f366
+002: table simple: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+002: table simple: i=1 r=3.5 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<5>
Open vSwitch CI 78f366
 003: commit, status=success
Open vSwitch CI 78f366
-004: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-004: i=2 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+004: table simple: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+004: table simple: i=2 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
 005: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -448,10 +448,10 @@ OVSDB_CHECK_IDL([simple idl, writing via IDL with unicode],
Open vSwitch CI 78f366
        "table": "simple",
Open vSwitch CI 78f366
        "row": {"s": "(╯°□°)╯︵ ┻━┻"}}]']],
Open vSwitch CI 78f366
   [['set 0 b 1, insert 1, set 1 s "¯\_(ツ)_/¯"']],
Open vSwitch CI 78f366
-  [[000: i=0 r=0 b=false s=(╯°□°)╯︵ ┻━┻ u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 r=0 b=false s=(╯°□°)╯︵ ┻━┻ u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
-002: i=0 r=0 b=true s=(╯°□°)╯︵ ┻━┻ u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-002: i=1 r=0 b=false s="¯\_(ツ)_/¯" u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+002: table simple: i=0 r=0 b=true s=(╯°□°)╯︵ ┻━┻ u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+002: table simple: i=1 r=0 b=false s="¯\_(ツ)_/¯" u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -475,10 +475,10 @@ OVSDB_CHECK_IDL_PY_WITH_EXPOUT([simple idl, writing large data via IDL with unic
Open vSwitch CI 78f366
        "table": "simple",
Open vSwitch CI 78f366
        "row": {"s": "'$(printf "测试超过四千零九十六个字节的中文字符串以使解码出现问题。%.0s" {1..50})'"}}]']],
Open vSwitch CI 78f366
   [['set 0 b 1, insert 1, set 1 s '$(printf "测试超过四千零九十六个字节的中文字符串以使解码出现问题。%.0s" {1..100})'']],
Open vSwitch CI 78f366
-  [[000: i=0 r=0 b=false s=$(printf "测试超过四千零九十六个字节的中文字符串以使解码出现问题。%.0s" {1..50}) u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 r=0 b=false s=$(printf "测试超过四千零九十六个字节的中文字符串以使解码出现问题。%.0s" {1..50}) u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
-002: i=0 r=0 b=true s=$(printf "测试超过四千零九十六个字节的中文字符串以使解码出现问题。%.0s" {1..50}) u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-002: i=1 r=0 b=false s=$(printf "测试超过四千零九十六个字节的中文字符串以使解码出现问题。%.0s" {1..100}) u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+002: table simple: i=0 r=0 b=true s=$(printf "测试超过四千零九十六个字节的中文字符串以使解码出现问题。%.0s" {1..50}) u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+002: table simple: i=1 r=0 b=false s=$(printf "测试超过四千零九十六个字节的中文字符串以使解码出现问题。%.0s" {1..100}) u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
 003: done]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 OVSDB_CHECK_IDL([simple idl, handling verification failure],
Open vSwitch CI 78f366
@@ -499,16 +499,16 @@ OVSDB_CHECK_IDL([simple idl, handling verification failure],
Open vSwitch CI 78f366
     '+verify 1 r, set 1 r 3' \
Open vSwitch CI 78f366
     'verify 1 r, set 1 r 3' \
Open vSwitch CI 78f366
     ]],
Open vSwitch CI 78f366
-  [[000: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-000: i=1 r=2 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+000: table simple: i=1 r=2 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
 002: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
 003: commit, status=try again
Open vSwitch CI 78f366
-004: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-004: i=1 r=5 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+004: table simple: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+004: table simple: i=1 r=5 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
 005: commit, status=success
Open vSwitch CI 78f366
-006: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-006: i=1 r=3 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+006: table simple: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+006: table simple: i=1 r=3 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
 007: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -518,9 +518,9 @@ OVSDB_CHECK_IDL([simple idl, increment operation],
Open vSwitch CI 78f366
        "table": "simple",
Open vSwitch CI 78f366
        "row": {}}]']],
Open vSwitch CI 78f366
   [['set 0 r 2.0, increment 0']],
Open vSwitch CI 78f366
-  [[000: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 001: commit, status=success, increment=1
Open vSwitch CI 78f366
-002: i=1 r=2 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+002: table simple: i=1 r=2 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -531,10 +531,10 @@ OVSDB_CHECK_IDL([simple idl, aborting],
Open vSwitch CI 78f366
        "row": {}}]']],
Open vSwitch CI 78f366
   [['set 0 r 2.0, abort' \
Open vSwitch CI 78f366
 '+set 0 b 1']],
Open vSwitch CI 78f366
-  [[000: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 001: commit, status=aborted
Open vSwitch CI 78f366
 002: commit, status=success
Open vSwitch CI 78f366
-003: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 004: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -545,10 +545,10 @@ OVSDB_CHECK_IDL([simple idl, destroy without commit or abort],
Open vSwitch CI 78f366
        "row": {}}]']],
Open vSwitch CI 78f366
   [['set 0 r 2.0, destroy' \
Open vSwitch CI 78f366
 '+set 0 b 1']],
Open vSwitch CI 78f366
-  [[000: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 001: destroy
Open vSwitch CI 78f366
 002: commit, status=success
Open vSwitch CI 78f366
-003: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: i=0 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 004: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -564,7 +564,7 @@ OVSDB_CHECK_IDL([simple idl, conditional, false condition],
Open vSwitch CI 78f366
   [[000: change conditions
Open vSwitch CI 78f366
 001: empty
Open vSwitch CI 78f366
 002: change conditions
Open vSwitch CI 78f366
-003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 004: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -580,7 +580,7 @@ OVSDB_CHECK_IDL([simple idl, conditional, true condition],
Open vSwitch CI 78f366
   [[000: change conditions
Open vSwitch CI 78f366
 001: empty
Open vSwitch CI 78f366
 002: change conditions
Open vSwitch CI 78f366
-003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 004: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -601,8 +601,8 @@ OVSDB_CHECK_IDL([simple idl, conditional, multiple clauses in condition],
Open vSwitch CI 78f366
   [[000: change conditions
Open vSwitch CI 78f366
 001: empty
Open vSwitch CI 78f366
 002: change conditions
Open vSwitch CI 78f366
-003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-003: i=2 r=3 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+003: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: i=2 r=3 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
 004: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -618,7 +618,7 @@ OVSDB_CHECK_IDL([simple idl, conditional, modify as insert due to condition],
Open vSwitch CI 78f366
   [[000: change conditions
Open vSwitch CI 78f366
 001: empty
Open vSwitch CI 78f366
 002: change conditions
Open vSwitch CI 78f366
-003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 004: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -641,11 +641,11 @@ OVSDB_CHECK_IDL([simple idl, conditional, modify as delete due to condition],
Open vSwitch CI 78f366
   [[000: change conditions
Open vSwitch CI 78f366
 001: empty
Open vSwitch CI 78f366
 002: change conditions
Open vSwitch CI 78f366
-003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 004: change conditions
Open vSwitch CI 78f366
 005: empty
Open vSwitch CI 78f366
 006: {"error":null,"result":[{"uuid":["uuid","<2>"]}]}
Open vSwitch CI 78f366
-007: i=2 r=3 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+007: table simple: i=2 r=3 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
 008: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -676,15 +676,15 @@ OVSDB_CHECK_IDL([simple idl, conditional, multiple tables],
Open vSwitch CI 78f366
   [[000: change conditions
Open vSwitch CI 78f366
 001: empty
Open vSwitch CI 78f366
 002: change conditions
Open vSwitch CI 78f366
-003: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 004: change conditions
Open vSwitch CI 78f366
-005: i=0 k=0 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
-005: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+005: table link1: i=0 k=0 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+005: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 006: change conditions
Open vSwitch CI 78f366
 007: {"error":null,"result":[{"uuid":["uuid","<3>"]}]}
Open vSwitch CI 78f366
-008: i=0 k=0 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
-008: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-008: i=3 l1= uuid=<3>
Open vSwitch CI 78f366
+008: table link1: i=0 k=0 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+008: table link2: i=3 l1= uuid=<3>
Open vSwitch CI 78f366
+008: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 009: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -716,19 +716,19 @@ OVSDB_CHECK_IDL([self-linking idl, consistent ops],
Open vSwitch CI 78f366
        "row": {"k": ["uuid", "#0#"]}}]']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<0>"]}]}
Open vSwitch CI 78f366
-002: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
+002: table link1: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
 003: {"error":null,"result":[{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]}]}
Open vSwitch CI 78f366
-004: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
-004: i=1 k=2 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
-004: i=2 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+004: table link1: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
+004: table link1: i=1 k=2 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
+004: table link1: i=2 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
 005: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-006: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
-006: i=1 k=1 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
-006: i=2 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+006: table link1: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
+006: table link1: i=1 k=1 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
+006: table link1: i=2 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
 007: {"error":null,"result":[{"count":3}]}
Open vSwitch CI 78f366
-008: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
-008: i=1 k=0 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
-008: i=2 k=0 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+008: table link1: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
+008: table link1: i=1 k=0 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
+008: table link1: i=2 k=0 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
 009: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -767,12 +767,12 @@ OVSDB_CHECK_IDL([self-linking idl, inconsistent ops],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"details":"Table link1 column k row <0> references nonexistent row <1> in table link1.","error":"referential integrity violation"}]}
Open vSwitch CI 78f366
 002: {"error":null,"result":[{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]}
Open vSwitch CI 78f366
-003: i=1 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
-003: i=2 k=1 ka=[] l2= uuid=<3>
Open vSwitch CI 78f366
+003: table link1: i=1 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+003: table link1: i=2 k=1 ka=[] l2= uuid=<3>
Open vSwitch CI 78f366
 004: {"error":null,"result":[{"count":2},{"details":"Table link1 column k row <x> references nonexistent row <4> in table link1.","error":"referential integrity violation"}]}
Open vSwitch CI 78f366
 005: {"error":null,"result":[{"count":1},{"details":"cannot delete link1 row <2> because of 1 remaining reference(s)","error":"referential integrity violation"}]}
Open vSwitch CI 78f366
 006: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-007: i=1 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+007: table link1: i=1 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
 008: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
 009: empty
Open vSwitch CI 78f366
 010: done
Open vSwitch CI 78f366
@@ -815,15 +815,15 @@ OVSDB_CHECK_IDL([self-linking idl, sets],
Open vSwitch CI 78f366
        "where": []}]']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]}
Open vSwitch CI 78f366
-002: i=0 k=0 ka=[0] l2= uuid=<0>
Open vSwitch CI 78f366
-002: i=1 k=0 ka=[1] l2= uuid=<1>
Open vSwitch CI 78f366
-002: i=2 k=0 ka=[2] l2= uuid=<2>
Open vSwitch CI 78f366
-002: i=3 k=0 ka=[3] l2= uuid=<3>
Open vSwitch CI 78f366
+002: table link1: i=0 k=0 ka=[0] l2= uuid=<0>
Open vSwitch CI 78f366
+002: table link1: i=1 k=0 ka=[1] l2= uuid=<1>
Open vSwitch CI 78f366
+002: table link1: i=2 k=0 ka=[2] l2= uuid=<2>
Open vSwitch CI 78f366
+002: table link1: i=3 k=0 ka=[3] l2= uuid=<3>
Open vSwitch CI 78f366
 003: {"error":null,"result":[{"count":4}]}
Open vSwitch CI 78f366
-004: i=0 k=0 ka=[0 1 2 3] l2= uuid=<0>
Open vSwitch CI 78f366
-004: i=1 k=0 ka=[0 1 2 3] l2= uuid=<1>
Open vSwitch CI 78f366
-004: i=2 k=0 ka=[0 1 2 3] l2= uuid=<2>
Open vSwitch CI 78f366
-004: i=3 k=0 ka=[0 1 2 3] l2= uuid=<3>
Open vSwitch CI 78f366
+004: table link1: i=0 k=0 ka=[0 1 2 3] l2= uuid=<0>
Open vSwitch CI 78f366
+004: table link1: i=1 k=0 ka=[0 1 2 3] l2= uuid=<1>
Open vSwitch CI 78f366
+004: table link1: i=2 k=0 ka=[0 1 2 3] l2= uuid=<2>
Open vSwitch CI 78f366
+004: table link1: i=3 k=0 ka=[0 1 2 3] l2= uuid=<3>
Open vSwitch CI 78f366
 005: {"error":null,"result":[{"count":1},{"details":"Table link1 column ka row <2> references nonexistent row <4> in table link1.","error":"referential integrity violation"}]}
Open vSwitch CI 78f366
 006: {"error":null,"result":[{"count":4}]}
Open vSwitch CI 78f366
 007: empty
Open vSwitch CI 78f366
@@ -843,8 +843,8 @@ OVSDB_CHECK_IDL([external-linking idl, consistent ops],
Open vSwitch CI 78f366
        "uuid-name": "row1"}]']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]}
Open vSwitch CI 78f366
-002: i=0 l1= uuid=<0>
Open vSwitch CI 78f366
-002: i=1 k=1 ka=[] l2=0 uuid=<1>
Open vSwitch CI 78f366
+002: table link1: i=1 k=1 ka=[] l2=0 uuid=<1>
Open vSwitch CI 78f366
+002: table link2: i=0 l1= uuid=<0>
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -867,20 +867,49 @@ OVSDB_CHECK_IDL([singleton idl, constraints],
Open vSwitch CI 78f366
        "row": {"name": "bar"}}]']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<0>"]}]}
Open vSwitch CI 78f366
-002: name=foo uuid=<0>
Open vSwitch CI 78f366
+002: table singleton: name=foo uuid=<0>
Open vSwitch CI 78f366
 003: {"error":null,"result":[{"uuid":["uuid","<1>"]},{"details":"transaction causes \"singleton\" table to contain 2 rows, greater than the schema-defined limit of 1 row(s)","error":"constraint violation"}]}
Open vSwitch CI 78f366
 004: {"error":null,"result":[{"count":1},{"uuid":["uuid","<2>"]}]}
Open vSwitch CI 78f366
-005: name=bar uuid=<2>
Open vSwitch CI 78f366
+005: table singleton: name=bar uuid=<2>
Open vSwitch CI 78f366
 006: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+dnl This test creates a database with references and checks that deleting both
Open vSwitch CI 78f366
+dnl source and destination rows of a reference in a single update doesn't leak
Open vSwitch CI 78f366
+dnl rows that got orphaned when processing the update.
Open vSwitch CI 78f366
+OVSDB_CHECK_IDL([simple idl, references, multiple deletes],
Open vSwitch CI 78f366
+  [['["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row0_s"},
Open vSwitch CI 78f366
+       "uuid-name": "weak_row0"},
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple6",
Open vSwitch CI 78f366
+       "row": {"name": "first_row",
Open vSwitch CI 78f366
+               "weak_ref": ["set",
Open vSwitch CI 78f366
+                             [["named-uuid", "weak_row0"]]
Open vSwitch CI 78f366
+                           ]}}]']],
Open vSwitch CI 78f366
+  [['["idltest",
Open vSwitch CI 78f366
+      {"op": "delete",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "where": [["s", "==", "row0_s"]]},
Open vSwitch CI 78f366
+      {"op": "delete",
Open vSwitch CI 78f366
+       "table": "simple6",
Open vSwitch CI 78f366
+       "where": [["name", "==", "first_row"]]}]']],
Open vSwitch CI 78f366
+  [[000: table simple6: name=first_row weak_ref=[<0>] uuid=<1>
Open vSwitch CI 78f366
+000: table simple: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<0>
Open vSwitch CI 78f366
+001: {"error":null,"result":[{"count":1},{"count":1}]}
Open vSwitch CI 78f366
+002: empty
Open vSwitch CI 78f366
+003: done
Open vSwitch CI 78f366
+]])
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
 OVSDB_CHECK_IDL_PY([external-linking idl, insert ops],
Open vSwitch CI 78f366
   [],
Open vSwitch CI 78f366
   [['linktest']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
-002: i=1 k=1 ka=[1] l2= uuid=<0>
Open vSwitch CI 78f366
-002: i=2 k=1 ka=[1 2] l2= uuid=<1>
Open vSwitch CI 78f366
+002: table link1: i=1 k=1 ka=[1] l2= uuid=<0>
Open vSwitch CI 78f366
+002: table link1: i=2 k=1 ka=[1 2] l2= uuid=<1>
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -889,7 +918,7 @@ OVSDB_CHECK_IDL_PY([getattr idl, insert ops],
Open vSwitch CI 78f366
   [['getattrtest']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
-002: i=2 k=2 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
+002: table link1: i=2 k=2 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -902,11 +931,11 @@ OVSDB_CHECK_IDL_PY([row-from-json idl, whats this],
Open vSwitch CI 78f366
        "table": "simple",
Open vSwitch CI 78f366
        "row": {}}]']],
Open vSwitch CI 78f366
   [['notifytest insert 2, notifytest set 1 b 1, notifytest delete 0']],
Open vSwitch CI 78f366
-  [[000: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-000: i=1 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+000: table simple: i=1 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
 001: commit, status=success, events=create|2|None, delete|0|None, update|1|b
Open vSwitch CI 78f366
-002: i=1 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
-002: i=2 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+002: table simple: i=1 r=0 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+002: table simple: i=2 r=0 b=false s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -946,19 +975,19 @@ AT_CHECK([test-ovsdb '-vPATTERN:console:test-ovsdb|%c|%m' -vjsonrpc -t10 idl uni
Open vSwitch CI 78f366
 AT_CHECK([sort stdout | uuidfilt], [0],
Open vSwitch CI 78f366
     [[000: empty
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<0>"]}]}
Open vSwitch CI 78f366
-002: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
+002: table link1: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
 003: {"error":null,"result":[{"uuid":["uuid","<1>"]},{"uuid":["uuid","<2>"]}]}
Open vSwitch CI 78f366
-004: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
-004: i=1 k=2 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
-004: i=2 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+004: table link1: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
+004: table link1: i=1 k=2 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
+004: table link1: i=2 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
 005: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-006: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
-006: i=1 k=1 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
-006: i=2 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+006: table link1: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
+006: table link1: i=1 k=1 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
+006: table link1: i=2 k=1 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
 007: {"error":null,"result":[{"count":3}]}
Open vSwitch CI 78f366
-008: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
-008: i=1 k=0 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
-008: i=2 k=0 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
+008: table link1: i=0 k=0 ka=[] l2= uuid=<0>
Open vSwitch CI 78f366
+008: table link1: i=1 k=0 ka=[] l2= uuid=<1>
Open vSwitch CI 78f366
+008: table link1: i=2 k=0 ka=[] l2= uuid=<2>
Open vSwitch CI 78f366
 009: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1022,11 +1051,11 @@ OVSDB_CHECK_IDL_FETCH_COLUMNS([simple idl, initially populated],
Open vSwitch CI 78f366
        "row": {}}]']],
Open vSwitch CI 78f366
   [?simple:i,r!],
Open vSwitch CI 78f366
   ['fetch 0 r'],
Open vSwitch CI 78f366
-  [[000: i=0 uuid=<0>
Open vSwitch CI 78f366
-000: i=1 uuid=<1>
Open vSwitch CI 78f366
+  [[000: table simple: i=0 uuid=<0>
Open vSwitch CI 78f366
+000: table simple: i=1 uuid=<1>
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
-002: i=0 r=0 uuid=<0>
Open vSwitch CI 78f366
-002: i=1 uuid=<1>
Open vSwitch CI 78f366
+002: table simple: i=0 r=0 uuid=<0>
Open vSwitch CI 78f366
+002: table simple: i=1 uuid=<1>
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1098,28 +1127,28 @@ OVSDB_CHECK_IDL_WO_MONITOR_COND([simple idl disable monitor-cond],
Open vSwitch CI 78f366
     'reconnect']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]}
Open vSwitch CI 78f366
-002: i=0 r=0 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-002: i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+002: table simple: i=0 r=0 b=false s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+002: table simple: i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 003: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-004: i=0 r=0 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-004: i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+004: table simple: i=0 r=0 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+004: table simple: i=1 r=2 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 005: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-006: i=0 r=123.5 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-006: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+006: table simple: i=0 r=123.5 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+006: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 007: {"error":null,"result":[{"uuid":["uuid","<6>"]}]}
Open vSwitch CI 78f366
-008: i=-1 r=125 b=false s= u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-008: i=0 r=123.5 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-008: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+008: table simple: i=-1 r=125 b=false s= u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+008: table simple: i=0 r=123.5 b=true s= u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+008: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 009: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-010: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-010: i=0 r=123.5 b=true s=newstring u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-010: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+010: table simple: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+010: table simple: i=0 r=123.5 b=true s=newstring u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+010: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 011: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-012: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-012: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+012: table simple: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+012: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 013: reconnect
Open vSwitch CI 78f366
-014: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-014: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
+014: table simple: i=-1 r=125 b=false s=newstring u=<2> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+014: table simple: i=1 r=123.5 b=true s=mystring u=<3> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<4> <5>] uuid=<0>
Open vSwitch CI 78f366
 015: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1162,13 +1191,12 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated],
Open vSwitch CI 78f366
        "table": "simple",
Open vSwitch CI 78f366
        "where": [],
Open vSwitch CI 78f366
        "row": {"b": true}}]']],
Open vSwitch CI 78f366
-  [[000: i=1 r=2 b=true s=mystring u=<0> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<1> <2>] uuid=<3>
Open vSwitch CI 78f366
-000: inserted row: uuid=<3>
Open vSwitch CI 78f366
-000: updated columns: b ba i ia r ra s sa u ua
Open vSwitch CI 78f366
+  [[000: table simple: inserted row: i=1 r=2 b=true s=mystring u=<0> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<1> <2>] uuid=<3>
Open vSwitch CI 78f366
+000: table simple: updated columns: b ba i ia r ra s sa u ua
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-002: i=0 r=0 b=true s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<5>
Open vSwitch CI 78f366
-002: i=1 r=2 b=true s=mystring u=<0> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<1> <2>] uuid=<3>
Open vSwitch CI 78f366
-002: updated columns: b
Open vSwitch CI 78f366
+002: table simple: i=0 r=0 b=true s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<5>
Open vSwitch CI 78f366
+002: table simple: i=1 r=2 b=true s=mystring u=<0> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<1> <2>] uuid=<3>
Open vSwitch CI 78f366
+002: table simple: updated columns: b
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1209,19 +1237,17 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated, orphan weak refer
Open vSwitch CI 78f366
       "table": "simple6",
Open vSwitch CI 78f366
       "where": []}]']],
Open vSwitch CI 78f366
   [[000: change conditions
Open vSwitch CI 78f366
-001: inserted row: uuid=<0>
Open vSwitch CI 78f366
-001: name=first_row weak_ref=[] uuid=<0>
Open vSwitch CI 78f366
-001: updated columns: name weak_ref
Open vSwitch CI 78f366
+001: table simple6: inserted row: name=first_row weak_ref=[] uuid=<0>
Open vSwitch CI 78f366
+001: table simple6: updated columns: name weak_ref
Open vSwitch CI 78f366
 002: change conditions
Open vSwitch CI 78f366
-003: i=0 r=0 b=false s=row1_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
-003: inserted row: uuid=<2>
Open vSwitch CI 78f366
-003: name=first_row weak_ref=[<2>] uuid=<0>
Open vSwitch CI 78f366
-003: updated columns: s
Open vSwitch CI 78f366
+003: table simple6: name=first_row weak_ref=[<1>] uuid=<0>
Open vSwitch CI 78f366
+003: table simple: inserted row: i=0 r=0 b=false s=row1_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: updated columns: s
Open vSwitch CI 78f366
 004: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-005: name=new_name weak_ref=[<2>] uuid=<0>
Open vSwitch CI 78f366
-005: updated columns: name
Open vSwitch CI 78f366
+005: table simple6: name=new_name weak_ref=[<1>] uuid=<0>
Open vSwitch CI 78f366
+005: table simple6: updated columns: name
Open vSwitch CI 78f366
 006: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-007: i=0 r=0 b=false s=row1_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+007: table simple: i=0 r=0 b=false s=row1_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 008: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1253,30 +1279,266 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated, orphan rows, cond
Open vSwitch CI 78f366
       "table": "simple6",
Open vSwitch CI 78f366
       "where": []}]']],
Open vSwitch CI 78f366
   [[000: change conditions
Open vSwitch CI 78f366
-001: inserted row: uuid=<0>
Open vSwitch CI 78f366
-001: name=first_row weak_ref=[] uuid=<0>
Open vSwitch CI 78f366
-001: updated columns: name weak_ref
Open vSwitch CI 78f366
+001: table simple6: inserted row: name=first_row weak_ref=[] uuid=<0>
Open vSwitch CI 78f366
+001: table simple6: updated columns: name weak_ref
Open vSwitch CI 78f366
 002: change conditions
Open vSwitch CI 78f366
-003: i=0 r=0 b=false s=row0_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
-003: inserted row: uuid=<2>
Open vSwitch CI 78f366
-003: name=first_row weak_ref=[<2>] uuid=<0>
Open vSwitch CI 78f366
-003: updated columns: s
Open vSwitch CI 78f366
+003: table simple6: name=first_row weak_ref=[<1>] uuid=<0>
Open vSwitch CI 78f366
+003: table simple: inserted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: updated columns: s
Open vSwitch CI 78f366
 004: change conditions
Open vSwitch CI 78f366
-005: i=0 r=0 b=false s=row1_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
-005: inserted row: uuid=<3>
Open vSwitch CI 78f366
-005: updated columns: s
Open vSwitch CI 78f366
+005: table simple6: name=first_row weak_ref=[] uuid=<0>
Open vSwitch CI 78f366
+005: table simple: deleted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+005: table simple: inserted row: i=0 r=0 b=false s=row1_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+005: table simple: updated columns: s
Open vSwitch CI 78f366
 006: change conditions
Open vSwitch CI 78f366
-007: deleted row: uuid=<3>
Open vSwitch CI 78f366
-007: i=0 r=0 b=false s=row0_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
-007: i=0 r=0 b=false s=row1_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
-007: inserted row: uuid=<2>
Open vSwitch CI 78f366
-007: name=first_row weak_ref=[<2>] uuid=<0>
Open vSwitch CI 78f366
-007: updated columns: s
Open vSwitch CI 78f366
+007: table simple6: name=first_row weak_ref=[<1>] uuid=<0>
Open vSwitch CI 78f366
+007: table simple: deleted row: i=0 r=0 b=false s=row1_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+007: table simple: inserted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+007: table simple: updated columns: s
Open vSwitch CI 78f366
+008: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
+009: table simple: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+010: done
Open vSwitch CI 78f366
+]])
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+dnl This test checks that deleting the destination of a weak reference
Open vSwitch CI 78f366
+dnl without deleting the source, through monitor condition change, updates
Open vSwitch CI 78f366
+dnl the source tracked record.
Open vSwitch CI 78f366
+OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated, references, conditional delete],
Open vSwitch CI 78f366
+  [['["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row0_s", "i": 0},
Open vSwitch CI 78f366
+       "uuid-name": "weak_row0"},
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row1_s", "i": 1},
Open vSwitch CI 78f366
+       "uuid-name": "weak_row1"},
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple6",
Open vSwitch CI 78f366
+       "row": {"name": "first_row",
Open vSwitch CI 78f366
+               "weak_ref": ["set",
Open vSwitch CI 78f366
+                             [["named-uuid", "weak_row0"],
Open vSwitch CI 78f366
+                              ["named-uuid", "weak_row1"]]
Open vSwitch CI 78f366
+                           ]}}]']],
Open vSwitch CI 78f366
+  [['condition simple []' \
Open vSwitch CI 78f366
+    'condition simple [["s","==","row0_s"]]' \
Open vSwitch CI 78f366
+    'condition simple [["s","==","row1_s"]]' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "update",
Open vSwitch CI 78f366
+      "table": "simple6",
Open vSwitch CI 78f366
+      "where": [],
Open vSwitch CI 78f366
+      "row": {"name": "new_name"}}]' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "delete",
Open vSwitch CI 78f366
+      "table": "simple6",
Open vSwitch CI 78f366
+      "where": []}]']],
Open vSwitch CI 78f366
+  [[000: change conditions
Open vSwitch CI 78f366
+001: table simple6: inserted row: name=first_row weak_ref=[] uuid=<0>
Open vSwitch CI 78f366
+001: table simple6: updated columns: name weak_ref
Open vSwitch CI 78f366
+002: change conditions
Open vSwitch CI 78f366
+003: table simple6: name=first_row weak_ref=[<1>] uuid=<0>
Open vSwitch CI 78f366
+003: table simple: inserted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: updated columns: s
Open vSwitch CI 78f366
+004: change conditions
Open vSwitch CI 78f366
+005: table simple6: name=first_row weak_ref=[<3>] uuid=<0>
Open vSwitch CI 78f366
+005: table simple: deleted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+005: table simple: inserted row: i=1 r=0 b=false s=row1_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+005: table simple: updated columns: i s
Open vSwitch CI 78f366
+006: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
+007: table simple6: name=new_name weak_ref=[<3>] uuid=<0>
Open vSwitch CI 78f366
+007: table simple6: updated columns: name
Open vSwitch CI 78f366
 008: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-009: i=0 r=0 b=false s=row0_s u=<1> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+009: table simple: i=1 r=0 b=false s=row1_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
 010: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+dnl This test checks that deleting the destination of a reference updates the
Open vSwitch CI 78f366
+dnl source tracked record.
Open vSwitch CI 78f366
+OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated, references, single delete],
Open vSwitch CI 78f366
+  [['["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row0_s"},
Open vSwitch CI 78f366
+       "uuid-name": "uuid_row0_s"},
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple6",
Open vSwitch CI 78f366
+       "row": {"name": "row0_s6",
Open vSwitch CI 78f366
+               "weak_ref": ["set",
Open vSwitch CI 78f366
+                             [["named-uuid", "uuid_row0_s"]]
Open vSwitch CI 78f366
+                           ]}}]']],
Open vSwitch CI 78f366
+  [['condition simple [true];simple6 [true]' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "delete",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "where": []}]' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row0_s"}}]']],
Open vSwitch CI 78f366
+  [[000: change conditions
Open vSwitch CI 78f366
+001: table simple6: inserted row: name=row0_s6 weak_ref=[<0>] uuid=<1>
Open vSwitch CI 78f366
+001: table simple6: updated columns: name weak_ref
Open vSwitch CI 78f366
+001: table simple: inserted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<0>
Open vSwitch CI 78f366
+001: table simple: updated columns: s
Open vSwitch CI 78f366
+002: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
+003: table simple6: name=row0_s6 weak_ref=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple6: updated columns: weak_ref
Open vSwitch CI 78f366
+003: table simple: deleted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<0>
Open vSwitch CI 78f366
+004: {"error":null,"result":[{"uuid":["uuid","<3>"]}]}
Open vSwitch CI 78f366
+005: table simple6: name=row0_s6 weak_ref=[] uuid=<1>
Open vSwitch CI 78f366
+005: table simple: inserted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+005: table simple: updated columns: s
Open vSwitch CI 78f366
+006: done
Open vSwitch CI 78f366
+]])
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+dnl This test checks that deleting both the destination and source of the
Open vSwitch CI 78f366
+dnl reference doesn't remove the reference in the source tracked record.
Open vSwitch CI 78f366
+OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated, weak references, multiple deletes],
Open vSwitch CI 78f366
+  [['["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row0_s"},
Open vSwitch CI 78f366
+       "uuid-name": "uuid_row0_s"},
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple6",
Open vSwitch CI 78f366
+       "row": {"name": "row0_s6",
Open vSwitch CI 78f366
+               "weak_ref": ["set",
Open vSwitch CI 78f366
+                             [["named-uuid", "uuid_row0_s"]]
Open vSwitch CI 78f366
+                           ]}}]']],
Open vSwitch CI 78f366
+  [['condition simple [true];simple6 [true]' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "delete",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "where": []},
Open vSwitch CI 78f366
+      {"op": "delete",
Open vSwitch CI 78f366
+       "table": "simple6",
Open vSwitch CI 78f366
+       "where": []}]' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row0_s"}}]']],
Open vSwitch CI 78f366
+  [[000: change conditions
Open vSwitch CI 78f366
+001: table simple6: inserted row: name=row0_s6 weak_ref=[<0>] uuid=<1>
Open vSwitch CI 78f366
+001: table simple6: updated columns: name weak_ref
Open vSwitch CI 78f366
+001: table simple: inserted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<0>
Open vSwitch CI 78f366
+001: table simple: updated columns: s
Open vSwitch CI 78f366
+002: {"error":null,"result":[{"count":1},{"count":1}]}
Open vSwitch CI 78f366
+003: table simple6: deleted row: name=row0_s6 weak_ref=[<0>] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: deleted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<0>
Open vSwitch CI 78f366
+004: {"error":null,"result":[{"uuid":["uuid","<3>"]}]}
Open vSwitch CI 78f366
+005: table simple: inserted row: i=0 r=0 b=false s=row0_s u=<2> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+005: table simple: updated columns: s
Open vSwitch CI 78f366
+006: done
Open vSwitch CI 78f366
+]])
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+dnl This test checks that deleting both the destination and source of the
Open vSwitch CI 78f366
+dnl reference doesn't remove the reference in the source tracked record.
Open vSwitch CI 78f366
+OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated, strong references, multiple deletes],
Open vSwitch CI 78f366
+  [['["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple4",
Open vSwitch CI 78f366
+       "row": {"name": "row0_s4"},
Open vSwitch CI 78f366
+       "uuid-name": "uuid_row0_s4"},
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple3",
Open vSwitch CI 78f366
+       "row": {"name": "row0_s3",
Open vSwitch CI 78f366
+               "uref": ["set",
Open vSwitch CI 78f366
+                         [["named-uuid", "uuid_row0_s4"]]
Open vSwitch CI 78f366
+                       ]}}]']],
Open vSwitch CI 78f366
+  [['condition simple [true];simple3 [true];simple4 [true]' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "delete",
Open vSwitch CI 78f366
+       "table": "simple3",
Open vSwitch CI 78f366
+       "where": []},
Open vSwitch CI 78f366
+      {"op": "delete",
Open vSwitch CI 78f366
+       "table": "simple4",
Open vSwitch CI 78f366
+       "where": []}]' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row0_s"}}]']],
Open vSwitch CI 78f366
+  [[000: change conditions
Open vSwitch CI 78f366
+001: table simple3: inserted row: name=row0_s3 uset=[] uref=[<0>] uuid=<1>
Open vSwitch CI 78f366
+001: table simple3: updated columns: name uref
Open vSwitch CI 78f366
+001: table simple4: inserted row: name=row0_s4 uuid=<0>
Open vSwitch CI 78f366
+001: table simple4: updated columns: name
Open vSwitch CI 78f366
+002: {"error":null,"result":[{"count":1},{"count":1}]}
Open vSwitch CI 78f366
+003: table simple3: deleted row: name=row0_s3 uset=[] uref=[<0>] uuid=<1>
Open vSwitch CI 78f366
+003: table simple4: deleted row: name=row0_s4 uuid=<0>
Open vSwitch CI 78f366
+004: {"error":null,"result":[{"uuid":["uuid","<2>"]}]}
Open vSwitch CI 78f366
+005: table simple: inserted row: i=0 r=0 b=false s=row0_s u=<3> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+005: table simple: updated columns: s
Open vSwitch CI 78f366
+006: done
Open vSwitch CI 78f366
+]])
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+dnl This test checks that changing conditions to not include the target of
Open vSwitch CI 78f366
+dnl a strong reference also updates the source row when change tracking is
Open vSwitch CI 78f366
+dnl enabled.
Open vSwitch CI 78f366
+OVSDB_CHECK_IDL_TRACK([track, simple idl, initially populated, strong references, conditional],
Open vSwitch CI 78f366
+  [['["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple4",
Open vSwitch CI 78f366
+       "row": {"name": "row0_s4"},
Open vSwitch CI 78f366
+       "uuid-name": "uuid_row0_s4"},
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple3",
Open vSwitch CI 78f366
+       "row": {"name": "row0_s3",
Open vSwitch CI 78f366
+               "uref": ["set",
Open vSwitch CI 78f366
+                         [["named-uuid", "uuid_row0_s4"]]
Open vSwitch CI 78f366
+                       ]}}]']],
Open vSwitch CI 78f366
+  [['condition simple [true];simple3 [true];simple4 [true]' \
Open vSwitch CI 78f366
+    'condition simple4 []' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row0_s"}}]']],
Open vSwitch CI 78f366
+  [[000: change conditions
Open vSwitch CI 78f366
+001: table simple3: inserted row: name=row0_s3 uset=[] uref=[<0>] uuid=<1>
Open vSwitch CI 78f366
+001: table simple3: updated columns: name uref
Open vSwitch CI 78f366
+001: table simple4: inserted row: name=row0_s4 uuid=<0>
Open vSwitch CI 78f366
+001: table simple4: updated columns: name
Open vSwitch CI 78f366
+002: change conditions
Open vSwitch CI 78f366
+003: table simple3: name=row0_s3 uset=[] uref=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple4: deleted row: name=row0_s4 uuid=<0>
Open vSwitch CI 78f366
+004: {"error":null,"result":[{"uuid":["uuid","<2>"]}]}
Open vSwitch CI 78f366
+005: table simple3: name=row0_s3 uset=[] uref=[] uuid=<1>
Open vSwitch CI 78f366
+005: table simple: inserted row: i=0 r=0 b=false s=row0_s u=<3> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+005: table simple: updated columns: s
Open vSwitch CI 78f366
+006: done
Open vSwitch CI 78f366
+]])
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+dnl This test checks that changing conditions to not include the target of
Open vSwitch CI 78f366
+dnl a strong reference also updates the source row when change tracking is
Open vSwitch CI 78f366
+dnl disabled.
Open vSwitch CI 78f366
+OVSDB_CHECK_IDL([simple idl, initially populated, strong references, conditional],
Open vSwitch CI 78f366
+  [['["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple4",
Open vSwitch CI 78f366
+       "row": {"name": "row0_s4"},
Open vSwitch CI 78f366
+       "uuid-name": "uuid_row0_s4"},
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple3",
Open vSwitch CI 78f366
+       "row": {"name": "row0_s3",
Open vSwitch CI 78f366
+               "uref": ["set",
Open vSwitch CI 78f366
+                         [["named-uuid", "uuid_row0_s4"]]
Open vSwitch CI 78f366
+                       ]}}]']],
Open vSwitch CI 78f366
+  [['condition simple [true];simple3 [true];simple4 [true]' \
Open vSwitch CI 78f366
+    'condition simple4 []' \
Open vSwitch CI 78f366
+    '["idltest",
Open vSwitch CI 78f366
+      {"op": "insert",
Open vSwitch CI 78f366
+       "table": "simple",
Open vSwitch CI 78f366
+       "row": {"s": "row0_s"}}]']],
Open vSwitch CI 78f366
+  [[000: change conditions
Open vSwitch CI 78f366
+001: table simple3: name=row0_s3 uset=[] uref=[<0>] uuid=<1>
Open vSwitch CI 78f366
+001: table simple4: name=row0_s4 uuid=<0>
Open vSwitch CI 78f366
+002: change conditions
Open vSwitch CI 78f366
+003: table simple3: name=row0_s3 uset=[] uref=[] uuid=<1>
Open vSwitch CI 78f366
+004: {"error":null,"result":[{"uuid":["uuid","<2>"]}]}
Open vSwitch CI 78f366
+005: table simple3: name=row0_s3 uset=[] uref=[] uuid=<1>
Open vSwitch CI 78f366
+005: table simple: i=0 r=0 b=false s=row0_s u=<3> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+006: done
Open vSwitch CI 78f366
+]])
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
 OVSDB_CHECK_IDL_TRACK([track, simple idl, initially empty, various ops],
Open vSwitch CI 78f366
   [],
Open vSwitch CI 78f366
   [['["idltest",
Open vSwitch CI 78f366
@@ -1330,34 +1592,31 @@ OVSDB_CHECK_IDL_TRACK([track, simple idl, initially empty, various ops],
Open vSwitch CI 78f366
     'reconnect']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<0>"]},{"uuid":["uuid","<1>"]}]}
Open vSwitch CI 78f366
-002: i=1 r=2 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<0>
Open vSwitch CI 78f366
-002: inserted row: uuid=<0>
Open vSwitch CI 78f366
-002: updated columns: b ba i ia r ra s sa u ua
Open vSwitch CI 78f366
+002: table simple: inserted row: i=1 r=2 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<0>
Open vSwitch CI 78f366
+002: table simple: updated columns: b ba i ia r ra s sa u ua
Open vSwitch CI 78f366
 003: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-004: i=0 r=0 b=true s= u=<5> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-004: updated columns: b
Open vSwitch CI 78f366
+004: table simple: i=0 r=0 b=true s= u=<5> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+004: table simple: updated columns: b
Open vSwitch CI 78f366
 005: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-006: i=0 r=123.5 b=true s= u=<5> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-006: i=1 r=123.5 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<0>
Open vSwitch CI 78f366
-006: updated columns: r
Open vSwitch CI 78f366
-006: updated columns: r
Open vSwitch CI 78f366
+006: table simple: i=0 r=123.5 b=true s= u=<5> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+006: table simple: i=1 r=123.5 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<0>
Open vSwitch CI 78f366
+006: table simple: updated columns: r
Open vSwitch CI 78f366
+006: table simple: updated columns: r
Open vSwitch CI 78f366
 007: {"error":null,"result":[{"uuid":["uuid","<6>"]}]}
Open vSwitch CI 78f366
-008: i=-1 r=125 b=false s= u=<5> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-008: inserted row: uuid=<6>
Open vSwitch CI 78f366
-008: updated columns: ba i ia r ra
Open vSwitch CI 78f366
+008: table simple: inserted row: i=-1 r=125 b=false s= u=<5> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+008: table simple: updated columns: ba i ia r ra
Open vSwitch CI 78f366
 009: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-010: i=-1 r=125 b=false s=newstring u=<5> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-010: i=0 r=123.5 b=true s=newstring u=<5> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
-010: updated columns: s
Open vSwitch CI 78f366
-010: updated columns: s
Open vSwitch CI 78f366
+010: table simple: i=-1 r=125 b=false s=newstring u=<5> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+010: table simple: i=0 r=123.5 b=true s=newstring u=<5> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+010: table simple: updated columns: s
Open vSwitch CI 78f366
+010: table simple: updated columns: s
Open vSwitch CI 78f366
 011: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-012: deleted row: uuid=<1>
Open vSwitch CI 78f366
-012: i=0 r=123.5 b=true s=newstring u=<5> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+012: table simple: deleted row: i=0 r=123.5 b=true s=newstring u=<5> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 013: reconnect
Open vSwitch CI 78f366
-014: i=-1 r=125 b=false s=newstring u=<5> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
-014: i=1 r=123.5 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<0>
Open vSwitch CI 78f366
-014: updated columns: b ba i ia r ra s sa u ua
Open vSwitch CI 78f366
-014: updated columns: ba i ia r ra s
Open vSwitch CI 78f366
+014: table simple: inserted row: i=-1 r=125 b=false s=newstring u=<5> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<6>
Open vSwitch CI 78f366
+014: table simple: inserted row: i=1 r=123.5 b=true s=mystring u=<2> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<3> <4>] uuid=<0>
Open vSwitch CI 78f366
+014: table simple: updated columns: b ba i ia r ra s sa u ua
Open vSwitch CI 78f366
+014: table simple: updated columns: ba i ia r ra s
Open vSwitch CI 78f366
 015: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1397,16 +1656,16 @@ OVSDB_CHECK_IDL_PY([partial-map idl],
Open vSwitch CI 78f366
                 "row":{"name":"myString1","smap":["map",[["key1","value1"],["key2","value2"]]]} }]']
Open vSwitch CI 78f366
 ],
Open vSwitch CI 78f366
   [?simple2:name,smap,imap 'partialmapinsertelement' 'partialmapinsertmultipleelements' 'partialmapdelelements' 'partialmapmutatenew'],
Open vSwitch CI 78f366
-[[000: name=myString1 smap=[(key1 value1) (key2 value2)] imap=[]
Open vSwitch CI 78f366
+[[000: table simple2: name=myString1 smap=[(key1 value1) (key2 value2)] imap=[] uuid=<0>
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
-002: name=String2 smap=[(key1 myList1) (key2 value2)] imap=[(3 myids2)]
Open vSwitch CI 78f366
+002: table simple2: name=String2 smap=[(key1 myList1) (key2 value2)] imap=[(3 myids2)] uuid=<0>
Open vSwitch CI 78f366
 003: commit, status=success
Open vSwitch CI 78f366
-004: name=String2 smap=[(key1 myList1) (key2 myList2) (key3 myList3) (key4 myList4)] imap=[(3 myids2)]
Open vSwitch CI 78f366
+004: table simple2: name=String2 smap=[(key1 myList1) (key2 myList2) (key3 myList3) (key4 myList4)] imap=[(3 myids2)] uuid=<0>
Open vSwitch CI 78f366
 005: commit, status=success
Open vSwitch CI 78f366
-006: name=String2 smap=[(key2 myList2)] imap=[(3 myids2)]
Open vSwitch CI 78f366
+006: table simple2: name=String2 smap=[(key2 myList2)] imap=[(3 myids2)] uuid=<0>
Open vSwitch CI 78f366
 007: commit, status=success
Open vSwitch CI 78f366
-008: name=String2 smap=[(key2 myList2)] imap=[(3 myids2)]
Open vSwitch CI 78f366
-008: name=String2New smap=[(key1 newList1) (key2 newList2)] imap=[]
Open vSwitch CI 78f366
+008: table simple2: name=String2 smap=[(key2 myList2)] imap=[(3 myids2)] uuid=<0>
Open vSwitch CI 78f366
+008: table simple2: name=String2New smap=[(key1 newList1) (key2 newList2)] imap=[] uuid=<1>
Open vSwitch CI 78f366
 009: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1414,11 +1673,11 @@ OVSDB_CHECK_IDL_PY([partial-map update set refmap idl],
Open vSwitch CI 78f366
 [['["idltest", {"op":"insert", "table":"simple3", "row":{"name":"myString1"}},
Open vSwitch CI 78f366
                {"op":"insert", "table":"simple5", "row":{"name":"myString2"}}]']],
Open vSwitch CI 78f366
 ['partialmapmutateirefmap'],
Open vSwitch CI 78f366
-[[000: name=myString1 uset=[]
Open vSwitch CI 78f366
-000: name=myString2 irefmap=[]
Open vSwitch CI 78f366
+[[000: table simple3: name=myString1 uset=[] uref=[] uuid=<0>
Open vSwitch CI 78f366
+000: table simple5: name=myString2 irefmap=[] uuid=<1>
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
-002: name=myString1 uset=[]
Open vSwitch CI 78f366
-002: name=myString2 irefmap=[(1 <0>)]
Open vSwitch CI 78f366
+002: table simple3: name=myString1 uset=[] uref=[] uuid=<0>
Open vSwitch CI 78f366
+002: table simple5: name=myString2 irefmap=[(1 <0>)] uuid=<1>
Open vSwitch CI 78f366
 003: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1441,17 +1700,17 @@ OVSDB_CHECK_IDL_PARTIAL_UPDATE_SET_COLUMN([set, simple3 idl-partial-update-set-c
Open vSwitch CI 78f366
 ],
Open vSwitch CI 78f366
 [],
Open vSwitch CI 78f366
 [[000: Getting records
Open vSwitch CI 78f366
-001: name=mySet1 uset=[[<0>],[<1>]] uref=[]
Open vSwitch CI 78f366
+001: table simple3: name=mySet1 uset=[<0>,<1>] uref=[] uuid=<2>
Open vSwitch CI 78f366
 002: After rename+add new value
Open vSwitch CI 78f366
-003: name=String2 uset=[[<0>],[<1>],[<2>]] uref=[]
Open vSwitch CI 78f366
+003: table simple3: name=String2 uset=[<0>,<1>,<3>] uref=[] uuid=<2>
Open vSwitch CI 78f366
 004: After add new value
Open vSwitch CI 78f366
-005: name=String2 uset=[[<0>],[<1>],[<2>],[<3>]] uref=[]
Open vSwitch CI 78f366
+005: table simple3: name=String2 uset=[<0>,<1>,<3>,<4>] uref=[] uuid=<2>
Open vSwitch CI 78f366
 006: After delete value
Open vSwitch CI 78f366
-007: name=String2 uset=[[<0>],[<1>],[<3>]] uref=[]
Open vSwitch CI 78f366
+007: table simple3: name=String2 uset=[<0>,<1>,<4>] uref=[] uuid=<2>
Open vSwitch CI 78f366
 008: After trying to delete a deleted value
Open vSwitch CI 78f366
-009: name=String2 uset=[[<0>],[<1>],[<3>]] uref=[]
Open vSwitch CI 78f366
+009: table simple3: name=String2 uset=[<0>,<1>,<4>] uref=[] uuid=<2>
Open vSwitch CI 78f366
 010: After add to other table + set of strong ref
Open vSwitch CI 78f366
-011: name=String2 uset=[[<0>],[<1>],[<3>]] uref=[[<4>]]
Open vSwitch CI 78f366
+011: table simple3: name=String2 uset=[<0>,<1>,<4>] uref=[<5>] uuid=<2>
Open vSwitch CI 78f366
 012: End test
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1463,22 +1722,26 @@ OVSDB_CHECK_IDL_PY([partial-set idl],
Open vSwitch CI 78f366
                     "mutations": [["uset", "insert", ["set", [["uuid", "000d2f6a-76af-412f-b59d-e7bcd3e84eff"]]]]]}]']
Open vSwitch CI 78f366
 ],
Open vSwitch CI 78f366
   ['partialrenamesetadd' 'partialduplicateadd' 'partialsetdel' 'partialsetref' 'partialsetoverrideops' 'partialsetadddelete' 'partialsetmutatenew'],
Open vSwitch CI 78f366
-[[000: name=mySet1 uset=[<0> <1>]
Open vSwitch CI 78f366
+[[000: table simple3: name=mySet1 uset=[<0> <1>] uref=[] uuid=<2>
Open vSwitch CI 78f366
 001: commit, status=success
Open vSwitch CI 78f366
-002: name=String2 uset=[<0> <1> <2>]
Open vSwitch CI 78f366
+002: table simple3: name=String2 uset=[<0> <1> <3>] uref=[] uuid=<2>
Open vSwitch CI 78f366
 003: commit, status=success
Open vSwitch CI 78f366
-004: name=String2 uset=[<0> <1> <2> <3>]
Open vSwitch CI 78f366
+004: table simple3: name=String2 uset=[<0> <1> <3> <4>] uref=[] uuid=<2>
Open vSwitch CI 78f366
 005: commit, status=success
Open vSwitch CI 78f366
-006: name=String2 uset=[<0> <1> <3>]
Open vSwitch CI 78f366
+006: table simple3: name=String2 uset=[<0> <1> <4>] uref=[] uuid=<2>
Open vSwitch CI 78f366
 007: commit, status=success
Open vSwitch CI 78f366
-008: name=String2 uset=[<0> <1> <3>]
Open vSwitch CI 78f366
+008: table simple3: name=String2 uset=[<0> <1> <4>] uref=[<5>] uuid=<2>
Open vSwitch CI 78f366
+008: table simple4: name=test uuid=<5>
Open vSwitch CI 78f366
 009: commit, status=success
Open vSwitch CI 78f366
-010: name=String2 uset=[<3>]
Open vSwitch CI 78f366
+010: table simple3: name=String2 uset=[<4>] uref=[<5>] uuid=<2>
Open vSwitch CI 78f366
+010: table simple4: name=test uuid=<5>
Open vSwitch CI 78f366
 011: commit, status=success
Open vSwitch CI 78f366
-012: name=String2 uset=[<4> <5>]
Open vSwitch CI 78f366
+012: table simple3: name=String2 uset=[<6> <7>] uref=[<5>] uuid=<2>
Open vSwitch CI 78f366
+012: table simple4: name=test uuid=<5>
Open vSwitch CI 78f366
 013: commit, status=success
Open vSwitch CI 78f366
-014: name=String2 uset=[<4> <5>]
Open vSwitch CI 78f366
-014: name=String3 uset=[<6>]
Open vSwitch CI 78f366
+014: table simple3: name=String2 uset=[<6> <7>] uref=[<5>] uuid=<2>
Open vSwitch CI 78f366
+014: table simple3: name=String3 uset=[<8>] uref=[] uuid=<9>
Open vSwitch CI 78f366
+014: table simple4: name=test uuid=<5>
Open vSwitch CI 78f366
 015: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1486,6 +1749,28 @@ m4_define([OVSDB_CHECK_IDL_NOTIFY],
Open vSwitch CI fe1a04
    [OVSDB_CHECK_IDL_PY([$1], [], [$2], [$3], [notify $4], [$5])
Open vSwitch CI fe1a04
     OVSDB_CHECK_IDL_SSL_PY([$1], [], [$2], [$3], [notify $4], [$5])])
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
+OVSDB_CHECK_IDL_NOTIFY([simple link idl verify notify],
Open vSwitch CI fe1a04
+  [['track-notify' \
Open vSwitch CI fe1a04
+    '["idltest",
Open vSwitch CI fe1a04
+       {"op": "insert",
Open vSwitch CI fe1a04
+       "table": "link1",
Open vSwitch CI fe1a04
+       "row": {"i": 1, "k": ["named-uuid", "l1row"], "l2": ["set", [["named-uuid", "l2row"]]]},
Open vSwitch CI fe1a04
+       "uuid-name": "l1row"},
Open vSwitch CI fe1a04
+      {"op": "insert",
Open vSwitch CI fe1a04
+       "table": "link2",
Open vSwitch CI fe1a04
+       "uuid-name": "l2row",
Open vSwitch CI fe1a04
+       "row": {"i": 2, "l1": ["set", [["named-uuid", "l1row"]]]}}]']],
Open vSwitch CI fe1a04
+[[000: empty
Open vSwitch CI 78f366
+000: event:create, row={}, uuid=<0>, updates=None
Open vSwitch CI 78f366
+000: event:create, row={}, uuid=<1>, updates=None
Open vSwitch CI fe1a04
+001: {"error":null,"result":[{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]}
Open vSwitch CI 78f366
+002: event:create, row={i=1 l2=[<3>]}, uuid=<2>, updates=None
Open vSwitch CI 78f366
+002: event:create, row={i=2 l1=[<2>]}, uuid=<3>, updates=None
Open vSwitch CI 78f366
+002: table link1: i=1 k=1 ka=[] l2=2 uuid=<2>
Open vSwitch CI 78f366
+002: table link2: i=2 l1=1 uuid=<3>
Open vSwitch CI fe1a04
+003: done
Open vSwitch CI fe1a04
+]])
Open vSwitch CI fe1a04
+
Open vSwitch CI fe1a04
 OVSDB_CHECK_IDL_NOTIFY([simple idl verify notify],
Open vSwitch CI fe1a04
   [['track-notify' \
Open vSwitch CI fe1a04
     '["idltest",
Open vSwitch CI 78f366
@@ -1538,44 +1823,44 @@ OVSDB_CHECK_IDL_NOTIFY([simple idl verify notify],
Open vSwitch CI 78f366
        "where": [["i", "==", 0]]}]' \
Open vSwitch CI 78f366
     'reconnect']],
Open vSwitch CI 78f366
   [[000: empty
Open vSwitch CI 78f366
-000: event:create, row={uuid=<0>}, updates=None
Open vSwitch CI 78f366
-000: event:create, row={uuid=<1>}, updates=None
Open vSwitch CI 78f366
+000: event:create, row={}, uuid=<0>, updates=None
Open vSwitch CI 78f366
+000: event:create, row={}, uuid=<1>, updates=None
Open vSwitch CI 78f366
 001: {"error":null,"result":[{"uuid":["uuid","<2>"]},{"uuid":["uuid","<3>"]}]}
Open vSwitch CI 78f366
-002: event:create, row={i=0 r=0 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>}, updates=None
Open vSwitch CI 78f366
-002: event:create, row={i=1 r=2 b=true s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>}, updates=None
Open vSwitch CI 78f366
-002: i=0 r=0 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
-002: i=1 r=2 b=true s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
+002: event:create, row={i=0 r=0 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[]}, uuid=<3>, updates=None
Open vSwitch CI 78f366
+002: event:create, row={i=1 r=2 b=true s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>]}, uuid=<2>, updates=None
Open vSwitch CI 78f366
+002: table simple: i=0 r=0 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+002: table simple: i=1 r=2 b=true s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
 003: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-004: event:update, row={i=1 r=2 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>}, updates={b=true uuid=<2>}
Open vSwitch CI 78f366
-004: i=0 r=0 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
-004: i=1 r=2 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
+004: event:update, row={i=1 r=2 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>]}, uuid=<2>, updates={b=true}
Open vSwitch CI 78f366
+004: table simple: i=0 r=0 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+004: table simple: i=1 r=2 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
 005: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-006: event:update, row={i=0 r=123.5 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>}, updates={r=0 uuid=<3>}
Open vSwitch CI 78f366
-006: event:update, row={i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>}, updates={r=2 uuid=<2>}
Open vSwitch CI 78f366
-006: i=0 r=123.5 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
-006: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
+006: event:update, row={i=0 r=123.5 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[]}, uuid=<3>, updates={r=0}
Open vSwitch CI 78f366
+006: event:update, row={i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>]}, uuid=<2>, updates={r=2}
Open vSwitch CI 78f366
+006: table simple: i=0 r=123.5 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+006: table simple: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
 007: {"error":null,"result":[{"uuid":["uuid","<8>"]}]}
Open vSwitch CI 78f366
-008: event:create, row={i=-1 r=125 b=false s= u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>}, updates=None
Open vSwitch CI 78f366
-008: i=-1 r=125 b=false s= u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>
Open vSwitch CI 78f366
-008: i=0 r=123.5 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
-008: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
+008: event:create, row={i=-1 r=125 b=false s= u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[]}, uuid=<8>, updates=None
Open vSwitch CI 78f366
+008: table simple: i=-1 r=125 b=false s= u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>
Open vSwitch CI 78f366
+008: table simple: i=0 r=123.5 b=false s= u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+008: table simple: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
 009: {"error":null,"result":[{"count":2}]}
Open vSwitch CI 78f366
-010: event:update, row={i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>}, updates={s= uuid=<8>}
Open vSwitch CI 78f366
-010: event:update, row={i=0 r=123.5 b=false s=newstring u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>}, updates={s= uuid=<3>}
Open vSwitch CI 78f366
-010: i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>
Open vSwitch CI 78f366
-010: i=0 r=123.5 b=false s=newstring u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
-010: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
+010: event:update, row={i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[]}, uuid=<8>, updates={s=}
Open vSwitch CI 78f366
+010: event:update, row={i=0 r=123.5 b=false s=newstring u=<4> ia=[] ra=[] ba=[] sa=[] ua=[]}, uuid=<3>, updates={s=}
Open vSwitch CI 78f366
+010: table simple: i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>
Open vSwitch CI 78f366
+010: table simple: i=0 r=123.5 b=false s=newstring u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>
Open vSwitch CI 78f366
+010: table simple: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
 011: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-012: event:delete, row={i=0 r=123.5 b=false s=newstring u=<4> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<3>}, updates=None
Open vSwitch CI 78f366
-012: i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>
Open vSwitch CI 78f366
-012: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
+012: event:delete, row={i=0 r=123.5 b=false s=newstring u=<4> ia=[] ra=[] ba=[] sa=[] ua=[]}, uuid=<3>, updates=None
Open vSwitch CI 78f366
+012: table simple: i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>
Open vSwitch CI 78f366
+012: table simple: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
 013: reconnect
Open vSwitch CI 78f366
-014: event:create, row={i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>}, updates=None
Open vSwitch CI 78f366
-014: event:create, row={i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>}, updates=None
Open vSwitch CI 78f366
-014: event:create, row={uuid=<0>}, updates=None
Open vSwitch CI 78f366
-014: event:create, row={uuid=<1>}, updates=None
Open vSwitch CI 78f366
-014: i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>
Open vSwitch CI 78f366
-014: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
+014: event:create, row={i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[]}, uuid=<8>, updates=None
Open vSwitch CI 78f366
+014: event:create, row={i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>]}, uuid=<2>, updates=None
Open vSwitch CI 78f366
+014: event:create, row={}, uuid=<0>, updates=None
Open vSwitch CI 78f366
+014: event:create, row={}, uuid=<1>, updates=None
Open vSwitch CI 78f366
+014: table simple: i=-1 r=125 b=false s=newstring u=<4> ia=[1] ra=[1.5] ba=[false] sa=[] ua=[] uuid=<8>
Open vSwitch CI 78f366
+014: table simple: i=1 r=123.5 b=false s=mystring u=<5> ia=[1 2 3] ra=[-0.5] ba=[true] sa=[abc def] ua=[<6> <7>] uuid=<2>
Open vSwitch CI 78f366
 015: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -1888,10 +2173,10 @@ OVSDB_CHECK_IDL_COMPOUND_INDEX_WITH_REF([set, simple3 idl-compound-index-with-re
Open vSwitch CI 78f366
 [],
Open vSwitch CI 78f366
 [],
Open vSwitch CI 78f366
 [[000: After add to other table + set of strong ref
Open vSwitch CI 78f366
-001: name= uset=[] uref=[[<0>]]
Open vSwitch CI 78f366
+001: table simple3: name= uset=[] uref=[<0>] uuid=<1>
Open vSwitch CI 78f366
 002: check simple4: not empty
Open vSwitch CI 78f366
 003: Query using index with reference
Open vSwitch CI 78f366
-004: name= uset=[] uref=[[<0>]]
Open vSwitch CI 78f366
+004: table simple3: name= uset=[] uref=[<0>] uuid=<1>
Open vSwitch CI 78f366
 005: After delete
Open vSwitch CI 78f366
 007: check simple4: empty
Open vSwitch CI 78f366
 008: End test
Open vSwitch CI 78f366
@@ -1989,11 +2274,11 @@ OVSDB_CHECK_CLUSTER_IDL_C([simple idl, monitor_cond_since, cluster disconnect],
Open vSwitch CI 78f366
   [[000: change conditions
Open vSwitch CI 78f366
 001: empty
Open vSwitch CI 78f366
 002: change conditions
Open vSwitch CI 78f366
-003: i=2 r=1 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+003: table simple: i=2 r=1 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 004: change conditions
Open vSwitch CI 78f366
 005: reconnect
Open vSwitch CI 78f366
-006: i=2 r=1 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
+006: table simple: i=2 r=1 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<1>
Open vSwitch CI 78f366
 007: {"error":null,"result":[{"count":1}]}
Open vSwitch CI 78f366
-008: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
+008: table simple: i=1 r=2 b=true s= u=<0> ia=[] ra=[] ba=[] sa=[] ua=[] uuid=<2>
Open vSwitch CI 78f366
 009: done
Open vSwitch CI 78f366
 ]])
Open vSwitch CI b3acf0
diff --git a/tests/system-offloads-traffic.at b/tests/system-offloads-traffic.at
Open vSwitch CI b3acf0
index 4f601ef939..c8e4c68fae 100644
Open vSwitch CI b3acf0
--- a/tests/system-offloads-traffic.at
Open vSwitch CI b3acf0
+++ b/tests/system-offloads-traffic.at
Open vSwitch CI b3acf0
@@ -70,3 +70,53 @@ AT_CHECK([ovs-appctl upcall/show | grep -E "offloaded flows : [[1-9]]"], [0], [i
Open vSwitch CI b3acf0
 
Open vSwitch CI b3acf0
 OVS_TRAFFIC_VSWITCHD_STOP
Open vSwitch CI b3acf0
 AT_CLEANUP
Open vSwitch CI b3acf0
+
Open vSwitch CI b3acf0
+AT_SETUP([offloads - set ingress_policing_rate and ingress_policing_burst - offloads disabled])
Open vSwitch CI b3acf0
+AT_KEYWORDS([ingress_policing])
Open vSwitch CI b3acf0
+AT_SKIP_IF([test $HAVE_TC = "no"])
Open vSwitch CI b3acf0
+OVS_TRAFFIC_VSWITCHD_START()
Open vSwitch CI b3acf0
+AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-offload=false])
Open vSwitch CI b3acf0
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
Open vSwitch CI b3acf0
+ADD_NAMESPACES(at_ns0)
Open vSwitch CI b3acf0
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
Open vSwitch CI b3acf0
+AT_CHECK([ovs-vsctl set interface ovs-p0 ingress_policing_rate=100])
Open vSwitch CI b3acf0
+AT_CHECK([ovs-vsctl set interface ovs-p0 ingress_policing_burst=10])
Open vSwitch CI b3acf0
+AT_CHECK([ovs-vsctl --columns=other_config list open], [0], [dnl
Open vSwitch CI b3acf0
+other_config        : {hw-offload="false"}
Open vSwitch CI b3acf0
+])
Open vSwitch CI b3acf0
+AT_CHECK([tc -o -s -d filter show dev ovs-p0 ingress |
Open vSwitch CI b3acf0
+  sed -n 's/.*\(rate [[0-9]]*[[a-zA-Z]]* burst [[0-9]]*[[a-zA-Z]]*\).*/\1/; T; p; q'],
Open vSwitch CI b3acf0
+  [0],[dnl
Open vSwitch CI b3acf0
+rate 100Kbit burst 1280b
Open vSwitch CI b3acf0
+])
Open vSwitch CI b3acf0
+AT_CHECK([tc -s -d filter show dev ovs-p0 ingress | grep basic |
Open vSwitch CI b3acf0
+  sed -n 's/.*\(basic\).*/\1/; T; p; q'], [0], [dnl
Open vSwitch CI b3acf0
+basic
Open vSwitch CI b3acf0
+])
Open vSwitch CI b3acf0
+OVS_TRAFFIC_VSWITCHD_STOP
Open vSwitch CI b3acf0
+AT_CLEANUP
Open vSwitch CI b3acf0
+
Open vSwitch CI b3acf0
+AT_SETUP([offloads - set ingress_policing_rate and ingress_policing_burst - offloads enabled])
Open vSwitch CI b3acf0
+AT_KEYWORDS([ingress_policing])
Open vSwitch CI b3acf0
+AT_SKIP_IF([test $HAVE_TC = "no"])
Open vSwitch CI b3acf0
+OVS_TRAFFIC_VSWITCHD_START()
Open vSwitch CI b3acf0
+AT_CHECK([ovs-vsctl set Open_vSwitch . other_config:hw-offload=true])
Open vSwitch CI b3acf0
+AT_CHECK([ovs-ofctl add-flow br0 "actions=normal"])
Open vSwitch CI b3acf0
+ADD_NAMESPACES(at_ns0)
Open vSwitch CI b3acf0
+ADD_VETH(p0, at_ns0, br0, "10.1.1.1/24")
Open vSwitch CI b3acf0
+AT_CHECK([ovs-vsctl set interface ovs-p0 ingress_policing_rate=100])
Open vSwitch CI b3acf0
+AT_CHECK([ovs-vsctl set interface ovs-p0 ingress_policing_burst=10])
Open vSwitch CI b3acf0
+AT_CHECK([ovs-vsctl --columns=other_config list open], [0], [dnl
Open vSwitch CI b3acf0
+other_config        : {hw-offload="true"}
Open vSwitch CI b3acf0
+])
Open vSwitch CI b3acf0
+AT_CHECK([tc -o -s -d filter show dev ovs-p0 ingress |
Open vSwitch CI b3acf0
+  sed -n 's/.*\(rate [[0-9]]*[[a-zA-Z]]* burst [[0-9]]*[[a-zA-Z]]*\).*/\1/; T; p; q'],
Open vSwitch CI b3acf0
+  [0],[dnl
Open vSwitch CI b3acf0
+rate 100Kbit burst 1280b
Open vSwitch CI b3acf0
+])
Open vSwitch CI b3acf0
+AT_CHECK([tc -o -s -d filter show dev ovs-p0 ingress | grep matchall |
Open vSwitch CI b3acf0
+  sed -n 's/.*\(matchall\).*/\1/; T; p; q'], [0], [dnl
Open vSwitch CI b3acf0
+matchall
Open vSwitch CI b3acf0
+])
Open vSwitch CI b3acf0
+OVS_TRAFFIC_VSWITCHD_STOP
Open vSwitch CI b3acf0
+AT_CLEANUP
Open vSwitch CI 78f366
diff --git a/tests/test-ovsdb.c b/tests/test-ovsdb.c
Open vSwitch CI 78f366
index 15433e3472..a886f971e7 100644
Open vSwitch CI 78f366
--- a/tests/test-ovsdb.c
Open vSwitch CI 78f366
+++ b/tests/test-ovsdb.c
Open vSwitch CI 78f366
@@ -1861,6 +1861,23 @@ print_and_log(const char *format, ...)
Open vSwitch CI 78f366
     free(message);
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+static char *
Open vSwitch CI 78f366
+format_idl_row(const struct ovsdb_idl_row *row, int step, const char *contents)
Open vSwitch CI 78f366
+{
Open vSwitch CI 78f366
+    const char *change_str =
Open vSwitch CI 78f366
+        !ovsdb_idl_track_is_set(row->table)
Open vSwitch CI 78f366
+        ? ""
Open vSwitch CI 78f366
+        : ovsdb_idl_row_get_seqno(row, OVSDB_IDL_CHANGE_INSERT) > 0
Open vSwitch CI 78f366
+          ? "inserted row: "
Open vSwitch CI 78f366
+          : ovsdb_idl_row_get_seqno(row, OVSDB_IDL_CHANGE_DELETE) > 0
Open vSwitch CI 78f366
+            ? "deleted row: "
Open vSwitch CI 78f366
+            : "";
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    return xasprintf("%03d: table %s: %s%s uuid=" UUID_FMT,
Open vSwitch CI 78f366
+                     step, row->table->class_->name, change_str, contents,
Open vSwitch CI 78f366
+                     UUID_ARGS(&row->uuid));
Open vSwitch CI 78f366
+}
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
 static void
Open vSwitch CI 78f366
 print_idl_row_updated_simple(const struct idltest_simple *s, int step)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
@@ -1871,7 +1888,9 @@ print_idl_row_updated_simple(const struct idltest_simple *s, int step)
Open vSwitch CI 78f366
         }
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
     if (updates.length) {
Open vSwitch CI 78f366
-        print_and_log("%03d: updated columns:%s", step, ds_cstr(&updates));
Open vSwitch CI 78f366
+        print_and_log("%03d: table %s: updated columns:%s",
Open vSwitch CI 78f366
+                      step, s->header_.table->class_->name,
Open vSwitch CI 78f366
+                      ds_cstr(&updates));
Open vSwitch CI 78f366
         ds_destroy(&updates);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
@@ -1886,7 +1905,9 @@ print_idl_row_updated_link1(const struct idltest_link1 *l1, int step)
Open vSwitch CI 78f366
         }
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
     if (updates.length) {
Open vSwitch CI 78f366
-        print_and_log("%03d: updated columns:%s", step, ds_cstr(&updates));
Open vSwitch CI 78f366
+        print_and_log("%03d: table %s: updated columns:%s",
Open vSwitch CI 78f366
+                      step, l1->header_.table->class_->name,
Open vSwitch CI 78f366
+                      ds_cstr(&updates));
Open vSwitch CI 78f366
         ds_destroy(&updates);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
@@ -1901,7 +1922,43 @@ print_idl_row_updated_link2(const struct idltest_link2 *l2, int step)
Open vSwitch CI 78f366
         }
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
     if (updates.length) {
Open vSwitch CI 78f366
-        print_and_log("%03d: updated columns:%s", step, ds_cstr(&updates));
Open vSwitch CI 78f366
+        print_and_log("%03d: table %s: updated columns:%s",
Open vSwitch CI 78f366
+                      step, l2->header_.table->class_->name,
Open vSwitch CI 78f366
+                      ds_cstr(&updates));
Open vSwitch CI 78f366
+        ds_destroy(&updates);
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+}
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+static void
Open vSwitch CI 78f366
+print_idl_row_updated_simple3(const struct idltest_simple3 *s3, int step)
Open vSwitch CI 78f366
+{
Open vSwitch CI 78f366
+    struct ds updates = DS_EMPTY_INITIALIZER;
Open vSwitch CI 78f366
+    for (size_t i = 0; i < IDLTEST_SIMPLE3_N_COLUMNS; i++) {
Open vSwitch CI 78f366
+        if (idltest_simple3_is_updated(s3, i)) {
Open vSwitch CI 78f366
+            ds_put_format(&updates, " %s", idltest_simple3_columns[i].name);
Open vSwitch CI 78f366
+        }
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+    if (updates.length) {
Open vSwitch CI 78f366
+        print_and_log("%03d: table %s: updated columns:%s",
Open vSwitch CI 78f366
+                      step, s3->header_.table->class_->name,
Open vSwitch CI 78f366
+                      ds_cstr(&updates));
Open vSwitch CI 78f366
+        ds_destroy(&updates);
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+}
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+static void
Open vSwitch CI 78f366
+print_idl_row_updated_simple4(const struct idltest_simple4 *s4, int step)
Open vSwitch CI 78f366
+{
Open vSwitch CI 78f366
+    struct ds updates = DS_EMPTY_INITIALIZER;
Open vSwitch CI 78f366
+    for (size_t i = 0; i < IDLTEST_SIMPLE4_N_COLUMNS; i++) {
Open vSwitch CI 78f366
+        if (idltest_simple4_is_updated(s4, i)) {
Open vSwitch CI 78f366
+            ds_put_format(&updates, " %s", idltest_simple4_columns[i].name);
Open vSwitch CI 78f366
+        }
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+    if (updates.length) {
Open vSwitch CI 78f366
+        print_and_log("%03d: table %s: updated columns:%s",
Open vSwitch CI 78f366
+                      step, s4->header_.table->class_->name,
Open vSwitch CI 78f366
+                      ds_cstr(&updates));
Open vSwitch CI 78f366
         ds_destroy(&updates);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
@@ -1916,7 +1973,9 @@ print_idl_row_updated_simple6(const struct idltest_simple6 *s6, int step)
Open vSwitch CI 78f366
         }
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
     if (updates.length) {
Open vSwitch CI 78f366
-        print_and_log("%03d: updated columns:%s", step, ds_cstr(&updates));
Open vSwitch CI 78f366
+        print_and_log("%03d: table %s: updated columns:%s",
Open vSwitch CI 78f366
+                      step, s6->header_.table->class_->name,
Open vSwitch CI 78f366
+                      ds_cstr(&updates));
Open vSwitch CI 78f366
         ds_destroy(&updates);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
@@ -1931,7 +1990,9 @@ print_idl_row_updated_singleton(const struct idltest_singleton *sng, int step)
Open vSwitch CI 78f366
         }
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
     if (updates.length) {
Open vSwitch CI 78f366
-        print_and_log("%03d: updated columns:%s", step, ds_cstr(&updates));
Open vSwitch CI 78f366
+        print_and_log("%03d: table %s: updated columns:%s",
Open vSwitch CI 78f366
+                      step, sng->header_.table->class_->name,
Open vSwitch CI 78f366
+                      ds_cstr(&updates));
Open vSwitch CI 78f366
         ds_destroy(&updates);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
@@ -1940,8 +2001,8 @@ static void
Open vSwitch CI 78f366
 print_idl_row_simple(const struct idltest_simple *s, int step)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
     struct ds msg = DS_EMPTY_INITIALIZER;
Open vSwitch CI 78f366
-    ds_put_format(&msg, "%03d: i=%"PRId64" r=%g b=%s s=%s u="UUID_FMT" ia=[",
Open vSwitch CI 78f366
-                  step, s->i, s->r, s->b ? "true" : "false",
Open vSwitch CI 78f366
+    ds_put_format(&msg, "i=%"PRId64" r=%g b=%s s=%s u="UUID_FMT" ia=[",
Open vSwitch CI 78f366
+                  s->i, s->r, s->b ? "true" : "false",
Open vSwitch CI 78f366
                   s->s, UUID_ARGS(&s->u));
Open vSwitch CI 78f366
     for (size_t i = 0; i < s->n_ia; i++) {
Open vSwitch CI 78f366
         ds_put_format(&msg, "%s%"PRId64, i ? " " : "", s->ia[i]);
Open vSwitch CI 78f366
@@ -1962,9 +2023,12 @@ print_idl_row_simple(const struct idltest_simple *s, int step)
Open vSwitch CI 78f366
     for (size_t i = 0; i < s->n_ua; i++) {
Open vSwitch CI 78f366
         ds_put_format(&msg, "%s"UUID_FMT, i ? " " : "", UUID_ARGS(&s->ua[i]));
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
-    ds_put_format(&msg, "] uuid="UUID_FMT, UUID_ARGS(&s->header_.uuid));
Open vSwitch CI 78f366
-    print_and_log("%s", ds_cstr(&msg));
Open vSwitch CI 78f366
+    ds_put_cstr(&msg, "]");
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    char *row_msg = format_idl_row(&s->header_, step, ds_cstr(&msg));
Open vSwitch CI 78f366
+    print_and_log("%s", row_msg);
Open vSwitch CI 78f366
     ds_destroy(&msg;;
Open vSwitch CI 78f366
+    free(row_msg);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     print_idl_row_updated_simple(s, step);
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
@@ -1973,7 +2037,7 @@ static void
Open vSwitch CI 78f366
 print_idl_row_link1(const struct idltest_link1 *l1, int step)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
     struct ds msg = DS_EMPTY_INITIALIZER;
Open vSwitch CI 78f366
-    ds_put_format(&msg, "%03d: i=%"PRId64" k=", step, l1->i);
Open vSwitch CI 78f366
+    ds_put_format(&msg, "i=%"PRId64" k=", l1->i);
Open vSwitch CI 78f366
     if (l1->k) {
Open vSwitch CI 78f366
         ds_put_format(&msg, "%"PRId64, l1->k->i);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
@@ -1988,9 +2052,11 @@ print_idl_row_link1(const struct idltest_link1 *l1, int step)
Open vSwitch CI 78f366
     if (l1->l2) {
Open vSwitch CI 78f366
         ds_put_format(&msg, "%"PRId64, l1->l2->i);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
-    ds_put_format(&msg, " uuid="UUID_FMT, UUID_ARGS(&l1->header_.uuid));
Open vSwitch CI 78f366
-    print_and_log("%s", ds_cstr(&msg));
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    char *row_msg = format_idl_row(&l1->header_, step, ds_cstr(&msg));
Open vSwitch CI 78f366
+    print_and_log("%s", row_msg);
Open vSwitch CI 78f366
     ds_destroy(&msg;;
Open vSwitch CI 78f366
+    free(row_msg);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     print_idl_row_updated_link1(l1, step);
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
@@ -1999,30 +2065,77 @@ static void
Open vSwitch CI 78f366
 print_idl_row_link2(const struct idltest_link2 *l2, int step)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
     struct ds msg = DS_EMPTY_INITIALIZER;
Open vSwitch CI 78f366
-    ds_put_format(&msg, "%03d: i=%"PRId64" l1=", step, l2->i);
Open vSwitch CI 78f366
+    ds_put_format(&msg, "i=%"PRId64" l1=", l2->i);
Open vSwitch CI 78f366
     if (l2->l1) {
Open vSwitch CI 78f366
         ds_put_format(&msg, "%"PRId64, l2->l1->i);
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
-    ds_put_format(&msg, " uuid="UUID_FMT, UUID_ARGS(&l2->header_.uuid));
Open vSwitch CI 78f366
-    print_and_log("%s", ds_cstr(&msg));
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    char *row_msg = format_idl_row(&l2->header_, step, ds_cstr(&msg));
Open vSwitch CI 78f366
+    print_and_log("%s", row_msg);
Open vSwitch CI 78f366
     ds_destroy(&msg;;
Open vSwitch CI 78f366
+    free(row_msg);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     print_idl_row_updated_link2(l2, step);
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+static void
Open vSwitch CI 78f366
+print_idl_row_simple3(const struct idltest_simple3 *s3, int step)
Open vSwitch CI 78f366
+{
Open vSwitch CI 78f366
+    struct ds msg = DS_EMPTY_INITIALIZER;
Open vSwitch CI 78f366
+    size_t i;
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    ds_put_format(&msg, "name=%s uset=[", s3->name);
Open vSwitch CI 78f366
+    for (i = 0; i < s3->n_uset; i++) {
Open vSwitch CI 78f366
+        ds_put_format(&msg, UUID_FMT"%s",
Open vSwitch CI 78f366
+                      UUID_ARGS(&s3->uset[i]),
Open vSwitch CI 78f366
+                      i < s3->n_uset - 1 ? "," : "");
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+    ds_put_cstr(&msg, "] uref=[");
Open vSwitch CI 78f366
+    for (i = 0; i < s3->n_uref; i++) {
Open vSwitch CI 78f366
+        ds_put_format(&msg, UUID_FMT"%s",
Open vSwitch CI 78f366
+                      UUID_ARGS(&s3->uref[i]->header_.uuid),
Open vSwitch CI 78f366
+                      i < s3->n_uref -1 ? "," : "");
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+    ds_put_cstr(&msg, "]");
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    char *row_msg = format_idl_row(&s3->header_, step, ds_cstr(&msg));
Open vSwitch CI 78f366
+    print_and_log("%s", row_msg);
Open vSwitch CI 78f366
+    ds_destroy(&msg;;
Open vSwitch CI 78f366
+    free(row_msg);
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    print_idl_row_updated_simple3(s3, step);
Open vSwitch CI 78f366
+}
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+static void
Open vSwitch CI 78f366
+print_idl_row_simple4(const struct idltest_simple4 *s4, int step)
Open vSwitch CI 78f366
+{
Open vSwitch CI 78f366
+    struct ds msg = DS_EMPTY_INITIALIZER;
Open vSwitch CI 78f366
+    ds_put_format(&msg, "name=%s", s4->name);
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    char *row_msg = format_idl_row(&s4->header_, step, ds_cstr(&msg));
Open vSwitch CI 78f366
+    print_and_log("%s", row_msg);
Open vSwitch CI 78f366
+    ds_destroy(&msg;;
Open vSwitch CI 78f366
+    free(row_msg);
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    print_idl_row_updated_simple4(s4, step);
Open vSwitch CI 78f366
+}
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
 static void
Open vSwitch CI 78f366
 print_idl_row_simple6(const struct idltest_simple6 *s6, int step)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
     struct ds msg = DS_EMPTY_INITIALIZER;
Open vSwitch CI 78f366
-    ds_put_format(&msg, "%03d: name=%s ", step, s6->name);
Open vSwitch CI 78f366
+    ds_put_format(&msg, "name=%s ", s6->name);
Open vSwitch CI 78f366
     ds_put_cstr(&msg, "weak_ref=[");
Open vSwitch CI 78f366
     for (size_t i = 0; i < s6->n_weak_ref; i++) {
Open vSwitch CI 78f366
         ds_put_format(&msg, "%s"UUID_FMT, i ? " " : "",
Open vSwitch CI 78f366
                       UUID_ARGS(&s6->weak_ref[i]->header_.uuid));
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
-    ds_put_format(&msg, "] uuid="UUID_FMT, UUID_ARGS(&s6->header_.uuid));
Open vSwitch CI 78f366
-    print_and_log("%s", ds_cstr(&msg));
Open vSwitch CI 78f366
+    ds_put_cstr(&msg, "]");
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    char *row_msg = format_idl_row(&s6->header_, step, ds_cstr(&msg));
Open vSwitch CI 78f366
+    print_and_log("%s", row_msg);
Open vSwitch CI 78f366
     ds_destroy(&msg;;
Open vSwitch CI 78f366
+    free(row_msg);
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     print_idl_row_updated_simple6(s6, step);
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
@@ -2030,14 +2143,23 @@ print_idl_row_simple6(const struct idltest_simple6 *s6, int step)
Open vSwitch CI 78f366
 static void
Open vSwitch CI 78f366
 print_idl_row_singleton(const struct idltest_singleton *sng, int step)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
-    print_and_log("%03d: name=%s uuid="UUID_FMT, step, sng->name,
Open vSwitch CI 78f366
-                  UUID_ARGS(&sng->header_.uuid));
Open vSwitch CI 78f366
+    struct ds msg = DS_EMPTY_INITIALIZER;
Open vSwitch CI 78f366
+    ds_put_format(&msg, "name=%s", sng->name);
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    char *row_msg = format_idl_row(&sng->header_, step, ds_cstr(&msg));
Open vSwitch CI 78f366
+    print_and_log("%s", row_msg);
Open vSwitch CI 78f366
+    ds_destroy(&msg;;
Open vSwitch CI 78f366
+    free(row_msg);
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
     print_idl_row_updated_singleton(sng, step);
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 static void
Open vSwitch CI 78f366
 print_idl(struct ovsdb_idl *idl, int step)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
+    const struct idltest_simple3 *s3;
Open vSwitch CI 78f366
+    const struct idltest_simple4 *s4;
Open vSwitch CI 78f366
+    const struct idltest_simple6 *s6;
Open vSwitch CI 78f366
     const struct idltest_simple *s;
Open vSwitch CI 78f366
     const struct idltest_link1 *l1;
Open vSwitch CI 78f366
     const struct idltest_link2 *l2;
Open vSwitch CI 78f366
@@ -2056,6 +2178,18 @@ print_idl(struct ovsdb_idl *idl, int step)
Open vSwitch CI 78f366
         print_idl_row_link2(l2, step);
Open vSwitch CI 78f366
         n++;
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
+    IDLTEST_SIMPLE3_FOR_EACH (s3, idl) {
Open vSwitch CI 78f366
+        print_idl_row_simple3(s3, step);
Open vSwitch CI 78f366
+        n++;
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+    IDLTEST_SIMPLE4_FOR_EACH (s4, idl) {
Open vSwitch CI 78f366
+        print_idl_row_simple4(s4, step);
Open vSwitch CI 78f366
+        n++;
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+    IDLTEST_SIMPLE6_FOR_EACH (s6, idl) {
Open vSwitch CI 78f366
+        print_idl_row_simple6(s6, step);
Open vSwitch CI 78f366
+        n++;
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
     IDLTEST_SINGLETON_FOR_EACH (sng, idl) {
Open vSwitch CI 78f366
         print_idl_row_singleton(sng, step);
Open vSwitch CI 78f366
         n++;
Open vSwitch CI 78f366
@@ -2068,6 +2202,8 @@ print_idl(struct ovsdb_idl *idl, int step)
Open vSwitch CI 78f366
 static void
Open vSwitch CI 78f366
 print_idl_track(struct ovsdb_idl *idl, int step)
Open vSwitch CI 78f366
 {
Open vSwitch CI 78f366
+    const struct idltest_simple3 *s3;
Open vSwitch CI 78f366
+    const struct idltest_simple4 *s4;
Open vSwitch CI 78f366
     const struct idltest_simple6 *s6;
Open vSwitch CI 78f366
     const struct idltest_simple *s;
Open vSwitch CI 78f366
     const struct idltest_link1 *l1;
Open vSwitch CI 78f366
@@ -2076,51 +2212,26 @@ print_idl_track(struct ovsdb_idl *idl, int step)
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     IDLTEST_SIMPLE_FOR_EACH_TRACKED (s, idl) {
Open vSwitch CI 78f366
         print_idl_row_simple(s, step);
Open vSwitch CI 78f366
-        if (idltest_simple_is_deleted(s)) {
Open vSwitch CI 78f366
-            print_and_log("%03d: deleted row: uuid="UUID_FMT, step,
Open vSwitch CI 78f366
-                          UUID_ARGS(&s->header_.uuid));
Open vSwitch CI 78f366
-        } else if (idltest_simple_is_new(s)) {
Open vSwitch CI 78f366
-            print_and_log("%03d: inserted row: uuid="UUID_FMT, step,
Open vSwitch CI 78f366
-                          UUID_ARGS(&s->header_.uuid));
Open vSwitch CI 78f366
-        }
Open vSwitch CI 78f366
         n++;
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
     IDLTEST_LINK1_FOR_EACH_TRACKED (l1, idl) {
Open vSwitch CI 78f366
-        if (idltest_link1_is_deleted(l1)) {
Open vSwitch CI 78f366
-            print_and_log("%03d: deleted row: uuid="UUID_FMT, step,
Open vSwitch CI 78f366
-                          UUID_ARGS(&l1->header_.uuid));
Open vSwitch CI 78f366
-        } else {
Open vSwitch CI 78f366
-            print_idl_row_link1(l1, step);
Open vSwitch CI 78f366
-            if (idltest_link1_is_new(l1)) {
Open vSwitch CI 78f366
-                print_and_log("%03d: inserted row: uuid="UUID_FMT, step,
Open vSwitch CI 78f366
-                              UUID_ARGS(&l1->header_.uuid));
Open vSwitch CI 78f366
-            }
Open vSwitch CI 78f366
-        }
Open vSwitch CI 78f366
+        print_idl_row_link1(l1, step);
Open vSwitch CI 78f366
         n++;
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
     IDLTEST_LINK2_FOR_EACH_TRACKED (l2, idl) {
Open vSwitch CI 78f366
-        if (idltest_link2_is_deleted(l2)) {
Open vSwitch CI 78f366
-            print_and_log("%03d: deleted row: uuid="UUID_FMT, step,
Open vSwitch CI 78f366
-                          UUID_ARGS(&l2->header_.uuid));
Open vSwitch CI 78f366
-        } else {
Open vSwitch CI 78f366
-            print_idl_row_link2(l2, step);
Open vSwitch CI 78f366
-            if (idltest_link2_is_new(l2)) {
Open vSwitch CI 78f366
-                print_and_log("%03d: inserted row: uuid="UUID_FMT, step,
Open vSwitch CI 78f366
-                              UUID_ARGS(&l2->header_.uuid));
Open vSwitch CI 78f366
-            }
Open vSwitch CI 78f366
-
Open vSwitch CI 78f366
-        }
Open vSwitch CI 78f366
+        print_idl_row_link2(l2, step);
Open vSwitch CI 78f366
+        n++;
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+    IDLTEST_SIMPLE3_FOR_EACH_TRACKED (s3, idl) {
Open vSwitch CI 78f366
+        print_idl_row_simple3(s3, step);
Open vSwitch CI 78f366
+        n++;
Open vSwitch CI 78f366
+    }
Open vSwitch CI 78f366
+    IDLTEST_SIMPLE4_FOR_EACH_TRACKED (s4, idl) {
Open vSwitch CI 78f366
+        print_idl_row_simple4(s4, step);
Open vSwitch CI 78f366
         n++;
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
     IDLTEST_SIMPLE6_FOR_EACH_TRACKED (s6, idl) {
Open vSwitch CI 78f366
         print_idl_row_simple6(s6, step);
Open vSwitch CI 78f366
-        if (idltest_simple6_is_deleted(s6)) {
Open vSwitch CI 78f366
-            print_and_log("%03d: deleted row: uuid="UUID_FMT, step,
Open vSwitch CI 78f366
-                   UUID_ARGS(&s6->header_.uuid));
Open vSwitch CI 78f366
-        } else if (idltest_simple6_is_new(s6)) {
Open vSwitch CI 78f366
-            print_and_log("%03d: inserted row: uuid="UUID_FMT, step,
Open vSwitch CI 78f366
-                          UUID_ARGS(&s6->header_.uuid));
Open vSwitch CI 78f366
-        }
Open vSwitch CI 78f366
         n++;
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
@@ -2349,6 +2460,10 @@ find_table_class(const char *name)
Open vSwitch CI 78f366
         return &idltest_table_link1;
Open vSwitch CI 78f366
     } else if (!strcmp(name, "link2")) {
Open vSwitch CI 78f366
         return &idltest_table_link2;
Open vSwitch CI 78f366
+    } else if (!strcmp(name, "simple3")) {
Open vSwitch CI 78f366
+        return &idltest_table_simple3;
Open vSwitch CI 78f366
+    } else if (!strcmp(name, "simple4")) {
Open vSwitch CI 78f366
+        return &idltest_table_simple4;
Open vSwitch CI 78f366
     } else if (!strcmp(name, "simple6")) {
Open vSwitch CI 78f366
         return &idltest_table_simple6;
Open vSwitch CI 78f366
     }
Open vSwitch CI 78f366
@@ -2702,27 +2817,6 @@ do_idl_partial_update_map_column(struct ovs_cmdl_context *ctx)
Open vSwitch CI 78f366
     printf("%03d: End test\n", step);
Open vSwitch CI 78f366
 }
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
-static void
Open vSwitch CI 78f366
-print_idl_row_simple3(const struct idltest_simple3 *s, int step)
Open vSwitch CI 78f366
-{
Open vSwitch CI 78f366
-    size_t i;
Open vSwitch CI 78f366
-    const struct ovsdb_datum *uset;
Open vSwitch CI 78f366
-    const struct ovsdb_datum *uref;
Open vSwitch CI 78f366
-
Open vSwitch CI 78f366
-    uset = idltest_simple3_get_uset(s, OVSDB_TYPE_UUID);
Open vSwitch CI 78f366
-    printf("%03d: name=%s uset=[",
Open vSwitch CI 78f366
-           step, s->name);
Open vSwitch CI 78f366
-    for (i = 0; i < uset->n; i++) {
Open vSwitch CI 78f366
-        printf("["UUID_FMT"]%s", UUID_ARGS(&(uset->keys[i].uuid)), i < uset->n-1? ",": "");
Open vSwitch CI 78f366
-    }
Open vSwitch CI 78f366
-    uref = idltest_simple3_get_uref(s, OVSDB_TYPE_UUID);
Open vSwitch CI 78f366
-    printf("] uref=[");
Open vSwitch CI 78f366
-    for (i = 0; i < uref->n; i++) {
Open vSwitch CI 78f366
-        printf("["UUID_FMT"]%s", UUID_ARGS(&(uref->keys[i].uuid)), i < uref->n-1? ",": "");
Open vSwitch CI 78f366
-    }
Open vSwitch CI 78f366
-    printf("]\n");
Open vSwitch CI 78f366
-}
Open vSwitch CI 78f366
-
Open vSwitch CI 78f366
 static void
Open vSwitch CI 78f366
 dump_simple3(struct ovsdb_idl *idl,
Open vSwitch CI 78f366
              const struct idltest_simple3 *myRow,
Open vSwitch CI fe1a04
diff --git a/tests/test-ovsdb.py b/tests/test-ovsdb.py
Open vSwitch CI 78f366
index a196802743..72a319123e 100644
Open vSwitch CI fe1a04
--- a/tests/test-ovsdb.py
Open vSwitch CI fe1a04
+++ b/tests/test-ovsdb.py
Open vSwitch CI 78f366
@@ -162,6 +162,10 @@ def get_simple_printable_row_string(row, columns):
Open vSwitch CI fe1a04
             if isinstance(value, dict):
Open vSwitch CI fe1a04
                 value = sorted((row_to_uuid(k), row_to_uuid(v))
Open vSwitch CI fe1a04
                                for k, v in value.items())
Open vSwitch CI fe1a04
+            if isinstance(value, (list, tuple)):
Open vSwitch CI fe1a04
+                value = sorted((row_to_uuid(v) for v in value))
Open vSwitch CI 78f366
+            elif isinstance(value, list):
Open vSwitch CI 78f366
+                value = sorted(row_to_uuid(v) for v in value)
Open vSwitch CI fe1a04
             s += "%s=%s " % (column, value)
Open vSwitch CI fe1a04
     s = s.strip()
Open vSwitch CI fe1a04
     s = re.sub('""|,|u?\'', "", s)
Open vSwitch CI 78f366
@@ -172,9 +176,10 @@ def get_simple_printable_row_string(row, columns):
Open vSwitch CI fe1a04
     return s
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
-def get_simple_table_printable_row(row):
Open vSwitch CI fe1a04
+def get_simple_table_printable_row(row, *additional_columns):
Open vSwitch CI fe1a04
     simple_columns = ["i", "r", "b", "s", "u", "ia",
Open vSwitch CI 78f366
-                      "ra", "ba", "sa", "ua", "uuid"]
Open vSwitch CI 78f366
+                      "ra", "ba", "sa", "ua"]
Open vSwitch CI fe1a04
+    simple_columns.extend(additional_columns)
Open vSwitch CI fe1a04
     return get_simple_printable_row_string(row, simple_columns)
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 
Open vSwitch CI 78f366
@@ -184,81 +189,118 @@ def get_simple2_table_printable_row(row):
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 def get_simple3_table_printable_row(row):
Open vSwitch CI 78f366
-    simple3_columns = ["name", "uset"]
Open vSwitch CI 78f366
+    simple3_columns = ["name", "uset", "uref"]
Open vSwitch CI 78f366
     return get_simple_printable_row_string(row, simple3_columns)
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
+def get_simple4_table_printable_row(row):
Open vSwitch CI 78f366
+    simple4_columns = ["name"]
Open vSwitch CI 78f366
+    return get_simple_printable_row_string(row, simple4_columns)
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+def get_simple5_table_printable_row(row):
Open vSwitch CI 78f366
+    simple5_columns = ["name", "irefmap"]
Open vSwitch CI 78f366
+    return get_simple_printable_row_string(row, simple5_columns)
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+def get_simple6_table_printable_row(row):
Open vSwitch CI 78f366
+    simple6_columns = ["name", "weak_ref"]
Open vSwitch CI 78f366
+    return get_simple_printable_row_string(row, simple6_columns)
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+def get_link1_table_printable_row(row):
Open vSwitch CI 78f366
+    s = ["i=%s k=" % row.i]
Open vSwitch CI 78f366
+    if hasattr(row, "k") and row.k:
Open vSwitch CI 78f366
+        s.append(str(row.k.i))
Open vSwitch CI 78f366
+    if hasattr(row, "ka"):
Open vSwitch CI 78f366
+        s.append(" ka=[")
Open vSwitch CI 78f366
+        s.append(' '.join(sorted(str(ka.i) for ka in row.ka)))
Open vSwitch CI 78f366
+        s.append("] l2=")
Open vSwitch CI 78f366
+    if hasattr(row, "l2") and row.l2:
Open vSwitch CI 78f366
+        s.append(str(row.l2[0].i))
Open vSwitch CI 78f366
+    return ''.join(s)
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+def get_link2_table_printable_row(row):
Open vSwitch CI 78f366
+    s = "i=%s l1=" % row.i
Open vSwitch CI 78f366
+    if hasattr(row, "l1") and row.l1:
Open vSwitch CI 78f366
+        s += str(row.l1[0].i)
Open vSwitch CI 78f366
+    return s
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+def get_singleton_table_printable_row(row):
Open vSwitch CI 78f366
+    return "name=%s" % row.name
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+def print_row(table, row, step, contents):
Open vSwitch CI 78f366
+    s = "%03d: table %s: %s " % (step, table, contents)
Open vSwitch CI 78f366
+    s += get_simple_printable_row_string(row, ["uuid"])
Open vSwitch CI 78f366
+    print(s)
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
 def print_idl(idl, step):
Open vSwitch CI 78f366
     n = 0
Open vSwitch CI 78f366
     if "simple" in idl.tables:
Open vSwitch CI 78f366
         simple = idl.tables["simple"].rows
Open vSwitch CI 78f366
         for row in simple.values():
Open vSwitch CI 78f366
-            s = "%03d: " % step
Open vSwitch CI 78f366
-            s += get_simple_table_printable_row(row)
Open vSwitch CI 78f366
-            print(s)
Open vSwitch CI 78f366
+            print_row("simple", row, step,
Open vSwitch CI 78f366
+                      get_simple_table_printable_row(row))
Open vSwitch CI 78f366
             n += 1
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     if "simple2" in idl.tables:
Open vSwitch CI 78f366
         simple2 = idl.tables["simple2"].rows
Open vSwitch CI 78f366
         for row in simple2.values():
Open vSwitch CI 78f366
-            s = "%03d: " % step
Open vSwitch CI 78f366
-            s += get_simple2_table_printable_row(row)
Open vSwitch CI 78f366
-            print(s)
Open vSwitch CI 78f366
+            print_row("simple2", row, step,
Open vSwitch CI 78f366
+                      get_simple2_table_printable_row(row))
Open vSwitch CI 78f366
             n += 1
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     if "simple3" in idl.tables:
Open vSwitch CI 78f366
         simple3 = idl.tables["simple3"].rows
Open vSwitch CI 78f366
         for row in simple3.values():
Open vSwitch CI 78f366
-            s = "%03d: " % step
Open vSwitch CI 78f366
-            s += get_simple3_table_printable_row(row)
Open vSwitch CI 78f366
-            print(s)
Open vSwitch CI 78f366
+            print_row("simple3", row, step,
Open vSwitch CI 78f366
+                      get_simple3_table_printable_row(row))
Open vSwitch CI 78f366
+            n += 1
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    if "simple4" in idl.tables:
Open vSwitch CI 78f366
+        simple4 = idl.tables["simple4"].rows
Open vSwitch CI 78f366
+        for row in simple4.values():
Open vSwitch CI 78f366
+            print_row("simple4", row, step,
Open vSwitch CI 78f366
+                      get_simple4_table_printable_row(row))
Open vSwitch CI 78f366
             n += 1
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     if "simple5" in idl.tables:
Open vSwitch CI 78f366
         simple5 = idl.tables["simple5"].rows
Open vSwitch CI 78f366
         for row in simple5.values():
Open vSwitch CI 78f366
-            s = "%03d: " % step
Open vSwitch CI 78f366
-            s += get_simple_printable_row_string(row, ["name", "irefmap"])
Open vSwitch CI 78f366
-            print(s)
Open vSwitch CI 78f366
+            print_row("simple5", row, step,
Open vSwitch CI 78f366
+                      get_simple5_table_printable_row(row))
Open vSwitch CI 78f366
+            n += 1
Open vSwitch CI 78f366
+
Open vSwitch CI 78f366
+    if "simple6" in idl.tables:
Open vSwitch CI 78f366
+        simple6 = idl.tables["simple6"].rows
Open vSwitch CI 78f366
+        for row in simple6.values():
Open vSwitch CI 78f366
+            print_row("simple6", row, step,
Open vSwitch CI 78f366
+                      get_simple6_table_printable_row(row))
Open vSwitch CI 78f366
             n += 1
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     if "link1" in idl.tables:
Open vSwitch CI 78f366
         l1 = idl.tables["link1"].rows
Open vSwitch CI 78f366
         for row in l1.values():
Open vSwitch CI 78f366
-            s = ["%03d: i=%s k=" % (step, row.i)]
Open vSwitch CI 78f366
-            if hasattr(row, "k") and row.k:
Open vSwitch CI 78f366
-                s.append(str(row.k.i))
Open vSwitch CI 78f366
-            if hasattr(row, "ka"):
Open vSwitch CI 78f366
-                s.append(" ka=[")
Open vSwitch CI 78f366
-                s.append(' '.join(sorted(str(ka.i) for ka in row.ka)))
Open vSwitch CI 78f366
-                s.append("] l2=")
Open vSwitch CI 78f366
-            if hasattr(row, "l2") and row.l2:
Open vSwitch CI 78f366
-                s.append(str(row.l2[0].i))
Open vSwitch CI 78f366
-            if hasattr(row, "uuid"):
Open vSwitch CI 78f366
-                s.append(" uuid=%s" % row.uuid)
Open vSwitch CI 78f366
-            print(''.join(s))
Open vSwitch CI 78f366
+            print_row("link1", row, step,
Open vSwitch CI 78f366
+                      get_link1_table_printable_row(row))
Open vSwitch CI 78f366
             n += 1
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     if "link2" in idl.tables:
Open vSwitch CI 78f366
         l2 = idl.tables["link2"].rows
Open vSwitch CI 78f366
         for row in l2.values():
Open vSwitch CI 78f366
-            s = ["%03d:" % step]
Open vSwitch CI 78f366
-            s.append(" i=%s l1=" % row.i)
Open vSwitch CI 78f366
-            if hasattr(row, "l1") and row.l1:
Open vSwitch CI 78f366
-                s.append(str(row.l1[0].i))
Open vSwitch CI 78f366
-            if hasattr(row, "uuid"):
Open vSwitch CI 78f366
-                s.append(" uuid=%s" % row.uuid)
Open vSwitch CI 78f366
-            print(''.join(s))
Open vSwitch CI 78f366
+            print_row("link2", row, step,
Open vSwitch CI 78f366
+                      get_link2_table_printable_row(row))
Open vSwitch CI 78f366
             n += 1
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     if "singleton" in idl.tables:
Open vSwitch CI 78f366
         sng = idl.tables["singleton"].rows
Open vSwitch CI 78f366
         for row in sng.values():
Open vSwitch CI 78f366
-            s = ["%03d:" % step]
Open vSwitch CI 78f366
-            s.append(" name=%s" % row.name)
Open vSwitch CI 78f366
-            if hasattr(row, "uuid"):
Open vSwitch CI 78f366
-                s.append(" uuid=%s" % row.uuid)
Open vSwitch CI 78f366
-            print(''.join(s))
Open vSwitch CI 78f366
+            print_row("singleton", row, step,
Open vSwitch CI 78f366
+                      get_singleton_table_printable_row(row))
Open vSwitch CI 78f366
             n += 1
Open vSwitch CI 78f366
 
Open vSwitch CI 78f366
     if not n:
Open vSwitch CI 78f366
@@ -637,7 +679,8 @@ def do_idl(schema_file, remote, *commands):
Open vSwitch CI fe1a04
     def mock_notify(event, row, updates=None):
Open vSwitch CI fe1a04
         output = "%03d: " % step
Open vSwitch CI fe1a04
         output += "event:" + str(event) + ", row={"
Open vSwitch CI fe1a04
-        output += get_simple_table_printable_row(row) + "}, updates="
Open vSwitch CI 78f366
+        output += get_simple_table_printable_row(row, 'l2', 'l1') + "}, "
Open vSwitch CI 78f366
+        output += get_simple_printable_row_string(row, ["uuid"]) + ", updates="
Open vSwitch CI fe1a04
         if updates is None:
Open vSwitch CI fe1a04
             output += "None"
Open vSwitch CI fe1a04
         else:
Open vSwitch CI fe1a04
diff --git a/utilities/ovs-ctl.in b/utilities/ovs-ctl.in
Open vSwitch CI fe1a04
index d71c34e691..4156da20ef 100644
Open vSwitch CI fe1a04
--- a/utilities/ovs-ctl.in
Open vSwitch CI fe1a04
+++ b/utilities/ovs-ctl.in
Open vSwitch CI fe1a04
@@ -226,7 +226,9 @@ start_forwarding () {
Open vSwitch CI fe1a04
     if test X"$OVS_VSWITCHD" = Xyes; then
Open vSwitch CI fe1a04
         do_start_forwarding || return 1
Open vSwitch CI fe1a04
     fi
Open vSwitch CI fe1a04
-    set_hostname &
Open vSwitch CI fe1a04
+    if test X"$RECORD_HOSTNAME" = Xyes; then
Open vSwitch CI fe1a04
+        set_hostname &
Open vSwitch CI fe1a04
+    fi
Open vSwitch CI fe1a04
     return 0
Open vSwitch CI fe1a04
 }
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
@@ -317,6 +319,7 @@ set_defaults () {
Open vSwitch CI fe1a04
     SYSTEM_ID=
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     FULL_HOSTNAME=yes
Open vSwitch CI fe1a04
+    RECORD_HOSTNAME=yes
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
     DELETE_BRIDGES=no
Open vSwitch CI fe1a04
     DELETE_TRANSIENT_PORTS=no
Open vSwitch CI fe1a04
@@ -378,19 +381,24 @@ This program is intended to be invoked internally by Open vSwitch startup
Open vSwitch CI fe1a04
 scripts.  System administrators should not normally invoke it directly.
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 Commands:
Open vSwitch CI fe1a04
-  start                   start Open vSwitch daemons
Open vSwitch CI fe1a04
-  stop                    stop Open vSwitch daemons
Open vSwitch CI fe1a04
-  restart                 stop and start Open vSwitch daemons
Open vSwitch CI fe1a04
-  status                  check whether Open vSwitch daemons are running
Open vSwitch CI fe1a04
-  version                 print versions of Open vSwitch daemons
Open vSwitch CI fe1a04
-  load-kmod               insert modules if not already present
Open vSwitch CI fe1a04
-  force-reload-kmod       save OVS network device state, stop OVS, unload kernel
Open vSwitch CI fe1a04
-                          module, reload kernel module, start OVS, restore state
Open vSwitch CI fe1a04
-  enable-protocol         enable protocol specified in options with iptables
Open vSwitch CI fe1a04
-  delete-transient-ports  delete transient (other_config:transient=true) ports
Open vSwitch CI fe1a04
-  start-ovs-ipsec         start Open vSwitch ipsec daemon
Open vSwitch CI fe1a04
-  stop-ovs-ipsec          stop Open vSwitch ipsec daemon
Open vSwitch CI fe1a04
-  help                    display this help message
Open vSwitch CI fe1a04
+  start                       start Open vSwitch daemons
Open vSwitch CI fe1a04
+  stop                        stop Open vSwitch daemons
Open vSwitch CI fe1a04
+  restart                     stop and start Open vSwitch daemons
Open vSwitch CI fe1a04
+  status                      check whether Open vSwitch daemons are running
Open vSwitch CI fe1a04
+  version                     print versions of Open vSwitch daemons
Open vSwitch CI fe1a04
+  load-kmod                   insert modules if not already present
Open vSwitch CI fe1a04
+  force-reload-kmod           save OVS network device state, stop OVS, unload
Open vSwitch CI fe1a04
+                              kernel module, reload kernel module, start OVS,
Open vSwitch CI fe1a04
+                              restore state
Open vSwitch CI fe1a04
+  enable-protocol             enable protocol specified in options with
Open vSwitch CI fe1a04
+                              iptables
Open vSwitch CI fe1a04
+  delete-transient-ports      delete transient (other_config:transient=true)
Open vSwitch CI fe1a04
+                              ports
Open vSwitch CI fe1a04
+  start-ovs-ipsec             start Open vSwitch ipsec daemon
Open vSwitch CI fe1a04
+  stop-ovs-ipsec              stop Open vSwitch ipsec daemon
Open vSwitch CI fe1a04
+  record-hostname-if-not-set  determine the system hostname and record it in
Open vSwitch CI fe1a04
+                              the Open vSwitch database if not already set
Open vSwitch CI fe1a04
+  help                        display this help message
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 One of the following options is required for "start", "restart" and "force-reload-kmod":
Open vSwitch CI fe1a04
   --system-id=UUID   set specific ID to uniquely identify this system
Open vSwitch CI fe1a04
@@ -411,6 +419,8 @@ Less important options for "start", "restart" and "force-reload-kmod":
Open vSwitch CI fe1a04
   --ovsdb-server-priority=NICE   set ovsdb-server's niceness (default: $OVSDB_SERVER_PRIORITY)
Open vSwitch CI fe1a04
   --ovs-vswitchd-priority=NICE   set ovs-vswitchd's niceness (default: $OVS_VSWITCHD_PRIORITY)
Open vSwitch CI fe1a04
   --no-full-hostname             set short hostname instead of full hostname
Open vSwitch CI fe1a04
+  --no-record-hostname           do not attempt to determine/record system
Open vSwitch CI fe1a04
+                                 hostname as part of start command
Open vSwitch CI fe1a04
 
Open vSwitch CI fe1a04
 Debugging options for "start", "restart" and "force-reload-kmod":
Open vSwitch CI fe1a04
   --ovsdb-server-wrapper=WRAPPER
Open vSwitch CI fe1a04
@@ -569,6 +579,9 @@ case $command in
Open vSwitch CI fe1a04
     stop-ovs-ipsec)
Open vSwitch CI fe1a04
         stop_ovs_ipsec
Open vSwitch CI fe1a04
         ;;
Open vSwitch CI fe1a04
+    record-hostname-if-not-set)
Open vSwitch CI fe1a04
+        set_hostname
Open vSwitch CI fe1a04
+        ;;
Open vSwitch CI fe1a04
     help)
Open vSwitch CI fe1a04
         usage
Open vSwitch CI fe1a04
         ;;
Open vSwitch CI e0c144
diff --git a/utilities/ovs-ofctl.c b/utilities/ovs-ofctl.c
Open vSwitch CI e0c144
index 3601890f40..62059e962f 100644
Open vSwitch CI e0c144
--- a/utilities/ovs-ofctl.c
Open vSwitch CI e0c144
+++ b/utilities/ovs-ofctl.c
Open vSwitch CI e0c144
@@ -4020,6 +4020,7 @@ ofctl_meter_mod__(const char *bridge, const char *str, int command)
Open vSwitch CI e0c144
     enum ofputil_protocol usable_protocols;
Open vSwitch CI e0c144
     enum ofp_version version;
Open vSwitch CI e0c144
 
Open vSwitch CI e0c144
+    memset(&mm, 0, sizeof mm);
Open vSwitch CI e0c144
     if (str) {
Open vSwitch CI e0c144
         char *error;
Open vSwitch CI e0c144
         error = parse_ofp_meter_mod_str(&mm, str, command, &usable_protocols);
Open vSwitch CI e0c144
@@ -4030,7 +4031,6 @@ ofctl_meter_mod__(const char *bridge, const char *str, int command)
Open vSwitch CI e0c144
         usable_protocols = OFPUTIL_P_OF13_UP;
Open vSwitch CI e0c144
         mm.command = command;
Open vSwitch CI e0c144
         mm.meter.meter_id = OFPM13_ALL;
Open vSwitch CI e0c144
-        mm.meter.bands = NULL;
Open vSwitch CI e0c144
     }
Open vSwitch CI e0c144
 
Open vSwitch CI e0c144
     protocol = open_vconn_for_flow_mod(bridge, &vconn, usable_protocols);
Open vSwitch CI e0c144
@@ -4050,6 +4050,7 @@ ofctl_meter_request__(const char *bridge, const char *str,
Open vSwitch CI e0c144
     enum ofputil_protocol protocol;
Open vSwitch CI e0c144
     enum ofp_version version;
Open vSwitch CI e0c144
 
Open vSwitch CI e0c144
+    memset(&mm, 0, sizeof mm);
Open vSwitch CI e0c144
     if (str) {
Open vSwitch CI e0c144
         char *error;
Open vSwitch CI e0c144
         error = parse_ofp_meter_mod_str(&mm, str, -1, &usable_protocols);
Open vSwitch CI e0c144
@@ -4059,7 +4060,6 @@ ofctl_meter_request__(const char *bridge, const char *str,
Open vSwitch CI e0c144
     } else {
Open vSwitch CI e0c144
         usable_protocols = OFPUTIL_P_OF13_UP;
Open vSwitch CI e0c144
         mm.meter.meter_id = OFPM13_ALL;
Open vSwitch CI e0c144
-        mm.meter.bands = NULL;
Open vSwitch CI e0c144
     }
Open vSwitch CI e0c144
 
Open vSwitch CI e0c144
     protocol = open_vconn_for_flow_mod(bridge, &vconn, usable_protocols);
Open vSwitch CI fe1a04
diff --git a/vswitchd/vswitch.xml b/vswitchd/vswitch.xml
Open vSwitch CI fe1a04
index a2ad84edef..4597a215d9 100644
Open vSwitch CI fe1a04
--- a/vswitchd/vswitch.xml
Open vSwitch CI fe1a04
+++ b/vswitchd/vswitch.xml
Open vSwitch CI fe1a04
@@ -4660,7 +4660,8 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
Open vSwitch CI fe1a04
         packets per second the CIR would be set to to to 46000000. This value
Open vSwitch CI fe1a04
         can be broken into '1,000,000 x 46'. Where 1,000,000 is the policing
Open vSwitch CI fe1a04
         rate for the number of packets per second and 46 represents the size
Open vSwitch CI fe1a04
-        of the packet data for a 64 byte ip packet.
Open vSwitch CI fe1a04
+        of the packet data for a 64 bytes IP packet without 14 bytes Ethernet
Open vSwitch CI fe1a04
+        and 4 bytes FCS header.
Open vSwitch CI fe1a04
       </column>
Open vSwitch CI fe1a04
       <column name="other_config" key="cbs" type='{"type": "integer"}'>
Open vSwitch CI fe1a04
         The Committed Burst Size (CBS) is measured in bytes and represents a
Open vSwitch CI fe1a04
@@ -4681,7 +4682,8 @@ ovs-vsctl add-port br0 p0 -- set Interface p0 type=patch options:peer=p1 \
Open vSwitch CI fe1a04
         packets per second the EIR would be set to to to 46000000. This value
Open vSwitch CI fe1a04
         can be broken into '1,000,000 x 46'. Where 1,000,000 is the policing
Open vSwitch CI fe1a04
         rate for the number of packets per second and 46 represents the size
Open vSwitch CI fe1a04
-        of the packet data for a 64 byte ip packet.
Open vSwitch CI fe1a04
+        of the packet data for a 64 bytes IP packet without 14 bytes Ethernet
Open vSwitch CI fe1a04
+        and 4 bytes FCS header.
Open vSwitch CI fe1a04
       </column>
Open vSwitch CI fe1a04
       <column name="other_config" key="ebs" type='{"type": "integer"}'>
Open vSwitch CI fe1a04
         The Excess Burst Size (EBS) is measured in bytes and represents a