22590644 OpenvSwitch should be updated to version 2.3.2
authorMark Haywood <Mark.Haywood@Oracle.COM>
Tue, 05 Apr 2016 20:57:21 -0700
changeset 5730 cca4aa297e68
parent 5729 ad3057df09ab
child 5736 a37849cb0841
22590644 OpenvSwitch should be updated to version 2.3.2 22557669 Openvswitch Multiple Uplink support 22634090 _ovs' user needs to have privilege to access datalink/flow sysevents 22725422 openvswitch package manifest file must have explicit dependency on rad-dlmgr 22920860 vswitch-server should start immediately after network/physical:default 22920351 datapath doesn't work for implicitly created OVS bridge VNIC 23020125 problem in SERVICE/OPENVSWITCH
components/openvswitch/Makefile
components/openvswitch/files/lib/dpif-solaris.c
components/openvswitch/files/lib/dpif-solaris.h
components/openvswitch/files/lib/netdev-solaris.c
components/openvswitch/files/lib/netdev-solaris.h
components/openvswitch/files/lib/util-solaris.c
components/openvswitch/files/ovs-clean.py
components/openvswitch/files/ovs-svc
components/openvswitch/files/ovs.exec_attr
components/openvswitch/files/ovsdb.xml
components/openvswitch/files/vswitch.xml
components/openvswitch/openvswitch.p5m
components/openvswitch/patches/01-solaris-port.patch
components/openvswitch/patches/02-bridge.patch
components/openvswitch/patches/03-dpif-provider.patch
components/openvswitch/patches/04-netdev-provider.patch
components/openvswitch/patches/05-usage.patch
components/openvswitch/patches/06-controller-fix.patch
components/openvswitch/patches/07-ovsthread_key_destruct-fix.patch
components/openvswitch/patches/08-self-test-fix.patch
components/openvswitch/patches/09-CVE-2016-2074.patch
components/openvswitch/test/results-64.master
--- a/components/openvswitch/Makefile	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/Makefile	Tue Apr 05 20:57:21 2016 -0700
@@ -31,14 +31,14 @@
 include ../../make-rules/shared-macros.mk
 
 COMPONENT_NAME=		openvswitch
-COMPONENT_VERSION=	2.3.1
+COMPONENT_VERSION=	2.3.2
 COMPONENT_ARCHIVE_HASH=	\
-    sha256:d6d96e45fd9c070cc2696a4a09b4cc4b48dd7fc367c0455725d00f7daa343bf0
+    sha256:386b11df94d06c68d391ee4091832360095bd3a14c72d454325fab284dad9887
 COMPONENT_PROJECT_URL=  http://openvswitch.org/
 COMPONENT_ARCHIVE_URL=  $(COMPONENT_PROJECT_URL)/releases/$(COMPONENT_ARCHIVE)
 COMPONENT_BUGDB=	service/openvswitch
 
-TPNO=			21407
+TPNO=			26090
 
 # Depends on S12-only changes in ON to build.
 ifeq ($(BUILD_TYPE), evaluation)
