24511676 Connectivity to LDOM with OVS is lost when start/stop of LDOM is performed
authorakshay.kale@oracle.com <akshay.kale@oracle.com>
Thu, 29 Sep 2016 10:38:55 -0700
changeset 7000 22f549e6467a
parent 6999 1238e930f8af
child 7001 49bc9df236c6
24511676 Connectivity to LDOM with OVS is lost when start/stop of LDOM is performed
components/openvswitch/files/lib/netdev-solaris.c
components/openvswitch/files/lib/util-solaris.c
--- a/components/openvswitch/files/lib/netdev-solaris.c	Thu Sep 29 09:48:10 2016 -0700
+++ b/components/openvswitch/files/lib/netdev-solaris.c	Thu Sep 29 10:38:55 2016 -0700
@@ -818,13 +818,25 @@
 
 	if (error == ENODEV) {
 		/*
-		 * No implicit VNIC being created yet, create it now
+		 * No implicit VNIC exists, create it now first over
+		 * NETDEV_IMPL_ETHERSTUB and later migrate onto new_uplink. Not
+		 * creating it directly over new_uplink as it may fail(for vnet)
+		 * if it doesn't support creating vnic with "auto" mac-addr-type
 		 */
-		VLOG_DBG("%s vnic being created on %s", brname, new_uplink);
-		error = solaris_create_vnic(new_uplink, brname);
+		VLOG_DBG("%s vnic being created on %s", brname,
+		    NETDEV_IMPL_ETHERSTUB);
+		error = solaris_create_vnic(NETDEV_IMPL_ETHERSTUB, brname);
 		if (error == 0) {
-			(void) strlcpy(netdev->brname, brname,
-			    sizeof (netdev->brname));
+			VLOG_DBG("%s vnic is being migrated on %s", brname,
+			    new_uplink);
+			error = solaris_modify_vnic(new_uplink, brname);
+			if (error == 0) {
+				(void) strlcpy(netdev->brname, brname,
+				    sizeof (netdev->brname));
+			} else {
+				VLOG_ERR("Failed to migrate %s vnic over %s:%s",
+				    brname, new_uplink, ovs_strerror(error));
+			}
 		} else {
 			VLOG_ERR("Failed to create vnic for %s: %s",
 			    brname, ovs_strerror(error));
--- a/components/openvswitch/files/lib/util-solaris.c	Thu Sep 29 09:48:10 2016 -0700
+++ b/components/openvswitch/files/lib/util-solaris.c	Thu Sep 29 10:38:55 2016 -0700
@@ -984,6 +984,50 @@
 	    temp));
 }
 
+static int
+dlmgr_DLValue_putstring(dlmgr__rad_dict_string_DLValue_t *ddvp,
+    const char *key, char *buf, char *dstr, size_t dstrlen)
+{
+	dlmgr_DLValue_t  *old_val = NULL;
+	dlmgr_DLValue_t  new_val;
+	rc_err_t status;
+
+	if (strlen(key) != 0) {
+		bzero(&new_val, sizeof (new_val));
+		new_val.ddlv_type = DDLVT_STRING;
+		new_val.ddlv_sval = buf;
+		if ((status = dlmgr__rad_dict_string_DLValue_put(ddvp, key,
+		    &new_val, &old_val)) != RCE_OK) {
+			return (EINVAL);
+		}
+		if (dstr)
+			snprintf(dstr, dstrlen, "%s,%s=%s", dstr, key, buf);
+		dlmgr_DLValue_free(old_val);
+	}
+	return (0);
+}
+
+static int
+dlmgr_DLValue_putdict(dlmgr__rad_dict_string_DLValue_t *ddvp,
+    const char *key, dlmgr__rad_dict_string_DLValue_t *dict)
+{
+	dlmgr_DLValue_t  *old_val = NULL;
+	dlmgr_DLValue_t  new_val;
+	rc_err_t status;
+
+	if (strlen(key) != 0) {
+		bzero(&new_val, sizeof (new_val));
+		new_val.ddlv_type = DDLVT_DICTIONARY;
+		new_val.ddlv_dval = dict;
+		if ((status = dlmgr__rad_dict_string_DLValue_put(ddvp, key,
+		    &new_val, &old_val)) != RCE_OK) {
+			return (EINVAL);
+		}
+		dlmgr_DLValue_free(old_val);
+	}
+	return (0);
+}
+
 int
 solaris_create_vnic(const char *linkname, const char *vnicname)
 {
@@ -1030,15 +1074,22 @@
 	return ((status != RCE_OK) ? ENOTSUP : 0);
 }
 