--- a/components/openvswitch/files/lib/dpif-solaris.c	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/lib/dpif-solaris.c	Tue Apr 05 20:57:21 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -84,10 +84,10 @@
 static struct vlog_rate_limit error_rl = VLOG_RATE_LIMIT_INIT(9999, 5);
 
 struct dpif_solaris_bridge {
-	char *physname;
+	char *name;
 	struct hmap_node node;	/* Node in dpif_solaris's 'bridges'. */
 	struct hmap ports;
-	struct dpif_solaris_port *uplink_port;
+	struct list uplink_port_list;	/* List of all uplinks to the bridge */
 };
 
 struct dpif_solaris_port {
@@ -98,10 +98,13 @@
 	char *type;			/* Port type as requested by user. */
 	char *name;
 	char *linkname;
+	char *physname;
 	enum ovs_vport_type vtype;
 	struct netdev *netdev;
 	struct dpif_solaris_bridge *bridge;
 	boolean_t is_uplink;
+	struct list uplink_node;	/* Node in dpif_solaris_bridge's */
+					/* uplink_port_list */
 
 	/* Receive the upcalls */
 	int upcall_fd;			/* PF_PACKET fd for MISS event */
@@ -132,9 +135,9 @@
 static int dpif_solaris_get_port_by_number(struct dpif_solaris *dpif,
     odp_port_t port_no, struct dpif_solaris_port **portp)
     OVS_REQ_RDLOCK(dpif->port_rwlock);
-static int dpif_solaris_get_uplink_port(struct dpif_solaris *dpif,
-    struct dpif_solaris_port **portp)
-    OVS_REQ_RDLOCK(dpif->port_rwlock);
+static int
+dpif_solaris_get_uplink_port_info(struct dpif_solaris *dpif,
+    odp_port_t port_no, odp_port_t *uport_nop, int *xfdp);
 static void dpif_solaris_flow_remove(struct dpif_solaris *dpif,
     struct dpif_solaris_flow *flow)
     OVS_REQ_WRLOCK(dpif->flow_rwlock);
@@ -201,12 +204,15 @@
 
 		status = dladm_open(&dh);
 		error = solaris_dladm_status2error(status);
-		if (error != 0)
+		if (error != 0) {
+			ovs_mutex_unlock(&dp_solaris_mutex);
 			return (error);
+		}
 
 		if (!dp_exists) {
 			error = netdev_create_impl_etherstub();
 			if (error != 0) {
+				ovs_mutex_unlock(&dp_solaris_mutex);
 				dladm_close(dh);
 				return (error);
 			}
@@ -356,6 +362,7 @@
 {
 	struct dpif_solaris		*dpif = dpif_solaris_cast(dpif_);
 	struct dpif_solaris_bridge	*bridge;
+	struct dpif_solaris_port	*port;
 	kstat2_status_t			stat;
 	kstat2_map_t			map;
 	char				kuri[1024];
@@ -384,29 +391,33 @@
 	}
 	ovs_rwlock_rdlock(&dpif->bridge_rwlock);
 	HMAP_FOR_EACH(bridge, node, &dpif->bridges) {
-		name = (char *)bridge->physname;
-		instance = 0;
-		if (strchr(bridge->physname, '/') != NULL) {
-			(void) solaris_dlparse_zonelinkname(bridge->physname,
-			    kstat_name, &zid);
-			name = kstat_name;
-			instance = zid;
-		}
-		(void) snprintf(kuri, sizeof (kuri), "kstat:/net/link/%s/%d",
-		    name, instance);
-		stat = kstat2_lookup_map(dpif_khandle, kuri, &map);
+
+		LIST_FOR_EACH(port, uplink_node, &bridge->uplink_port_list) {
+			name = (char *)port->physname;
+			instance = 0;
+			if (strchr(port->physname, '/') != NULL) {
+				(void) solaris_dlparse_zonelinkname(
+				    port->physname, kstat_name, &zid);
+				name = kstat_name;
+				instance = zid;
+			}
+			(void) snprintf(kuri, sizeof (kuri),
+			    "kstat:/net/link/%s/%d", name, instance);
+			stat = kstat2_lookup_map(dpif_khandle, kuri, &map);
 
-		if (stat != KSTAT2_S_OK) {
-			ovs_rwlock_unlock(&dpif->bridge_rwlock);
-			ovs_mutex_unlock(&kstat_mutex);
-			VLOG_WARN("dpif_solaris_get_stats kstat_lookup of %s"
-			    " failed: %s", kuri, kstat2_status_string(stat));
-			return (-1);
+			if (stat != KSTAT2_S_OK) {
+				ovs_rwlock_unlock(&dpif->bridge_rwlock);
+				ovs_mutex_unlock(&kstat_mutex);
+				VLOG_WARN("dpif_solaris_get_stats kstat_lookup "
+				    "of %s failed: %s", kuri,
+				    kstat2_status_string(stat));
+				return (-1);
+			}
+			stats->n_hit += (get_nvvt_int(map, "ipkthit") +
+			    get_nvvt_int(map, "opkthit"));
+			stats->n_missed += (get_nvvt_int(map, "ipktmiss") +
+			    get_nvvt_int(map, "opktmiss"));
 		}
-		stats->n_hit += (get_nvvt_int(map, "ipkthit") +
-		    get_nvvt_int(map, "opkthit"));
-		stats->n_missed += (get_nvvt_int(map, "ipktmiss") +
-		    get_nvvt_int(map, "opktmiss"));
 	}
 	ovs_rwlock_unlock(&dpif->bridge_rwlock);
 	ovs_mutex_unlock(&kstat_mutex);
@@ -444,7 +455,8 @@
 	int error;
 
 	if (port->vtype != OVS_VPORT_TYPE_NETDEV &&
-	    port->vtype != OVS_VPORT_TYPE_VXLAN)
+	    port->vtype != OVS_VPORT_TYPE_VXLAN &&
+	    port->vtype != OVS_VPORT_TYPE_INTERNAL)
 		return (0);
 
 	if ((fd = socket(PF_PACKET, SOCK_RAW, ETH_P_ALL)) == -1) {
@@ -516,13 +528,13 @@
 
 static struct dpif_solaris_bridge *
 dpif_solaris_lookup_bridge(const struct dpif_solaris *dpif,
-    const char *physname)
+    const char *brname)
     OVS_REQ_RDLOCK(dpif->bridge_rwlock)
 {
 	struct dpif_solaris_bridge *bridge;
 
 	HMAP_FOR_EACH(bridge, node, &dpif->bridges) {
-		if (strcmp(bridge->physname, physname) == 0) {
+		if (strcmp(bridge->name, brname) == 0) {
 			return (bridge);
 		}
 	}
@@ -536,25 +548,46 @@
     OVS_REQ_WRLOCK(dpif->port_rwlock)
 {
 	struct dpif_solaris_bridge *bridge;
+	const char *brname = NULL;
 
 	ovs_rwlock_wrlock(&dpif->bridge_rwlock);
 	VLOG_DBG("dpif_solaris_bridge_add_port adding port %d to uplink %s",
 	    port->port_no, physname);
-	bridge = dpif_solaris_lookup_bridge(dpif, physname);
+
+	if (strcmp(physname, NETDEV_IMPL_ETHERSTUB) == 0)
+		brname = port->name;
+	else
+		brname = shash_find_data(&port_to_bridge_map, port->name);
+
+	if (brname == NULL) {
+		/*
+		 * For vxlan or for such cases where we couldn't obtain
+		 * brname
+		 */
+		brname = physname;
+	}
+	bridge = dpif_solaris_lookup_bridge(dpif, brname);
 	if (bridge == NULL) {
-		VLOG_DBG("dpif_solaris_bridge_add_port creating bridge");
+		VLOG_DBG("dpif_solaris_bridge_add_port creating bridge %s",
+		    brname);
 		bridge = xzalloc(sizeof (*bridge));
-		bridge->physname = xstrdup(physname);
+		bridge->name = xstrdup(brname);
 		hmap_insert(&dpif->bridges, &bridge->node,
-		    hash_string(bridge->physname, 0));
+		    hash_string(bridge->name, 0));
 		hmap_init(&bridge->ports);
+		list_init(&bridge->uplink_port_list);
 	}
 	port->bridge = bridge;
 	hmap_insert(&bridge->ports, &port->brnode,
 	    hash_odp_port(port->port_no));
-	if (port->is_uplink)
-		bridge->uplink_port = port;
+	VLOG_DBG("dpif_solaris_bridge_add_port add port %s portno %d to "
+	    "bridge %s", port->name, port->port_no, brname);
 
+	if ((port->is_uplink) && (port->vtype != OVS_VPORT_TYPE_VXLAN)) {
+		VLOG_DBG("Insert port %s into bridge %s uplink_port_list",
+		    port->name, bridge->name);
+		list_push_back(&bridge->uplink_port_list, &port->uplink_node);
+	}
 	ovs_rwlock_unlock(&dpif->bridge_rwlock);
 	return (bridge);
 }
@@ -565,6 +598,7 @@
     OVS_REQ_WRLOCK(dpif->port_rwlock)
 {
 	struct dpif_solaris_bridge *bridge = port->bridge;
+	struct dpif_solaris_port *i_port;
 
 	if (bridge == NULL) {
 		VLOG_DBG("dpif_solaris_bridge_del_port port %d not assigned "
@@ -572,18 +606,34 @@
 		return;
 	}
 	VLOG_DBG("dpif_solaris_bridge_del_port deleting port %d from %s",
-	    port->port_no, bridge->physname);
+	    port->port_no, bridge->name);
 
 	ovs_rwlock_wrlock(&dpif->bridge_rwlock);
+
+	if ((port->is_uplink) && (port->vtype != OVS_VPORT_TYPE_VXLAN)) {
+		/*
+		 * The extra thing we do if it's uplink (other than vxlan)
+		 * is to remove the uplink port from bridge's uplink_port_list.
+		 */
+		LIST_FOR_EACH(i_port, uplink_node, &bridge->uplink_port_list) {
+			if (strcmp(i_port->name, port->name) == 0) {
+				list_remove(&port->uplink_node);
+				VLOG_DBG("dpif_solaris_port_del__: Removed the "
+				    "uplink %s from bridge's(%s) "
+				    "uplink_port_list\n", i_port->name,
+				    bridge->name);
+				break;
+			}
+		}
+	}
+
 	hmap_remove(&bridge->ports, &port->brnode);
-	if (port == bridge->uplink_port)
-		bridge->uplink_port = NULL;
 
 	if (hmap_is_empty(&bridge->ports)) {
 		VLOG_DBG("dpif_solaris_bridge_del_port destroying bridge");
 		hmap_destroy(&bridge->ports);
 		hmap_remove(&dpif->bridges, &bridge->node);
-		free(bridge->physname);
+		free(bridge->name);
 		free(bridge);
 	}
 	ovs_rwlock_unlock(&dpif->bridge_rwlock);
@@ -617,7 +667,9 @@
 	VLOG_DBG("dpif_solaris_port_add %s (%s) type %s port_no %d vtype %d",
 	    name, linkname, type, *port_nop, vtype);
 
-	if (vtype == OVS_VPORT_TYPE_NETDEV || vtype == OVS_VPORT_TYPE_VXLAN) {
+	physname[0] = '\0';
+	if (vtype == OVS_VPORT_TYPE_NETDEV || vtype == OVS_VPORT_TYPE_VXLAN ||
+	    vtype == OVS_VPORT_TYPE_INTERNAL) {
 		error = solaris_get_dlclass(linkname, dlbuffer,
 		    sizeof (dlbuffer));
 		if (error != 0)
@@ -641,9 +693,6 @@
 			VLOG_DBG("dpif_solaris_port_add non-primary port "
 			    "%s to %s", name, dlbuffer);
 		}
-	} else if (vtype == OVS_VPORT_TYPE_INTERNAL) {
-		VLOG_DBG("dpif_solaris_port_add adding internal port %s",
-		    name);
 	} else {
 		VLOG_DBG("dpif_solaris_port_add adding unknown type");
 		return (EINVAL);
@@ -664,7 +713,8 @@
 		error = EFBIG;
 		goto fail;
 	}
-	if (vtype == OVS_VPORT_TYPE_NETDEV || vtype == OVS_VPORT_TYPE_VXLAN) {
+	if (vtype == OVS_VPORT_TYPE_NETDEV || vtype == OVS_VPORT_TYPE_VXLAN ||
+	    vtype == OVS_VPORT_TYPE_INTERNAL) {
 		uint64_t u64 = (uint32_t)(*port_nop);
 
 		VLOG_DBG("set portno %d on %s", (uint32_t)(*port_nop),
@@ -683,6 +733,7 @@
 	port->pf_port_no = pf_port_no;
 	port->name = xstrdup(name);
 	port->linkname = xstrdup(linkname);
+	port->physname = xstrdup(physname);
 	port->type = xstrdup(type);
 	port->vtype = vtype;
 	port->netdev = netdev;
@@ -707,7 +758,8 @@
 		goto fail;
 	}
 
-	if (vtype == OVS_VPORT_TYPE_NETDEV || vtype == OVS_VPORT_TYPE_VXLAN)
+	if (vtype == OVS_VPORT_TYPE_NETDEV || vtype == OVS_VPORT_TYPE_VXLAN ||
+	    vtype == OVS_VPORT_TYPE_INTERNAL)
 		dpif_solaris_bridge_add_port(dpif, physname, port);
 	hmap_insert(&dpif->ports, &port->node, hash_odp_port(port->port_no));
 
@@ -726,9 +778,11 @@
 		free(port->name);
 		free(port->linkname);
 		free(port->type);
+		free(port->physname);
 		free(port);
 	}
-	if (vtype == OVS_VPORT_TYPE_NETDEV || vtype == OVS_VPORT_TYPE_VXLAN) {
+	if (vtype == OVS_VPORT_TYPE_NETDEV || vtype == OVS_VPORT_TYPE_VXLAN ||
+	    vtype == OVS_VPORT_TYPE_INTERNAL) {
 		VLOG_DBG("reset portno on %s", linkname);
 		(void) solaris_set_dlprop_ulong(linkname, "ofport", NULL);
 	}
@@ -773,20 +827,33 @@
 }
 
 static int
-dpif_solaris_get_uplink_port(struct dpif_solaris *dpif,
-    struct dpif_solaris_port **portp)
-    OVS_REQ_RDLOCK(dpif->port_rwlock)
+dpif_solaris_get_uplink_port_info(struct dpif_solaris *dpif,
+    odp_port_t port_no, odp_port_t *uport_nop, int *xfdp)
 {
-	struct dpif_solaris_port *port;
+	struct dpif_solaris_port *port, *uport;
+
+	ovs_rwlock_rdlock(&dpif->port_rwlock);
+	HMAP_FOR_EACH(port, node, &dpif->ports)
+		if (port->port_no == port_no)
+			break;
 
-	HMAP_FOR_EACH(port, node, &dpif->ports) {
-		if (port->is_uplink) {
-			*portp = port;
+	if (port == NULL)
+		goto done;
+
+	HMAP_FOR_EACH(uport, node, &dpif->ports) {
+		if (uport->is_uplink &&
+		    strcmp(port->physname, uport->linkname) == 0) {
+			if (uport_nop != NULL)
+				*uport_nop = uport->port_no;
+			if (xfdp != NULL)
+				*xfdp = uport->xfd;
+			ovs_rwlock_unlock(&dpif->port_rwlock);
 			return (0);
 		}
 	}
 
-	*portp = NULL;
+done:
+	ovs_rwlock_unlock(&dpif->port_rwlock);
 	return (ENOENT);
 }
 
@@ -809,7 +876,7 @@
 		(void) close(port->upcall_fd);
 	}
 	if (port->vtype == OVS_VPORT_TYPE_NETDEV || port->vtype ==
-	    OVS_VPORT_TYPE_VXLAN) {
+	    OVS_VPORT_TYPE_VXLAN || port->vtype == OVS_VPORT_TYPE_INTERNAL) {
 			VLOG_DBG("1.reset portno on %s", port->linkname);
 			(void) solaris_set_dlprop_ulong(port->linkname,
 			    "ofport", NULL);
@@ -824,6 +891,7 @@
 	free(port->type);
 	free(port->name);
 	free(port->linkname);
+	free(port->physname);
 	free(port);
 }
 
@@ -896,61 +964,6 @@
 	return (ENOENT);
 }
 
-static int
-dpif_solaris_configure_bridge_port(const struct dpif *dpif_,
-    const char *devname)
-{
-	struct dpif_solaris *dpif = dpif_solaris_cast(dpif_);
-	struct dpif_solaris_port *port = NULL;
-	char dlbuffer[DLADM_PROP_VAL_MAX];
-	char physname[MAXLINKNAMELEN];
-	uint64_t u64;
-	int error = 0;
-
-	VLOG_DBG("dpif_solaris_configure_bridge_port %s", devname);
-
-	ovs_rwlock_wrlock(&dpif->port_rwlock);
-	HMAP_FOR_EACH(port, node, &dpif->ports) {
-		if (strcmp(port->name, devname) == 0) {
-			error = solaris_get_dllower(devname, dlbuffer,
-			    sizeof (dlbuffer));
-			if (error != 0) {
-				VLOG_ERR("failed to get lowerlink: %s",
-				    ovs_strerror(error));
-				goto out;
-			}
-			if (strlcpy(physname, dlbuffer, sizeof (physname)) >=
-			    sizeof (physname)) {
-				VLOG_ERR("invalid lowerlink size");
-				error = EINVAL;
-				goto out;
-			}
-
-			u64 = (uint32_t)(port->port_no);
-			VLOG_DBG("set portno %d on %s",
-			    (uint32_t)(port->port_no), devname);
-			error = solaris_set_dlprop_ulong(devname, "ofport",
-			    &u64);
-			if (error != 0) {
-				VLOG_ERR("set portno %d on %s failed: %s",
-				    (uint32_t)(port->port_no), devname,
-				    ovs_strerror(error));
-				goto out;
-			}
-			VLOG_DBG("dpif_solaris_port_add internal port "
-			    "%s to %s", devname, physname);
-			(void) dpif_solaris_bridge_add_port(dpif, physname,
-			    port);
-			goto out;
-		}
-	}
-	error = ENOENT;
-
-out:
-	ovs_rwlock_unlock(&dpif->port_rwlock);
-	return (error);
-}
-
 struct dpif_solaris_port_state {
 	struct hmap ports;
 	struct ovs_rwlock port_rwlock;
@@ -1391,17 +1404,28 @@
 
 	if (solaris_flow == NULL) {
 		if (put->flags & DPIF_FP_CREATE) {
-			struct dpif_solaris_port	*port = NULL;
-			odp_port_t			inport;
+			struct dpif_solaris_port *port = NULL;
+			odp_port_t		inport;
+			char			physname[MAXLINKNAMESPECIFIER];
+			char			portname[MAXLINKNAMESPECIFIER];
 
 			inport = f.in_port.odp_port;
 			ovs_rwlock_rdlock(&dpif->port_rwlock);
 			error = dpif_solaris_get_port_by_number(dpif, inport,
 			    &port);
+			if (error == 0) {
+				(void) strlcpy(physname, port->physname,
+				    sizeof (physname));
+				(void) strlcpy(portname, port->name,
+				    sizeof (portname));
+			}
 			ovs_rwlock_unlock(&dpif->port_rwlock);
 			if (error == 0) {
+				VLOG_DBG("dpif_solaris_flow_put on %s",
+				    physname);
+
 				solaris_flow = dpif_solaris_flow_add(dpif,
-				    port->bridge->physname, &f, &wc);
+				    physname, &f, &wc);
 				(void) strlcpy(flowname,
 				    solaris_flow->flowname,
 				    MAXUSERFLOWNAMELEN);
@@ -1416,17 +1440,20 @@
 				 * implementations.
 				 */
 				error = solaris_add_flow((void *)dpif,
-				    port->bridge->physname, flowname, &f,
+				    physname, flowname, &f,
 				    &wc.masks, put->actions, put->actions_len);
 				if (error == 0) {
 					VLOG_DBG("dpif_solaris_flow_put "
-					    "solaris_add_flow %s on %s succeed",
-					    flowname, port->bridge->physname);
+					    "solaris_add_flow %s on %s succeed"
+					    "(port:%s)",
+					    flowname, physname, portname);
 				} else {
 					VLOG_ERR("dpif_solaris_flow_put "
 					    "solaris_add_flow %s on %s failed "
+					    "(port:%s)"
 					    "%d", flowname,
-					    port->bridge->physname,
+					    physname,
+					    portname,
 					    error);
 					dpif_solaris_flow_remove(dpif,
 					    solaris_flow);
@@ -1784,7 +1811,6 @@
 dpif_solaris_port_output(struct dpif_solaris *dpif, odp_port_t port_no,
     struct ofpbuf *packet, bool may_steal)
 {
-	struct dpif_solaris_port	*port;
 	struct msghdr			msghdr;
 	struct iovec 			iov;
 	struct cmsghdr			*cmsg;
@@ -1798,12 +1824,8 @@
 
 	VLOG_DBG("dpif_solaris_port_output %d", port_no);
 
-	ovs_rwlock_rdlock(&dpif->port_rwlock);
-	error = dpif_solaris_get_uplink_port(dpif, &port);
-	if (error == 0 && port->is_uplink)
-		fd = port->xfd;
-	ovs_rwlock_unlock(&dpif->port_rwlock);
-	if (fd == -1) {
+	error = dpif_solaris_get_uplink_port_info(dpif, port_no, NULL, &fd);
+	if (error != 0 || fd == -1) {
 		if (may_steal) {
 			ofpbuf_delete(packet);
 		}
@@ -1851,26 +1873,137 @@
 	return (0);
 }
 
-/*
- * Return the port number of the uplink port; 0 if there is no uplink port
- * Assumes caller holds port_rwlock.
- */
-static odp_port_t
-dp_solaris_uplink_port(struct dpif_solaris *dpif)
+static struct dpif_solaris *
+get_dp_by_name(char *dp_name)
+{
+	struct dpif_solaris *dpif = NULL;
+
+	ovs_mutex_lock(&dp_solaris_mutex);
+	dpif = shash_find_data(&dp_all_solaris, dp_name);
+	if (!dpif) {
+		VLOG_ERR("get_dp_by_name: couldn't get a hold on dpif for %s",
+		    dp_name);
+	}
+	ovs_mutex_unlock(&dp_solaris_mutex);
+	return (dpif);
+}
+
+struct netdev *
+dpif_solaris_obtain_netdev_to_migrate(char *brname, bool *error)
 {
-	odp_port_t			port_no = 0;
-	struct dpif_solaris_port	*port;
+	struct dpif_solaris		*dpif;
+	struct dpif_solaris_bridge	*bridge;
+	struct dpif_solaris_port	*i_port;
+	struct netdev			*i_netdev;
+	struct netdev			*netdev_to_migrate = NULL;
+
+	dpif = get_dp_by_name("ovs-system");
+	if (dpif == NULL) {
+		*error = true;
+		return (NULL);
+	}
+	ovs_rwlock_wrlock(&dpif->bridge_rwlock);
+	bridge = dpif_solaris_lookup_bridge(dpif, brname);
+	if (bridge == NULL) {
+		VLOG_ERR("dpif_solaris_obtain_netdev_to_migrate: Could not "
+		    "locate bridge for %s", brname);
+		ovs_rwlock_unlock(&dpif->bridge_rwlock);
+		*error = true;
+		return (NULL);
+	}
+	/*
+	 * If bridge has no uplinks migrate bridge vnic to implicit etherstub.
+	 * If it has uplinks, look for an uplink which is not etherstub. If not
+	 * get the first uplink from the uplink_port_list.
+	 */
+
+	if (list_is_empty(&bridge->uplink_port_list)) {
+		ovs_rwlock_unlock(&dpif->bridge_rwlock);
+		return (NULL);
+	} else {
+		LIST_FOR_EACH(i_port, uplink_node, &bridge->uplink_port_list) {
+			i_netdev = i_port->netdev;
+			if (i_netdev == NULL) {
+				VLOG_ERR(
+				    "dpif_solaris_obtain_netdev_to_migrate:"
+				    " Could not obtain netdev for %s",
+				    i_port->name);
+				ovs_rwlock_unlock(&dpif->bridge_rwlock);
+				*error = true;
+				return (NULL);
+			}
+
+			if (strcmp(netdev_solaris_get_class(i_netdev),
+			    "etherstub") != 0) {
+				netdev_to_migrate = i_netdev;
+				break;
+			}
+		}
 
-	ovs_rwlock_rdlock(&dpif->port_rwlock);
-	HMAP_FOR_EACH(port, node, &dpif->ports) {
-		if (port->is_uplink) {
-			port_no = port->port_no;
+		if (netdev_to_migrate == NULL) {
+			VLOG_DBG("Couldn't find a netdev other than etherstub. "
+			    "Thus migrating to first etherstub");
+			ASSIGN_CONTAINER(i_port,
+			    (&(bridge->uplink_port_list))->next,
+			    uplink_node);
+			netdev_to_migrate = i_port->netdev;
+			if (netdev_to_migrate == NULL) {
+				VLOG_ERR(
+				    "dpif_solaris_obtain_netdev_to_migrate:"
+				    " Could not obtain netdev for %s",
+				    i_port->name);
+				ovs_rwlock_unlock(&dpif->bridge_rwlock);
+				*error = true;
+				return (NULL);
+			}
+		}
+	}
+
+	ovs_rwlock_unlock(&dpif->bridge_rwlock);
+	return (netdev_to_migrate);
+}
+
+/*
+ * Migrate the internal port to a different lower link, sets its physname, and
+ * refresh its port channel.
+ *
+ * Note that the internal port's name is the same as bridge name
+ */
+void
+dpif_solaris_migrate_internal_port(const char *bridge, const char *physname)
+{
+	struct dpif_solaris		*dpif;
+	struct dpif_solaris_port	*port;
+	int				err;
+
+	VLOG_DBG("dpif_solaris_migrate_internal_port port %s on %s", bridge,
+	    physname);
+
+	if ((dpif = get_dp_by_name("ovs-system")) != NULL) {
+		ovs_rwlock_wrlock(&dpif->port_rwlock);
+		HMAP_FOR_EACH(port, node, &dpif->ports) {
+			if (strcmp(port->name, bridge) != 0)
+				continue;
+			if (port->upcall_fd != -1) {
+				(void) setsockopt(port->upcall_fd, SOL_PACKET,
+				    PACKET_REM_OF_DEFFLOW, NULL, 0);
+				(void) close(port->upcall_fd);
+			}
+			free(port->physname);
+			port->physname = xstrdup(physname);
+			err = dpif_solaris_refresh_port_channel(dpif, port,
+			    physname, false);
+			if (err == 0)
+				VLOG_DBG("dpif_solaris_migrate_internal_port %s"
+				    " on %s succeed", bridge, physname);
+			else
+				VLOG_ERR("dpif_solaris_migrate_internal_port %s"
+				    " on %s failed %d", bridge, physname, err);
 			break;
 		}
+		ovs_rwlock_unlock(&dpif->port_rwlock);
 	}
-	ovs_rwlock_unlock(&dpif->port_rwlock);
 
-	return (port_no);
 }
 
 static void
@@ -1879,16 +2012,61 @@
 {
 	struct dpif_solaris *dpif = aux_;
 	int type = nl_attr_type(a);
+	odp_port_t pin, pout;
+	int err;
 
 	VLOG_DBG("dp_solaris_execute_cb type %d", type);
 
 	switch ((enum ovs_action_attr)type) {
 	case OVS_ACTION_ATTR_OUTPUT: {
-		odp_port_t port_no = u32_to_odp(nl_attr_get_u32(a));
+		odp_port_t			port_no;
+
+		port_no = u32_to_odp(nl_attr_get_u32(a));
 
 		VLOG_DBG("dp_solaris_execute_cb OVS_ACTION_ATTR_OUTPUT "
-		    "%d", port_no);
+		    "%d: inport is %d", port_no, md->in_port.odp_port);
 
+		/*
+		 * If in_port number is OFPP_NONE, this means this packet out
+		 * request comes from the controller.
+		 */
+		if (md->in_port.odp_port != ODPP_NONE) {
+			err = dpif_solaris_get_uplink_port_info(dpif,
+			    md->in_port.odp_port, &pin, NULL);
+			if (err != 0) {
+				VLOG_DBG("dp_solaris_execute_cb "
+				    "OVS_ACTION_ATTR_OUTPUT Error getting "
+				    "uplink for inport %d ",
+				    md->in_port.odp_port);
+				if (may_steal)
+					ofpbuf_delete(packet);
+				break;
+			}
+			err = dpif_solaris_get_uplink_port_info(dpif, port_no,
+			    &pout, NULL);
+			if (err != 0) {
+				VLOG_DBG("dp_solaris_execute_cb "
+				    "OVS_ACTION_ATTR_OUTPUT Error getting "
+				    "uplink for outport %d ", port_no);
+				if (may_steal)
+					ofpbuf_delete(packet);
+				break;
+			}
+			/*
+			 * Bridging across different uplinks is not supported
+			 * in the kernel currently, so we disable that support
+			 * here as well.
+			 */
+			if (pin != pout) {
+				VLOG_DBG("dp_solaris_execute_cb "
+				    "OVS_ACTION_ATTR_OUTPUT inport %d and "
+				    "outport %d on different uplinks",
+				    md->in_port.odp_port, port_no);
+				if (may_steal)
+					ofpbuf_delete(packet);
+				break;
+			}
+		}
 		(void) dpif_solaris_port_output(dpif, port_no, packet,
 		    may_steal);
 		break;
@@ -1901,25 +2079,25 @@
 	 * sockets, it will still get to the kernel before coming back.
 	 * Need a short-cut. Note we don't care about any userland data
 	 * since we will get it when the packets comes back from the
-	 * kernel. Also, currently we always send using the uplink in
-	 * dpif_solaris_port_output so we don't have to dp_solaris_uplink_port.
+	 * kernel. Also, currently we always send using the uplink associated
+	 * with the in_port number.
 	 */
 	case OVS_ACTION_ATTR_USERSPACE:	{	/* controller */
-		odp_port_t port_no = dp_solaris_uplink_port(dpif);
+		VLOG_DBG("dp_solaris_execute_cb OVS_ACTION_ATTR_USERSPACE");
 
-		VLOG_DBG("dp_solaris_execute_cb OVS_ACTION_ATTR_USERSPACE");
-		if (port_no == 0) {
-			VLOG_DBG("dp_solaris_execute_cb "
-			"OVS_ACTION_ATTR_USERSPACE: no uplink port.");
-			if (may_steal) {
+		err = dpif_solaris_get_uplink_port_info(dpif,
+		    md->in_port.odp_port, &pin, NULL);
+		if (err != 0) {
+			VLOG_DBG("dp_solaris_execute_cb OVS_ACTION_ATTR_OUTPUT "
+			    "Error getting uplink for inport %d",
+			    md->in_port.odp_port);
+			if (may_steal)
 				ofpbuf_delete(packet);
-			}
 			break;
 		}
 		VLOG_DBG("dp_solaris_execute_cb OVS_ACTION_ATTR_USERSPACE "
-		    "%d", port_no);
-		(void) dpif_solaris_port_output(dpif, port_no, packet,
-		    may_steal);
+		    "%d", pin);
+		(void) dpif_solaris_port_output(dpif, pin, packet, may_steal);
 		break;
 	}
 	case OVS_ACTION_ATTR_HASH:		/* for bonding */
@@ -1991,11 +2169,12 @@
 	int error;
 
 	if (!dpif->recv_set || (port->vtype != OVS_VPORT_TYPE_NETDEV &&
-	    port->vtype != OVS_VPORT_TYPE_VXLAN))
+	    port->vtype != OVS_VPORT_TYPE_VXLAN && port->vtype !=
+	    OVS_VPORT_TYPE_INTERNAL))
 		return (0);
 
-	VLOG_DBG("dpif_solaris_refresh_port_channel on %s port_no: %d%s",
-	    port->linkname, port->port_no, notify ? " notify" : "");
+	VLOG_DBG("dpif_solaris_refresh_port_channel(%s) port_no: %d on %s%s",
+	    port->linkname, port->port_no, physname, notify ? " notify" : "");
 
 	fd = socket(PF_PACKET, SOCK_RAW, ETH_P_ALL);
 	if (fd == -1) {
@@ -2126,7 +2305,7 @@
 	ovs_rwlock_wrlock(&dpif->port_rwlock);
 	HMAP_FOR_EACH(port, node, &dpif->ports) {
 		error = dpif_solaris_refresh_port_channel(dpif, port,
-		    port->bridge->physname, false);
+		    port->physname, false);
 		if (error != 0) {
 			ovs_rwlock_unlock(&dpif->port_rwlock);
 			dpif_solaris_destroy_channels(dpif);
@@ -2460,6 +2639,5 @@
 	dpif_solaris_queue_to_priority,
 	dpif_solaris_recv,
 	dpif_solaris_recv_wait,
-	dpif_solaris_recv_purge,
-	dpif_solaris_configure_bridge_port
+	dpif_solaris_recv_purge
 };
--- a/components/openvswitch/files/lib/dpif-solaris.h	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/lib/dpif-solaris.h	Tue Apr 05 20:57:21 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -34,4 +34,7 @@
 int dpif_solaris_get_priority_details(void *, odp_port_t, uint_t,
     struct smap *);
 void dpif_log(int, const char *, ...);
+void dpif_solaris_migrate_internal_port(const char *, const char *);
+struct netdev *dpif_solaris_obtain_netdev_to_migrate(char *, bool *);
+
 #endif	/* DPIF_SOLARIS_H */
--- a/components/openvswitch/files/lib/netdev-solaris.c	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/lib/netdev-solaris.c	Tue Apr 05 20:57:21 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -65,6 +65,7 @@
 
 #include "netdev-solaris.h"
 #include "util-solaris.h"
+#include "dpif-solaris.h"
 
 /*
  * Enable vlog() for this module
@@ -124,13 +125,6 @@
 };
 
 /*
- * When network devices are constructed, the internal devices (i.e., bridges)
- * are initially created over this etherstub and are moved when uplink ports
- * are added to the bridge.
- */
-#define	NETDEV_IMPL_ETHERSTUB	"ovs.etherstub0"
-
-/*
  * Used to track state of IP plumbing on network devices.
  */
 #define	SOLARIS_IPV4 0x01
@@ -153,6 +147,9 @@
 static int netdev_solaris_init(void);
 static struct netdev_solaris *netdev_solaris_cast(const struct netdev *);
 
+/* Maintaining a mapping of every netdev->name to its bridge name. */
+struct shash port_to_bridge_map = SHASH_INITIALIZER(&port_to_bridge_map);
+
 /*
  * An instance of a traffic control class.
  *
@@ -465,6 +462,12 @@
 	return (CONTAINER_OF(netdev, struct netdev_solaris, up));
 }
 
+char *
+netdev_solaris_get_class(struct netdev *netdev)
+{
+	return ((netdev_solaris_cast(netdev))->class);
+}
+
 static int
 netdev_solaris_plumb(const struct netdev *netdev_, sa_family_t af)
 {
@@ -524,13 +527,19 @@
 		proto = SOLARIS_IPV6;
 	}
 
-	if ((netdev->implicitly_plumbed & proto) == 0)
+	if ((netdev->implicitly_plumbed & proto) == 0 &&
+	    (netdev->up.netdev_class != &netdev_internal_class)) {
 		return (0);
+	}
 
 	error = solaris_unplumb_if(sock, netdev_name, af);
 	if (error != 0) {
-		VLOG_ERR("%s device could not be unplumbed", netdev_name);
-		return (error);
+		if (error == ENXIO &&
+		    netdev->up.netdev_class == &netdev_internal_class) {
+			return (0);
+		}
+		VLOG_ERR("%s device could not be unplumbed %d", netdev_name,
+		    error);
 	}
 	VLOG_ERR("%s device unplumbed for %s", netdev_name, astring);
 	netdev->implicitly_plumbed &= ~proto;
@@ -707,20 +716,75 @@
 	return (&netdev->up);
 }
 
+static void
+netdev_solaris_add_port_to_bridge_mapping(const struct netdev
+		*netdev, const char *brname)
+{
+	VLOG_DBG("netdev_solaris_add_port_to_bridge_mapping: adding a mapping "
+	    "<%s,%s> to port_to_bridge_map", netdev->name, brname);
+	shash_add_nocopy(&port_to_bridge_map, netdev->name, brname);
+}
+
 static int
 netdev_solaris_unconfigure_uplink(const struct netdev *netdev_)
 {
 	struct netdev_solaris	*netdev = netdev_solaris_cast(netdev_);
 	const char		*netdev_name = netdev_get_name(netdev_);
 	int			error;
+	char			curr_lower[DLADM_PROP_VAL_MAX];
+	struct netdev		*netdev_to_migrate = NULL;
+	char			*new_lower = NULL;
+	bool			b_error = false;
 
 	VLOG_DBG("netdev_solaris_unconfigure_uplink device %s", netdev_name);
 
-	error = solaris_modify_vnic(NETDEV_IMPL_ETHERSTUB, netdev->brname);
-	if (error != 0 && error != ENODEV) {
-		VLOG_ERR("failed to unconfigure %s as uplink for %s: "
-		    "%s", netdev_name, netdev->brname,
-		    ovs_strerror(error));
+	error = solaris_get_dlprop(netdev->brname, "lower-link", "current",
+	    curr_lower, sizeof (curr_lower));
+	if (error) {
+		VLOG_ERR("netdev_solaris_unconfigure_uplink couldn't obtain "
+		    "bridge(%s) lowerlink", netdev->brname);
+		return (0);
+	}
+
+	if (strcmp(netdev_name, curr_lower) == 0) {
+		/*
+		 * The uplink which we are trying to remove has bridge vnic on
+		 * top of it. We need to migrate bridge vnic to a different
+		 * uplink or to ovs.etherstub0 if uplink_port_list is empty.
+		 */
+		VLOG_DBG("netdev_solaris_unconfigure_uplink: unconfiguring the "
+		    "uplink (%s) which is the bridge %s's lowerlink (%s)",
+		    netdev_name, netdev->brname, curr_lower);
+
+		netdev_to_migrate = dpif_solaris_obtain_netdev_to_migrate(
+		    netdev->brname, &b_error);
+		if (b_error) {
+			VLOG_ERR("netdev_solaris_unconfigure_uplink: couldn't "
+			    "obtain netdev_to_migrate for bridge vnic %s",
+			    netdev->brname);
+			return (0);
+		}
+
+		if (netdev_to_migrate == NULL)
+			new_lower = NETDEV_IMPL_ETHERSTUB;
+		else
+			new_lower = netdev_to_migrate->name;
+
+		VLOG_DBG("netdev_solaris_unconfigure_uplink migrating bridge "
+		    "vnic to %s", new_lower);
+
+		error = solaris_modify_vnic(new_lower, netdev->brname);
+		if (error != 0) {
+			VLOG_ERR("failed to unconfigure %s as uplink for %s: "
+			    "%s", netdev_name, netdev->brname,
+			    ovs_strerror(error));
+			return (0);
+		}
+
+		/*
+		 * reset internal port's physname and refresh its port channel.
+		 */
+		dpif_solaris_migrate_internal_port(netdev->brname, new_lower);
 	}
 	return (0);
 }
@@ -730,11 +794,14 @@
     const char *brname)
 {
 	struct netdev_solaris	*netdev = netdev_solaris_cast(netdev_);
-	const char		*netdev_name = netdev_get_name(netdev_);
-	char			buffer[DLADM_PROP_VAL_MAX];
+	const char		*new_uplink = netdev_get_name(netdev_);
+	char			curr_lower[DLADM_PROP_VAL_MAX];
 	int			error;
-
-	VLOG_DBG("netdev_solaris_configure_uplink device %s", netdev_name);
+	const char		*netdev_existing_class;
+	struct netdev		*i_netdev;
+	boolean_t		migrated = B_FALSE;
+
+	VLOG_DBG("netdev_solaris_configure_uplink device %s", new_uplink);
 
 	/*
 	 * Normally, we would expect to see that the bridge VNIC has already
@@ -745,12 +812,19 @@
 	 * already exist.
 	 */
 	error = solaris_get_dlprop(brname, "lower-link", "current",
-	    buffer, sizeof (buffer));
+	    curr_lower, sizeof (curr_lower));
+	VLOG_DBG("netdev_solaris_configure_uplink lower-link:%s", curr_lower);
+
 	if (error == ENODEV) {
-		VLOG_DBG("%s vnic being created on %s",
-		    brname, netdev_name);
-		error = solaris_create_vnic(netdev_name, brname);
-		if (error != 0) {
+		/*
+		 * No implicit VNIC being created yet, create it now
+		 */
+		VLOG_DBG("%s vnic being created on %s", brname, new_uplink);
+		error = solaris_create_vnic(new_uplink, brname);
+		if (error == 0) {
+			(void) strlcpy(netdev->brname, brname,
+			    sizeof (netdev->brname));
+		} else {
 			VLOG_ERR("Failed to create vnic for %s: %s",
 			    brname, ovs_strerror(error));
 		}
@@ -765,34 +839,65 @@
 	 * If the lower-link is already set correctly, then return with
 	 * success.
 	 */
-	if (strcmp(buffer, netdev_name) == 0) {
+	if (strcmp(curr_lower, new_uplink) == 0) {
+		VLOG_DBG("netdev_solaris_configure_uplink lower-link(%s) is "
+		    "already correctly set. (%s)", curr_lower, new_uplink);
 		error = 0;
 		goto exit;
 	}
 
-	/*
-	 * If the lower-link is already set to something other than the
-	 * etherstub, something is wrong.
-	 */
-	if (strcmp(buffer, NETDEV_IMPL_ETHERSTUB) != 0) {
-		VLOG_ERR("Bridge already has uplink %s", buffer);
-		error = EEXIST;
-		goto exit;
-	}
-
-	/*
-	 * This is the "normal" case, where the bridge VNIC existed and had
-	 * the etherstub as its lower-link. Move the VNIC to its uplink.
-	 */
-	error = solaris_modify_vnic(netdev_name, brname);
-	if (error != 0) {
-		VLOG_ERR("failed to configure %s as uplink: %s",
-		    netdev_name, ovs_strerror(error));
-		goto exit;
+	if (strcmp(curr_lower, NETDEV_IMPL_ETHERSTUB) == 0) {
+		/*
+		 * Bridge vnic is on ovs.etherstub0. We have to migrate the
+		 * bridge vnic to the uplink
+		 */
+		VLOG_DBG("bridge vnic %s is on %s, migrating it to %s",
+		    brname, curr_lower, new_uplink);
+
+		error = solaris_modify_vnic(new_uplink, brname);
+		if (error != 0) {
+			VLOG_ERR("failed to configure %s as uplink: %s",
+			    new_uplink, ovs_strerror(error));
+			goto exit;
+		}
+		migrated = B_TRUE;
+	} else {
+		/*
+		 * Bridge vnic is already on an uplink. Now we see if the
+		 * uplink to be added is other than etherstub or not.
+		 * If the bridge vnic is currently residing on an etherstub
+		 * and the one to be configured is not etherstub,
+		 * then we migrate the bridge vnic.
+		 */
+		i_netdev = netdev_from_name(curr_lower);
+		if (!i_netdev) {
+			VLOG_ERR("netdev_solaris_configure_uplink error "
+			    "in fetching lower-link netdev for %s", curr_lower);
+			goto exit;
+		}
+		/* i_netdev->ref_cnt--; */
+		netdev_close(i_netdev);
+
+		netdev_existing_class = netdev_solaris_get_class(i_netdev);
+		if ((strcmp(netdev_existing_class, "etherstub") == 0) &&
+		    (strcmp(netdev->class, "etherstub") != 0)) {
+			error = solaris_modify_vnic(new_uplink, brname);
+			if (error != 0) {
+				VLOG_ERR("failed to configure %s as uplink: %s",
+				    new_uplink, ovs_strerror(error));
+				goto exit;
+			}
+			migrated = B_TRUE;
+		}
 	}
 	(void) strlcpy(netdev->brname, brname, sizeof (netdev->brname));
 
 exit:
+	/*
+	 * reset internal port's physname and refresh its port channel.
+	 */
+	if (migrated)
+		dpif_solaris_migrate_internal_port(brname, new_uplink);
 	return (error);
 }
 
@@ -2339,6 +2444,7 @@
 	netdev_solaris_update_flags,					\
 	netdev_solaris_configure_uplink,				\
 	netdev_solaris_is_uplink,					\
+	netdev_solaris_add_port_to_bridge_mapping,			\
 	NULL,								\
 	NULL,								\
 	NULL,								\
--- a/components/openvswitch/files/lib/netdev-solaris.h	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/lib/netdev-solaris.h	Tue Apr 05 20:57:21 2016 -0700
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
  */
 
 /*
@@ -25,14 +25,24 @@
 #include <stdbool.h>
 
 /*
+ * When network devices are constructed, the internal devices (i.e., bridges)
+ * are initially created over this etherstub and are moved when uplink ports
+ * are added to the bridge.
+ */
+#define	NETDEV_IMPL_ETHERSTUB	"ovs.etherstub0"
+
+/*
  * These functions are Solaris specific, so they should be used directly only by
  * Solaris-specific code.
  */
 
 struct netdev;
 
+extern struct shash port_to_bridge_map;
+
 int netdev_create_impl_etherstub(void);
 void netdev_delete_impl_etherstub(void);
 boolean_t netdev_impl_etherstub_exists(void);
+char *netdev_solaris_get_class(struct netdev *);
 
 #endif	/* NETDEV_SOLARIS_H */
--- a/components/openvswitch/files/lib/util-solaris.c	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/lib/util-solaris.c	Tue Apr 05 20:57:21 2016 -0700
@@ -629,8 +629,8 @@
 		rc_free_uri(rc_uri);
 		if (rad_conn == NULL)
 			return (ENODEV); /* Not sure what to return */
-	}
-	return (0);
+		}
+		return (0);
 }
 
 static rc_err_t
@@ -972,7 +972,6 @@
 	dlmgr_DatalinkError_t		*derrp = NULL;
 	dlmgr_DLValue_t			*old_val = NULL;
 	dlmgr_DLValue_t			name_val;
-	dlmgr_DLValue_t			temp_val;
 	dlmgr_DLValue_t			type_val;
 	dlmgr_DLValue_t			macaddr_info_val;
 	rc_instance_t			*linkmgr = NULL;
@@ -999,16 +998,6 @@
 	dlmgr_DLValue_free(old_val);
 	old_val = NULL;
 
-	bzero(&temp_val, sizeof (temp_val));
-	temp_val.ddlv_type = DDLVT_BOOLEAN;
-	temp_val.ddlv_bval = &b_true;
-	status = dlmgr__rad_dict_string_DLValue_put(prop, "temporary",
-	    &temp_val, &old_val);
-	if (status != RCE_OK)
-		goto out;
-	dlmgr_DLValue_free(old_val);
-	old_val = NULL;
-
 	macaddr_info = dlmgr__rad_dict_string_DLValue_create(linkmgr);
 	if (macaddr_info == NULL)
 		goto out;
@@ -1143,39 +1132,17 @@
 int
 solaris_delete_vnic(const char *vnicname)
 {
-	dlmgr__rad_dict_string_DLValue_t *prop = NULL;
 	dlmgr_DatalinkError_t		*derrp = NULL;
-	dlmgr_DLValue_t			*old_val = NULL;
-	dlmgr_DLValue_t			temp_val;
 	rc_instance_t			*linkmgr = NULL;
 	rc_err_t			status;
 	int				err = 0;
 
 	status = dlmgr_DatalinkManager__rad_lookup(rad_conn, B_TRUE,
 	    &linkmgr, 0);
-	if (status != RCE_OK) {
-		err = EINVAL;
-		goto out;
-	}
-
-	prop = dlmgr__rad_dict_string_DLValue_create(linkmgr);
-	if (prop == NULL) {
-		err = EINVAL;
-		goto out;
-	}
-
-	bzero(&temp_val, sizeof (temp_val));
-	temp_val.ddlv_type = DDLVT_BOOLEAN;
-	temp_val.ddlv_bval = &b_true;
-	status = dlmgr__rad_dict_string_DLValue_put(prop, "temporary",
-	    &temp_val, &old_val);
-	if (status != RCE_OK) {
-		err = EINVAL;
-		goto out;
-	}
-	dlmgr_DLValue_free(old_val);
-
-	status = dlmgr_DatalinkManager_deleteVNIC(linkmgr, vnicname, prop,
+	if (status != RCE_OK)
+		return (EINVAL);
+
+	status = dlmgr_DatalinkManager_deleteVNIC(linkmgr, vnicname, NULL,
 	    &derrp);
 	if (status != RCE_OK) {
 		err = -1;
@@ -1188,8 +1155,6 @@
 	}
 	dlmgr_DatalinkError_free(derrp);
 
-out:
-	dlmgr__rad_dict_string_DLValue_free(prop);
 	rc_instance_rele(linkmgr);
 	return (err);
 }
@@ -1197,10 +1162,7 @@
 int
 solaris_create_etherstub(const char *name)
 {
-	dlmgr__rad_dict_string_DLValue_t *prop = NULL;
 	dlmgr_DatalinkError_t		*derrp = NULL;
-	dlmgr_DLValue_t			*old_val = NULL;
-	dlmgr_DLValue_t			temp_val;
 	rc_instance_t			*linkmgr = NULL;
 	rc_instance_t			*etherstub = NULL;
 	rc_err_t			status;
@@ -1208,22 +1170,9 @@
 	status = dlmgr_DatalinkManager__rad_lookup(rad_conn, B_TRUE,
 	    &linkmgr, 0);
 	if (status != RCE_OK)
-		goto out;
-
-	prop = dlmgr__rad_dict_string_DLValue_create(linkmgr);
-	if (prop == NULL)
-		goto out;
-
-	bzero(&temp_val, sizeof (temp_val));
-	temp_val.ddlv_type = DDLVT_BOOLEAN;
-	temp_val.ddlv_bval = &b_true;
-	status = dlmgr__rad_dict_string_DLValue_put(prop, "temporary",
-	    &temp_val, &old_val);
-	if (status != RCE_OK)
-		goto out;
-	dlmgr_DLValue_free(old_val);
-
-	status = dlmgr_DatalinkManager_createEtherstub(linkmgr, name, prop,
+		return (ENOTSUP);
+
+	status = dlmgr_DatalinkManager_createEtherstub(linkmgr, name, NULL,
 	    &etherstub, &derrp);
 	if (status == RCE_SERVER_OBJECT) {
 		dpif_log(derrp->dde_err,
@@ -1232,9 +1181,6 @@
 	}
 	rc_instance_rele(etherstub);
 	dlmgr_DatalinkError_free(derrp);
-
-out:
-	dlmgr__rad_dict_string_DLValue_free(prop);
 	rc_instance_rele(linkmgr);
 
 	return ((status != RCE_OK) ? ENOTSUP : 0);
@@ -1243,32 +1189,16 @@
 int
 solaris_delete_etherstub(const char *name)
 {
-	dlmgr__rad_dict_string_DLValue_t *prop = NULL;
 	dlmgr_DatalinkError_t		*derrp = NULL;
-	dlmgr_DLValue_t			*old_val = NULL;
-	dlmgr_DLValue_t			temp_val;
 	rc_instance_t			*linkmgr = NULL;
 	rc_err_t			status;
 
 	status = dlmgr_DatalinkManager__rad_lookup(rad_conn, B_TRUE,
 	    &linkmgr, 0);
 	if (status != RCE_OK)
-		goto out;
-
-	prop = dlmgr__rad_dict_string_DLValue_create(linkmgr);
-	if (prop == NULL)
-		goto out;
-
-	bzero(&temp_val, sizeof (temp_val));
-	temp_val.ddlv_type = DDLVT_BOOLEAN;
-	temp_val.ddlv_bval = &b_true;
-	status = dlmgr__rad_dict_string_DLValue_put(prop, "temporary",
-	    &temp_val, &old_val);
-	if (status != RCE_OK)
-		goto out;
-	dlmgr_DLValue_free(old_val);
-
-	status = dlmgr_DatalinkManager_deleteEtherstub(linkmgr, name, prop,
+		return (ENOTSUP);
+
+	status = dlmgr_DatalinkManager_deleteEtherstub(linkmgr, name, NULL,
 	    &derrp);
 	if (status == RCE_SERVER_OBJECT) {
 		dpif_log(derrp->dde_err,
@@ -1276,10 +1206,8 @@
 		    name, derrp->dde_errmsg);
 	}
 	dlmgr_DatalinkError_free(derrp);
-
-out:
-	dlmgr__rad_dict_string_DLValue_free(prop);
 	rc_instance_rele(linkmgr);
+
 	return ((status != RCE_OK) ? ENOTSUP : 0);
 }
 
@@ -1436,66 +1364,39 @@
 	}
 }
 
+#define	FP_NAME_VAL_DELIM		'@'
+#define	FP_MULTI_ACTION_DELIM		'#'
+#define	FP_ACTION_NAME_VALUE_DELIM	'-'
+#define	FP_ACTION_MULTI_VAL_DELIM	'^'
+#define	FP_MULTI_ACTION_DELIM_STR	"#"
+
 static int
-flow_ofports2propstr(uint32_t *ofports, int nofports, char ***ofportstr,
-    int *cnt)
+flow_ofports2propstr(char *str, size_t strsize, uint32_t *ofports,
+    int nofports)
 {
-	dladm_status_t		dlstatus;
-	mac_propval_range_t	*pv_range = NULL;
-	mac_propval_uint32_range_t *ur;
-	char			buf[DLADM_STRSIZE];
-	int			i, error = 0;
-	char			**strs;
-
-	*ofportstr = NULL;
-	*cnt = 0;
-	if (nofports != 0) {
-		/* Sort OF port list and convert it to a mac_propval_range */
-		dlstatus = dladm_list2range(ofports, nofports,
-		    MAC_PROPVAL_UINT32, &pv_range);
-		if (dlstatus != DLADM_STATUS_OK) {
-			error = EINVAL;
-			goto out;
-		}
-
-		strs = calloc(pv_range->mpr_count, sizeof (char *));
-		if (strs == NULL) {
-			error = ENOMEM;
-			goto out;
-		}
-		/*
-		 * Write ranges and individual elements into their own
-		 * buffer.
-		 */
-		for (i = 0; i < pv_range->mpr_count; i++, ur++) {
-			ur = &pv_range->mpr_range_uint32[i];
-			if (ur->mpur_min == ur->mpur_max) {
-				/* single element */
-				(void) snprintf(buf, sizeof (buf), "%u",
-				    ur->mpur_min);
-				strs[i] = strdup(buf);
-			} else {
-				/* range of elements */
-				(void) snprintf(buf, sizeof (buf), "%u-%u",
-				    ur->mpur_min, ur->mpur_max);
-				strs[i] = strdup(buf);
-			}
-			if (strs[i] == NULL) {
-				while (i >= 0) {
-					free(strs[i]);
-					i--;
-				}
-				free(strs);
-				error = ENOMEM;
-				goto out;
-			}
-		}
-		*cnt = pv_range->mpr_count;
-		*ofportstr = strs;
+	char	buf[DLADM_STRSIZE];
+	int	i;
+
+	if (nofports == 0) {
+		(void) snprintf(buf, sizeof (buf), "%soutports%cdrop",
+		    strlen(str) == 0 ? "" : FP_MULTI_ACTION_DELIM_STR,
+		    FP_NAME_VAL_DELIM);
+
+		if (strlcat(str, buf, strsize) >= strsize)
+			return (EINVAL);
+
+		return (0);
 	}
-out:
-	free(pv_range);
-	return (error);
+
+	for (i = 0; i < nofports; i++) {
+		(void) snprintf(buf, sizeof (buf), "%soutports%c%u",
+		    (i == 0) && strlen(str) == 0 ? "" :
+		    FP_MULTI_ACTION_DELIM_STR, FP_NAME_VAL_DELIM, ofports[i]);
+
+		if (strlcat(str, buf, strsize) >= strsize)
+			return (EINVAL);
+	}
+	return (0);
 }
 
 static int
@@ -1506,7 +1407,7 @@
 	dlmgr_DLValue_t  new_val;
 	rc_err_t status;
 
-	if (strlen(buf) != 0) {
+	if (strlen(key) != 0) {
 		bzero(&new_val, sizeof (new_val));
 		new_val.ddlv_type = DDLVT_STRING;
 		new_val.ddlv_sval = buf;
@@ -1551,41 +1452,6 @@
 	return (0);
 }
 
-/*
- * Caller allocated "pvals" is freed here
- */
-static int
-dlmgr_DLValue_putstrings(dlmgr__rad_dict_string_DLValue_t *ddvp,
-    const char *key, char **pvals, int pvalcnt, char *dstr, size_t dstrlen)
-{
-	dlmgr_DLValue_t  *old_val = NULL;
-	dlmgr_DLValue_t  new_val;
-	rc_err_t status;
-	int i, err = 0;
-
-	if (pvalcnt != 0) {
-		bzero(&new_val, sizeof (new_val));
-		new_val.ddlv_type = DDLVT_STRINGS;
-		new_val.ddlv_slist = pvals;
-		new_val.ddlv_slist_count = pvalcnt;
-		status = dlmgr__rad_dict_string_DLValue_put(
-		    ddvp, key, &new_val, &old_val);
-		if (status != RCE_OK) {
-			err = EINVAL;
-			goto out;
-		}
-		for (i = 0; i < pvalcnt; i++)
-			snprintf(dstr, dstrlen, "%s,%s=%s", dstr, key,
-			    pvals[i]);
-		dlmgr_DLValue_free(old_val);
-out:
-		for (i = 0; i < pvalcnt; i++)
-			free(pvals[i]);
-		free(pvals);
-	}
-	return (err);
-}
-
 static int
 dlmgr_DLValue_putboolean(dlmgr__rad_dict_string_DLValue_t *ddvp,
     const char *key, boolean_t val, char *dstr, size_t dstrlen)
@@ -1815,7 +1681,7 @@
 			goto out;
 	}
 
-	if (f->vlan_tci != 0 || m->vlan_tci != 0) {
+	if ((f->vlan_tci != 0) || (m->vlan_tci != htons(0xffff))) {
 		err = dlmgr_DLValue_fm_putulong(ddvp, ddmp,
 		    "vlan-tci", ntohs(f->vlan_tci),
 		    ntohs(m->vlan_tci), dstr, sizeof (dstr));
@@ -1843,7 +1709,7 @@
 }
 
 static int
-solaris_outports_action_to_DLVal(dlmgr__rad_dict_string_DLValue_t *prop,
+solaris_maxbw_action_to_DLVal(dlmgr__rad_dict_string_DLValue_t *prop,
     void *cookie, uint32_t ofports[], int nofports, uint32_t queueid,
     char *dstr, size_t dstrlen)
 {
@@ -1851,248 +1717,187 @@
 	const char *max_rate = NULL;
 	uint64_t maxbw;
 	char *endp = NULL;
-	char **pvals = NULL;
-	int  pvalcnt, err;
+	int err;
 
 	smap_init(&details);
 	if (queueid == UINT32_MAX || nofports != 1)
-		goto outport;
+		goto done;
 
 	if ((err = dpif_solaris_get_priority_details(cookie, ofports[0],
 	    queueid, &details)) != 0) {
-		smap_destroy(&details);
-		goto outport;
+		goto done;
 	}
 	/* min-rate and priority not currently used */
 	max_rate = smap_get(&details, "max-rate");
 	if (max_rate == NULL)
-		goto outport;
+		goto done;
 
 	errno = 0;
 	maxbw = strtoull(max_rate, &endp, 10);
 	if (errno != 0 || *endp != '\0')
-		goto outport;
+		goto done;
 
 	err = dlmgr_DLValue_putulong(prop, "max-bw", maxbw, dstr, dstrlen);
 
-outport:
-	err = flow_ofports2propstr(ofports, nofports, &pvals, &pvalcnt);
-	if (err == 0) {
-		err = dlmgr_DLValue_putstrings(prop, "outports", pvals,
-		    pvalcnt, dstr, dstrlen);
-	}
+done:
 	smap_destroy(&details);
-
-	dpif_log(err, "dpif_solaris_to_outport_action PROP: %s", dstr);
 	return (err);
 }
 
 static int
-solaris_setether_action_to_DLVal(dlmgr__rad_dict_string_DLValue_t *prop,
-    const struct ovs_key_ethernet *ek, char *ds, size_t dslen)
+solaris_setether_action_to_str(char *str, size_t strsize,
+    const struct ovs_key_ethernet *ek)
 {
 	char *sstr = NULL, *dstr = NULL;
-	char **pvals = NULL;
 	char buf[DLADM_STRSIZE];
-	int err;
+	int err = 0;
 
 	sstr = _link_ntoa(ek->eth_src, NULL, ETHERADDRL, IFT_ETHER);
 	dstr = _link_ntoa(ek->eth_dst, NULL, ETHERADDRL, IFT_ETHER);
 	if (sstr != NULL && dstr != NULL) {
-		(void) snprintf(buf, sizeof (buf), "ether_src:%s,ether_dst:%s",
-		    sstr, dstr);
+		(void) snprintf(buf, sizeof (buf),
+		    "%ssetether%cether_src%c%s%cether_dst%c%s",
+		    (strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
+		    FP_NAME_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM, sstr,
+		    FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
+		    dstr);
+		if (strlcat(str, buf, strsize) >= strsize)
+			err = EINVAL;
 	}
 	free(sstr);
 	free(dstr);
-	if (sstr == NULL || dstr == NULL) {
-		err = ENOMEM;
-		goto out;
-	}
-	pvals = calloc(1, sizeof (char *));
-	if (pvals == NULL) {
+	if (sstr == NULL || dstr == NULL)
 		err = ENOMEM;
-		goto out;
-	}
-	pvals[0] = strdup(buf);
-	if (pvals[0] == NULL) {
-		err = ENOMEM;
-		free(pvals);
-		goto out;
-	}
-
-	/* TODO(gmoodalb): this should be two entries. fix later */
-	err = dlmgr_DLValue_putstrings(prop, "set-ether", pvals, 1, ds,
-	    dslen);
-
-out:
-	dpif_log(err, "solaris_setether_action_to_DLVal PROP: %s", ds);
 	return (err);
 }
 
 static int
-solaris_setipv4_action_to_DLVal(dlmgr__rad_dict_string_DLValue_t *prop,
-    const struct ovs_key_ipv4 *ipv4, char *dstr, size_t dstrlen)
+solaris_setipv4_action_to_str(char *str, size_t strsize,
+    const struct ovs_key_ipv4 *ipv4)
 {
 	struct in_addr ipaddr;
 	char *cp;
-	char **pvals = NULL;
 	char buf[DLADM_STRSIZE];
-	int err;
+	int err = 0;
 
 	ipaddr.s_addr = ipv4->ipv4_src;
 	cp = inet_ntoa(ipaddr);
-	(void) snprintf(buf, sizeof (buf), "src:%s,", cp);
+	(void) snprintf(buf, sizeof (buf), "%sset-ipv4%cdst%c%s%c",
+	    (strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
+	    FP_NAME_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM, cp,
+	    FP_ACTION_MULTI_VAL_DELIM);
+
 	ipaddr.s_addr = ipv4->ipv4_dst;
 	cp = inet_ntoa(ipaddr);
 	(void) snprintf(buf, sizeof (buf),
-	    "%sdst:%s,protocol:%s,tos:0x%x,hoplimit:%d",
-	    buf, cp, solaris_proto2str(ipv4->ipv4_proto), ipv4->ipv4_tos,
-	    ipv4->ipv4_ttl);
-
-	pvals = calloc(1, sizeof (char *));
-	if (pvals == NULL) {
-		err = ENOMEM;
-		goto out;
-	}
-	pvals[0] = strdup(buf);
-	if (pvals[0] == NULL) {
-		err = ENOMEM;
-		free(pvals);
-		goto out;
-	}
-
-	err = dlmgr_DLValue_putstrings(prop, "set-ipv4", pvals, 1, dstr,
-	    dstrlen);
-
-out:
-	dpif_log(err, "solaris_setipv4_action_to_DLVal PROP: %s", dstr);
+	    "%sdst%c%s%cprotocol%c%s%ctos%c0x%x%choplimit%c%d",
+	    buf, FP_ACTION_NAME_VALUE_DELIM, cp, FP_ACTION_MULTI_VAL_DELIM,
+	    FP_ACTION_NAME_VALUE_DELIM, solaris_proto2str(ipv4->ipv4_proto),
+	    FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
+	    ipv4->ipv4_tos, FP_ACTION_MULTI_VAL_DELIM,
+	    FP_ACTION_NAME_VALUE_DELIM, ipv4->ipv4_ttl);
+	if (strlcat(str, buf, strsize) >= strsize)
+		err = EINVAL;
+
 	return (err);
 }
 
 static int
-solaris_setipv6_action_to_DLVal(dlmgr__rad_dict_string_DLValue_t *prop,
-    const struct ovs_key_ipv6 *ipv6, char *dstr, size_t dstrlen)
+solaris_setipv6_action_to_str(char *str, size_t strsize,
+    const struct ovs_key_ipv6 *ipv6)
 {
 	char abuf[INET6_ADDRSTRLEN];
-	char **pvals = NULL;
 	char buf[DLADM_STRSIZE];
-	int err;
+	int err = 0;
 
 	(void) inet_ntop(AF_INET6, ipv6->ipv6_src, abuf, INET6_ADDRSTRLEN);
-	(void) snprintf(buf, sizeof (buf), "src:%s,", abuf);
+	(void) snprintf(buf, sizeof (buf),
+	    "%sset-ipv6%csrc%c%s%c", (strlen(str) == 0) ? "" :
+	    FP_MULTI_ACTION_DELIM_STR, FP_NAME_VAL_DELIM,
+	    FP_ACTION_NAME_VALUE_DELIM, abuf, FP_ACTION_MULTI_VAL_DELIM);
+
 	(void) inet_ntop(AF_INET6, ipv6->ipv6_dst, abuf, INET6_ADDRSTRLEN);
 	(void) snprintf(buf, sizeof (buf),
-	    "%sdst:%s,label:0x%x,protocol:%s,tos:0x%x,hoplimit:%d", buf, abuf,
-	    ipv6->ipv6_label, solaris_proto2str(ipv6->ipv6_proto),
-	    ipv6->ipv6_tclass, ipv6->ipv6_hlimit);
-
-	pvals = calloc(1, sizeof (char *));
-	if (pvals == NULL) {
-		err = ENOMEM;
-		goto out;
-	}
-
-	pvals[0] = strdup(buf);
-	if (pvals[0] == NULL) {
-		err = ENOMEM;
-		free(pvals);
-		goto out;
-	}
-
-	err = dlmgr_DLValue_putstrings(prop, "set-ipv6", pvals, 1, dstr,
-	    dstrlen);
-
-out:
-	dpif_log(err, "solaris_setipv6_action_to_DLVal PROP: %s", dstr);
+	    "%sdst%c%s%clabel%c0x%x%cprotocol%c%s%ctos%c0x%x%choplimit%c%d",
+	    buf, FP_ACTION_NAME_VALUE_DELIM, abuf, FP_ACTION_MULTI_VAL_DELIM,
+	    FP_ACTION_NAME_VALUE_DELIM, ipv6->ipv6_label,
+	    FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
+	    solaris_proto2str(ipv6->ipv6_proto), FP_ACTION_MULTI_VAL_DELIM,
+	    FP_ACTION_NAME_VALUE_DELIM, ipv6->ipv6_tclass,
+	    FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
+	    ipv6->ipv6_hlimit);
+	if (strlcat(str, buf, strsize) >= strsize)
+		err = EINVAL;
+
 	return (err);
 }
 
 static int
-solaris_settransport_action_to_DLVal(dlmgr__rad_dict_string_DLValue_t *prop,
-    const char *key, uint16_t src, uint16_t dst, char *dstr, size_t dstrlen)
+solaris_settransport_action_to_str(char *str, size_t strsize, const char *key,
+    uint16_t src, uint16_t dst)
 {
-	char **pvals = NULL;
 	char buf[DLADM_STRSIZE];
-	int err;
-
-	(void) snprintf(buf, sizeof (buf), "sport:%d,dport:%d", src, dst);
-
-	pvals = calloc(1, sizeof (char *));
-	if (pvals == NULL) {
-		err = ENOMEM;
-		goto out;
-	}
-	pvals[0] = strdup(buf);
-	if (pvals[0] == NULL) {
-		err = ENOMEM;
-		free(pvals);
-		goto out;
-	}
-
-	err = dlmgr_DLValue_putstrings(prop, key, pvals, 1, dstr, dstrlen);
-
-out:
-	dpif_log(err, "solaris_settransport_action_to_DLVal PROP: %s %s", key,
-	    dstr);
+	int err = 0;
+
+	(void) snprintf(buf, sizeof (buf),
+	    "%s%s%csport%c%d%cdport%c%d", (strlen(str) == 0) ? "" :
+	    FP_MULTI_ACTION_DELIM_STR, key, FP_NAME_VAL_DELIM,
+	    FP_ACTION_NAME_VALUE_DELIM, src, FP_ACTION_MULTI_VAL_DELIM,
+	    FP_ACTION_NAME_VALUE_DELIM, dst);
+	if (strlcat(str, buf, strsize) >= strsize)
+		err = EINVAL;
+
 	return (err);
 }
 
 static int
-solaris_settnl_action_to_DLVal(dlmgr__rad_dict_string_DLValue_t *prop,
-    const struct flow_tnl *tnl, char *dstr, size_t dstrlen)
+solaris_settnl_action_to_str(char *str, size_t strsize,
+    const struct flow_tnl *tnl)
 {
 	struct in_addr ipaddr;
 	char *cp;
-	char **pvals = NULL;
 	char buf[DLADM_STRSIZE];
-	int err;
+	int err = 0;
 
 	ipaddr.s_addr = tnl->ip_src;
 	cp = inet_ntoa(ipaddr);
-	(void) snprintf(buf, sizeof (buf), "src:%s,", cp);
+	(void) snprintf(buf, sizeof (buf), "%sset-tunnel%csrc%c%s%c",
+	    (strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
+	    FP_NAME_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM, cp,
+	    FP_ACTION_MULTI_VAL_DELIM);
+
 	ipaddr.s_addr = tnl->ip_dst;
 	cp = inet_ntoa(ipaddr);
 	(void) snprintf(buf, sizeof (buf),
-	    "%sdst:%s,tun_id:0x%"PRIx64",tos:0x%x,hoplimit:%d",
-	    buf, cp, ntohll(tnl->tun_id), tnl->ip_tos, tnl->ip_ttl);
-
-	pvals = calloc(1, sizeof (char *));
-	if (pvals == NULL) {
-		err = ENOMEM;
-		goto out;
-	}
-	pvals[0] = strdup(buf);
-	if (pvals[0] == NULL) {
-		err = ENOMEM;
-		free(pvals);
-		goto out;
-	}
-
-	err = dlmgr_DLValue_putstrings(prop, "set-tunnel", pvals, 1, dstr,
-	    dstrlen);
-
-out:
-	dpif_log(err, "solaris_setipv6_action_to_DLVal PROP: %s", dstr);
+	    "%sdst%c%s%ctun_id%c0x%"PRIx64"%ctos%c0x%x%choplimit%c%d",
+	    buf, FP_ACTION_NAME_VALUE_DELIM, cp, FP_ACTION_MULTI_VAL_DELIM,
+	    FP_ACTION_NAME_VALUE_DELIM, ntohll(tnl->tun_id),
+	    FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
+	    tnl->ip_tos, FP_ACTION_MULTI_VAL_DELIM, FP_ACTION_NAME_VALUE_DELIM,
+	    tnl->ip_ttl);
+	if (strlcat(str, buf, strsize) >= strsize)
+		err = EINVAL;
+
 	return (err);
 }
 
 static int
 solaris_nlattr_to_DLVal(void *cookie,
     const struct nlattr *actions_nlattr, size_t actions_len,
-    dlmgr__rad_dict_string_DLValue_t **propp)
+    dlmgr__rad_dict_string_DLValue_t *prop)
 {
 	const struct nlattr *a;
 	unsigned int left;
-	dlmgr__rad_dict_string_DLValue_t *prop = *propp;
 	char buf[DLADM_STRSIZE];
+	char str[DLADM_STRSIZE];
 	char dstr[DLADM_STRSIZE];
-	char **pvals;
 	int err = 0, nofports = 0;
 	uint32_t ofports[MAC_OF_MAXPORT];
 	enum ovs_action_attr type = -1, lasttype;
 	uint_t queueid = UINT32_MAX;
 
 	dstr[0] = '\0';
+	str[0] = '\0';
 	err = dlmgr_DLValue_putboolean(prop, "temporary", B_TRUE, dstr,
 	    sizeof (dstr));
 	if (err != 0)
@@ -2100,20 +1905,7 @@
 
 	/* if actions_len == 0, then the action is drop */
 	if (actions_len == 0) {
-		pvals = calloc(1, sizeof (char *));
-		if (pvals == NULL) {
-			err = ENOMEM;
-			goto out;
-		}
-		(void) snprintf(buf, sizeof (buf), "drop");
-		pvals[0] = strdup(buf);
-		if (pvals[0] == NULL) {
-			err = ENOMEM;
-			free(pvals);
-			goto out;
-		}
-		err = dlmgr_DLValue_putstrings(prop, "outports", pvals, 1,
-		    dstr, sizeof (dstr));
+		err = flow_ofports2propstr(str, sizeof (str), ofports, 0);
 		goto out;
 	}
 
@@ -2125,11 +1917,13 @@
 			if (lasttype == OVS_ACTION_ATTR_OUTPUT) {
 				dpif_log(0, "solaris_nlattr_to_DLVal outports "
 				    "total %d ports", nofports);
-				err = solaris_outports_action_to_DLVal(prop,
-				    cookie, ofports, nofports, queueid,
-				    dstr, sizeof (dstr));
+				err = flow_ofports2propstr(str, sizeof (str),
+				    ofports, nofports);
 				if (err != 0)
 					goto out;
+				(void) solaris_maxbw_action_to_DLVal(prop,
+				    cookie, ofports, nofports, queueid, dstr,
+				    sizeof (dstr));
 			}
 			nofports = 0;
 		}
@@ -2174,21 +1968,14 @@
 			if (cookie.slow_path.reason != SLOW_CONTROLLER)
 				break;
 
-			pvals = calloc(1, sizeof (char *));
-			if (pvals == NULL) {
-				err = ENOMEM;
+			(void) snprintf(buf, sizeof (buf), "%scontroller%c%u",
+			    (strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
+			    FP_NAME_VAL_DELIM, PORT_PF_PACKET_UPLINK);
+
+			if (strlcat(str, buf, sizeof (str)) >= sizeof (str)) {
+				err = EINVAL;
 				break;
 			}
-			(void) snprintf(buf, sizeof (buf), "%u",
-			    PORT_PF_PACKET_UPLINK);
-			pvals[0] = strdup(buf);
-			if (pvals[0] == NULL) {
-				err = ENOMEM;
-				free(pvals);
-				break;
-			}
-			err = dlmgr_DLValue_putstrings(prop, "controller",
-			    pvals, 1, dstr, sizeof (dstr));
 			break;
 		}
 		case OVS_ACTION_ATTR_SET: {
@@ -2204,8 +1991,8 @@
 
 				ek = nl_attr_get_unspec(aset,
 				    sizeof (struct ovs_key_ethernet));
-				err = solaris_setether_action_to_DLVal(prop,
-				    ek, dstr, sizeof (dstr));
+				err = solaris_setether_action_to_str(str,
+				    sizeof (str), ek);
 				break;
 			}
 			case OVS_KEY_ATTR_IPV4: {
@@ -2213,8 +2000,8 @@
 
 				eip4 = nl_attr_get_unspec(aset,
 				    sizeof (struct ovs_key_ipv4));
-				err = solaris_setipv4_action_to_DLVal(prop,
-				    eip4, dstr, sizeof (dstr));
+				err = solaris_setipv4_action_to_str(str,
+				    sizeof (str), eip4);
 				break;
 			}
 			case OVS_KEY_ATTR_IPV6: {
@@ -2222,35 +2009,35 @@
 
 				eip6 = nl_attr_get_unspec(aset,
 				    sizeof (struct ovs_key_ipv6));
-				err = solaris_setipv6_action_to_DLVal(prop,
-				    eip6, dstr, sizeof (dstr));
+				err = solaris_setipv6_action_to_str(str,
+				    sizeof (str), eip6);
 				break;
 			}
 			case OVS_KEY_ATTR_TCP: {
 				const struct ovs_key_tcp *etcp;
 				etcp = nl_attr_get_unspec(aset,
 				    sizeof (struct ovs_key_tcp));
-				err = solaris_settransport_action_to_DLVal(
-				    prop, "set-tcp", etcp->tcp_src,
-				    etcp->tcp_dst, dstr, sizeof (dstr));
+				err = solaris_settransport_action_to_str(
+				    str, sizeof (str), "set-tcp", etcp->tcp_src,
+				    etcp->tcp_dst);
 				break;
 			}
 			case OVS_KEY_ATTR_UDP: {
 				const struct ovs_key_udp *eudp;
 				eudp = nl_attr_get_unspec(aset,
 				    sizeof (struct ovs_key_udp));
-				err = solaris_settransport_action_to_DLVal(
-				    prop, "set-udp", eudp->udp_src,
-				    eudp->udp_dst, dstr, sizeof (dstr));
+				err = solaris_settransport_action_to_str(
+				    str, sizeof (str), "set-udp", eudp->udp_src,
+				    eudp->udp_dst);
 				break;
 			}
 			case OVS_KEY_ATTR_SCTP: {
 				const struct ovs_key_sctp *esctp;
 				esctp = nl_attr_get_unspec(aset,
 				    sizeof (struct ovs_key_sctp));
-				err = solaris_settransport_action_to_DLVal(
-				    prop, "set-sctp", esctp->sctp_src,
-				    esctp->sctp_dst, dstr, sizeof (dstr));
+				err = solaris_settransport_action_to_str(str,
+				    sizeof (str), "set-sctp", esctp->sctp_src,
+				    esctp->sctp_dst);
 				break;
 			}
 			case OVS_KEY_ATTR_TUNNEL: {
@@ -2260,8 +2047,8 @@
 				memset(&tnl, 0, sizeof (tnl));
 				fitness = odp_tun_key_from_attr(aset, &tnl);
 				ovs_assert(fitness != ODP_FIT_ERROR);
-				err = solaris_settnl_action_to_DLVal(
-				    prop, &tnl, dstr, sizeof (dstr));
+				err = solaris_settnl_action_to_str(
+				    str, sizeof (str), &tnl);
 				break;
 			}
 			default:
@@ -2278,16 +2065,25 @@
 			vlan = nl_attr_get_unspec(a,
 			    sizeof (struct ovs_action_push_vlan));
 
-			(void) snprintf(buf, sizeof (buf), "%u",
-			    ntohs(vlan->vlan_tci));
-			err = dlmgr_DLValue_putstring(prop, "vlan-tag", buf,
-			    dstr, sizeof (dstr));
+			(void) snprintf(buf, sizeof (buf), "%svlan-tag%c%u",
+			    (strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
+			    FP_NAME_VAL_DELIM, ntohs(vlan->vlan_tci));
+
+			if (strlcat(str, buf, sizeof (str)) >= sizeof (str)) {
+				err = EINVAL;
+				break;
+			}
 			break;
 		}
 		case OVS_ACTION_ATTR_POP_VLAN:
-			(void) snprintf(buf, sizeof (buf), "on");
-			err = dlmgr_DLValue_putstring(prop,
-			    "vlan-strip", buf, dstr, sizeof (dstr));
+			(void) snprintf(buf, sizeof (buf), "%svlan-strip%c%s",
+			    (strlen(str) == 0) ? "" : FP_MULTI_ACTION_DELIM_STR,
+			    FP_NAME_VAL_DELIM, "on");
+
+			if (strlcat(str, buf, sizeof (str)) >= sizeof (str)) {
+				err = EINVAL;
+				break;
+			}
 			break;
 		case OVS_ACTION_ATTR_RECIRC:
 		case OVS_ACTION_ATTR_HASH:
@@ -2308,11 +2104,21 @@
 	if (type == OVS_ACTION_ATTR_OUTPUT) {
 		dpif_log(0, "solaris_nlattr_to_DLVal outports total %d ports",
 		    nofports);
-		err = solaris_outports_action_to_DLVal(prop, cookie, ofports,
+		err = flow_ofports2propstr(str, sizeof (str),
+		    ofports, nofports);
+		if (err != 0)
+			goto out;
+		(void) solaris_maxbw_action_to_DLVal(prop, cookie, ofports,
 		    nofports, queueid, dstr, sizeof (dstr));
 	}
+
+	err = dlmgr_DLValue_putstring(prop, "ofaction", str, dstr,
+	    sizeof (dstr));
 out:
-	dpif_log(err, "solaris_nlattr_to_DLVal %s", dstr);
+
+	if (err == 0)
+		dpif_log(err, "solaris_nlattr_to_DLVal %s", dstr);
+
 	return (err);
 }
 
@@ -2362,7 +2168,7 @@
 		goto out;
 
 	err = solaris_nlattr_to_DLVal(cookie, actions_nlattr,
-	    actions_len, &prop);
+	    actions_len, prop);
 	if (err != 0)
 		goto out;
 
@@ -2377,7 +2183,6 @@
 			    flowname, linkname, derrp->dde_errmsg);
 		}
 	}
-
 	rc_instance_rele(flow);
 	dlmgr_DatalinkError_free(derrp);
 
@@ -2399,6 +2204,7 @@
 	rc_err_t status;
 	int err;
 
+	dpif_log(0, "solaris_modify_flow(%s)", flowname);
 	status = dlmgr_Flow__rad_lookup(rad_conn, B_TRUE, &flow, 1,
 	    "name", flowname);
 	if (status != RCE_OK) {
@@ -2413,7 +2219,7 @@
 	}
 
 	err = solaris_nlattr_to_DLVal(cookie, actions_nlattr,
-	    actions_len, &prop);
+	    actions_len, prop);
 	if (err != 0)
 		goto out;
 
@@ -2553,6 +2359,8 @@
 	}
 
 out:
+	if (err != 0)
+		dpif_log(err, "solaris_flowinfo2flowmap %s failed", key);
 	dlmgr_DLValue_free(val);
 	return (err == 0 ? RCE_OK : -1);
 }
@@ -2638,40 +2446,22 @@
 }
 
 static int
-flow_propval2action_drop(char **propvals, int nval,
-    struct ofpbuf *action OVS_UNUSED)
-{
-	if (nval == 1 && strcmp(propvals[0], "drop") == 0)
-		return (0);
-
-	return (EINVAL);
-}
-
-static int
-flow_propval2action_outports(char **propvals, int nval, struct ofpbuf *action)
+flow_propval2action_outports_drop(char **propvals, int nval OVS_UNUSED,
+    struct ofpbuf *action)
 {
-	mac_propval_range_t *pv_range = NULL;
-	uint32_t ofports[MAC_OF_MAXPORT], i, nofports = MAC_OF_MAXPORT;
-	dladm_status_t status;
-	int err = 0;
-
-	status = dladm_strs2range(propvals, nval, MAC_PROPVAL_UINT32,
-	    &pv_range);
-	if (status != DLADM_STATUS_OK)
-		return (solaris_dladm_status2error(status));
-
-	/* Convert mac_propval_range to a single ofports list */
-	status = dladm_range2list(pv_range, ofports, &nofports);
-	if (status != DLADM_STATUS_OK) {
-		err = solaris_dladm_status2error(status);
-		goto out;
-	}
-	for (i = 0; i < nofports; i++)
-		nl_msg_put_u32(action, OVS_ACTION_ATTR_OUTPUT, ofports[i]);
-
-out:
-	free(pv_range);
-	return (err);
+	char *endp = NULL;
+	int64_t n;
+
+	if (strcmp(propvals[0], "drop") == 0)
+		return (0);
+
+	errno = 0;
+	n = strtoull(propvals[0], &endp, 10);
+	if ((errno != 0) || *endp != '\0')
+		return (EINVAL);
+
+	nl_msg_put_u32(action, OVS_ACTION_ATTR_OUTPUT, (uint32_t)n);
+	return (0);
 }
 
 static int
@@ -2745,14 +2535,15 @@
 	int err = 0;
 
 	/*
-	 * The property value is in the format of "ether_src:xxx"
-	 * "ether_dst:xxx"
+	 * The property value is in the format of "ether_src-xxx"
+	 * "ether_dst-xxx"
 	 */
 	bzero(&eth_key, sizeof (eth_key));
 	src_set = dst_set = B_FALSE;
+
 	for (i = 0; i < nval; i++) {
-		bcopy(propvals[i], pval, strlen(propvals[i]) + 1);
-		if ((sep = strchr(pval, ':')) == NULL) {
+		(void) strlcpy(pval, propvals[i], sizeof (pval));
+		if ((sep = strchr(pval, FP_ACTION_NAME_VALUE_DELIM)) == NULL) {
 			err = EINVAL;
 			goto out;
 		}
@@ -2820,8 +2611,8 @@
 	 */
 	bzero(&ipv4, sizeof (ipv4));
 	for (i = 0; i < nval; i++) {
-		bcopy(propvals[i], pval, strlen(propvals[i]) + 1);
-		if ((sep = strchr(pval, ':')) == NULL) {
+		(void) strlcpy(pval, propvals[i], sizeof (pval));
+		if ((sep = strchr(pval, FP_ACTION_NAME_VALUE_DELIM)) == NULL) {
 			err = EINVAL;
 			goto out;
 		}
@@ -2893,8 +2684,8 @@
 	 */
 	bzero(&ipv6, sizeof (ipv6));
 	for (i = 0; i < nval; i++) {
-		bcopy(propvals[i], pval, strlen(propvals[i]) + 1);
-		if ((sep = strchr(pval, ':')) == NULL)
+		(void) strlcpy(pval, propvals[i], sizeof (pval));
+		if ((sep = strchr(pval, FP_ACTION_NAME_VALUE_DELIM)) == NULL)
 			goto out;
 		*sep = '\0';
 		sep++;
@@ -2971,10 +2762,10 @@
 	int err = EINVAL;
 	uint16_t sport = 0, dport = 0;
 
-	/* The property value is in the format of "sport:xxx" "dport:xxx" */
+	/* The property value is in the format of "sport-xxx" "dport-xxx" */
 	for (i = 0; i < nval; i++) {
-		bcopy(propvals, pval, strlen(propvals[i]) + 1);
-		if ((sep = strchr(pval, ':')) == NULL)
+		(void) strlcpy(pval, propvals[i], sizeof (pval));
+		if ((sep = strchr(pval, FP_ACTION_NAME_VALUE_DELIM)) == NULL)
 			goto out;
 		*sep = '\0';
 		sep++;
@@ -3106,7 +2897,7 @@
 	char *sep, *endp;
 	uint_t i, value;
 	struct flow_tnl tnl;
-	size_t start_ofs;
+	size_t start_ofs, tun_key_ofs;
 	boolean_t id_set, src_set, dst_set, tos_set, ttl_set;
 	int err = 0;
 
@@ -3118,8 +2909,8 @@
 	 */
 	tnl.ip_tos = 0xff;
 	for (i = 0; i < nval; i++) {
-		bcopy(propvals[i], pval, strlen(propvals[i]) + 1);
-		if ((sep = strchr(pval, ':')) == NULL)
+		(void) strlcpy(pval, propvals[i], sizeof (pval));
+		if ((sep = strchr(pval, FP_ACTION_NAME_VALUE_DELIM)) == NULL)
 			return (EINVAL);
 		*sep = '\0';
 		sep++;
@@ -3173,32 +2964,155 @@
 	}
 
 	start_ofs = nl_msg_start_nested(action, OVS_ACTION_ATTR_SET);
-	nl_msg_put_be64(action, OVS_TUNNEL_KEY_ATTR_ID, (uint64_t)tnl.tun_id);
+	tun_key_ofs = nl_msg_start_nested(action, OVS_KEY_ATTR_TUNNEL);
+	nl_msg_put_be64(action, OVS_TUNNEL_KEY_ATTR_ID,
+	    ntohll((uint64_t)tnl.tun_id));
 	nl_msg_put_be32(action, OVS_TUNNEL_KEY_ATTR_IPV4_SRC, tnl.ip_src);
 	nl_msg_put_be32(action, OVS_TUNNEL_KEY_ATTR_IPV4_DST, tnl.ip_dst);
 	nl_msg_put_u8(action, OVS_TUNNEL_KEY_ATTR_TOS, tnl.ip_tos);
 	nl_msg_put_u8(action, OVS_TUNNEL_KEY_ATTR_TTL, tnl.ip_ttl);
 	nl_msg_put_flag(action, OVS_TUNNEL_KEY_ATTR_DONT_FRAGMENT);
+	nl_msg_end_nested(action, tun_key_ofs);
 	nl_msg_end_nested(action, start_ofs);
 	return (0);
 }
 
+static int
+flow_propstr2vals(char *key, char *val, char ***propvalsp, int *valcntp)
+{
+	char **propvals = *propvalsp, *curr;
+	int i, j, len;
+	char c;
+
+	dpif_log(0, "flow_propstr2vals key %s val %s", key, val);
+	len = strlen(val);
+	for (i = 0, j = 0, curr = val; i < len; i++) {
+		if ((c = val[i]) != FP_ACTION_MULTI_VAL_DELIM && i != len -1)
+			continue;
+
+		if (c == FP_ACTION_MULTI_VAL_DELIM)
+			val[i] = '\0';
+
+		if (strlcpy(propvals[j++], curr, DLADM_PROP_VAL_MAX) >=
+		    DLADM_PROP_VAL_MAX) {
+			dpif_log(EINVAL, "flow_propstr2vals key %s %dth string "
+			    "too long %s", key, j - 1, curr);
+			return (EINVAL);
+		}
+		curr = val + i + 1;
+	}
+
+	*valcntp = j;
+	for (i = 0; i < j; i++)
+		dpif_log(0, "flow_propstr2vals key %s %dth: %s", key, i+1,
+		    propvals[i]);
+	return (0);
+}
+
+static int
+flow_propval2action_ofaction(char *propval, struct ofpbuf *action)
+{
+	char ofaction_str[DLADM_STRSIZE];
+	char **pvals, *buf = NULL;
+	size_t len;
+	char *curr, *key, c;
+	boolean_t match;
+	int nval, err = 0, i;
+
+	buf = malloc((sizeof (char *) +
+	    DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT);
+
+	pvals = (char **)(void *)buf;
+	for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) {
+		pvals[i] = buf + sizeof (char *) * DLADM_MAX_PROP_VALCNT +
+		    i * DLADM_PROP_VAL_MAX;
+	}
+
+	if (strlcpy(ofaction_str, propval, sizeof (ofaction_str)) >=
+	    sizeof (ofaction_str)) {
+		err = EINVAL;
+		goto done;
+	}
+
+	len = strlen(ofaction_str);
+	curr = ofaction_str;
+	key = NULL;
+	for (i = 0; i < len; i++) {
+		c = ofaction_str[i];
+
+		match = (c == FP_NAME_VAL_DELIM || c == FP_MULTI_ACTION_DELIM);
+		if (!match && i != len - 1)
+			continue;
+		if (match) {
+			ofaction_str[i] = '\0';
+			if (*curr == '\0') {
+				err = EINVAL;
+				goto done;
+			}
+		}
+		if (c == FP_NAME_VAL_DELIM) {
+			key = curr;
+			curr = ofaction_str + i + 1;
+			continue;
+		}
+
+		if (key == NULL) {
+			err = EINVAL;
+			goto done;
+		}
+
+		err = flow_propstr2vals(key, curr, &pvals, &nval);
+		if (err != 0)
+			goto done;
+
+		if (strcmp(key, "outports") == 0)
+			err = flow_propval2action_outports_drop(pvals, nval,
+			    action);
+		else if (strcmp(key, "max-bw") == 0)
+			err = flow_propval2action_setpri(pvals, nval, action);
+		else if (strcmp(key, "controller") == 0)
+			err = flow_propval2action_controller(pvals, nval,
+			    action);
+		else if (strcmp(key, "vlan-tag") == 0)
+			err = flow_propval2action_pushvlan(pvals, nval, action);
+		else if (strcmp(key, "vlan-strip") == 0)
+			err = flow_propval2action_popvlan(pvals, nval, action);
+		else if (strcmp(key, "set-ether") == 0)
+			err = flow_propval2action_setether(pvals, nval, action);
+		else if (strcmp(key, "set-ipv4") == 0)
+			err = flow_propval2action_setipv4(pvals, nval, action);
+		else if (strcmp(key, "set-ipv6") == 0)
+			err = flow_propval2action_setipv6(pvals, nval, action);
+		else if (strcmp(key, "set-tcp") == 0)
+			err = flow_propval2action_settcp(pvals, nval, action);
+		else if (strcmp(key, "set-udp") == 0)
+			err = flow_propval2action_setudp(pvals, nval, action);
+		else if (strcmp(key, "set-sctp") == 0)
+			err = flow_propval2action_setsctp(pvals, nval, action);
+		else if (strcmp(key, "set-tunnel") == 0)
+			err = flow_propval2action_settnl(pvals, nval, action);
+		else
+			err = EINVAL;
+
+		if (err != 0)
+			goto done;
+
+		key = NULL;
+		curr = ofaction_str + i + 1;
+	}
+done:
+	free(buf);
+	return (err);
+}
+
+/* valcnt must be 1 */
 static rc_err_t
 solaris_flowinfo2actionmap(const char *key, dlmgr_DLValue_t *val,
     void *arg)
 {
 	struct ofpbuf *action = arg;
-	char **propvals, *buf = NULL;
-	int valcnt, err = 0, i;
-
-	buf = malloc((sizeof (char *) +
-	    DLADM_PROP_VAL_MAX) * DLADM_MAX_PROP_VALCNT);
-
-	propvals = (char **)(void *)buf;
-	for (i = 0; i < DLADM_MAX_PROP_VALCNT; i++) {
-		propvals[i] = buf + sizeof (char *) * DLADM_MAX_PROP_VALCNT +
-		    i * DLADM_PROP_VAL_MAX;
-	}
+	char propval[DLADM_STRSIZE];
+	int valcnt, err = 0;
 
 	switch (val->ddlv_type) {
 	case DDLVT_STRING:
@@ -3207,24 +3121,25 @@
 		if (strlen(val->ddlv_sval) == 0)
 			goto out;
 		valcnt = 1;
-		memcpy(propvals[0], val->ddlv_sval, DLADM_PROP_VAL_MAX);
+		if (strlcpy(propval, val->ddlv_sval, DLADM_STRSIZE) >=
+		    DLADM_STRSIZE)
+			goto out;
 		break;
 	case DDLVT_STRINGS:
 		if (val->ddlv_slist_count == 0)
 			goto out;
 		valcnt = val->ddlv_slist_count;
-		if (valcnt == 1 && strlen(val->ddlv_slist[0]) == 0)
+		if (valcnt != 1 || strlen(val->ddlv_slist[0]) == 0)
 			goto out;
-		for (i = 0; i < val->ddlv_slist_count; i++) {
-			memcpy(propvals[i], val->ddlv_slist[i],
-			    DLADM_PROP_VAL_MAX);
-		}
+		if (strlcpy(propval, val->ddlv_slist[0], DLADM_STRSIZE) >=
+		    DLADM_STRSIZE)
+			goto out;
 		break;
 	case DDLVT_ULONG:
 		if (val->ddlv_ulval == NULL || *val->ddlv_ulval == 0)
 			goto out;
 		valcnt = 1;
-		(void) snprintf(propvals[0], DLADM_PROP_VAL_MAX, "%llu",
+		(void) snprintf(propval, DLADM_STRSIZE, "%llu",
 		    *val->ddlv_ulval);
 		break;
 	case DDLVT_BOOLEAN:
@@ -3238,40 +3153,13 @@
 		goto out;
 	}
 	dpif_log(0, "solaris_flowinfo2actionmap %s:%d %s", key, valcnt,
-	    propvals[0]);
-
-	if (strcmp(key, "outports") == 0) {
-		err = flow_propval2action_drop(propvals, valcnt, action);
-		if (err == 0)
-			goto out;
-
-		err = flow_propval2action_outports(propvals, valcnt, action);
-	} else if (strcmp(key, "max-bw") == 0) {
-		err = flow_propval2action_setpri(propvals, valcnt, action);
-	} else if (strcmp(key, "controller") == 0) {
-		err = flow_propval2action_controller(propvals, valcnt, action);
-	} else if (strcmp(key, "vlan-tag") == 0) {
-		err = flow_propval2action_pushvlan(propvals, valcnt, action);
-	} else if (strcmp(key, "vlan-strip") == 0) {
-		err = flow_propval2action_popvlan(propvals, valcnt, action);
-	} else if (strcmp(key, "set-ether") == 0) {
-		err = flow_propval2action_setether(propvals, valcnt, action);
-	} else if (strcmp(key, "set-ipv4") == 0) {
-		err = flow_propval2action_setipv4(propvals, valcnt, action);
-	} else if (strcmp(key, "set-ipv6") == 0) {
-		err = flow_propval2action_setipv6(propvals, valcnt, action);
-	} else if (strcmp(key, "set-tcp") == 0) {
-		err = flow_propval2action_settcp(propvals, valcnt, action);
-	} else if (strcmp(key, "set-udp") == 0) {
-		err = flow_propval2action_setudp(propvals, valcnt, action);
-	} else if (strcmp(key, "set-sctp") == 0) {
-		err = flow_propval2action_setsctp(propvals, valcnt, action);
-	} else if (strcmp(key, "set-tunnel") == 0) {
-		err = flow_propval2action_settnl(propvals, valcnt, action);
-	}
+	    propval);
+
+	if (strcmp(key, "ofaction") == 0)
+		err = flow_propval2action_ofaction(propval, action);
+
 out:
 	dlmgr_DLValue_free(val);
-	free(buf);
 	return (err == 0 ? RCE_OK : -1);
 }
 
@@ -3286,14 +3174,20 @@
 
 	status = dlmgr__rad_dict_string_DLValue_get(flowinfo, "properties",
 	    &flist);
-	if (status != RCE_OK)
+	if (status != RCE_OK) {
+		dpif_log(EINVAL, "solaris_flowinfo2action get properties failed"
+		    " %d", status);
 		return (EINVAL);
+	}
 
 	fdict = flist->ddlv_dval;
 	status = dlmgr__rad_dict_string_DLValue_map(fdict,
 	    solaris_flowinfo2actionmap, action);
-	if (status != RCE_OK)
+	if (status != RCE_OK) {
 		err = EINVAL;
+		dpif_log(EINVAL, "solaris_flowinfo2action get walk actionmap "
+		    "failed %d", status);
+	}
 
 	dlmgr_DLValue_free(flist);
 	return (err);
@@ -3545,6 +3439,7 @@
 		dlmgr_DLValue_free(dlval);
 		dlmgr_DLDict_array_free(dlist, ndlist);
 	}
+
 	for (i = 0; i < anamecnt; i++)
 		adr_name_rele(anamearr[i]);
 	free(anamearr);
@@ -3595,7 +3490,11 @@
 				continue;
 			else
 				is_default = B_TRUE;
+		} else if (strstr(adr_name_key(anamearr[i], "name"),
+		    "sys.of") == NULL) {
+			continue;
 		}
+
 		rerr = rc_lookup(rad_conn, anamearr[i], NULL, B_FALSE, &rip);
 		if (rerr != RCE_OK)
 			continue;
@@ -3678,7 +3577,7 @@
 			err = solaris_flowinfo2action(flowinfo, action);
 			if (err != 0) {
 				dpif_log(err, "solaris_flow_walk "
-				    "flowinfo2flow failed for %s: %d",
+				    "flowinfo2action failed for %s: %d",
 				    adr_name_key(anamearr[i], "name"), err);
 				goto done;
 			}
@@ -3698,6 +3597,7 @@
 	for (i = 0; i < anamecnt; i++)
 		adr_name_rele(anamearr[i]);
 	free(anamearr);
+
 	return (n_flows);
 }
 
--- a/components/openvswitch/files/ovs-clean.py	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/ovs-clean.py	Tue Apr 05 20:57:21 2016 -0700
@@ -23,7 +23,7 @@
 #
 
 #
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 #
 
 from rad.bindings.com.oracle.solaris.rad.dlmgr import *
@@ -136,8 +136,9 @@
                 datalink.removeFlow(flow_name._kvpairs["name"])
             except radcli.ObjectError as ex:
                 dlerr = ex.get_payload()
-                # ignore if the flow is no longer found
-                if dlerr.err == DLSTATUS.NOT_FOUND._value:
+                # ignore if the flow is no longer found or is a system
+		# generated flow (e.g., vxlan system flows)
+                if dlerr.err == DLSTATUS.NOT_FOUND._value or dlerr.err == DLSTATUS.SYSTEM_FLOW._value:
                     continue
                 printError(ex)
                 rval = False
@@ -153,7 +154,6 @@
     try:
         etherstub = rc.get_object(Etherstub(), ADRGlobPattern({'name': name}))
         etherstub.setProperties({
-            'temporary': DLValue(type=DLValueType.BOOLEAN, bval="True"),
             'openvswitch': DLValue(type=DLValueType.BOOLEAN, bval=None)
             })
         dm.deleteEtherstub(name)
--- a/components/openvswitch/files/ovs-svc	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/ovs-svc	Tue Apr 05 20:57:21 2016 -0700
@@ -23,7 +23,7 @@
 #
 
 #
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 #
 
 . /lib/svc/share/smf_include.sh
@@ -57,8 +57,7 @@
 typeset -r MKDIR=/usr/bin/mkdir
 typeset -r CHOWN=/usr/bin/chown
 typeset -r PKILL=/usr/bin/pkill
-typeset -r DLADM=/usr/sbin/dladm
-typeset -r FLOWADM=/usr/sbin/flowadm
+typeset -r IPADM=/usr/sbin/ipadm
 
 errlog () {
 	echo $1 >&2
@@ -93,7 +92,7 @@
 	typeset -r OVSDB_PIDFILE=${OVS_TMP_DIR}/ovsdb-server.pid
 
 	${OVSDB_SERVER_PATH} ${OVSDB_DATABASE} \
-	    -vconsole:emer -vsyslog:err -vfile:info \
+	    -vconsole:emer -vsyslog:off -vfile:info \
 	    --remote=punix:${OVSDB_REMOTE} \
 	    --remote=db:Open_vSwitch,Open_vSwitch,manager_options \
 	    --private-key=db:Open_vSwitch,SSL,private_key \
@@ -127,6 +126,7 @@
 
         ${OVS_VSCTL} list-br |
                 while read BRIDGENAME; do
+			${PFEXEC} ${IPADM} disable-if -t ${BRIDGENAME} >/dev/null 2>&1
                         ${OVS_CLEAN_PATH} delete-vnic ${BRIDGENAME}
                         if [ $? -ne 0 ]; then
                                 errlog "Error $? removing ${BRIDGENAME} VNIC"
@@ -155,8 +155,8 @@
 
 	create_ovs_tempdir
 
-	${OVS_VSWITCHD_PATH} unix:${OVSDB_REMOTE} \
-	    -vconsole:emer -vsyslog:err -vfile:info --mlockall --no-chdir \
+	 ${PFEXEC} ${OVS_VSWITCHD_PATH} unix:${OVSDB_REMOTE} \
+	    -vconsole:emer -vsyslog:off -vfile:info --mlockall --no-chdir \
 	    --log-file=${VSWITCHD_LOGFILE} \
 	    --pidfile=${VSWITCHD_PIDFILE} \
 	    --detach
@@ -164,6 +164,12 @@
 		errlog "${OVS_VSWITCHD} failed with $?"
 		exit $SMF_EXIT_ERR_FATAL
 	fi
+
+
+	${OVS_VSCTL} list-br |
+		while read BRIDGENAME; do
+			${PFEXEC} ${IPADM} enable-if -t ${BRIDGENAME} >/dev/null 2>&1
+		done
 }
 
 case "$1" in
--- a/components/openvswitch/files/ovs.exec_attr	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/ovs.exec_attr	Tue Apr 05 20:57:21 2016 -0700
@@ -1,5 +1,8 @@
 ovs-agent:solaris:cmd:RO::/usr/lib/rad/module/mod_dlmgr.so.1:\
-privs=sys_dl_config
+privs=sys_dl_config,{zone}\:/devices/pseudo/sysevent*
+
+ovs-agent:solaris:cmd:::/usr/lib/ovs/ovs-vswitchd:privs=sys_ip_config
+ovs-agent:solaris:cmd:RO::/usr/sbin/ipadm:euid=0;egid=netadm;privs=net_rawaccess,sys_ip_config
 
 ovs-agent:solaris:cmd:::/usr/bin/mkdir:privs={zone}\:/system/volatile/ovs
 ovs-agent:solaris:cmd:::/usr/bin/chown:privs={zone}\:/system/volatile/ovs
--- a/components/openvswitch/files/ovsdb.xml	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/ovsdb.xml	Tue Apr 05 20:57:21 2016 -0700
@@ -20,7 +20,7 @@
 
 CDDL HEADER END
 
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 
  NOTE:  This service manifest is not editable; its contents will
  be overwritten by package or patch operations, including
@@ -32,11 +32,11 @@
 
     <service name="application/openvswitch/ovsdb-server" type="service" version="1">
         <dependency
-            name='multiuser'
+            name='net-physical'
             grouping='require_all'
-            restart_on='error'
+            restart_on='none'
             type='service'>
-            <service_fmri value='svc:/milestone/multi-user:default'/>
+            <service_fmri value='svc:/network/physical:default'/>
         </dependency>
 
         <instance name='default' enabled='true'>
--- a/components/openvswitch/files/vswitch.xml	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/files/vswitch.xml	Tue Apr 05 20:57:21 2016 -0700
@@ -20,7 +20,7 @@
 
 CDDL HEADER END
 
- Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 
  NOTE:  This service manifest is not editable; its contents will
  be overwritten by package or patch operations, including
@@ -32,11 +32,11 @@
 
     <service name="application/openvswitch/vswitch-server" type="service" version="1">
         <dependency
-            name='multiuser'
+            name='net-physical'
             grouping='require_all'
-            restart_on='error'
+            restart_on='none'
             type='service'>
-            <service_fmri value='svc:/milestone/multi-user:default'/>
+            <service_fmri value='svc:/network/physical:default'/>
         </dependency>
 
         <dependency
@@ -48,6 +48,23 @@
                 value='svc:/application/openvswitch/ovsdb-server:default'/>
         </dependency>
 
+	<dependency
+            name='rad-local'
+            grouping='require_all'
+            restart_on='refresh'
+            type='service'>
+            <service_fmri
+                value='svc:/system/rad:local'/>
+	</dependency> 
+
+	<dependent
+	    name='ovs-network'
+	    grouping='optional_all'
+	    restart_on='none'>
+	    <service_fmri
+		value='svc:/milestone/network' />
+	</dependent>
+
         <instance name='default' enabled='true'>
             <exec_method
                 type="method"
--- a/components/openvswitch/openvswitch.p5m	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/openvswitch.p5m	Tue Apr 05 20:57:21 2016 -0700
@@ -20,7 +20,7 @@
 #
 
 #
-# Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2015, 2016, Oracle and/or its affiliates. All rights reserved.
 #
 
 <transform file path=usr.*/man/.+ -> default mangler.man.stability committed>
@@ -88,3 +88,4 @@
 depend type=require fmri=__TBD \
     pkg.debug.depend.file=lib/svc/share/net_include.sh \
     pkg.debug.reason=lib/svc/method/ovs
+depend type=require fmri=system/management/rad/module/rad-dlmgr
--- a/components/openvswitch/patches/01-solaris-port.patch	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/patches/01-solaris-port.patch	Tue Apr 05 20:57:21 2016 -0700
@@ -15,23 +15,22 @@
     lib/socket_util.h
 
     lib/socket-util.c      Fix set_dscp setsockopt error return for Solaris
-    python/ovs/socket_util.py
 
     vswitchd/automake.mk   Solaris sed whitespace fix
     vtep/automake.mk
 
-    lib/socket-util.c      Rename 'sun' argument
+    lib/socket-util.c      Rename 'sun' variables.
     lib/lib-stream-unix.c
 
 This patch has not been proposed upstream because we are not yet
 proposing Solaris specific requirements upstream.
 
 diff --git a/acinclude.m4 b/acinclude.m4
-index 8d10360..2b5944e 100644
+index 0f53ea7..f729947 100644
 --- a/acinclude.m4
 +++ b/acinclude.m4
-@@ -378,6 +378,22 @@ AC_DEFUN([OVS_CHECK_IF_DL],
-       AC_SEARCH_LIBS([pcap_open_live], [pcap])
+@@ -407,6 +407,22 @@ AC_DEFUN([OVS_CHECK_IF_PACKET],
+                 [Define to 1 if net/if_packet.h is available.])
     fi])
  
 +dnl Checks for rad/client/1/dlmgr.h
@@ -50,11 +49,24 @@
 +      LDFLAGS="$LDFLAGS -R /usr/lib/rad/client/c/64"
 +   fi])
 +
- dnl Checks for buggy strtok_r.
+ dnl Checks for net/if_dl.h.
  dnl
- dnl Some versions of glibc 2.7 has a bug in strtok_r when compiling
+ dnl (We use this as a proxy for checking whether we're building on FreeBSD
+@@ -415,6 +431,12 @@ AC_DEFUN([OVS_CHECK_IF_DL],
+   [AC_CHECK_HEADER([net/if_dl.h],
+                    [HAVE_IF_DL=yes],
+                    [HAVE_IF_DL=no])
++   AC_CHECK_HEADER([rad/client/1/dlmgr.h],
++                   [HAVE_DLMGR=yes],
++                   [HAVE_DLMGR=no])
++   if test "$HAVE_DLMGR" = yes; then
++      HAVE_IF_DL=no
++   fi
+    AM_CONDITIONAL([HAVE_IF_DL], [test "$HAVE_IF_DL" = yes])
+    if test "$HAVE_IF_DL" = yes; then
+       AC_DEFINE([HAVE_IF_DL], [1],
 diff --git a/configure.ac b/configure.ac
-index 5c1f398..56ce096 100644
+index ae38a1e..0db0e6e 100644
 --- a/configure.ac
 +++ b/configure.ac
 @@ -61,6 +61,7 @@ OVS_CHECK_PYTHON_COMPAT
@@ -77,7 +89,7 @@
  include include/sparse/automake.mk
  include include/windows/automake.mk
 diff --git a/lib/automake.mk b/lib/automake.mk
-index de3f068..5029dd3 100644
+index de3f068..b96eca7 100644
 --- a/lib/automake.mk
 +++ b/lib/automake.mk
 @@ -13,8 +13,21 @@ if WIN32
@@ -102,7 +114,7 @@
  lib_libopenvswitch_la_SOURCES = \
  	lib/aes128.c \
  	lib/aes128.h \
-@@ -304,6 +317,16 @@ lib_libopenvswitch_la_SOURCES += \
+@@ -304,6 +317,17 @@ lib_libopenvswitch_la_SOURCES += \
  	lib/route-table.h
  endif
  
@@ -112,6 +124,7 @@
 +	lib/dpif-solaris.h \
 +	lib/netdev-solaris.c \
 +	lib/netdev-solaris.h \
++	lib/route-table-solaris.c \
 +	lib/util-solaris.c \
 +	lib/util-solaris.h
 +endif
@@ -119,23 +132,15 @@
  if DPDK_NETDEV
  lib_libopenvswitch_la_SOURCES += \
         lib/netdev-dpdk.c \
-@@ -322,12 +345,16 @@ lib_libopenvswitch_la_SOURCES += \
+@@ -321,7 +345,7 @@ lib_libopenvswitch_la_SOURCES += \
+         lib/route-table-stub.c
  endif
  
- if HAVE_IF_DL
-+if SOLARIS
+-if HAVE_IF_DL
++if HAVE_IF_DL 
  lib_libopenvswitch_la_SOURCES += \
-+	lib/route-table-solaris.c
-+else
  	lib/netdev-bsd.c \
  	lib/rtbsd.c \
- 	lib/rtbsd.h \
- 	lib/route-table-bsd.c
- endif
-+endif
- 
- if HAVE_OPENSSL
- lib_libopenvswitch_la_SOURCES += lib/stream-ssl.c
 diff --git a/lib/byte-order.h b/lib/byte-order.h
 index 544f46f..b63a2b9 100644
 --- a/lib/byte-order.h
@@ -189,7 +194,7 @@
      SFL_DSCLASS_IFINDEX = 0,
      SFL_DSCLASS_VLAN = 1,
 diff --git a/lib/socket-util.h b/lib/socket-util.h
-index 2acc974..ebd3ae5 100644
+index 63f1d5f..f99a6ee 100644
 --- a/lib/socket-util.h
 +++ b/lib/socket-util.h
 @@ -27,6 +27,10 @@
@@ -202,66 +207,12 @@
 +
  int set_nonblocking(int fd);
  void xset_nonblocking(int fd);
- int set_dscp(int fd, uint8_t dscp);
+ int set_dscp(int fd, int family, uint8_t dscp);
 diff --git a/lib/socket-util.c b/lib/socket-util.c
-index aa0c719..afc607e 100644
+index e32aa2b..e9c8ae5 100644
 --- a/lib/socket-util.c
 +++ b/lib/socket-util.c
-@@ -111,6 +111,7 @@ set_dscp(int fd, uint8_t dscp)
- {
-     int val;
-     bool success;
-+    int err = 0;
- 
-     if (dscp > 63) {
-         return EINVAL;
-@@ -120,29 +121,39 @@ set_dscp(int fd, uint8_t dscp)
-     success = false;
-     val = dscp << 2;
-     if (setsockopt(fd, IPPROTO_IP, IP_TOS, &val, sizeof val)) {
-+	err = sock_errno();
-+#ifndef __sun
- #ifndef _WIN32
--        if (sock_errno() != ENOPROTOOPT) {
-+        if (err != ENOPROTOOPT) {
- #else
--        if (sock_errno() != WSAENOPROTOOPT) {
-+        if (err != WSAENOPROTOOPT) {
- #endif
--            return sock_errno();
-+            return err;
-         }
-+#endif
-     } else {
-         success = true;
-     }
-     if (setsockopt(fd, IPPROTO_IPV6, IPV6_TCLASS, &val, sizeof val)) {
-+	err = sock_errno();
-+#ifndef __sun
- #ifndef _WIN32
--        if (sock_errno() != ENOPROTOOPT) {
-+        if (err != ENOPROTOOPT) {
- #else
--        if (sock_errno() != WSAENOPROTOOPT) {
-+        if (err != WSAENOPROTOOPT) {
- #endif
--            return sock_errno();
-+            return err;
-         }
-+#endif
-     } else {
-         success = true;
-     }
-     if (!success) {
-+#ifndef __sun
-         return ENOPROTOOPT;
-+#else
-+	return err;
-+#endif
-     }
- 
-     return 0;
-@@ -505,11 +516,11 @@ free_sockaddr_un(int dirfd, const char *linkname)
+@@ -493,11 +493,11 @@ free_sockaddr_un(int dirfd, const char *linkname)
  
  /* Binds Unix domain socket 'fd' to a file with permissions 0700. */
  static int
@@ -275,7 +226,7 @@
      umask(old_umask);
      return error;
  }
-@@ -1115,15 +1126,15 @@ describe_sockaddr(struct ds *string, int fd,
+@@ -1103,15 +1103,15 @@ describe_sockaddr(struct ds *string, int fd,
                            ss_get_port(&ss));
  #ifndef _WIN32
          } else if (ss.ss_family == AF_UNIX) {
@@ -297,7 +248,7 @@
          }
  #ifdef HAVE_NETLINK
 diff --git a/lib/stream-unix.c b/lib/stream-unix.c
-index b3d70b6..a8cacc4 100644
+index fafdc8d..53dddb7 100644
 --- a/lib/stream-unix.c
 +++ b/lib/stream-unix.c
 @@ -108,12 +108,12 @@ static int
@@ -315,24 +266,6 @@
      } else {
          strcpy(name, "unix");
      }
-diff --git a/python/ovs/socket_util.py b/python/ovs/socket_util.py
-index 1af6474..b334d7e 100644
---- a/python/ovs/socket_util.py
-+++ b/python/ovs/socket_util.py
-@@ -302,11 +302,11 @@ def set_dscp(sock, dscp):
-     try:
-         sock.setsockopt(socket.IPPROTO_IP, socket.IP_TOS, val)
-     except socket.error, e:
--        if get_exception_errno(e) != errno.ENOPROTOOPT:
-+        if get_exception_errno(e) != errno.EINVAL:
-             raise
-     success = True
-     try:
-         sock.setsockopt(socket.IPPROTO_IPV6, socket.IPV6_TCLASS, val)
-     except socket.error, e:
--        if get_exception_errno(e) != errno.ENOPROTOOPT or not success:
-+        if get_exception_errno(e) != errno.EINVAL or not success:
-             raise
 diff --git a/vswitchd/automake.mk b/vswitchd/automake.mk
 index a09605f..19bf9ea 100644
 --- a/vswitchd/automake.mk
--- a/components/openvswitch/patches/02-bridge.patch	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/patches/02-bridge.patch	Tue Apr 05 20:57:21 2016 -0700
@@ -4,7 +4,7 @@
 proposing Solaris specific requirements upstream.
 
 diff --git a/vswitchd/bridge.c b/vswitchd/bridge.c
-index 6cd30b8..19ff759 100644
+index 6cd30b8..67120d4 100644
 --- a/vswitchd/bridge.c
 +++ b/vswitchd/bridge.c
 @@ -943,6 +943,12 @@ port_configure(struct port *port)
@@ -25,12 +25,12 @@
  
      bridge_pick_local_hw_addr(br, ea, &hw_addr_iface);
 +#ifdef __sun
-+    /* Solaris "system" bridges are implicitly created VNICs. They 
++    /* Solaris "system" bridges are implicitly created VNICs. They
 +     * already have their ethernet addresses set, so there is no
 +     * reason to set them. We prefer that they be "auto" generated.
 +     */
 +    if (bridge_is_system(br))
-+	goto skip;
++        goto skip;
 +#endif
      local_iface = iface_from_ofp_port(br, OFPP_LOCAL);
      if (local_iface) {
@@ -45,73 +45,60 @@
      memcpy(br->ea, ea, ETH_ADDR_LEN);
  
      dpid = bridge_pick_datapath_id(br, ea, hw_addr_iface);
-@@ -1485,6 +1502,16 @@ iface_do_create(const struct bridge *br,
+@@ -1485,6 +1502,19 @@ iface_do_create(const struct bridge *br,
          goto error;
      }
  
 +#ifdef __sun
-+    if (bridge_is_system(br) && netdev_is_uplink(netdev)) {
-+        VLOG_INFO("bridge %s: uplink %s", br->name, iface_cfg->name);
-+        error = netdev_configure_uplink(netdev, br->name);
-+        if (error) {
-+            goto error;
++    if (bridge_is_system(br)) {
++        if (netdev_is_uplink(netdev)) {
++            VLOG_INFO("bridge %s: uplink %s", br->name, iface_cfg->name);
++            error = netdev_configure_uplink(netdev, br->name);
++            if (error) {
++                goto error;
++            }
 +        }
++        netdev_add_port_to_bridge_mapping(netdev, br->name);
 +    }
 +#endif
 +
      *ofp_portp = iface_pick_ofport(iface_cfg);
      error = ofproto_port_add(br->ofproto, netdev, ofp_portp);
      if (error) {
-@@ -1494,6 +1521,15 @@ iface_do_create(const struct bridge *br,
-     VLOG_INFO("bridge %s: added interface %s on port %d",
-               br->name, iface_cfg->name, *ofp_portp);
- 
-+#ifdef __sun
-+    if (bridge_is_system(br) && iface_is_internal(iface_cfg, br->cfg)) {
-+	error = ofproto_configure_bridge_port(br->ofproto, br->name);
-+        if (error) {
-+            goto error;
-+        }
-+    }
-+#endif
-+
-     if (port_cfg->vlan_mode && !strcmp(port_cfg->vlan_mode, "splinter")) {
-         netdev_turn_flags_on(netdev, NETDEV_UP, NULL);
-     }
-@@ -1620,10 +1656,31 @@ find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
+@@ -1620,10 +1650,32 @@ find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
  {
      struct hmapx mirror_output_ports;
      struct port *port;
-+    int i;
 +    struct iface *iface = NULL;
 +    uint8_t iface_ea[ETH_ADDR_LEN];
      bool found_addr = false;
      int error;
--    int i;
+     int i;
  
 +#ifdef __sun
 +    /*
 +     * Solaris does not currently support fake bridges.
 +     */
 +    if (bridge_is_system(br)) {
-+	if (fake_br == NULL) {
-+	    iface = iface_lookup(br, br->name);
-+	    if (iface != NULL) {
-+		error = netdev_get_etheraddr(iface->netdev, iface_ea);
-+		if (error == 0) {
-+		    memcpy(ea, iface_ea, ETH_ADDR_LEN);
-+		    *hw_addr_iface = iface;
-+		    found_addr = true;
-+		}
++        if (fake_br == NULL) {
++            iface = iface_lookup(br, br->name);
++            if (iface != NULL) {
++                error = netdev_get_etheraddr(iface->netdev, iface_ea);
++                if (error == 0) {
++                    memcpy(ea, iface_ea, ETH_ADDR_LEN);
++                    *hw_addr_iface = iface;
++                    found_addr = true;
++                }
 +            }
 +        }
-+	goto skip;
++        goto skip;
 +    }
 +#endif
++
      /* Mirror output ports don't participate in picking the local hardware
       * address.  ofproto can't help us find out whether a given port is a
       * mirror output because we haven't configured mirrors yet, so we need to
-@@ -1639,9 +1696,7 @@ find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
+@@ -1639,9 +1691,7 @@ find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
      /* Otherwise choose the minimum non-local MAC address among all of the
       * interfaces. */
      HMAP_FOR_EACH (port, hmap_node, &br->ports) {
@@ -121,7 +108,7 @@
  
          /* Mirror output ports don't participate. */
          if (hmapx_contains(&mirror_output_ports, port->cfg)) {
-@@ -1708,13 +1763,15 @@ find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
+@@ -1708,13 +1758,15 @@ find_local_hw_addr(const struct bridge *br, uint8_t ea[ETH_ADDR_LEN],
              found_addr = true;
          }
      }
--- a/components/openvswitch/patches/03-dpif-provider.patch	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/patches/03-dpif-provider.patch	Tue Apr 05 20:57:21 2016 -0700
@@ -3,29 +3,11 @@
 This patch has not been proposed upstream because we are not yet
 proposing Solaris specific requirements upstream.
 
-diff --git a/lib/dpif-netdev.c b/lib/dpif-netdev.c
-index 78f8636..d9b18d0 100644
---- a/lib/dpif-netdev.c
-+++ b/lib/dpif-netdev.c
-@@ -2269,6 +2269,7 @@ const struct dpif_class dpif_netdev_class = {
-     dpif_netdev_recv,
-     dpif_netdev_recv_wait,
-     dpif_netdev_recv_purge,
-+    NULL,
- };
- 
- static void
 diff --git a/lib/dpif-provider.h b/lib/dpif-provider.h
-index 389e84e..7df0e3c 100644
+index 389e84e..5f2d50a 100644
 --- a/lib/dpif-provider.h
 +++ b/lib/dpif-provider.h
-@@ -436,9 +436,13 @@ struct dpif_class {
-     /* Throws away any queued upcalls that 'dpif' currently has ready to
-      * return. */
-     void (*recv_purge)(struct dpif *dpif);
-+
-+    /* Configure port on bridge. */
-+    int (*configure_bridge_port)(const struct dpif *, const char *devname);
+@@ -439,6 +439,7 @@ struct dpif_class {
  };
  
  extern const struct dpif_class dpif_linux_class;
@@ -34,7 +16,7 @@
  
  #ifdef  __cplusplus
 diff --git a/lib/dpif.c b/lib/dpif.c
-index 450c6c8..d5a89da 100644
+index 450c6c8..337cf4b 100644
 --- a/lib/dpif.c
 +++ b/lib/dpif.c
 @@ -60,6 +60,9 @@ static const struct dpif_class *base_dpif_classes[] = {
@@ -47,38 +29,11 @@
      &dpif_netdev_class,
  };
  
-@@ -661,6 +664,14 @@ dpif_port_get_pid(const struct dpif *dpif, odp_port_t port_no, uint32_t hash)
-             : 0);
- }
- 
-+int
-+dpif_configure_bridge_port(const struct dpif *dpif, const char *devname)
-+{
-+    return (dpif->dpif_class->configure_bridge_port
-+	    ? (dpif->dpif_class->configure_bridge_port)(dpif, devname)
-+	    : 0);
-+}
-+
- /* Looks up port number 'port_no' in 'dpif'.  On success, returns 0 and copies
-  * the port's name into the 'name_size' bytes in 'name', ensuring that the
-  * result is null-terminated.  On failure, returns a positive errno value and
-diff --git a/lib/dpif.h b/lib/dpif.h
-index f13cc36..25b4845 100644
---- a/lib/dpif.h
-+++ b/lib/dpif.h
-@@ -468,6 +468,7 @@ int dpif_port_get_name(struct dpif *, odp_port_t port_no,
-                        char *name, size_t name_size);
- uint32_t dpif_port_get_pid(const struct dpif *, odp_port_t port_no,
-                            uint32_t hash);
-+int dpif_configure_bridge_port(const struct dpif *dpif, const char *devname);
- 
- struct dpif_port_dump {
-     const struct dpif *dpif;
 diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
-index 46595f8..2bb200c 100644
+index 9b87248..656e6b1 100644
 --- a/ofproto/ofproto-dpif.c
 +++ b/ofproto/ofproto-dpif.c
-@@ -1431,7 +1431,7 @@ run(struct ofproto *ofproto_)
+@@ -1469,7 +1469,7 @@ run(struct ofproto *ofproto_)
  }
  
  static void
@@ -87,25 +42,7 @@
  {
      struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
  
-@@ -2839,6 +2839,17 @@ port_query_by_name(const struct ofproto *ofproto_, const char *devname,
- }
- 
- static int
-+configure_bridge_port(const struct ofproto *ofproto_, const char *devname)
-+{
-+    struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
-+
-+    if (!sset_contains(&ofproto->ports, devname)) {
-+        return ENODEV;
-+    }
-+    return (dpif_configure_bridge_port(ofproto->backer->dpif, devname));
-+}
-+
-+static int
- port_add(struct ofproto *ofproto_, struct netdev *netdev)
- {
-     struct ofproto_dpif *ofproto = ofproto_dpif_cast(ofproto_);
-@@ -4867,7 +4878,7 @@ const struct ofproto_class ofproto_dpif_class = {
+@@ -4946,7 +4946,7 @@ const struct ofproto_class ofproto_dpif_class = {
      destruct,
      dealloc,
      run,
@@ -114,68 +51,19 @@
      NULL,                       /* get_memory_usage. */
      type_get_memory_usage,
      flush,
-@@ -4934,4 +4945,5 @@ const struct ofproto_class ofproto_dpif_class = {
-     group_dealloc,              /* group_dealloc */
-     group_modify,               /* group_modify */
-     group_get_stats,            /* group_get_stats */
-+    configure_bridge_port       /* configure_bridge_port */
- };
-diff --git a/ofproto/ofproto-provider.h b/ofproto/ofproto-provider.h
-index 1978a20..f743a8a 100644
---- a/ofproto/ofproto-provider.h
-+++ b/ofproto/ofproto-provider.h
-@@ -1695,6 +1695,8 @@ struct ofproto_class {
- 
-     enum ofperr (*group_get_stats)(const struct ofgroup *,
-                                    struct ofputil_group_stats *);
-+    int (*configure_bridge_port)(const struct ofproto *ofproto,
-+                              const char *devname);
- };
- 
- extern const struct ofproto_class ofproto_dpif_class;
-diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
-index 2048fde..2b25fe4 100644
---- a/ofproto/ofproto.c
-+++ b/ofproto/ofproto.c
-@@ -1826,6 +1826,13 @@ ofproto_port_query_by_name(const struct ofproto *ofproto, const char *devname,
-     return error;
- }
- 
-+int
-+ofproto_configure_bridge_port(const struct ofproto *ofproto,
-+    const char *devname)
-+{
-+    return (ofproto->ofproto_class->configure_bridge_port(ofproto, devname));
-+}
-+
- /* Deletes port number 'ofp_port' from the datapath for 'ofproto'.
-  * Returns 0 if successful, otherwise a positive errno. */
- int
-diff --git a/ofproto/ofproto.h b/ofproto/ofproto.h
-index 9a06849..94dce34 100644
---- a/ofproto/ofproto.h
-+++ b/ofproto/ofproto.h
-@@ -224,6 +224,7 @@ int ofproto_port_get_stats(const struct ofport *, struct netdev_stats *stats);
- 
- int ofproto_port_query_by_name(const struct ofproto *, const char *devname,
-                                struct ofproto_port *);
-+int ofproto_configure_bridge_port(const struct ofproto *, const char *);
- 
- /* Top-level configuration. */
- uint64_t ofproto_get_datapath_id(const struct ofproto *);
 diff --git a/ofproto/ofproto-dpif-xlate.c b/ofproto/ofproto-dpif-xlate.c
-index 4f77ac5..b9f1801 100644
+index 028e7e0..62e0cf1 100644
 --- a/ofproto/ofproto-dpif-xlate.c
 +++ b/ofproto/ofproto-dpif-xlate.c
-@@ -3184,6 +3184,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
-     ovs_rwlock_unlock(&xlate_rwlock);
+@@ -3236,6 +3236,7 @@ xlate_actions(struct xlate_in *xin, struct xlate_out *xout)
+     fat_rwlock_unlock(&xlate_rwlock);
  }
  
 +#ifdef __linux__
  /* Returns the maximum number of packets that the Linux kernel is willing to
   * queue up internally to certain kinds of software-implemented ports, or the
   * default (and rarely modified) value if it cannot be determined. */
-@@ -3236,7 +3237,9 @@ count_output_actions(const struct ofpbuf *odp_actions)
+@@ -3288,7 +3289,9 @@ count_output_actions(const struct ofpbuf *odp_actions)
      }
      return n;
  }
@@ -185,7 +73,7 @@
  /* Returns true if 'odp_actions' contains more output actions than the datapath
   * can reliably handle in one go.  On Linux, this is the value of the
   * net.core.netdev_max_backlog sysctl, which limits the maximum number of
-@@ -3245,15 +3248,18 @@ count_output_actions(const struct ofpbuf *odp_actions)
+@@ -3297,15 +3300,19 @@ count_output_actions(const struct ofpbuf *odp_actions)
  static bool
  too_many_output_actions(const struct ofpbuf *odp_actions)
  {
@@ -197,6 +85,7 @@
 +static bool
 +too_many_output_actions(const struct ofpbuf *odp_actions OVS_UNUSED)
 +{
++
      /* OSes other than Linux might have similar limits, but we don't know how
       * to determine them.*/
      return false;
--- a/components/openvswitch/patches/04-netdev-provider.patch	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/patches/04-netdev-provider.patch	Tue Apr 05 20:57:21 2016 -0700
@@ -4,10 +4,10 @@
 proposing Solaris specific requirements upstream.
 
 diff --git a/lib/netdev-dummy.c b/lib/netdev-dummy.c
-index 501fb82..1051f08 100644
+index b087ed1..6e260e8 100644
 --- a/lib/netdev-dummy.c
 +++ b/lib/netdev-dummy.c
-@@ -1043,7 +1043,10 @@ static const struct netdev_class dummy_class = {
+@@ -1068,7 +1068,11 @@ static const struct netdev_class dummy_class = {
      NULL,                       /* arp_lookup */
  
      netdev_dummy_update_flags,
@@ -15,30 +15,37 @@
 +#ifdef __sun
 +    NULL,
 +    NULL,
++    NULL,
 +#endif
      netdev_dummy_rxq_alloc,
      netdev_dummy_rxq_construct,
      netdev_dummy_rxq_destruct,
 diff --git a/lib/netdev-provider.h b/lib/netdev-provider.h
-index 37b9da3..bcec96a 100644
+index 37b9da3..37487f0 100644
 --- a/lib/netdev-provider.h
 +++ b/lib/netdev-provider.h
-@@ -647,6 +647,14 @@ struct netdev_class {
+@@ -647,6 +647,20 @@ struct netdev_class {
      int (*update_flags)(struct netdev *netdev, enum netdev_flags off,
                          enum netdev_flags on, enum netdev_flags *old_flags);
  
-+
-+    /* Returns true if netdev represents uplink for the switch */
++   /* Returns true if netdev represents uplink for the switch */
 +    int (*configure_uplink)(const struct netdev *netdev,
 +                            const char *brname);
 +
 +    /* Returns true if netdev represents uplink for the switch */
 +    bool (*is_uplink)(const struct netdev *netdev);
 +
++    /* Adds a mapping into port_to_bridge_map hashmap. We need to maintain
++     * this mapping for every port(netdev) that we add onto the bridge.
++     * Specific to Solaris' netdev provider(netdev_solaris_class)
++     * and multiple uplink implementation */
++    void (*add_port_to_bridge_mapping)(const struct netdev *netdev,
++                        const char *name);
++
  /* ## -------------------- ## */
  /* ## netdev_rxq Functions ## */
  /* ## -------------------- ## */
-@@ -692,6 +700,9 @@ extern const struct netdev_class netdev_tap_class;
+@@ -692,6 +706,9 @@ extern const struct netdev_class netdev_tap_class;
  #if defined(__FreeBSD__) || defined(__NetBSD__)
  extern const struct netdev_class netdev_bsd_class;
  #endif
@@ -49,21 +56,22 @@
  #ifdef  __cplusplus
  }
 diff --git a/lib/netdev-vport.c b/lib/netdev-vport.c
-index a676784..54c9e0b 100644
+index 0c22378..d442345 100644
 --- a/lib/netdev-vport.c
 +++ b/lib/netdev-vport.c
-@@ -814,7 +814,9 @@ get_stats(const struct netdev *netdev, struct netdev_stats *stats)
+@@ -818,7 +818,10 @@ get_stats(const struct netdev *netdev, struct netdev_stats *stats)
      NULL,                   /* rx_dealloc */                \
      NULL,                   /* rx_recv */                   \
      NULL,                   /* rx_wait */                   \
 -    NULL,                   /* rx_drain */
-+    NULL,                   /* rx_drain */		    \
-+    NULL,                   /* configure_uplink */	    \
-+    NULL                    /* is_uplink */
++    NULL,                   /* rx_drain */                  \
++    NULL,                   /* configure_uplink */          \
++    NULL,                   /* is_uplink */		    \
++    NULL                    /* add_port_to_bridge_mapping */
  
  #define TUNNEL_CLASS(NAME, DPIF_PORT)                       \
      { DPIF_PORT,                                            \
-@@ -827,12 +829,14 @@ void
+@@ -831,12 +834,14 @@ void
  netdev_vport_tunnel_register(void)
  {
      static const struct vport_class vport_classes[] = {
@@ -81,22 +89,23 @@
      static struct ovsthread_once once = OVSTHREAD_ONCE_INITIALIZER;
  
 diff --git a/lib/netdev.c b/lib/netdev.c
-index 5bf2220..c59a308 100644
+index 5bf2220..3c9081c 100644
 --- a/lib/netdev.c
 +++ b/lib/netdev.c
-@@ -135,6 +135,11 @@ netdev_initialize(void)
+@@ -135,6 +135,12 @@ netdev_initialize(void)
          netdev_register_provider(&netdev_tap_class);
          netdev_register_provider(&netdev_bsd_class);
  #endif
 +#ifdef __sun
-+	netdev_register_provider(&netdev_solaris_class);
-+	netdev_register_provider(&netdev_internal_class);
++       netdev_register_provider(&netdev_solaris_class);
++       netdev_register_provider(&netdev_internal_class);
 +        netdev_vport_tunnel_register();
 +#endif
++
          netdev_dpdk_register();
  
          ovsthread_once_done(&once);
-@@ -684,6 +689,23 @@ netdev_get_etheraddr(const struct netdev *netdev, uint8_t mac[ETH_ADDR_LEN])
+@@ -684,6 +690,30 @@ netdev_get_etheraddr(const struct netdev *netdev, uint8_t mac[ETH_ADDR_LEN])
      return netdev->netdev_class->get_etheraddr(netdev, mac);
  }
  
@@ -117,20 +126,28 @@
 +    return(class->is_uplink ? class->is_uplink(netdev) : false);
 +}
 +
++void
++netdev_add_port_to_bridge_mapping(const struct netdev *netdev, const char *brname)
++{
++    if (netdev->netdev_class->add_port_to_bridge_mapping)
++        netdev->netdev_class->add_port_to_bridge_mapping(netdev, brname);
++}
++
  /* Returns the name of the network device that 'netdev' represents,
   * e.g. "eth0".  The caller must not modify or free the returned string. */
  const char *
 diff --git a/lib/netdev.h b/lib/netdev.h
-index 7cb3c80..9b663b7 100644
+index 7cb3c80..f450f64 100644
 --- a/lib/netdev.h
 +++ b/lib/netdev.h
-@@ -177,6 +177,9 @@ void netdev_send_wait(struct netdev *);
+@@ -176,7 +176,9 @@ void netdev_send_wait(struct netdev *);
+ /* Hardware address. */
  int netdev_set_etheraddr(struct netdev *, const uint8_t mac[6]);
  int netdev_get_etheraddr(const struct netdev *, uint8_t mac[6]);
- 
+-
 +int netdev_configure_uplink(const struct netdev *, const char *);
 +bool netdev_is_uplink(const struct netdev *);
-+
++void netdev_add_port_to_bridge_mapping(const struct netdev *, const char *);
  /* PHY interface. */
  bool netdev_get_carrier(const struct netdev *);
  long long int netdev_get_carrier_resets(const struct netdev *);
--- a/components/openvswitch/patches/05-usage.patch	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/patches/05-usage.patch	Tue Apr 05 20:57:21 2016 -0700
@@ -1211,7 +1211,7 @@
      printf("\
    --no-syslog             equivalent to --verbose=vsctl:syslog:warn\n");
 diff --git a/vswitchd/ovs-vswitchd.8.in b/vswitchd/ovs-vswitchd.8.in
-index 8ffa7a0..12f8e55 100644
+index e9dc483..c060259 100644
 --- a/vswitchd/ovs-vswitchd.8.in
 +++ b/vswitchd/ovs-vswitchd.8.in
 @@ -30,32 +30,6 @@ switching across each bridge described in its configuration files.  As
@@ -1365,3 +1365,10 @@
  .
  .so ofproto/ofproto-dpif-unixctl.man
  .so ofproto/ofproto-unixctl.man
+@@ -281,5 +160,4 @@ time linear in the number of flows.
+ .
+ .SH "SEE ALSO"
+ .BR ovs\-appctl (8),
+-.BR ovsdb\-server (1),
+-\fBINSTALL.Linux\fR in the Open vSwitch distribution.
++.BR ovsdb\-server (1)
--- a/components/openvswitch/patches/06-controller-fix.patch	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/patches/06-controller-fix.patch	Tue Apr 05 20:57:21 2016 -0700
@@ -1,12 +1,12 @@
 This patch fixes a bug in the test controller.
 
-This patch was developed upstream in OVS 2.4.
+This patch was developed upstream in OVS 2.5.
 
 diff --git a/lib/learning-switch.c b/lib/learning-switch.c
-index ca57911..e037310 100644
+index f6182ba..e27f811 100644
 --- a/lib/learning-switch.c
 +++ b/lib/learning-switch.c
-@@ -173,10 +173,49 @@ static void
+@@ -180,10 +180,49 @@ static void
  lswitch_handshake(struct lswitch *sw)
  {
      enum ofputil_protocol protocol;
--- a/components/openvswitch/patches/07-ovsthread_key_destruct-fix.patch	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/patches/07-ovsthread_key_destruct-fix.patch	Tue Apr 05 20:57:21 2016 -0700
@@ -1,9 +1,9 @@
 This patch fixes a bug in ovsthread_key_destruct__.
 
-This patch has not been proposed upstream but will be proposed for 2.4.
+This patch has not been proposed upstream but will be proposed for 2.5.
 
 diff --git a/lib/ovs-thread.c b/lib/ovs-thread.c
-index 529756f..11735f9 100644
+index 529756f..8b76eb9 100644
 --- a/lib/ovs-thread.c
 +++ b/lib/ovs-thread.c
 @@ -641,8 +641,10 @@ ovsthread_key_destruct__(void *slots_)
@@ -13,9 +13,9 @@
 -    for (i = 0; i < n / L2_SIZE; i++) {
 -        free(slots->p1[i]);
 +    if (n > 0) {
-+	    for (i = 0; i <= (n - 1) / L2_SIZE; i++) {
-+                free(slots->p1[i]);
-+        }
++        for (i = 0; i <= (n - 1) / L2_SIZE; i++) {
++            free(slots->p1[i]);
++         }
      }
      free(slots);
  }
--- a/components/openvswitch/patches/08-self-test-fix.patch	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/patches/08-self-test-fix.patch	Tue Apr 05 20:57:21 2016 -0700
@@ -1,6 +1,6 @@
 This patch fixes a bug in the self test.
 
-This patch has not been proposed upstream but will be proposed for 2.4.
+This patch has not been proposed upstream but will be proposed for 2.5.
 
 diff --git a/tests/ofp-print.at b/tests/ofp-print.at
 index c25da53..07cea7b 100644
@@ -48,10 +48,10 @@
  AT_CLEANUP
  
 diff --git a/tests/ofproto-dpif.at b/tests/ofproto-dpif.at
-index 1fcd937..97433a8 100644
+index d350b40..f7e921e 100644
 --- a/tests/ofproto-dpif.at
 +++ b/tests/ofproto-dpif.at
-@@ -55,147 +55,156 @@ OVS_VSWITCHD_STOP
+@@ -55,148 +55,157 @@ OVS_VSWITCHD_STOP
  AT_CLEANUP
  
  AT_SETUP([ofproto-dpif, active-backup bonding])
@@ -73,6 +73,7 @@
 -   add-port br1 p3 -- set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=3 -- \
 -   add-port br1 p4 -- set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 -- \
 -   add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --])
+-WAIT_FOR_DUMMY_PORTS([p3], [p4])
 -AT_CHECK([ovs-appctl vlog/set dpif:dbg])
 -
 -AT_CHECK([ovs-ofctl add-flow br0 action=normal])
@@ -114,6 +115,7 @@
 +#   add-port br1 p3 -- set interface p3 type=dummy options:stream=unix:$OVS_RUNDIR/p1.sock ofport_request=3 -- \
 +#   add-port br1 p4 -- set interface p4 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=4 -- \
 +#   add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --])
++#WAIT_FOR_DUMMY_PORTS([p3], [p4])
 +#AT_CHECK([ovs-appctl vlog/set dpif:dbg])
 +#
 +#AT_CHECK([ovs-ofctl add-flow br0 action=normal])
@@ -167,12 +169,11 @@
 -   add-port br1 p5 -- set interface p5 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=5 -- \
 -   add-port br1 p6 -- set interface p6 type=dummy options:stream=unix:$OVS_RUNDIR/p3.sock ofport_request=6 -- \
 -   add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --])
--
+-WAIT_FOR_DUMMY_PORTS([p4], [p5], [p6])
 -AT_CHECK([ovs-ofctl add-flow br0 action=normal])
 -AT_CHECK([ovs-ofctl add-flow br1 action=normal])
 -AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK
 -])
--ovs-appctl netdev-dummy/set-admin-state up
 -ovs-appctl time/stop
 -ovs-appctl time/warp 100
 -(
@@ -184,6 +185,12 @@
 -)
 -ovs-appctl time/warp 100
 -AT_CHECK([ovs-appctl dpif/dump-flows br1 > br1_flows.txt])
+-# Make sure there is resonable distribution to all three ports.
+-# We don't want to make this check precise, in case hash function changes.
+-AT_CHECK([test `egrep 'in_port\(4\)' br1_flows.txt |wc -l` -gt 3])
+-AT_CHECK([test `egrep 'in_port\(5\)' br1_flows.txt |wc -l` -gt 3])
+-AT_CHECK([test `egrep 'in_port\(6\)' br1_flows.txt |wc -l` -gt 3])
+-OVS_VSWITCHD_STOP
 +#OVS_VSWITCHD_START(
 +#  [add-bond br0 bond0 p1 p2 p3 bond_mode=balance-slb --\
 +#   set interface p1 type=dummy options:pstream=punix:$OVS_RUNDIR/p1.sock ofport_request=1 -- \
@@ -198,12 +205,11 @@
 +#   add-port br1 p5 -- set interface p5 type=dummy options:stream=unix:$OVS_RUNDIR/p2.sock ofport_request=5 -- \
 +#   add-port br1 p6 -- set interface p6 type=dummy options:stream=unix:$OVS_RUNDIR/p3.sock ofport_request=6 -- \
 +#   add-port br1 p8 -- set interface p8 ofport_request=8 type=dummy --])
-+
++#WAIT_FOR_DUMMY_PORTS([p4], [p5], [p6])
 +#AT_CHECK([ovs-ofctl add-flow br0 action=normal])
 +#AT_CHECK([ovs-ofctl add-flow br1 action=normal])
 +#AT_CHECK([ovs-appctl netdev-dummy/set-admin-state up], 0, [OK
 +#])
-+#ovs-appctl netdev-dummy/set-admin-state up
 +#ovs-appctl time/stop
 +#ovs-appctl time/warp 100
 +#(
@@ -215,12 +221,8 @@
 +#)
 +#ovs-appctl time/warp 100
 +#AT_CHECK([ovs-appctl dpif/dump-flows br1 > br1_flows.txt])
- # Make sure there is resonable distribution to all three ports.
- # We don't want to make this check precise, in case hash function changes.
--AT_CHECK([test `egrep 'in_port\(4\)' br1_flows.txt |wc -l` -gt 3])
--AT_CHECK([test `egrep 'in_port\(5\)' br1_flows.txt |wc -l` -gt 3])
--AT_CHECK([test `egrep 'in_port\(6\)' br1_flows.txt |wc -l` -gt 3])
--OVS_VSWITCHD_STOP
++## Make sure there is resonable distribution to all three ports.
++## We don't want to make this check precise, in case hash function changes.
 +#AT_CHECK([test `egrep 'in_port\(4\)' br1_flows.txt |wc -l` -gt 3])
 +#AT_CHECK([test `egrep 'in_port\(5\)' br1_flows.txt |wc -l` -gt 3])
 +#AT_CHECK([test `egrep 'in_port\(6\)' br1_flows.txt |wc -l` -gt 3])
@@ -258,7 +260,7 @@
 -AT_CHECK([ovs-ofctl add-flow br1 action=normal])
 -AT_CHECK([ovs-appctl upcall/disable-megaflows], [0], [megaflows disabled
 -], [])
--sleep 1;
+-OVS_WAIT_WHILE([ovs-appctl bond/show | grep "may_enable: false"])
 -ovs-appctl time/stop
 -ovs-appctl time/warp 100
 -ovs-appctl lacp/show > lacp.txt
@@ -280,6 +282,7 @@
 -AT_CHECK([test `grep in_port.4 br1_flows.txt |wc -l` -gt 24])
 -AT_CHECK([test `grep in_port.5 br1_flows.txt |wc -l` -gt 24])
 -AT_CHECK([test `grep in_port.6 br1_flows.txt |wc -l` -gt 24])
+-
 -OVS_VSWITCHD_STOP()
 +#OVS_VSWITCHD_START(
 +#  [add-bond br0 bond0 p1 p2 p3 bond_mode=balance-tcp lacp=active \
@@ -304,7 +307,7 @@
 +#AT_CHECK([ovs-ofctl add-flow br1 action=normal])
 +#AT_CHECK([ovs-appctl upcall/disable-megaflows], [0], [megaflows disabled
 +#], [])
-+#sleep 1;
++#OVS_WAIT_WHILE([ovs-appctl bond/show | grep "may_enable: false"])
 +#ovs-appctl time/stop
 +#ovs-appctl time/warp 100
 +#ovs-appctl lacp/show > lacp.txt
@@ -326,10 +329,11 @@
 +#AT_CHECK([test `grep in_port.4 br1_flows.txt |wc -l` -gt 24])
 +#AT_CHECK([test `grep in_port.5 br1_flows.txt |wc -l` -gt 24])
 +#AT_CHECK([test `grep in_port.6 br1_flows.txt |wc -l` -gt 24])
++#
 +#OVS_VSWITCHD_STOP()
  AT_CLEANUP
  
- AT_SETUP([ofproto-dpif - resubmit])
+ # Makes sure recirculation does not change the way packet is handled.
 diff --git a/tests/cfm.at b/tests/cfm.at
 index 06cab90..a8572f0 100644
 --- a/tests/cfm.at
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/components/openvswitch/patches/09-CVE-2016-2074.patch	Tue Apr 05 20:57:21 2016 -0700
@@ -0,0 +1,47 @@
+This patch fixes CVE-2016-2074.
+
+Multiple versions of Open vSwitch are vulnerable to remote buffer
+overflow attacks, in which crafted MPLS packets could overflow the
+buffer reserved for MPLS labels in an OVS internal data structure.
+The MPLS packets that trigger the vulnerability and the potential for
+exploitation vary depending on version:
+
+    - Open vSwitch 2.1.x and earlier are not vulnerable.
+
+    - In Open vSwitch 2.2.x and 2.3.x, the MPLS buffer overflow can be
+      exploited for arbitrary remote code execution.
+    - In Open vSwitch 2.4.x, the MPLS buffer overflow does not
+      obviously lead to a remote code execution exploit, but testing
+      shows that it can allow a remote denial of service.  See the
+      mitigation section for details.
+
+    - Open vSwitch 2.5.x is not vulnerable.
+
+The Common Vulnerabilities and Exposures project (cve.mitre.org) has
+assigned the identifier CVE-2016-2074 to this issue.
+
+In OVS 2.3.x, this fix was applied by changeset:
+    f4137393ef2fd23a70d987ee9f89454e25db1700
+
+diff --git a/lib/flow.c b/lib/flow.c
+index 9018b66..c565032 100644
+--- a/lib/flow.c
++++ b/lib/flow.c
+@@ -159,7 +159,7 @@ struct mf_ctx {
+ 
+ /* Data at 'valuep' may be unaligned. */
+ #define miniflow_push_words_(MF, OFS, VALUEP, N_WORDS)          \
+-{                                                               \
++if (N_WORDS) {							\
+     int ofs32 = (OFS) / 4;                                      \
+                                                                         \
+     MINIFLOW_ASSERT(MF.data + (N_WORDS) <= MF.end && (OFS) % 4 == 0     \
+@@ -210,7 +210,7 @@ parse_mpls(void **datap, size_t *sizep)
+             break;
+         }
+     }
+-    return MAX(count, FLOW_MAX_MPLS_LABELS);
++    return MIN(count, FLOW_MAX_MPLS_LABELS);
+ }
+ 
+ static inline ovs_be16
--- a/components/openvswitch/test/results-64.master	Tue Apr 05 15:53:34 2016 -0700
+++ b/components/openvswitch/test/results-64.master	Tue Apr 05 20:57:21 2016 -0700
@@ -1,16 +1,16 @@
-make[1]: Entering directory `$(@D)'
+make[1]: Entering directory '$(@D)'
 /usr/gnu/bin/make  check-recursive
-make[2]: Entering directory `$(@D)'
+make[2]: Entering directory '$(@D)'
 Making check in datapath
-make[3]: Entering directory `$(@D)/datapath'
-make[4]: Entering directory `$(@D)/datapath'
-make[4]: Nothing to be done for `check-am'.
-make[4]: Leaving directory `$(@D)/datapath'
-make[3]: Leaving directory `$(@D)/datapath'
-make[3]: Entering directory `$(@D)'
+make[3]: Entering directory '$(@D)/datapath'
+make[4]: Entering directory '$(@D)/datapath'
+make[4]: Nothing to be done for 'check-am'.
+make[4]: Leaving directory '$(@D)/datapath'
+make[3]: Leaving directory '$(@D)/datapath'
+make[3]: Entering directory '$(@D)'
 /usr/gnu/bin/make  tests/flowgen.pl tests/testpki-cacert.pem tests/testpki-cert.pem tests/testpki-privkey.pem tests/testpki-req.pem tests/testpki-cert2.pem tests/testpki-privkey2.pem tests/testpki-req2.pem
-make[4]: Entering directory `$(@D)'
-make[4]: Nothing to be done for `$(SOURCE_DIR)/tests/flowgen.pl'.
+make[4]: Entering directory '$(@D)'
+make[4]: Nothing to be done for '$(SOURCE_DIR)/tests/flowgen.pl'.
 rm -f tests/pki/stamp
 rm -rf tests/pki
 /bin/bash $(SOURCE_DIR)/utilities/ovs-pki.in --dir=tests/pki --log=tests/ovs-pki.log init
@@ -30,12 +30,12 @@
 cp tests/pki/test2-cert.pem tests/testpki-cert2.pem
 cp tests/pki/test2-privkey.pem tests/testpki-privkey2.pem
 cp tests/pki/test2-req.pem tests/testpki-req2.pem
-make[4]: Leaving directory `$(@D)'
+make[4]: Leaving directory '$(@D)'
 /usr/gnu/bin/make  check-local
-make[4]: Entering directory `$(@D)'
+make[4]: Entering directory '$(@D)'
 /bin/bash '$(SOURCE_DIR)/tests/testsuite' -C tests AUTOTEST_PATH=utilities:vswitchd:ovsdb:vtep:tests 
 ## ----------------------------- ##
-## openvswitch 2.3.1 test suite. ##
+## openvswitch 2.3.2 test suite. ##
 ## ----------------------------- ##
 
 bfd
@@ -888,983 +888,989 @@
 714: ofproto-dpif, active-backup bonding             ok
 715: ofproto-dpif, balance-slb bonding               ok
 716: ofproto-dpif, balance-tcp bonding               ok
-717: ofproto-dpif - resubmit                         ok
-718: ofproto-dpif - goto table                       ok
-719: ofproto-dpif - write actions                    ok
-720: ofproto-dpif - clear actions                    ok
-721: ofproto-dpif - group chaining not supported     ok
-722: ofproto-dpif - all group in action list         ok
-723: ofproto-dpif - indirect group in action list    ok
-724: ofproto-dpif - all group in action set          ok
-725: ofproto-dpif - indirect group in action set     ok
-726: ofproto-dpif - select group                     ok
-727: ofproto-dpif - select group with watch port     ok
-728: ofproto-dpif - select group with weight         ok
-729: ofproto-dpif - fast failover group              ok
-730: ofproto-dpif - registers                        ok
-731: ofproto-dpif - push-pop                         ok
-732: ofproto-dpif - output                           ok
-733: ofproto-dpif - dec_ttl                          ok
-734: ofproto-dpif - dec_ttl without arguments at offset 32 in ofpacts ok
-735: ofproto-dpif - dec_ttl with arguments at offset 32 in ofpacts ok
-736: ofproto-dpif - note at offset 24 in ofpacts     ok
-737: ofproto-dpif - output, OFPP_NONE ingress port   ok
-738: ofproto-dpif - DSCP                             ok
-739: ofproto-dpif - output/flood flags               ok
-740: ofproto-dpif - Default Table Miss - OF1.0 (OFPTC_TABLE_MISS_CONTROLLER) ok
-741: ofproto-dpif - Default Table Miss - OF1.3 (OFPTC_TABLE_MISS_DROP) ok
-742: ofproto-dpif - Table Miss - goto table and OFPTC_TABLE_MISS_CONTROLLER ok
-743: ofproto-dpif - Table Miss - resubmit and OFPTC_TABLE_MISS_CONTROLLER ok
-744: ofproto-dpif - Table Miss - OFPTC_TABLE_MISS_CONTINUE ok
-745: ofproto-dpif - Table Miss - goto table and OFPTC_TABLE_MISS_CONTINUE ok
-746: ofproto-dpif - Table Miss - resubmit and OFPTC_TABLE_MISS_CONTINUE ok
-747: ofproto-dpif - Table Miss - OFPTC_TABLE_MISS_DROP ok
-748: ofproto-dpif - Table Miss - goto table and OFPTC_TABLE_MISS_DROP ok
-749: ofproto-dpif - Table Miss - resubmit and OFPTC_TABLE_MISS_DROP ok
-750: ofproto-dpif - controller                       ok
-751: ofproto-dpif - table-miss flow (OpenFlow 1.0)   ok
-752: ofproto-dpif - table-miss flow (OpenFlow 1.3)   ok
-753: ofproto-dpif - ARP modification slow-path       ok
-754: ofproto-dpif - VLAN handling                    ok
-755: ofproto-dpif - MPLS handling                    ok
-756: ofproto-dpif - VLAN+MPLS handling               ok
-757: ofproto-dpif - fragment handling                ok
-758: ofproto-dpif - exit                             ok
-759: ofproto-dpif - mirroring, select_all            ok
-760: ofproto-dpif - mirroring, select_src            ok
-761: ofproto-dpif - mirroring, OFPP_NONE ingress port ok
-762: ofproto-dpif - mirroring, select_dst            ok
-763: ofproto-dpif - mirroring, select_vlan           ok
-764: ofproto-dpif - mirroring, output_port           ok
-765: ofproto-dpif - mirroring, output_vlan           ok
-766: ofproto-dpif - ofproto/trace command 1          ok
-767: ofproto-dpif - ofproto/trace command 2          ok
-768: ofproto-dpif - ofproto/trace-packet-out         ok
-769: ofproto-dpif - MAC learning                     ok
-770: ofproto-dpif - MAC table overflow               ok
-771: ofproto-dpif - sFlow packet sampling - IPv4 collector FAILED (ofproto-dpif.at:3345)
-772: ofproto-dpif - sFlow packet sampling - IPv6 collector FAILED (ofproto-dpif.at:3346)
-773: ofproto-dpif - NetFlow flow expiration - IPv4 collector ok
-774: ofproto-dpif - NetFlow flow expiration - IPv6 collector ok
-775: ofproto-dpif - NetFlow active expiration - IPv4 collector ok
-776: ofproto-dpif - NetFlow active expiration - IPv6 collector ok
-777: ofproto-dpif - flow stats                       ok
-778: ofproto-dpif - flow stats, set-n-threads        ok
-779: idle_age and hard_age increase over time        ok
-780: ofproto-dpif - fin_timeout                      ok
-781: ofproto-dpif - ovs-appctl dpif/dump-dps         ok
-782: ofproto-dpif - ovs-appctl dpif/show             ok
-783: ofproto-dpif - ovs-appctl dpif/dump-flows       ok
-784: ofproto-dpif - MPLS actions that result in a userspace action ok
-785: ofproto-dpif - MPLS actions that result in a drop ok
-786: ofproto-dpif - patch ports                      ok
-787: ofproto-dpif - port duration                    ok
+717: ofproto-dpif, balance-tcp bonding, different recirc flow  ok
+718: ofproto-dpif - resubmit                         ok
+719: ofproto-dpif - goto table                       ok
+720: ofproto-dpif - write actions                    ok
+721: ofproto-dpif - clear actions                    ok
+722: ofproto-dpif - group chaining not supported     ok
+723: ofproto-dpif - all group in action list         ok
+724: ofproto-dpif - indirect group in action list    ok
+725: ofproto-dpif - group actions have no effect afterwards ok
+726: ofproto-dpif - all group in action set          ok
+727: ofproto-dpif - indirect group in action set     ok
+728: ofproto-dpif - select group                     ok
+729: ofproto-dpif - select group with watch port     ok
+730: ofproto-dpif - select group with weight         ok
+731: ofproto-dpif - fast failover group              ok
+732: ofproto-dpif - registers                        ok
+733: ofproto-dpif - push-pop                         ok
+734: ofproto-dpif - output                           ok
+735: ofproto-dpif - dec_ttl                          ok
+736: ofproto-dpif - dec_ttl without arguments at offset 32 in ofpacts ok
+737: ofproto-dpif - dec_ttl with arguments at offset 32 in ofpacts ok
+738: ofproto-dpif - note at offset 24 in ofpacts     ok
+739: ofproto-dpif - output, OFPP_NONE ingress port   ok
+740: ofproto-dpif - DSCP                             ok
+741: ofproto-dpif - output/flood flags               ok
+742: ofproto-dpif - Default Table Miss - OF1.0 (OFPTC_TABLE_MISS_CONTROLLER) ok
+743: ofproto-dpif - Default Table Miss - OF1.3 (OFPTC_TABLE_MISS_DROP) ok
+744: ofproto-dpif - Table Miss - goto table and OFPTC_TABLE_MISS_CONTROLLER ok
+745: ofproto-dpif - Table Miss - resubmit and OFPTC_TABLE_MISS_CONTROLLER ok
+746: ofproto-dpif - Table Miss - OFPTC_TABLE_MISS_CONTINUE ok
+747: ofproto-dpif - Table Miss - goto table and OFPTC_TABLE_MISS_CONTINUE ok
+748: ofproto-dpif - Table Miss - resubmit and OFPTC_TABLE_MISS_CONTINUE ok
+749: ofproto-dpif - Table Miss - OFPTC_TABLE_MISS_DROP ok
+750: ofproto-dpif - Table Miss - goto table and OFPTC_TABLE_MISS_DROP ok
+751: ofproto-dpif - Table Miss - resubmit and OFPTC_TABLE_MISS_DROP ok
+752: ofproto-dpif - controller                       ok
+753: ofproto-dpif - table-miss flow (OpenFlow 1.0)   ok
+754: ofproto-dpif - table-miss flow (OpenFlow 1.3)   ok
+755: ofproto-dpif - ARP modification slow-path       ok
+756: ofproto-dpif - VLAN handling                    ok
+757: ofproto-dpif - MPLS handling                    ok
+758: ofproto-dpif - VLAN+MPLS handling               ok
+759: ofproto-dpif - fragment handling                ok
+760: ofproto-dpif - exit                             ok
+761: ofproto-dpif - mirroring, select_all            ok
+762: ofproto-dpif - mirroring, select_src            ok
+763: ofproto-dpif - mirroring, OFPP_NONE ingress port ok
+764: ofproto-dpif - mirroring, select_dst            ok
+765: ofproto-dpif - mirroring, select_vlan           ok
+766: ofproto-dpif - mirroring, output_port           ok
+767: ofproto-dpif - mirroring, output_vlan           ok
+768: ofproto-dpif - ofproto/trace command 1          ok
+769: ofproto-dpif - ofproto/trace command 2          ok
+770: ofproto-dpif - ofproto/trace-packet-out         ok
+771: ofproto-dpif - MAC learning                     ok
+772: ofproto-dpif - MAC table overflow               ok
+773: ofproto-dpif - MAC table overflow fairness      ok
+774: ofproto-dpif - sFlow packet sampling - IPv4 collector FAILED (ofproto-dpif.at:3489)
+775: ofproto-dpif - sFlow packet sampling - IPv6 collector FAILED (ofproto-dpif.at:3490)
+776: ofproto-dpif - NetFlow flow expiration - IPv4 collector ok
+777: ofproto-dpif - NetFlow flow expiration - IPv6 collector ok
+778: ofproto-dpif - NetFlow active expiration - IPv4 collector ok
+779: ofproto-dpif - NetFlow active expiration - IPv6 collector ok
+780: ofproto-dpif - flow stats                       ok
+781: ofproto-dpif - flow stats, set-n-threads        ok
+782: idle_age and hard_age increase over time        ok
+783: ofproto-dpif - fin_timeout                      ok
+784: ofproto-dpif - ovs-appctl dpif/dump-dps         ok
+785: ofproto-dpif - ovs-appctl dpif/show             ok
+786: ofproto-dpif - ovs-appctl dpif/dump-flows       ok
+787: ofproto-dpif - MPLS actions that result in a userspace action ok
+788: ofproto-dpif - MPLS actions that result in a drop ok
+789: ofproto-dpif - patch ports                      ok
+790: ofproto-dpif - port duration                    ok
 
 ofproto-dpif -- megaflows
 
-788: ofproto-dpif megaflow - port classification     ok
-789: ofproto-dpif megaflow - L2 classification       ok
-790: ofproto-dpif megaflow - L3 classification       ok
-791: ofproto-dpif megaflow - IPv6 classification     ok
-792: ofproto-dpif megaflow - L4 classification       ok
-793: ofproto-dpif megaflow - normal                  ok
-794: ofproto-dpif megaflow - mpls                    ok
-795: ofproto-dpif megaflow - netflow - IPv4 collector ok
-796: ofproto-dpif megaflow - netflow - IPv6 collector ok
-797: ofproto-dpif megaflow - normal, active-backup bonding ok
-798: ofproto-dpif megaflow - normal, balance-slb bonding ok
-799: ofproto-dpif megaflow - normal, balance-tcp bonding ok
-800: ofproto-dpif megaflow - resubmit port action    ok
-801: ofproto-dpif megaflow - resubmit table action   ok
-802: ofproto-dpif megaflow - goto_table action       ok
-803: ofproto-dpif megaflow - mirroring, select_all   ok
-804: ofproto-dpif megaflow - mirroring, select_vlan  ok
-805: ofproto-dpif megaflow - move action             ok
-806: ofproto-dpif megaflow - push action             ok
-807: ofproto-dpif megaflow - learning                ok
-808: ofproto-dpif megaflow - tunnels                 FAILED (ofproto-dpif.at:4302)
-809: ofproto-dpif megaflow - dec_ttl                 ok
-810: ofproto-dpif megaflow - set dl_dst              ok
-811: ofproto-dpif megaflow - disabled                ok
-812: ofproto-dpif - datapath port number change      ok
-813: ofproto - bundle with variable bfd/cfm config   ok
-814: ofproto-dpif - ofproto-dpif-monitor 1           FAILED (ofproto-dpif.at:4510)
-815: ofproto-dpif - ofproto-dpif-monitor 2           FAILED (ofproto-dpif.at:4561)
+791: ofproto-dpif megaflow - port classification     ok
+792: ofproto-dpif megaflow - L2 classification       ok
+793: ofproto-dpif megaflow - L3 classification       ok
+794: ofproto-dpif megaflow - IPv6 classification     ok
+795: ofproto-dpif megaflow - L4 classification       ok
+796: ofproto-dpif megaflow - normal                  ok
+797: ofproto-dpif megaflow - mpls                    ok
+798: ofproto-dpif megaflow - netflow - IPv4 collector ok
+799: ofproto-dpif megaflow - netflow - IPv6 collector ok
+800: ofproto-dpif megaflow - normal, active-backup bonding ok
+801: ofproto-dpif megaflow - normal, balance-slb bonding ok
+802: ofproto-dpif megaflow - normal, balance-tcp bonding ok
+803: ofproto-dpif megaflow - resubmit port action    ok
+804: ofproto-dpif megaflow - resubmit table action   ok
+805: ofproto-dpif megaflow - goto_table action       ok
+806: ofproto-dpif megaflow - mirroring, select_all   ok
+807: ofproto-dpif megaflow - mirroring, select_vlan  ok
+808: ofproto-dpif megaflow - move action             ok
+809: ofproto-dpif megaflow - push action             ok
+810: ofproto-dpif megaflow - learning                ok
+811: ofproto-dpif megaflow - tunnels                 FAILED (ofproto-dpif.at:4446)
+812: ofproto-dpif megaflow - dec_ttl                 ok
+813: ofproto-dpif megaflow - set dl_dst              ok
+814: ofproto-dpif megaflow - disabled                ok
+815: ofproto-dpif - datapath port number change      ok
+816: ofproto - bundle with variable bfd/cfm config   ok
+817: ofproto-dpif - ofproto-dpif-monitor 1           FAILED (ofproto-dpif.at:4654)
+818: ofproto-dpif - ofproto-dpif-monitor 2           FAILED (ofproto-dpif.at:4705)
 
 ofproto-dpif - flow translation resource limits
 
-816: ofproto-dpif - infinite resubmit                ok
-817: ofproto-dpif - exponential resubmit chain       ok
-818: ofproto-dpif - too many output actions          ok
-819: ofproto-dpif - stack too deep                   ok
-820: ofproto-dpif - ICMPv6                           ok
+819: ofproto-dpif - infinite resubmit                ok
+820: ofproto-dpif - exponential resubmit chain       ok
+821: ofproto-dpif - too many output actions          ok
+822: ofproto-dpif - stack too deep                   ok
+823: ofproto-dpif - ICMPv6                           ok
+824: ofproto-dpif - vlan matching                    ok
 
 VLAN splinters
 
-821: VLAN splinters                                  ok
+825: VLAN splinters                                  ok
 
 OVSDB -- logging
 
-822: create empty, reread                            ok
-823: write one, reread                               ok
-824: check that create fails if file exists          ok
-825: write one, reread                               ok
-826: write one, reread, append                       ok
-827: write, reread one, overwrite                    ok
-828: write, add corrupted data, read                 ok
-829: write, add corrupted data, read, overwrite      ok
-830: write, corrupt some data, read, overwrite       ok
-831: write, truncate file, read, overwrite           ok
-832: write bad JSON, read, overwrite                 ok
+826: create empty, reread                            ok
+827: write one, reread                               ok
+828: check that create fails if file exists          ok
+829: write one, reread                               ok
+830: write one, reread, append                       ok
+831: write, reread one, overwrite                    ok
+832: write, add corrupted data, read                 ok
+833: write, add corrupted data, read, overwrite      ok
+834: write, corrupt some data, read, overwrite       ok
+835: write, truncate file, read, overwrite           ok
+836: write bad JSON, read, overwrite                 ok
 
 OVSDB -- atomic types
 
-833: integer - C                                     ok
-834: integer - Python                                ok
-835: real - C                                        ok
-836: real - Python                                   ok
-837: boolean - C                                     ok
-838: boolean - Python                                ok
-839: string - C                                      ok
-840: string - Python                                 ok
-841: uuid - C                                        ok
-842: uuid - Python                                   ok
-843: void is not a valid atomic-type - C             ok
-844: void is not a valid atomic-type - Python        ok
+837: integer - C                                     ok
+838: integer - Python                                ok
+839: real - C                                        ok
+840: real - Python                                   ok
+841: boolean - C                                     ok
+842: boolean - Python                                ok
+843: string - C                                      ok
+844: string - Python                                 ok
+845: uuid - C                                        ok
+846: uuid - Python                                   ok
+847: void is not a valid atomic-type - C             ok
+848: void is not a valid atomic-type - Python        ok
 
 OVSDB -- base types
 
-845: integer enum - C                                ok
-846: integer enum - Python                           ok
-847: integer >= 5 - C                                ok
-848: integer >= 5 - Python                           ok
-849: integer <= 7 - C                                ok
-850: integer <= 7 - Python                           ok
-851: integer between -5 and 10 - C                   ok
-852: integer between -5 and 10 - Python              ok
-853: integer max may not be less than min - C        ok
-854: integer max may not be less than min - Python   ok
-855: real enum - C                                   ok
-856: real enum - Python                              ok
-857: real >= -1.5 - C                                ok
-858: real >= -1.5 - Python                           ok
-859: real <= 1e5 - C                                 ok
-860: real <= 1e5 - Python                            ok
-861: real between -2.5 and 3.75 - C                  ok
-862: real between -2.5 and 3.75 - Python             ok
-863: real max may not be less than min - C           ok
-864: real max may not be less than min - Python      ok
-865: boolean - C                                     ok
-866: boolean - Python                                ok
-867: boolean enum - C                                ok
-868: boolean enum - Python                           ok
-869: string enum - C                                 ok
-870: string enum - Python                            ok
-871: string minLength - C                            ok
-872: string minLength - Python                       ok
-873: string maxLength - C                            ok
-874: string maxLength - Python                       ok
-875: string minLength and maxLength - C              ok
-876: string minLength and maxLength - Python         ok
-877: maxLength must not be less than minLength - C   ok
-878: maxLength must not be less than minLength - Python ok
-879: maxLength must not be negative - C              ok
-880: maxLength must not be negative - Python         ok
-881: uuid enum - C                                   ok
-882: uuid enum - Python                              ok
-883: uuid refTable - C                               ok
-884: uuid refTable - Python                          ok
-885: uuid refTable must be valid id - C              ok
-886: uuid refTable must be valid id - Python         ok
-887: void is not a valid base-type - C               ok
-888: void is not a valid base-type - Python          ok
-889: "type" member must be present - C               ok
-890: "type" member must be present - Python          ok
+849: integer enum - C                                ok
+850: integer enum - Python                           ok
+851: integer >= 5 - C                                ok
+852: integer >= 5 - Python                           ok
+853: integer <= 7 - C                                ok
+854: integer <= 7 - Python                           ok
+855: integer between -5 and 10 - C                   ok
+856: integer between -5 and 10 - Python              ok
+857: integer max may not be less than min - C        ok
+858: integer max may not be less than min - Python   ok
+859: real enum - C                                   ok
+860: real enum - Python                              ok
+861: real >= -1.5 - C                                ok
+862: real >= -1.5 - Python                           ok
+863: real <= 1e5 - C                                 ok
+864: real <= 1e5 - Python                            ok
+865: real between -2.5 and 3.75 - C                  ok
+866: real between -2.5 and 3.75 - Python             ok
+867: real max may not be less than min - C           ok
+868: real max may not be less than min - Python      ok
+869: boolean - C                                     ok
+870: boolean - Python                                ok
+871: boolean enum - C                                ok
+872: boolean enum - Python                           ok
+873: string enum - C                                 ok
+874: string enum - Python                            ok
+875: string minLength - C                            ok
+876: string minLength - Python                       ok
+877: string maxLength - C                            ok
+878: string maxLength - Python                       ok
+879: string minLength and maxLength - C              ok
+880: string minLength and maxLength - Python         ok
+881: maxLength must not be less than minLength - C   ok
+882: maxLength must not be less than minLength - Python ok
+883: maxLength must not be negative - C              ok
+884: maxLength must not be negative - Python         ok
+885: uuid enum - C                                   ok
+886: uuid enum - Python                              ok
+887: uuid refTable - C                               ok
+888: uuid refTable - Python                          ok
+889: uuid refTable must be valid id - C              ok
+890: uuid refTable must be valid id - Python         ok
+891: void is not a valid base-type - C               ok
+892: void is not a valid base-type - Python          ok
+893: "type" member must be present - C               ok
+894: "type" member must be present - Python          ok
 
 OVSDB -- simple types
 
-891: simple integer - C                              ok
-892: simple integer - Python                         ok
-893: simple real - C                                 ok
-894: simple real - Python                            ok
-895: simple boolean - C                              ok
-896: simple boolean - Python                         ok
-897: simple string - C                               ok
-898: simple string - Python                          ok
-899: simple uuid - C                                 ok
-900: simple uuid - Python                            ok
-901: integer in object - C                           ok
-902: integer in object - Python                      ok
-903: real in object with explicit min and max - C    ok
-904: real in object with explicit min and max - Python ok
-905: key type is required - C                        ok
-906: key type is required - Python                   ok
-907: void is not a valid type - C                    ok
-908: void is not a valid type - Python               ok
+895: simple integer - C                              ok
+896: simple integer - Python                         ok
+897: simple real - C                                 ok
+898: simple real - Python                            ok
+899: simple boolean - C                              ok
+900: simple boolean - Python                         ok
+901: simple string - C                               ok
+902: simple string - Python                          ok
+903: simple uuid - C                                 ok
+904: simple uuid - Python                            ok
+905: integer in object - C                           ok
+906: integer in object - Python                      ok
+907: real in object with explicit min and max - C    ok
+908: real in object with explicit min and max - Python ok
+909: key type is required - C                        ok
+910: key type is required - Python                   ok
+911: void is not a valid type - C                    ok
+912: void is not a valid type - Python               ok
 
 OVSDB -- set types
 
-909: optional boolean - C                            ok
-910: optional boolean - Python                       ok
-911: set of 1 to 3 uuids - C                         ok
-912: set of 1 to 3 uuids - Python                    ok
-913: set of 0 to 3 strings - C                       ok
-914: set of 0 to 3 strings - Python                  ok
-915: set of 0 or more integers - C                   ok
-916: set of 0 or more integers - Python              ok
-917: set of 1 or more reals - C                      ok
-918: set of 1 or more reals - Python                 ok
-919: set max cannot be less than min - C             ok
-920: set max cannot be less than min - Python        ok
-921: set max cannot be negative - C                  ok
-922: set max cannot be negative - Python             ok
-923: set min cannot be negative - C                  ok
-924: set min cannot be negative - Python             ok
-925: set min cannot be greater than one - C          ok
-926: set min cannot be greater than one - Python     ok
+913: optional boolean - C                            ok
+914: optional boolean - Python                       ok
+915: set of 1 to 3 uuids - C                         ok
+916: set of 1 to 3 uuids - Python                    ok
+917: set of 0 to 3 strings - C                       ok
+918: set of 0 to 3 strings - Python                  ok
+919: set of 0 or more integers - C                   ok
+920: set of 0 or more integers - Python              ok
+921: set of 1 or more reals - C                      ok
+922: set of 1 or more reals - Python                 ok
+923: set max cannot be less than min - C             ok
+924: set max cannot be less than min - Python        ok
+925: set max cannot be negative - C                  ok
+926: set max cannot be negative - Python             ok
+927: set min cannot be negative - C                  ok
+928: set min cannot be negative - Python             ok
+929: set min cannot be greater than one - C          ok
+930: set min cannot be greater than one - Python     ok
 
 OVSDB -- map types
 
-927: map of 1 integer to boolean - C                 ok
-928: map of 1 integer to boolean - Python            ok
-929: map of 1 boolean to integer, explicit min and max - C ok
-930: map of 1 boolean to integer, explicit min and max - Python ok
-931: map of 1 to 5 uuid to real - C                  ok
-932: map of 1 to 5 uuid to real - Python             ok
-933: map of 0 to 10 string to uuid - C               ok
-934: map of 0 to 10 string to uuid - Python          ok
-935: map of 1 to 20 real to string - C               ok
-936: map of 1 to 20 real to string - Python          ok
-937: map of 0 or more string to real - C             ok
-938: map of 0 or more string to real - Python        ok
-939: map key type is required - C                    ok
-940: map key type is required - Python               ok
+931: map of 1 integer to boolean - C                 ok
+932: map of 1 integer to boolean - Python            ok
+933: map of 1 boolean to integer, explicit min and max - C ok
+934: map of 1 boolean to integer, explicit min and max - Python ok
+935: map of 1 to 5 uuid to real - C                  ok
+936: map of 1 to 5 uuid to real - Python             ok
+937: map of 0 to 10 string to uuid - C               ok
+938: map of 0 to 10 string to uuid - Python          ok
+939: map of 1 to 20 real to string - C               ok
+940: map of 1 to 20 real to string - Python          ok
+941: map of 0 or more string to real - C             ok
+942: map of 0 or more string to real - Python        ok
+943: map key type is required - C                    ok
+944: map key type is required - Python               ok
 
 OVSDB -- default values
 
-941: default atoms - C                               ok
-942: default atoms - Python                          ok
-943: default data - C                                ok
-944: default data - Python                           ok
+945: default atoms - C                               ok
+946: default atoms - Python                          ok
+947: default data - C                                ok
+948: default data - Python                           ok
 
 OVSDB -- atoms without constraints
 
-945: integer atom from JSON - C                      ok
-946: integer atom from JSON - Python                 ok
-947: integer atom from string                        ok
-948: real atom from JSON - C                         ok
-949: real atom from JSON - Python                    ok
-950: real atom from string                           ok
-951: boolean atom from JSON - C                      ok
-952: boolean atom from JSON - Python                 ok
-953: boolean atom from string                        ok
-954: string atom from JSON - C                       ok
-955: string atom from JSON - Python                  ok
-956: string atom from string                         ok
-957: uuid atom from JSON - C                         ok
-958: uuid atom from JSON - Python                    ok
-959: uuid atom from string                           ok
-960: integer atom sorting - C                        ok
-961: integer atom sorting - Python                   ok
-962: real atom sorting - C                           ok
-963: real atom sorting - Python                      ok
-964: boolean atom sorting - C                        ok
-965: boolean atom sorting - Python                   ok
-966: string atom sorting - C                         ok
-967: string atom sorting - Python                    ok
-968: uuid atom sorting - C                           ok
-969: uuid atom sorting - Python                      ok
-970: real not acceptable integer JSON atom - C       ok
-971: real not acceptable integer JSON atom - Python  ok
-972: no invalid UTF-8 sequences in strings           ok
-973: no invalid UTF-8 sequences in strings - Python  ok
-974: real not acceptable integer string atom         ok
-975: string "true" not acceptable boolean JSON atom - C ok
-976: string "true" not acceptable boolean JSON atom - Python ok
-977: string "true" not acceptable boolean string atom ok
-978: integer not acceptable string JSON atom - C     ok
-979: integer not acceptable string JSON atom - Python ok
-980: uuid atom must be expressed as JSON array - C   ok
-981: uuid atom must be expressed as JSON array - Python ok
-982: named-uuid requires symbol table - C            ok
-983: named-uuid requires symbol table - Python       ok
-984: empty string atom must be quoted                ok
-985: quotes must be balanced                         ok
-986: uuids must be valid                             ok
+949: integer atom from JSON - C                      ok
+950: integer atom from JSON - Python                 ok
+951: integer atom from string                        ok
+952: real atom from JSON - C                         ok
+953: real atom from JSON - Python                    ok
+954: real atom from string                           ok
+955: boolean atom from JSON - C                      ok
+956: boolean atom from JSON - Python                 ok
+957: boolean atom from string                        ok
+958: string atom from JSON - C                       ok
+959: string atom from JSON - Python                  ok
+960: string atom from string                         ok
+961: uuid atom from JSON - C                         ok
+962: uuid atom from JSON - Python                    ok
+963: uuid atom from string                           ok
+964: integer atom sorting - C                        ok
+965: integer atom sorting - Python                   ok
+966: real atom sorting - C                           ok
+967: real atom sorting - Python                      ok
+968: boolean atom sorting - C                        ok
+969: boolean atom sorting - Python                   ok
+970: string atom sorting - C                         ok
+971: string atom sorting - Python                    ok
+972: uuid atom sorting - C                           ok
+973: uuid atom sorting - Python                      ok
+974: real not acceptable integer JSON atom - C       ok
+975: real not acceptable integer JSON atom - Python  ok
+976: no invalid UTF-8 sequences in strings           ok
+977: no invalid UTF-8 sequences in strings - Python  ok
+978: real not acceptable integer string atom         ok
+979: string "true" not acceptable boolean JSON atom - C ok
+980: string "true" not acceptable boolean JSON atom - Python ok
+981: string "true" not acceptable boolean string atom ok
+982: integer not acceptable string JSON atom - C     ok
+983: integer not acceptable string JSON atom - Python ok
+984: uuid atom must be expressed as JSON array - C   ok
+985: uuid atom must be expressed as JSON array - Python ok
+986: named-uuid requires symbol table - C            ok
+987: named-uuid requires symbol table - Python       ok
+988: empty string atom must be quoted                ok
+989: quotes must be balanced                         ok
+990: quoted string must not contain unescaped quote  ok
+991: quoted string must not end with backslash       ok
+992: uuids must be valid                             ok
 
 OVSDB -- atoms with enum constraints
 
-987: integer atom enum - C                           ok
-988: integer atom enum - Python                      ok
-989: real atom enum - C                              ok
-990: real atom enum - Python                         ok
-991: boolean atom enum - C                           ok
-992: boolean atom enum - Python                      ok
-993: string atom enum - C                            ok
-994: string atom enum - Python                       ok
-995: uuid atom enum - C                              ok
-996: uuid atom enum - Python                         ok
+993: integer atom enum - C                           ok
+994: integer atom enum - Python                      ok
+995: real atom enum - C                              ok
+996: real atom enum - Python                         ok
+997: boolean atom enum - C                           ok
+998: boolean atom enum - Python                      ok
+999: string atom enum - C                            ok
+1000: string atom enum - Python                       ok
+1001: uuid atom enum - C                              ok
+1002: uuid atom enum - Python                         ok
 
 OVSDB -- atoms with other constraints
 
-997: integers >= 5 - C                               ok
-998: integers >= 5 - Python                          ok
-999: integers <= -1 - C                              ok
-1000: integers <= -1 - Python                         ok
-1001: integers in range -10 to 10 - C                 ok
-1002: integers in range -10 to 10 - Python            ok
-1003: reals >= 5 - C                                  ok
-1004: reals >= 5 - Python                             ok
-1005: reals <= -1 - C                                 ok
-1006: reals <= -1 - Python                            ok
-1007: reals in range -10 to 10 - C                    ok
-1008: reals in range -10 to 10 - Python               ok
-1009: strings at least 2 characters long - C          ok
-1010: strings at least 2 characters long - Python     skipped (ovsdb-data.at:458)
-1011: strings no more than 2 characters long - C      ok
-1012: strings no more than 2 characters long - Python ok
+1003: integers >= 5 - C                               ok
+1004: integers >= 5 - Python                          ok
+1005: integers <= -1 - C                              ok
+1006: integers <= -1 - Python                         ok
+1007: integers in range -10 to 10 - C                 ok
+1008: integers in range -10 to 10 - Python            ok
+1009: reals >= 5 - C                                  ok
+1010: reals >= 5 - Python                             ok
+1011: reals <= -1 - C                                 ok
+1012: reals <= -1 - Python                            ok
+1013: reals in range -10 to 10 - C                    ok
+1014: reals in range -10 to 10 - Python               ok
+1015: strings at least 2 characters long - C          ok
+1016: strings at least 2 characters long - Python     skipped (ovsdb-data.at:466)
+1017: strings no more than 2 characters long - C      ok
+1018: strings no more than 2 characters long - Python ok
 
 OSVDB -- simple data
 
-1013: integer JSON datum - C                          ok
-1014: integer JSON datum - Python                     ok
-1015: integer string datum                            ok
-1016: real JSON datum - C                             ok
-1017: real JSON datum - Python                        ok
-1018: real string datum                               ok
-1019: boolean JSON datum - C                          ok
-1020: boolean JSON datum - Python                     ok
-1021: boolean string datum                            ok
-1022: string JSON datum - C                           ok
-1023: string JSON datum - Python                      ok
-1024: string string datum                             ok
+1019: integer JSON datum - C                          ok
+1020: integer JSON datum - Python                     ok
+1021: integer string datum                            ok
+1022: real JSON datum - C                             ok
+1023: real JSON datum - Python                        ok
+1024: real string datum                               ok
+1025: boolean JSON datum - C                          ok
+1026: boolean JSON datum - Python                     ok
+1027: boolean string datum                            ok
+1028: string JSON datum - C                           ok
+1029: string JSON datum - Python                      ok
+1030: string string datum                             ok
 
 OVSDB -- set data
 
-1025: JSON optional boolean - C                       ok
-1026: JSON optional boolean - Python                  ok
-1027: string optional boolean                         ok
-1028: JSON set of 0 or more integers - C              ok
-1029: JSON set of 0 or more integers - Python         ok
-1030: string set of 0 or more integers                ok
-1031: JSON set of 1 to 3 uuids - C                    ok
-1032: JSON set of 1 to 3 uuids - Python               ok
-1033: string set of 1 to 3 uuids                      ok
-1034: JSON set of 0 to 3 strings - C                  ok
-1035: JSON set of 0 to 3 strings - Python             ok
-1036: string set of 0 to 3 strings                    ok
-1037: duplicate boolean not allowed in JSON set - C   ok
-1038: duplicate boolean not allowed in JSON set - Python ok
-1039: duplicate boolean not allowed in string set     ok
-1040: duplicate integer not allowed in JSON set - C   ok
-1041: duplicate integer not allowed in JSON set - Python ok
-1042: duplicate integer not allowed in string set     ok
-1043: duplicate real not allowed in JSON set - C      ok
-1044: duplicate real not allowed in JSON set - Python ok
-1045: duplicate real not allowed in string set        ok
-1046: duplicate string not allowed in JSON set - C    ok
-1047: duplicate string not allowed in JSON set - Python ok
-1048: duplicate string not allowed in string set      ok
-1049: duplicate uuid not allowed in JSON set - C      ok
-1050: duplicate uuid not allowed in JSON set - Python ok
-1051: duplicate uuid not allowed in string set        ok
+1031: JSON optional boolean - C                       ok
+1032: JSON optional boolean - Python                  ok
+1033: string optional boolean                         ok
+1034: JSON set of 0 or more integers - C              ok
+1035: JSON set of 0 or more integers - Python         ok
+1036: string set of 0 or more integers                ok
+1037: JSON set of 1 to 3 uuids - C                    ok
+1038: JSON set of 1 to 3 uuids - Python               ok
+1039: string set of 1 to 3 uuids                      ok
+1040: JSON set of 0 to 3 strings - C                  ok
+1041: JSON set of 0 to 3 strings - Python             ok
+1042: string set of 0 to 3 strings                    ok
+1043: duplicate boolean not allowed in JSON set - C   ok
+1044: duplicate boolean not allowed in JSON set - Python ok
+1045: duplicate boolean not allowed in string set     ok
+1046: duplicate integer not allowed in JSON set - C   ok
+1047: duplicate integer not allowed in JSON set - Python ok
+1048: duplicate integer not allowed in string set     ok
+1049: duplicate real not allowed in JSON set - C      ok
+1050: duplicate real not allowed in JSON set - Python ok
+1051: duplicate real not allowed in string set        ok
+1052: duplicate string not allowed in JSON set - C    ok
+1053: duplicate string not allowed in JSON set - Python ok
+1054: duplicate string not allowed in string set      ok
+1055: duplicate uuid not allowed in JSON set - C      ok
+1056: duplicate uuid not allowed in JSON set - Python ok
+1057: duplicate uuid not allowed in string set        ok
 
 OVSDB -- map data
 
-1052: JSON map of 1 integer to boolean - C            ok
-1053: JSON map of 1 integer to boolean - Python       ok
-1054: string map of 1 integer to boolean              ok
-1055: JSON map of at least 1 integer to boolean - C   ok
-1056: JSON map of at least 1 integer to boolean - Python ok
-1057: string map of at least 1 integer to boolean     ok
-1058: JSON map of 1 boolean to integer - C            ok
-1059: JSON map of 1 boolean to integer - Python       ok
-1060: string map of 1 boolean to integer              ok
-1061: JSON map of 1 uuid to real - C                  ok
-1062: JSON map of 1 uuid to real - Python             ok
-1063: string map of 1 uuid to real                    ok
-1064: JSON map of 10 string to string - C             ok
-1065: JSON map of 10 string to string - Python        ok
-1066: string map of 10 string to string               ok
-1067: duplicate integer key not allowed in JSON map - C ok
-1068: duplicate integer key not allowed in JSON map - Python ok
-1069: duplicate integer key not allowed in string map ok
+1058: JSON map of 1 integer to boolean - C            ok
+1059: JSON map of 1 integer to boolean - Python       ok
+1060: string map of 1 integer to boolean              ok
+1061: JSON map of at least 1 integer to boolean - C   ok
+1062: JSON map of at least 1 integer to boolean - Python ok
+1063: string map of at least 1 integer to boolean     ok
+1064: JSON map of 1 boolean to integer - C            ok
+1065: JSON map of 1 boolean to integer - Python       ok
+1066: string map of 1 boolean to integer              ok
+1067: JSON map of 1 uuid to real - C                  ok
+1068: JSON map of 1 uuid to real - Python             ok
+1069: string map of 1 uuid to real                    ok
+1070: JSON map of 10 string to string - C             ok
+1071: JSON map of 10 string to string - Python        ok
+1072: string map of 10 string to string               ok
+1073: duplicate integer key not allowed in JSON map - C ok
+1074: duplicate integer key not allowed in JSON map - Python ok
+1075: duplicate integer key not allowed in string map ok
 
 OVSDB -- columns
 
-1070: ordinary column - C                             ok
-1071: ordinary column - Python                        ok
-1072: immutable column - C                            ok
-1073: immutable column - Python                       ok
-1074: ephemeral column - C                            ok
-1075: ephemeral column - Python                       ok
+1076: ordinary column - C                             ok
+1077: ordinary column - Python                        ok
+1078: immutable column - C                            ok
+1079: immutable column - Python                       ok
+1080: ephemeral column - C                            ok
+1081: ephemeral column - Python                       ok
 
 OVSDB -- tables
 
-1076: non-root table with one column - C              ok
-1077: non-root table with one column - Python         ok
-1078: immutable table with one column - C             ok
-1079: immutable table with one column - Python        ok
-1080: root table with one column - C                  ok
-1081: root table with one column - Python             ok
-1082: non-root table with default_is_root=true - C    ok
-1083: non-root table with default_is_root=true - Python ok
-1084: root table with default_is_root=true - C        ok
-1085: root table with default_is_root=true - Python   ok
-1086: table with maxRows of 2 - C                     ok
-1087: table with maxRows of 2 - Python                ok
-1088: table with index - C                            ok
-1089: table with index - Python                       ok
-1090: table with syntax error in index - C            ok
-1091: table with syntax error in index - Python       ok
-1092: table with empty index - C                      ok
-1093: table with empty index - Python                 ok
-1094: table with index of ephemeral column - C        ok
-1095: table with index of ephemeral column - Python   ok
-1096: column names may not begin with _ - C           ok
-1097: column names may not begin with _ - Python      ok
-1098: table must have at least one column (1) - C     ok
-1099: table must have at least one column (1) - Python ok
-1100: table must have at least one column (2) - C     ok
-1101: table must have at least one column (2) - Python ok
-1102: table maxRows must be positive - C              ok
-1103: table maxRows must be positive - Python         ok
+1082: non-root table with one column - C              ok
+1083: non-root table with one column - Python         ok
+1084: immutable table with one column - C             ok
+1085: immutable table with one column - Python        ok
+1086: root table with one column - C                  ok
+1087: root table with one column - Python             ok
+1088: non-root table with default_is_root=true - C    ok
+1089: non-root table with default_is_root=true - Python ok
+1090: root table with default_is_root=true - C        ok
+1091: root table with default_is_root=true - Python   ok
+1092: table with maxRows of 2 - C                     ok
+1093: table with maxRows of 2 - Python                ok
+1094: table with index - C                            ok
+1095: table with index - Python                       ok
+1096: table with syntax error in index - C            ok
+1097: table with syntax error in index - Python       ok
+1098: table with empty index - C                      ok
+1099: table with empty index - Python                 ok
+1100: table with index of ephemeral column - C        ok
+1101: table with index of ephemeral column - Python   ok
+1102: column names may not begin with _ - C           ok
+1103: column names may not begin with _ - Python      ok
+1104: table must have at least one column (1) - C     ok
+1105: table must have at least one column (1) - Python ok
+1106: table must have at least one column (2) - C     ok
+1107: table must have at least one column (2) - Python ok
+1108: table maxRows must be positive - C              ok
+1109: table maxRows must be positive - Python         ok
 
 OVSDB -- rows
 
-1104: row with one string column                      ok
-1105: row with one integer column                     ok
-1106: row with one real column                        ok
-1107: row with one boolean column                     ok
-1108: row with one uuid column                        ok
-1109: row with set of 1 to 2 elements                 ok
-1110: row with map of 1 to 2 elements                 ok
-1111: row with several columns                        ok
-1112: row hashing (scalars)                           ok
-1113: row hashing (sets)                              ok
-1114: row hashing (maps)                              ok
+1110: row with one string column                      ok
+1111: row with one integer column                     ok
+1112: row with one real column                        ok
+1113: row with one boolean column                     ok
+1114: row with one uuid column                        ok
+1115: row with set of 1 to 2 elements                 ok
+1116: row with map of 1 to 2 elements                 ok
+1117: row with several columns                        ok
+1118: row hashing (scalars)                           ok
+1119: row hashing (sets)                              ok
+1120: row hashing (maps)                              ok
 
 OVSDB -- schemas
 
-1115: schema with valid refTables - C                 ok
-1116: schema with valid refTables - Python            ok
-1117: schema with ephemeral strong references - C     ok
-1118: schema with ephemeral strong references - Python ok
-1119: schema without version number - C               ok
-1120: schema without version number - Python          ok
-1121: schema with invalid refTables - C               ok
-1122: schema with invalid refTables - Python          ok
-1123: schema with invalid version number - C          ok
-1124: schema with invalid version number - Python     ok
+1121: schema with valid refTables - C                 ok
+1122: schema with valid refTables - Python            ok
+1123: schema with ephemeral strong references - C     ok
+1124: schema with ephemeral strong references - Python ok
+1125: schema without version number - C               ok
+1126: schema without version number - Python          ok
+1127: schema with invalid refTables - C               ok
+1128: schema with invalid refTables - Python          ok
+1129: schema with invalid version number - C          ok
+1130: schema with invalid version number - Python     ok
 
 OVSDB -- conditions
 
-1125: null condition                                  ok
-1126: conditions on scalars                           ok
-1127: disallowed conditions on scalars                ok
-1128: conditions on sets                              ok
-1129: condition sorting                               ok
-1130: evaluating null condition                       ok
-1131: evaluating conditions on integers               ok
-1132: evaluating conditions on reals                  ok
-1133: evaluating conditions on booleans               ok
-1134: evaluating conditions on strings                ok
-1135: evaluating conditions on UUIDs                  ok
-1136: evaluating conditions on sets                   ok
-1137: evaluating conditions on maps (1)               ok
-1138: evaluating conditions on maps (2)               ok
+1131: null condition                                  ok
+1132: conditions on scalars                           ok
+1133: disallowed conditions on scalars                ok
+1134: conditions on sets                              ok
+1135: condition sorting                               ok
+1136: evaluating null condition                       ok
+1137: evaluating conditions on integers               ok
+1138: evaluating conditions on reals                  ok
+1139: evaluating conditions on booleans               ok
+1140: evaluating conditions on strings                ok
+1141: evaluating conditions on UUIDs                  ok
+1142: evaluating conditions on sets                   ok
+1143: evaluating conditions on maps (1)               ok
+1144: evaluating conditions on maps (2)               ok
 
 OVSDB -- mutations
 
-1139: null mutation                                   ok
-1140: mutations on scalars                            ok
-1141: disallowed mutations on scalars                 ok
-1142: disallowed mutations on immutable columns       ok
-1143: mutations on sets                               ok
-1144: executing null mutation                         ok
-1145: executing mutations on integers                 ok
-1146: integer overflow detection                      ok
-1147: executing mutations on integers with constraints ok
-1148: executing mutations on reals                    ok
-1149: real overflow detection                         ok
-1150: executing mutations on reals with constraints   ok
-1151: executing mutations on integer sets             ok
-1152: executing mutations on integer sets with constraints ok
-1153: executing mutations on real sets                ok
-1154: executing mutations on boolean sets             ok
-1155: executing mutations on string sets              ok
-1156: executing mutations on uuid sets                ok
-1157: executing mutations on integer maps             ok
+1145: null mutation                                   ok
+1146: mutations on scalars                            ok
+1147: disallowed mutations on scalars                 ok
+1148: disallowed mutations on immutable columns       ok
+1149: mutations on sets                               ok
+1150: executing null mutation                         ok
+1151: executing mutations on integers                 ok
+1152: integer overflow detection                      ok
+1153: executing mutations on integers with constraints ok
+1154: executing mutations on reals                    ok
+1155: real overflow detection                         ok
+1156: executing mutations on reals with constraints   ok
+1157: executing mutations on integer sets             ok
+1158: executing mutations on integer sets with constraints ok
+1159: executing mutations on real sets                ok
+1160: executing mutations on boolean sets             ok
+1161: executing mutations on string sets              ok
+1162: executing mutations on uuid sets                ok
+1163: executing mutations on integer maps             ok
 
 OVSDB -- queries
 
-1158: queries on scalars                              ok
-1159: queries on sets                                 ok
-1160: queries on maps (1)                             ok
-1161: queries on maps (2)                             ok
-1162: UUID-distinct queries on scalars                ok
-1163: Boolean-distinct queries on scalars             ok
-1164: parse colunn set containing bad name            ok
+1164: queries on scalars                              ok
+1165: queries on sets                                 ok
+1166: queries on maps (1)                             ok
+1167: queries on maps (2)                             ok
+1168: UUID-distinct queries on scalars                ok
+1169: Boolean-distinct queries on scalars             ok
+1170: parse colunn set containing bad name            ok
 
 OVSDB -- transactions
 
-1165: empty table, empty transaction                  ok
-1166: nonempty table, empty transaction               ok
-1167: insert, commit                                  ok
-1168: insert, abort                                   ok
-1169: modify, commit                                  ok
-1170: modify, abort                                   ok
-1171: delete, commit                                  ok
-1172: delete, abort                                   ok
-1173: modify, delete, commit                          ok
-1174: modify, delete, abort                           ok
-1175: insert, delete, commit                          ok
-1176: insert, delete, abort                           ok
-1177: insert, modify, delete, commit                  ok
-1178: insert, modify, delete, abort                   ok
-1179: deletes are aborted cleanly                     ok
+1171: empty table, empty transaction                  ok
+1172: nonempty table, empty transaction               ok
+1173: insert, commit                                  ok
+1174: insert, abort                                   ok
+1175: modify, commit                                  ok
+1176: modify, abort                                   ok
+1177: delete, commit                                  ok
+1178: delete, abort                                   ok
+1179: modify, delete, commit                          ok
+1180: modify, delete, abort                           ok
+1181: insert, delete, commit                          ok
+1182: insert, delete, abort                           ok
+1183: insert, modify, delete, commit                  ok
+1184: insert, modify, delete, abort                   ok
+1185: deletes are aborted cleanly                     ok
 
 OVSDB -- execution
 
-1180: uuid-name must be <id>                          ok
-1181: named-uuid must be <id>                         ok
-1182: duplicate uuid-name not allowed                 ok
-1183: insert default row, query table                 ok
-1184: insert row, query table                         ok
-1185: insert rows, query by value                     ok
-1186: insert rows, query by named-uuid                ok
-1187: insert rows, update rows by value               ok
-1188: insert rows, mutate rows                        ok
-1189: insert rows, delete by named-uuid               ok
-1190: insert rows, delete rows by value               ok
-1191: insert rows, delete by (non-matching) value     ok
-1192: insert rows, delete all                         ok
-1193: insert row, query table, commit                 ok
-1194: insert row, query table, commit durably         ok
-1195: equality wait with correct rows                 ok
-1196: equality wait with extra row                    ok
-1197: equality wait with missing row                  ok
-1198: inequality wait with correct rows               ok
-1199: inequality wait with extra row                  ok
-1200: inequality wait with missing row                ok
-1201: insert and update constraints                   ok
-1202: index uniqueness checking                       ok
-1203: referential integrity -- simple                 ok
-1204: referential integrity -- mutual references      ok
-1205: weak references                                 ok
-1206: immutable columns                               ok
-1207: garbage collection                              ok
+1186: uuid-name must be <id>                          ok
+1187: named-uuid must be <id>                         ok
+1188: duplicate uuid-name not allowed                 ok
+1189: insert default row, query table                 ok
+1190: insert row, query table                         ok
+1191: insert rows, query by value                     ok
+1192: insert rows, query by named-uuid                ok
+1193: insert rows, update rows by value               ok
+1194: insert rows, mutate rows                        ok
+1195: insert rows, delete by named-uuid               ok
+1196: insert rows, delete rows by value               ok
+1197: insert rows, delete by (non-matching) value     ok
+1198: insert rows, delete all                         ok
+1199: insert row, query table, commit                 ok
+1200: insert row, query table, commit durably         ok
+1201: equality wait with correct rows                 ok
+1202: equality wait with extra row                    ok
+1203: equality wait with missing row                  ok
+1204: inequality wait with correct rows               ok
+1205: inequality wait with extra row                  ok
+1206: inequality wait with missing row                ok
+1207: insert and update constraints                   ok
+1208: index uniqueness checking                       ok
+1209: referential integrity -- simple                 ok
+1210: referential integrity -- mutual references      ok
+1211: weak references                                 ok
+1212: immutable columns                               ok
+1213: garbage collection                              ok
 
 OVSDB -- triggers
 
-1208: trigger fires immediately                       ok
-1209: trigger times out                               ok
-1210: trigger fires after delay                       ok
-1211: delayed trigger modifies database               ok
-1212: one delayed trigger wakes up another            ok
+1214: trigger fires immediately                       ok
+1215: trigger times out                               ok
+1216: trigger fires after delay                       ok
+1217: delayed trigger modifies database               ok
+1218: one delayed trigger wakes up another            ok
 
 OVSDB -- ovsdb-tool
 
-1213: insert default row, query table                 ok
-1214: insert row, query table                         ok
-1215: insert rows, query by value                     ok
-1216: insert rows, query by named-uuid                ok
-1217: insert rows, update rows by value               ok
-1218: insert rows, mutate rows                        ok
-1219: insert rows, delete by named-uuid               ok
-1220: insert rows, delete rows by value               ok
-1221: insert rows, delete by (non-matching) value     ok
-1222: insert rows, delete all                         ok
-1223: insert row, query table, commit                 ok
-1224: insert row, query table, commit durably         ok
-1225: equality wait with correct rows                 ok
-1226: equality wait with extra row                    ok
-1227: equality wait with missing row                  ok
-1228: inequality wait with correct rows               ok
-1229: inequality wait with extra row                  ok
-1230: inequality wait with missing row                ok
-1231: insert and update constraints                   ok
-1232: index uniqueness checking                       ok
-1233: referential integrity -- simple                 ok
-1234: referential integrity -- mutual references      ok
-1235: weak references                                 ok
-1236: immutable columns                               ok
-1237: garbage collection                              ok
-1238: transaction comments                            ok
-1239: ovsdb-tool compact                              ok
-1240: ovsdb-tool convert -- removing a column         ok
-1241: ovsdb-tool convert -- adding a column           ok
-1242: ovsdb-tool schema-version                       ok
-1243: ovsdb-tool db-version                           ok
-1244: ovsdb-tool schema-cksum                         ok
-1245: ovsdb-tool db-cksum                             ok
-1246: ovsdb-tool needs-conversion (no conversion needed) ok
-1247: ovsdb-tool needs-conversion (conversion needed) ok
+1219: insert default row, query table                 ok
+1220: insert row, query table                         ok
+1221: insert rows, query by value                     ok
+1222: insert rows, query by named-uuid                ok
+1223: insert rows, update rows by value               ok
+1224: insert rows, mutate rows                        ok
+1225: insert rows, delete by named-uuid               ok
+1226: insert rows, delete rows by value               ok
+1227: insert rows, delete by (non-matching) value     ok
+1228: insert rows, delete all                         ok
+1229: insert row, query table, commit                 ok
+1230: insert row, query table, commit durably         ok
+1231: equality wait with correct rows                 ok
+1232: equality wait with extra row                    ok
+1233: equality wait with missing row                  ok
+1234: inequality wait with correct rows               ok
+1235: inequality wait with extra row                  ok
+1236: inequality wait with missing row                ok
+1237: insert and update constraints                   ok
+1238: index uniqueness checking                       ok
+1239: referential integrity -- simple                 ok
+1240: referential integrity -- mutual references      ok
+1241: weak references                                 ok
+1242: immutable columns                               ok
+1243: garbage collection                              ok
+1244: transaction comments                            ok
+1245: ovsdb-tool compact                              ok
+1246: ovsdb-tool convert -- removing a column         ok
+1247: ovsdb-tool convert -- adding a column           ok
+1248: ovsdb-tool schema-version                       ok
+1249: ovsdb-tool db-version                           ok
+1250: ovsdb-tool schema-cksum                         ok
+1251: ovsdb-tool db-cksum                             ok
+1252: ovsdb-tool needs-conversion (no conversion needed) ok
+1253: ovsdb-tool needs-conversion (conversion needed) ok
 
 OVSDB -- ovsdb-server transactions (Unix sockets)
 
-1248: insert default row, query table                 ok
-1249: insert row, query table                         ok
-1250: insert rows, query by value                     ok
-1251: insert rows, query by named-uuid                ok
-1252: insert rows, update rows by value               ok
-1253: insert rows, mutate rows                        ok
-1254: insert rows, delete by named-uuid               ok
-1255: insert rows, delete rows by value               ok
-1256: insert rows, delete by (non-matching) value     ok
-1257: insert rows, delete all                         ok
-1258: insert row, query table, commit                 ok
-1259: insert row, query table, commit durably         ok
-1260: equality wait with correct rows                 ok
-1261: equality wait with extra row                    ok
-1262: equality wait with missing row                  ok
-1263: inequality wait with correct rows               ok
-1264: inequality wait with extra row                  ok
-1265: inequality wait with missing row                ok
-1266: insert and update constraints                   ok
-1267: index uniqueness checking                       ok
-1268: referential integrity -- simple                 ok
-1269: referential integrity -- mutual references      ok
-1270: weak references                                 ok
-1271: immutable columns                               ok
-1272: garbage collection                              ok
+1254: insert default row, query table                 ok
+1255: insert row, query table                         ok
+1256: insert rows, query by value                     ok
+1257: insert rows, query by named-uuid                ok
+1258: insert rows, update rows by value               ok
+1259: insert rows, mutate rows                        ok
+1260: insert rows, delete by named-uuid               ok
+1261: insert rows, delete rows by value               ok
+1262: insert rows, delete by (non-matching) value     ok
+1263: insert rows, delete all                         ok
+1264: insert row, query table, commit                 ok
+1265: insert row, query table, commit durably         ok
+1266: equality wait with correct rows                 ok
+1267: equality wait with extra row                    ok
+1268: equality wait with missing row                  ok
+1269: inequality wait with correct rows               ok
+1270: inequality wait with extra row                  ok
+1271: inequality wait with missing row                ok
+1272: insert and update constraints                   ok
+1273: index uniqueness checking                       ok
+1274: referential integrity -- simple                 ok
+1275: referential integrity -- mutual references      ok
+1276: weak references                                 ok
+1277: immutable columns                               ok
+1278: garbage collection                              ok
 
 ovsdb-server miscellaneous features
 
-1273: truncating corrupted database log               ok
-1274: truncating database log with bad transaction    ok
-1275: ovsdb-client get-schema-version                 ok
-1276: database multiplexing implementation            ok
-1277: ovsdb-server/add-db and remove-db               ok
-1278: ovsdb-server/add-db with --monitor              ok
-1279: ovsdb-server/add-db and remove-db with --monitor ok
-1280: --remote=db: implementation                     ok
-1281: ovsdb-server/add-remote and remove-remote       ok
-1282: ovsdb-server/add-remote with --monitor          ok
-1283: ovsdb-server/add-remote and remove-remote with --monitor ok
-1284: SSL db: implementation                          ok
-1285: compacting online                               ok
-1286: ovsdb-server combines updates on backlogged connections skipped (ovsdb-server.at:681)
+1279: truncating corrupted database log               ok
+1280: truncating database log with bad transaction    ok
+1281: ovsdb-client get-schema-version                 ok
+1282: database multiplexing implementation            ok
+1283: ovsdb-server/add-db and remove-db               ok
+1284: ovsdb-server/add-db with --monitor              ok
+1285: ovsdb-server/add-db and remove-db with --monitor ok
+1286: --remote=db: implementation                     ok
+1287: ovsdb-server/add-remote and remove-remote       ok
+1288: ovsdb-server/add-remote with --monitor          ok
+1289: ovsdb-server/add-remote and remove-remote with --monitor ok
+1290: SSL db: implementation                          ok
+1291: compacting online                               ok
+1292: ovsdb-server combines updates on backlogged connections skipped (ovsdb-server.at:681)
 
 OVSDB -- ovsdb-server transactions (SSL IPv4 sockets)
 
-1287: insert default row, query table                 ok
-1288: insert row, query table                         ok
-1289: insert rows, query by value                     ok
-1290: insert rows, query by named-uuid                ok
-1291: insert rows, update rows by value               ok
-1292: insert rows, mutate rows                        ok
-1293: insert rows, delete by named-uuid               ok
-1294: insert rows, delete rows by value               ok
-1295: insert rows, delete by (non-matching) value     ok
-1296: insert rows, delete all                         ok
-1297: insert row, query table, commit                 ok
-1298: insert row, query table, commit durably         ok
-1299: equality wait with correct rows                 ok
-1300: equality wait with extra row                    ok
-1301: equality wait with missing row                  ok
-1302: inequality wait with correct rows               ok
-1303: inequality wait with extra row                  ok
-1304: inequality wait with missing row                ok
-1305: insert and update constraints                   ok
-1306: index uniqueness checking                       ok
-1307: referential integrity -- simple                 ok
-1308: referential integrity -- mutual references      ok
-1309: weak references                                 ok
-1310: immutable columns                               ok
-1311: garbage collection                              ok
+1293: insert default row, query table                 ok
+1294: insert row, query table                         ok
+1295: insert rows, query by value                     ok
+1296: insert rows, query by named-uuid                ok
+1297: insert rows, update rows by value               ok
+1298: insert rows, mutate rows                        ok
+1299: insert rows, delete by named-uuid               ok
+1300: insert rows, delete rows by value               ok
+1301: insert rows, delete by (non-matching) value     ok
+1302: insert rows, delete all                         ok
+1303: insert row, query table, commit                 ok
+1304: insert row, query table, commit durably         ok
+1305: equality wait with correct rows                 ok
+1306: equality wait with extra row                    ok
+1307: equality wait with missing row                  ok
+1308: inequality wait with correct rows               ok
+1309: inequality wait with extra row                  ok
+1310: inequality wait with missing row                ok
+1311: insert and update constraints                   ok
+1312: index uniqueness checking                       ok
+1313: referential integrity -- simple                 ok
+1314: referential integrity -- mutual references      ok
+1315: weak references                                 ok
+1316: immutable columns                               ok
+1317: garbage collection                              ok
 
 OVSDB -- ovsdb-server transactions (SSL IPv6 sockets)
 
-1312: insert default row, query table                 ok
+1318: insert default row, query table                 ok
 
 OVSDB -- ovsdb-server transactions (TCP IPv4 sockets)
 
-1313: ovsdb-client get-schema-version - tcp socket    ok
-1314: insert default row, query table                 ok
-1315: insert row, query table                         ok
-1316: insert rows, query by value                     ok
-1317: insert rows, query by named-uuid                ok
-1318: insert rows, update rows by value               ok
-1319: insert rows, mutate rows                        ok
-1320: insert rows, delete by named-uuid               ok
-1321: insert rows, delete rows by value               ok
-1322: insert rows, delete by (non-matching) value     ok
-1323: insert rows, delete all                         ok
-1324: insert row, query table, commit                 ok
-1325: insert row, query table, commit durably         ok
-1326: equality wait with correct rows                 ok
-1327: equality wait with extra row                    ok
-1328: equality wait with missing row                  ok
-1329: inequality wait with correct rows               ok
-1330: inequality wait with extra row                  ok
-1331: inequality wait with missing row                ok
-1332: insert and update constraints                   ok
-1333: index uniqueness checking                       ok
-1334: referential integrity -- simple                 ok
-1335: referential integrity -- mutual references      ok
-1336: weak references                                 ok
-1337: immutable columns                               ok
-1338: garbage collection                              ok
+1319: ovsdb-client get-schema-version - tcp socket    ok
+1320: insert default row, query table                 ok
+1321: insert row, query table                         ok
+1322: insert rows, query by value                     ok
+1323: insert rows, query by named-uuid                ok
+1324: insert rows, update rows by value               ok
+1325: insert rows, mutate rows                        ok
+1326: insert rows, delete by named-uuid               ok
+1327: insert rows, delete rows by value               ok
+1328: insert rows, delete by (non-matching) value     ok
+1329: insert rows, delete all                         ok
+1330: insert row, query table, commit                 ok
+1331: insert row, query table, commit durably         ok
+1332: equality wait with correct rows                 ok
+1333: equality wait with extra row                    ok
+1334: equality wait with missing row                  ok
+1335: inequality wait with correct rows               ok
+1336: inequality wait with extra row                  ok
+1337: inequality wait with missing row                ok
+1338: insert and update constraints                   ok
+1339: index uniqueness checking                       ok
+1340: referential integrity -- simple                 ok
+1341: referential integrity -- mutual references      ok
+1342: weak references                                 ok
+1343: immutable columns                               ok
+1344: garbage collection                              ok
 
 OVSDB -- ovsdb-server transactions (TCP IPv6 sockets)
 
-1339: insert default row, query table                 ok
+1345: insert default row, query table                 ok
 
 OVSDB -- transactions on transient ovsdb-server
 
-1340: insert default row, query table                 ok
-1341: insert row, query table                         ok
-1342: insert rows, query by value                     ok
-1343: insert rows, query by named-uuid                ok
-1344: insert rows, update rows by value               ok
-1345: insert rows, mutate rows                        ok
-1346: insert rows, delete by named-uuid               ok
-1347: insert rows, delete rows by value               ok
-1348: insert rows, delete by (non-matching) value     ok
-1349: insert rows, delete all                         ok
-1350: insert row, query table, commit                 ok
-1351: insert row, query table, commit durably         ok
-1352: equality wait with correct rows                 ok
-1353: equality wait with extra row                    ok
-1354: equality wait with missing row                  ok
-1355: inequality wait with correct rows               ok
-1356: inequality wait with extra row                  ok
-1357: inequality wait with missing row                ok
-1358: insert and update constraints                   ok
-1359: index uniqueness checking                       ok
-1360: referential integrity -- simple                 ok
-1361: referential integrity -- mutual references      ok
-1362: weak references                                 ok
-1363: immutable columns                               ok
-1364: garbage collection                              ok
+1346: insert default row, query table                 ok
+1347: insert row, query table                         ok
+1348: insert rows, query by value                     ok
+1349: insert rows, query by named-uuid                ok
+1350: insert rows, update rows by value               ok
+1351: insert rows, mutate rows                        ok
+1352: insert rows, delete by named-uuid               ok
+1353: insert rows, delete rows by value               ok
+1354: insert rows, delete by (non-matching) value     ok
+1355: insert rows, delete all                         ok
+1356: insert row, query table, commit                 ok
+1357: insert row, query table, commit durably         ok
+1358: equality wait with correct rows                 ok
+1359: equality wait with extra row                    ok
+1360: equality wait with missing row                  ok
+1361: inequality wait with correct rows               ok
+1362: inequality wait with extra row                  ok
+1363: inequality wait with missing row                ok
+1364: insert and update constraints                   ok
+1365: index uniqueness checking                       ok
+1366: referential integrity -- simple                 ok
+1367: referential integrity -- mutual references      ok
+1368: weak references                                 ok
+1369: immutable columns                               ok
+1370: garbage collection                              ok
 
 OVSDB -- ovsdb-server monitors
 
-1365: monitor insert into empty table                 ok
-1366: monitor insert into populated table             ok
-1367: monitor delete                                  ok
-1368: monitor row update                              ok
-1369: monitor no-op row updates                       ok
-1370: monitor insert-and-update transaction           ok
-1371: monitor insert-update-and-delete transaction    ok
-1372: monitor weak reference change                   ok
-1373: monitor insert-update-and-delete transaction    ok
+1371: monitor insert into empty table                 ok
+1372: monitor insert into populated table             ok
+1373: monitor delete                                  ok
+1374: monitor row update                              ok
+1375: monitor no-op row updates                       ok
+1376: monitor insert-and-update transaction           ok
+1377: monitor insert-update-and-delete transaction    ok
+1378: monitor weak reference change                   ok
+1379: monitor insert-update-and-delete transaction    ok
 
 ovsdb -- ovsdb-monitor monitor only some operations
 
-1374: monitor all operations                          ok
-1375: monitor initial only                            ok
-1376: monitor insert only                             ok
-1377: monitor delete only                             ok
-1378: monitor modify only                             ok
+1380: monitor all operations                          ok
+1381: monitor initial only                            ok
+1382: monitor insert only                             ok
+1383: monitor delete only                             ok
+1384: monitor modify only                             ok
 
 OVSDB -- interface description language (IDL)
 
-1379: simple idl, initially empty, no ops - C         ok
-1380: simple idl, initially empty, no ops - Python    ok
-1381: simple idl, initially empty, no ops - Python tcp ok
-1382: simple idl, initially empty, no ops - Python tcp6 ok
-1383: simple idl, initially empty, various ops - C    ok
-1384: simple idl, initially empty, various ops - Python ok
-1385: simple idl, initially empty, various ops - Python tcp ok
-1386: simple idl, initially empty, various ops - Python tcp6 ok
-1387: simple idl, initially populated - C             ok
-1388: simple idl, initially populated - Python        ok
-1389: simple idl, initially populated - Python tcp    ok
-1390: simple idl, initially populated - Python tcp6   ok
-1391: simple idl, writing via IDL - C                 ok
-1392: simple idl, writing via IDL - Python            ok
-1393: simple idl, writing via IDL - Python tcp        ok
-1394: simple idl, writing via IDL - Python tcp6       ok
-1395: simple idl, handling verification failure - C   ok
-1396: simple idl, handling verification failure - Python ok
-1397: simple idl, handling verification failure - Python tcp ok
-1398: simple idl, handling verification failure - Python tcp6 ok
-1399: simple idl, increment operation - C             ok
-1400: simple idl, increment operation - Python        ok
-1401: simple idl, increment operation - Python tcp    ok
-1402: simple idl, increment operation - Python tcp6   ok
-1403: simple idl, aborting - C                        ok
-1404: simple idl, aborting - Python                   ok
-1405: simple idl, aborting - Python tcp               ok
-1406: simple idl, aborting - Python tcp6              ok
-1407: simple idl, destroy without commit or abort - C ok
-1408: simple idl, destroy without commit or abort - Python ok
-1409: simple idl, destroy without commit or abort - Python tcp ok
-1410: simple idl, destroy without commit or abort - Python tcp6 ok
-1411: self-linking idl, consistent ops - C            ok
-1412: self-linking idl, consistent ops - Python       ok
-1413: self-linking idl, consistent ops - Python tcp   ok
-1414: self-linking idl, consistent ops - Python tcp6  ok
-1415: self-linking idl, inconsistent ops - C          ok
-1416: self-linking idl, inconsistent ops - Python     ok
-1417: self-linking idl, inconsistent ops - Python tcp ok
-1418: self-linking idl, inconsistent ops - Python tcp6 ok
-1419: self-linking idl, sets - C                      ok
-1420: self-linking idl, sets - Python                 ok
-1421: self-linking idl, sets - Python tcp             ok
-1422: self-linking idl, sets - Python tcp6            ok
-1423: external-linking idl, consistent ops - C        ok
-1424: external-linking idl, consistent ops - Python   ok
-1425: external-linking idl, consistent ops - Python tcp ok
-1426: external-linking idl, consistent ops - Python tcp6 ok
-1427: external-linking idl, insert ops - Python       ok
-1428: getattr idl, insert ops - Python                ok
+1385: simple idl, initially empty, no ops - C         ok
+1386: simple idl, initially empty, no ops - Python    ok
+1387: simple idl, initially empty, no ops - Python tcp ok
+1388: simple idl, initially empty, no ops - Python tcp6 ok
+1389: simple idl, initially empty, various ops - C    ok
+1390: simple idl, initially empty, various ops - Python ok
+1391: simple idl, initially empty, various ops - Python tcp ok
+1392: simple idl, initially empty, various ops - Python tcp6 ok
+1393: simple idl, initially populated - C             ok
+1394: simple idl, initially populated - Python        ok
+1395: simple idl, initially populated - Python tcp    ok
+1396: simple idl, initially populated - Python tcp6   ok
+1397: simple idl, writing via IDL - C                 ok
+1398: simple idl, writing via IDL - Python            ok
+1399: simple idl, writing via IDL - Python tcp        ok
+1400: simple idl, writing via IDL - Python tcp6       ok
+1401: simple idl, handling verification failure - C   ok
+1402: simple idl, handling verification failure - Python ok
+1403: simple idl, handling verification failure - Python tcp ok
+1404: simple idl, handling verification failure - Python tcp6 ok
+1405: simple idl, increment operation - C             ok
+1406: simple idl, increment operation - Python        ok
+1407: simple idl, increment operation - Python tcp    ok
+1408: simple idl, increment operation - Python tcp6   ok
+1409: simple idl, aborting - C                        ok
+1410: simple idl, aborting - Python                   ok
+1411: simple idl, aborting - Python tcp               ok
+1412: simple idl, aborting - Python tcp6              ok
+1413: simple idl, destroy without commit or abort - C ok
+1414: simple idl, destroy without commit or abort - Python ok
+1415: simple idl, destroy without commit or abort - Python tcp ok
+1416: simple idl, destroy without commit or abort - Python tcp6 ok
+1417: self-linking idl, consistent ops - C            ok
+1418: self-linking idl, consistent ops - Python       ok
+1419: self-linking idl, consistent ops - Python tcp   ok
+1420: self-linking idl, consistent ops - Python tcp6  ok
+1421: self-linking idl, inconsistent ops - C          ok
+1422: self-linking idl, inconsistent ops - Python     ok
+1423: self-linking idl, inconsistent ops - Python tcp ok
+1424: self-linking idl, inconsistent ops - Python tcp6 ok
+1425: self-linking idl, sets - C                      ok
+1426: self-linking idl, sets - Python                 ok
+1427: self-linking idl, sets - Python tcp             ok
+1428: self-linking idl, sets - Python tcp6            ok
+1429: external-linking idl, consistent ops - C        ok
+1430: external-linking idl, consistent ops - Python   ok
+1431: external-linking idl, consistent ops - Python tcp ok
+1432: external-linking idl, consistent ops - Python tcp6 ok
+1433: external-linking idl, insert ops - Python       ok
+1434: getattr idl, insert ops - Python                ok
 
 ovs-vsctl unit tests
 
-1429: ovs-vsctl connection retry                      ok
+1435: ovs-vsctl connection retry                      ok
 
 ovs-vsctl unit tests -- real bridges
 
-1430: add-br a                                        ok
-1431: add-br a, add-br a                              ok
-1432: add-br a, add-br b                              ok
-1433: add-br a, add-br b, del-br a                    ok
-1434: add-br a, del-br a, add-br a                    ok
-1435: add-br a, add-port a a1, add-port a a2          ok
-1436: add-br a, add-port a a1, add-port a a1          ok
-1437: add-br a b, add-port a a1, add-port b b1, del-br a ok
-1438: add-br a, add-bond a bond0 a1 a2 a3             ok
-1439: add-br a b, add-port a a1, add-port b b1, del-port a a1 ok
-1440: add-br a, add-bond a bond0 a1 a2 a3, del-port bond0 ok
-1441: external IDs                                    ok
-1442: controllers                                     ok
+1436: add-br a                                        ok
+1437: add-br a, add-br a                              ok
+1438: add-br a, add-br b                              ok
+1439: add-br a, add-br b, del-br a                    ok
+1440: add-br a, del-br a, add-br a                    ok
+1441: add-br a, add-port a a1, add-port a a2          ok
+1442: add-br a, add-port a a1, add-port a a1          ok
+1443: add-br a b, add-port a a1, add-port b b1, del-br a ok
+1444: add-br a, add-bond a bond0 a1 a2 a3             ok
+1445: add-br a b, add-port a a1, add-port b b1, del-port a a1 ok
+1446: add-br a, add-bond a bond0 a1 a2 a3, del-port bond0 ok
+1447: external IDs                                    ok
+1448: controllers                                     ok
 
 ovs-vsctl unit tests -- fake bridges (VLAN 9)
 
-1443: simple fake bridge (VLAN 9)                     ok
-1444: list bridges -- real and fake (VLAN 9)          ok
-1445: simple fake bridge + del-br fake bridge (VLAN 9) ok
-1446: simple fake bridge + del-br real bridge (VLAN 9) ok
-1447: simple fake bridge + external IDs (VLAN 9)      ok
+1449: simple fake bridge (VLAN 9)                     ok
+1450: list bridges -- real and fake (VLAN 9)          ok
+1451: simple fake bridge + del-br fake bridge (VLAN 9) ok
+1452: simple fake bridge + del-br real bridge (VLAN 9) ok
+1453: simple fake bridge + external IDs (VLAN 9)      ok
 
 ovs-vsctl unit tests -- fake bridges (VLAN 0)
 
-1448: simple fake bridge (VLAN 0)                     ok
-1449: list bridges -- real and fake (VLAN 0)          ok
-1450: simple fake bridge + del-br fake bridge (VLAN 0) ok
-1451: simple fake bridge + del-br real bridge (VLAN 0) ok
-1452: simple fake bridge + external IDs (VLAN 0)      ok
-1453: fake bridge on bond                             ok
-1454: fake bridge on bond + del-br fake bridge        ok
-1455: fake bridge on bond + del-br real bridge        ok
+1454: simple fake bridge (VLAN 0)                     ok
+1455: list bridges -- real and fake (VLAN 0)          ok
+1456: simple fake bridge + del-br fake bridge (VLAN 0) ok
+1457: simple fake bridge + del-br real bridge (VLAN 0) ok
+1458: simple fake bridge + external IDs (VLAN 0)      ok
+1459: fake bridge on bond                             ok
+1460: fake bridge on bond + del-br fake bridge        ok
+1461: fake bridge on bond + del-br real bridge        ok
 
 ovs-vsctl unit tests -- manager commands
 
-1456: managers                                        ok
+1462: managers                                        ok
 
 ovs-vsctl unit tests -- database commands
 
-1457: database commands -- positive checks            ok
-1458: database commands -- negative checks            ok
-1459: database commands -- conditions                 ok
-1460: database commands -- wait-until immediately true ok
-1461: database commands -- wait-until must wait       ok
-1462: --id option on create, get commands             ok
-1463: unreferenced record warnings                    ok
-1464: created row UUID is wrong in same execution     ok
-1465: --all option on destroy command                 ok
+1463: database commands -- positive checks            ok
+1464: database commands -- negative checks            ok
+1465: database commands -- conditions                 ok
+1466: database commands -- wait-until immediately true ok
+1467: database commands -- wait-until must wait       ok
+1468: --id option on create, get commands             ok
+1469: unreferenced record warnings                    ok
+1470: created row UUID is wrong in same execution     ok
+1471: --all option on destroy command                 ok
 
 ovs-vsctl add-port -- reserved port names
 
-1466: add-port -- reserved names 1                    FAILED (ovs-vsctl.at:1205)
-1467: add-port -- reserved names 2                    FAILED (ovs-vsctl.at:1231)
+1472: add-port -- reserved names 1                    FAILED (ovs-vsctl.at:1205)
+1473: add-port -- reserved names 2                    FAILED (ovs-vsctl.at:1233)
 
 ovs-monitor-ipsec
 
-1468: ovs-monitor-ipsec                               ok
+1474: ovs-monitor-ipsec                               ok
 
 ovs-xapi-sync
 
-1469: ovs-xapi-sync                                   ok
+1475: ovs-xapi-sync                                   ok
 
 interface-reconfigure
 
-1470: non-VLAN, non-bond                              ok
-1471: VLAN, non-bond                                  ok
-1472: Bond, non-VLAN                                  ok
-1473: VLAN on bond                                    ok
-1474: Re-create port with different types             FAILED (interface-reconfigure.at:1038)
+1476: non-VLAN, non-bond                              ok
+1477: VLAN, non-bond                                  ok
+1478: Bond, non-VLAN                                  ok
+1479: VLAN on bond                                    ok
+1480: Re-create port with different types             FAILED (interface-reconfigure.at:1038)
 
 Spanning Tree Protocol unit tests
 
-1475: STP example from IEEE 802.1D-1998               ok
-1476: STP example from IEEE 802.1D-2004 figures 17.4 and 17.5 ok
-1477: STP example from IEEE 802.1D-2004 figure 17.6   ok
-1478: STP example from IEEE 802.1D-2004 figure 17.7   ok
-1479: STP.io.1.1: Link Failure                        ok
-1480: STP.io.1.2: Repeated Network                    ok
-1481: STP.io.1.4: Network Initialization              ok
-1482: STP.io.1.5: Topology Change                     ok
-1483: STP.op.1.1 and STP.op.1.2                       ok
-1484: STP.op.1.4: All Ports Initialized to Designated Ports ok
-1485: STP.op.3.1: Root Bridge Selection: Root ID Values ok
-1486: STP.op.3.3: Root Bridge Selection: Bridge ID Values ok
-1487: STP.op.3.3: Root Bridge Selection: Bridge ID Values ok
+1481: STP example from IEEE 802.1D-1998               ok
+1482: STP example from IEEE 802.1D-2004 figures 17.4 and 17.5 ok
+1483: STP example from IEEE 802.1D-2004 figure 17.6   ok
+1484: STP example from IEEE 802.1D-2004 figure 17.7   ok
+1485: STP.io.1.1: Link Failure                        ok
+1486: STP.io.1.2: Repeated Network                    ok
+1487: STP.io.1.4: Network Initialization              ok
+1488: STP.io.1.5: Topology Change                     ok
+1489: STP.op.1.1 and STP.op.1.2                       ok
+1490: STP.op.1.4: All Ports Initialized to Designated Ports ok
+1491: STP.op.3.1: Root Bridge Selection: Root ID Values ok
+1492: STP.op.3.3: Root Bridge Selection: Bridge ID Values ok
+1493: STP.op.3.3: Root Bridge Selection: Bridge ID Values ok
 
 vlog
 
-1488: vlog - Python                                   ok
-1489: vlog - vlog/reopen - Python                     ok
-1490: vlog - vlog/reopen without log file - Python    ok
-1491: vlog - vlog/reopen can't reopen log file - Python skipped (vlog.at:155)
-1492: vlog - vlog/set and vlog/list - Python          ok
+1494: vlog - Python                                   ok
+1495: vlog - vlog/reopen - Python                     ok
+1496: vlog - vlog/reopen without log file - Python    ok
+1497: vlog - vlog/reopen can't reopen log file - Python skipped (vlog.at:155)
+1498: vlog - vlog/set and vlog/list - Python          ok
 
 vtep-ctl unit tests -- physical switch tests
 
-1493: add-ps a                                        ok
-1494: add-ps a, add-ps a                              ok
-1495: add-ps a, add-ps b                              ok
-1496: add-ps a, add-ps b, del-ps a                    ok
-1497: add-ps a, del-ps a, add-ps a                    ok
-1498: add-ps a, add-port a a1, add-port a a2          ok
-1499: add-ps a, add-port a a1, add-port a a1          ok
-1500: add-ps a b, add-port a a1, add-port b b1, del-ps a ok
-1501: add-ps a b, add-port a a1, add-port b b1, del-port a a1 ok
-1502: add-ps a b, add-port a p1, add-port b p1, del-port a p1 ok
+1499: add-ps a                                        ok
+1500: add-ps a, add-ps a                              ok
+1501: add-ps a, add-ps b                              ok
+1502: add-ps a, add-ps b, del-ps a                    ok
+1503: add-ps a, del-ps a, add-ps a                    ok
+1504: add-ps a, add-port a a1, add-port a a2          ok
+1505: add-ps a, add-port a a1, add-port a a1          ok
+1506: add-ps a b, add-port a a1, add-port b b1, del-ps a ok
+1507: add-ps a b, add-port a a1, add-port b b1, del-port a a1 ok
+1508: add-ps a b, add-port a p1, add-port b p1, del-port a p1 ok
 
 vtep-ctl unit tests -- logical switch tests
 
-1503: add-ls a                                        ok
-1504: add-ls a, add-ls a                              ok
-1505: add-ls a, add-ls b                              ok
-1506: add-ls a, add-ls b, del-ls a                    ok
-1507: add-ls a, del-ls a, add-ls a                    ok
+1509: add-ls a                                        ok
+1510: add-ls a, add-ls a                              ok
+1511: add-ls a, add-ls b                              ok
+1512: add-ls a, add-ls b, del-ls a                    ok
+1513: add-ls a, del-ls a, add-ls a                    ok
 
 vtep-ctl unit tests -- logical binding tests
 
-1508: bind-ls ps1 pp1 300 ls1                         ok
-1509: bind-ls ps1 pp1 300 ls1, bind-ls ps1 pp1 400 ls2 ok
-1510: bind-ls ps1 pp1 300, bind-ls ps2 pp2 300 ls2    ok
+1514: bind-ls ps1 pp1 300 ls1                         ok
+1515: bind-ls ps1 pp1 300 ls1, bind-ls ps1 pp1 400 ls2 ok
+1516: bind-ls ps1 pp1 300, bind-ls ps2 pp2 300 ls2    ok
 
 vtep-ctl unit tests -- MAC binding tests
 
-1511: add-ucast-local ls1                             ok
-1512: add-ucast-local ls1, overwrite                  ok
-1513: add-ucast-local ls1, del-ucast-local ls1        ok
-1514: add-ucast-remote ls1                            ok
-1515: add-ucast-remote ls1, overwrite                 ok
-1516: add-ucast-remote ls1, del-ucast-remote ls1      ok
-1517: add-ucast-local ls1, add-ucast-remote ls1       ok
-1518: add-mcast-local ls1                             ok
-1519: add-mcast-local ls1, del-mcast-local ls1        ok
-1520: add-mcast-remote ls1                            ok
-1521: add-mcast-remote ls1, del-mcast-remote ls1      ok
-1522: add-mcast-local ls1, add-mcast-remote ls1       ok
-1523: add local and remote macs, clear-local-macs     ok
-1524: add local and remote macs, clear-remote-macs    ok
+1517: add-ucast-local ls1                             ok
+1518: add-ucast-local ls1, overwrite                  ok
+1519: add-ucast-local ls1, del-ucast-local ls1        ok
+1520: add-ucast-remote ls1                            ok
+1521: add-ucast-remote ls1, overwrite                 ok
+1522: add-ucast-remote ls1, del-ucast-remote ls1      ok
+1523: add-ucast-local ls1, add-ucast-remote ls1       ok
+1524: add-mcast-local ls1                             ok
+1525: add-mcast-local ls1, del-mcast-local ls1        ok
+1526: add-mcast-remote ls1                            ok
+1527: add-mcast-remote ls1, del-mcast-remote ls1      ok
+1528: add-mcast-local ls1, add-mcast-remote ls1       ok
+1529: add local and remote macs, clear-local-macs     ok
+1530: add local and remote macs, clear-remote-macs    ok
 
 vtep-ctl unit tests -- manager commands
 
-1525: managers                                        ok
+1531: managers                                        ok
 
 ## ------------- ##
 ## Test results. ##
 ## ------------- ##
 
-ERROR: 1520 tests were run,
+ERROR: 1526 tests were run,
 21 failed (1 expected failure).
 5 tests were skipped.
 ## -------------------------- ##
@@ -1874,17 +1880,21 @@
 Please send `tests/testsuite.log' and all information you think might help:
 
    To: <[email protected]>
-   Subject: [openvswitch 2.3.1] testsuite: 5 12 31 578 579 580 581 582 583 584 586 588 771 772 808 814 815 1466 1467 1474 failed
+   Subject: [openvswitch 2.3.2] testsuite: 5 12 31 578 579 580 581 582 583 584 586 588 774 775 811 817 818 1472 1473 1480 failed
 
 You may investigate any problem if you feel able to do so, in which
 case the test suite provides a good starting point.  Its output may
 be found below `tests/testsuite.dir'.
 
+Makefile:4555: recipe for target 'check-local' failed
 make[4]: *** [check-local] Error 1
-make[4]: Leaving directory `$(@D)'
+make[4]: Leaving directory '$(@D)'
+Makefile:3880: recipe for target 'check-am' failed
 make[3]: *** [check-am] Error 2
-make[3]: Leaving directory `$(@D)'
+make[3]: Leaving directory '$(@D)'
+Makefile:3589: recipe for target 'check-recursive' failed
 make[2]: *** [check-recursive] Error 1
-make[2]: Leaving directory `$(@D)'
+make[2]: Leaving directory '$(@D)'
+Makefile:3883: recipe for target 'check' failed
 make[1]: *** [check] Error 2
-make[1]: Leaving directory `$(@D)'
+make[1]: Leaving directory '$(@D)'