+/*
+ * Try setting implicit VNIC's mac-addr-type as "fixed", if it fails then try
+ * with "auto" else bail out. This procedure is to ensure vnic migration
+ * succeeds specifically on LDOM's vnet (ensuring it works on other uplinks too)
+ * with any of its config (custom=enable/disable).
+ */
 int
 solaris_modify_vnic(const char *linkname, const char *vnicname)
 {
 	dlmgr__rad_dict_string_DLValue_t *sprop_dict = NULL;
+	dlmgr__rad_dict_string_DLValue_t *mac_info_dict = NULL;
 	dlmgr_DLValue_t			*old_val = NULL;
-	dlmgr_DLValue_t			new_val;
 	rc_instance_t			*link = NULL;
 	rc_err_t			status;
 	dlmgr_DatalinkError_t   	*derrp = NULL;
+	char				mac_address[DLADM_PROP_VAL_MAX];
 	int				error = 0;
 
 	status = dlmgr_Datalink__rad_lookup(rad_conn, B_TRUE, &link, 1,
@@ -1050,33 +1101,70 @@
 
 	sprop_dict = dlmgr__rad_dict_string_DLValue_create(link);
 	if (sprop_dict == NULL) {
-		status = ENOMEM;
+		error = ENOMEM;
+		goto out;
+	}
+	mac_info_dict = dlmgr__rad_dict_string_DLValue_create(link);
+	if (mac_info_dict == NULL) {
+		error = ENOMEM;
+		goto out;
+	}
+
+	if ((error = dlmgr_DLValue_putstring(sprop_dict, "lower-link",
+	    strdupa(linkname), NULL, 0)) != 0) {
 		goto out;
 	}
 
-	bzero(&new_val, sizeof (new_val));
-	new_val.ddlv_type = DDLVT_STRING;
-	new_val.ddlv_sval = strdupa(linkname);
-	status = dlmgr__rad_dict_string_DLValue_put(
-	    sprop_dict, "lower-link", &new_val, &old_val);
-	if (status != RCE_OK) {
-		error = EINVAL;
+	if ((error = solaris_get_dlprop(vnicname, "mac-address", "current",
+	    mac_address, sizeof (mac_address))) != 0) {
+		goto out;
+	}
+
+	if ((error = dlmgr_DLValue_putstring(mac_info_dict, "mac-address-type",
+	    "fixed", NULL, 0)) != 0) {
 		goto out;
 	}
-	dlmgr_DLValue_free(old_val);
+	if ((error = dlmgr_DLValue_putstring(mac_info_dict, "mac-address",
+	    mac_address, NULL, 0)) != 0) {
+		goto out;
+	}
+	if ((error = dlmgr_DLValue_putdict(sprop_dict, "mac-address-info",
+	    mac_info_dict)) != 0) {
+		goto out;
+	}
 
 	status = dlmgr_Datalink_setProperties(link, sprop_dict, &derrp);
 	if (status != RCE_OK) {
-		if (status == RCE_SERVER_OBJECT) {
-			dpif_log(derrp->dde_err,
-			    "failed Datalink_setPropertiess(%s, lower-link): "
-			    " %s", vnicname, derrp->dde_errmsg);
+		/* If it fails with "fixed" as mac-addr-type, try with "auto" */
+		if ((status = dlmgr__rad_dict_string_DLValue_remove(
+		    mac_info_dict, "mac-address", &old_val)) != RCE_OK) {
+			error = ENOTSUP;
+			goto out;
+		}
+		dlmgr_DLValue_free(old_val);
+
+		if ((error = dlmgr_DLValue_putstring(mac_info_dict,
+		    "mac-address-type", "auto", NULL, 0))
+		    != 0) {
+			goto out;
 		}
-		error = ENOTSUP;
+
+		status = dlmgr_Datalink_setProperties(link, sprop_dict,
+		    &derrp);
+		if (status != RCE_OK) {
+			if (status == RCE_SERVER_OBJECT) {
+				dpif_log(derrp->dde_err,
+				    "failed Datalink_setProperties"
+				    "(%s, lower-link): %s",
+				    vnicname, derrp->dde_errmsg);
+			}
+			error = ENOTSUP;
+		}
 	}
 out:
 	dlmgr_DatalinkError_free(derrp);
 	dlmgr__rad_dict_string_DLValue_free(sprop_dict);
+	dlmgr__rad_dict_string_DLValue_free(mac_info_dict);
 	rc_instance_rele(link);
 	return (error);
 }
@@ -1392,28 +1480,6 @@
 }
 
 static int
-dlmgr_DLValue_putstring(dlmgr__rad_dict_string_DLValue_t *ddvp,
-    const char *key, char *buf, char *dstr, size_t dstrlen)
-{
-	dlmgr_DLValue_t  *old_val = NULL;
-	dlmgr_DLValue_t  new_val;
-	rc_err_t status;
-
-	if (strlen(key) != 0) {
-		bzero(&new_val, sizeof (new_val));
-		new_val.ddlv_type = DDLVT_STRING;
-		new_val.ddlv_sval = buf;
-		if ((status = dlmgr__rad_dict_string_DLValue_put(ddvp, key,
-		    &new_val, &old_val)) != RCE_OK) {
-			return (EINVAL);
-		}
-		snprintf(dstr, dstrlen, "%s,%s=%s", dstr, key, buf);
-		dlmgr_DLValue_free(old_val);
-	}
-	return (0);
-}
-
-static int
 dlmgr_DLValue_fm_putstring(dlmgr__rad_dict_string_DLValue_t *ddvp,
     dlmgr__rad_dict_string_DLValue_t *ddmp, const char *key,
     char *buf, char *rbuf, char *dstr, size_t dstrlen)