--- old/usr/src/cmd/zonecfg/zonecfg.c	Wed Aug 31 11:44:08 2016
+++ new/usr/src/cmd/zonecfg/zonecfg.c	Wed Aug 31 11:44:08 2016
@@ -235,6 +235,11 @@
 	"fs-allowed",
 	ALIAS_MAXPROCS,
 	"allowed-address",
+	ALIAS_ZFSPRI,
+	"mac-addr",
+	"vlan-id",
+	"global-nic",
+	"property",
 	NULL
 };
 
@@ -407,9 +412,20 @@
 	"exit",
 	"help",
 	"info",
+	"add property ",
+	"clear allowed-address",
+	"clear defrouter",
+	"clear global-nic",
+	"clear mac-addr",
+	"clear vlan-id",
+	"remove property ",
 	"set address=",
-	"set physical=",
+	"set allowed-address=",
 	"set defrouter=",
+	"set global-nic=",
+	"set mac-addr=",
+	"set physical=",
+	"set vlan-id=",
 	NULL
 };
 
@@ -419,6 +435,7 @@
 	"exit",
 	"help",
 	"info",
+	"add property ",
 	"set match=",
 	NULL
 };
@@ -1078,11 +1095,20 @@
 			(void) fprintf(fp, gettext("Valid commands:\n"));
 			(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
 			    pt_to_str(PT_ADDRESS), gettext("<IP-address>"));
+			(void) fprintf(fp, "\t%s %s (%s=<value>,%s=<value>)\n",
+			    cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP),
+			    pt_to_str(PT_NAME), pt_to_str(PT_VALUE));
 			(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
 			    pt_to_str(PT_ALLOWED_ADDRESS),
 			    gettext("<IP-address>"));
 			(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
 			    pt_to_str(PT_PHYSICAL), gettext("<interface>"));
+			(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
+			    pt_to_str(PT_MAC), gettext("<mac-address>"));
+			(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
+			    pt_to_str(PT_GNIC), gettext("<global zone NIC>"));
+			(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
+			    pt_to_str(PT_VLANID), gettext("<vlan ID>"));
 			(void) fprintf(fp, gettext("See ifconfig(1M) for "
 			    "details of the <interface> string.\n"));
 			(void) fprintf(fp, gettext("%s %s is valid "
@@ -1090,10 +1116,12 @@
 			    "must not be set.\n"),
 			    cmd_to_str(CMD_SET), pt_to_str(PT_ADDRESS),
 			    pt_to_str(PT_IPTYPE), gettext("shared"));
-			(void) fprintf(fp, gettext("%s %s is valid "
-			    "if the %s property is set to %s, otherwise it "
-			    "must not be set.\n"),
-			    cmd_to_str(CMD_SET), pt_to_str(PT_ALLOWED_ADDRESS),
+			(void) fprintf(fp, gettext("%s (%s, %s, %s, %s) are "
+			    "valid if the %s property is set to %s, otherwise "
+			    "they must not be set.\n"),
+			    cmd_to_str(CMD_SET),
+			    pt_to_str(PT_ALLOWED_ADDRESS), pt_to_str(PT_MAC),
+			    pt_to_str(PT_VLANID), pt_to_str(PT_GNIC),
 			    pt_to_str(PT_IPTYPE), gettext("exclusive"));
 			(void) fprintf(fp, gettext("\t%s %s=%s\n%s %s "
 			    "is valid if the %s or %s property is set, "
@@ -1109,6 +1137,9 @@
 			    "used to configure a device node.\n"),
 			    rt_to_str(resource_scope));
 			(void) fprintf(fp, gettext("Valid commands:\n"));
+			(void) fprintf(fp, "\t%s %s (%s=<value>,%s=<value>)\n",
+			    cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP),
+			    pt_to_str(PT_NAME), pt_to_str(PT_VALUE));
 			(void) fprintf(fp, "\t%s %s=%s\n", cmd_to_str(CMD_SET),
 			    pt_to_str(PT_MATCH), gettext("<device-path>"));
 			break;
@@ -1336,11 +1367,14 @@
 		    rt_to_str(RT_FS), pt_to_str(PT_DIR),
 		    pt_to_str(PT_SPECIAL), pt_to_str(PT_RAW),
 		    pt_to_str(PT_TYPE), pt_to_str(PT_OPTIONS));
-		(void) fprintf(fp, "\t%s\t\t%s, %s, %s|%s\n", rt_to_str(RT_NET),
+		(void) fprintf(fp, "\t%s\t\t%s, %s, %s, %s, %s, %s, %s %s\n",
+		    rt_to_str(RT_NET),
 		    pt_to_str(PT_ADDRESS), pt_to_str(PT_ALLOWED_ADDRESS),
-		    pt_to_str(PT_PHYSICAL), pt_to_str(PT_DEFROUTER));
-		(void) fprintf(fp, "\t%s\t\t%s\n", rt_to_str(RT_DEVICE),
-		    pt_to_str(PT_MATCH));
+		    pt_to_str(PT_GNIC), pt_to_str(PT_MAC),
+		    pt_to_str(PT_PHYSICAL), pt_to_str(PT_NPROP),
+		    pt_to_str(PT_VLANID), pt_to_str(PT_DEFROUTER));
+		(void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_DEVICE),
+		    pt_to_str(PT_MATCH), pt_to_str(PT_NPROP));
 		(void) fprintf(fp, "\t%s\t\t%s, %s\n", rt_to_str(RT_RCTL),
 		    pt_to_str(PT_NAME), pt_to_str(PT_VALUE));
 		(void) fprintf(fp, "\t%s\t\t%s, %s, %s\n", rt_to_str(RT_ATTR),
@@ -1698,6 +1732,17 @@
 			(void) strlcpy(zone_template, optarg,
 			    sizeof (zone_template));
 			break;
+		case 'X':
+			(void) snprintf(zone_template, sizeof (zone_template),
+			    "%s/%s.xml", ZONE_CONFIG_ROOT, zone);
+			err = zonecfg_get_xml_handle(zone_template, handle);
+			if (err != Z_OK) {
+				zone_perror(execname, err, B_TRUE);
+				exit(Z_ERR);
+			}
+			got_handle = B_TRUE;
+			need_to_commit = B_TRUE;
+			return;
 		default:
 			short_usage(CMD_CREATE);
 			arg_err = B_TRUE;
@@ -1801,6 +1846,7 @@
 	struct zone_dstab dstab;
 	struct zone_psettab psettab;
 	struct zone_rctlvaltab *valptr;
+	struct zone_res_attrtab *rap;
 	struct zone_admintab admintab;
 	int err, arg;
 	char zonepath[MAXPATHLEN], outfile[MAXPATHLEN], pool[MAXNAMELEN];
@@ -1970,7 +2016,17 @@
 		export_prop(of, PT_ALLOWED_ADDRESS,
 		    nwiftab.zone_nwif_allowed_address);
 		export_prop(of, PT_PHYSICAL, nwiftab.zone_nwif_physical);
+		export_prop(of, PT_MAC, nwiftab.zone_nwif_mac);
+		export_prop(of, PT_VLANID, nwiftab.zone_nwif_vlan_id);
+		export_prop(of, PT_GNIC, nwiftab.zone_nwif_gnic);
 		export_prop(of, PT_DEFROUTER, nwiftab.zone_nwif_defrouter);
+		for (rap = nwiftab.zone_nwif_attrp; rap != NULL;
+		    rap = rap->zone_res_attr_next) {
+			fprintf(of, "%s %s (%s=%s,%s=\"%s\")\n",
+			    cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP),
+			    pt_to_str(PT_NAME), rap->zone_res_attr_name,
+			    pt_to_str(PT_VALUE), rap->zone_res_attr_value);
+		}
 		(void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
 	}
 	(void) zonecfg_endnwifent(handle);
@@ -1983,6 +2039,13 @@
 		(void) fprintf(of, "%s %s\n", cmd_to_str(CMD_ADD),
 		    rt_to_str(RT_DEVICE));
 		export_prop(of, PT_MATCH, devtab.zone_dev_match);
+		for (rap = devtab.zone_dev_attrp; rap != NULL;
+		    rap = rap->zone_res_attr_next) {
+			fprintf(of, "%s %s (%s=%s,%s=\"%s\")\n",
+			    cmd_to_str(CMD_ADD), pt_to_str(PT_NPROP),
+			    pt_to_str(PT_NAME), rap->zone_res_attr_name,
+			    pt_to_str(PT_VALUE), rap->zone_res_attr_value);
+		}
 		(void) fprintf(of, "%s\n", cmd_to_str(CMD_END));
 	}
 	(void) zonecfg_enddevent(handle);
@@ -2349,7 +2412,69 @@
 	zonecfg_free_rctl_value_list(rctlvaltab);
 }
 
+/*
+ * Resource attribute ("property" resource embedded on net or dev resource)
+ */
 static void
+do_res_attr(struct zone_res_attrtab **headp, complex_property_ptr_t cpp)
+{
+	complex_property_ptr_t cp;
+	struct zone_res_attrtab *np;
+	int err;
+	boolean_t seen_name = B_FALSE, seen_value = B_FALSE;
+
+	if ((np = calloc(1, sizeof (struct zone_res_attrtab))) == NULL) {
+		zone_perror(zone, Z_NOMEM, B_TRUE);
+		exit(Z_ERR);
+	}
+
+	for (cp = cpp; cp != NULL; cp = cp->cp_next) {
+		switch (cp->cp_type) {
+		case PT_NAME:
+			if (seen_name) {
+				zerr(gettext("%s already specified"),
+				    pt_to_str(PT_NAME));
+				goto bad;
+			}
+			(void) strlcpy(np->zone_res_attr_name, cp->cp_value,
+			    sizeof (np->zone_res_attr_name));
+			seen_name = B_TRUE;
+			break;
+		case PT_VALUE:
+			if (seen_value) {
+				zerr(gettext("%s already specified"),
+				    pt_to_str(PT_VALUE));
+				goto bad;
+			}
+			(void) strlcpy(np->zone_res_attr_value, cp->cp_value,
+			    sizeof (np->zone_res_attr_value));
+			seen_value = B_TRUE;
+			break;
+		default:
+			zone_perror(pt_to_str(PT_NPROP), Z_NO_PROPERTY_TYPE,
+			    B_TRUE);
+			long_usage(CMD_ADD, B_TRUE);
+			usage(B_FALSE, HELP_PROPS);
+			zonecfg_free_res_attr_list(np);
+			return;
+		}
+	}
+
+	if (!seen_name)
+		zerr(gettext("%s not specified"), pt_to_str(PT_NAME));
+	if (!seen_value)
+		zerr(gettext("%s not specified"), pt_to_str(PT_VALUE));
+
+	err = zonecfg_add_res_attr(headp, np);
+	if (err != Z_OK)
+		zone_perror(pt_to_str(PT_NPROP), err, B_TRUE);
+	return;
+
+bad:
+	zonecfg_free_res_attr_list(np);
+}
+
+static void
 add_property(cmd_t *cmd)
 {
 	char *prop_id;
@@ -2416,6 +2541,44 @@
 			}
 		}
 		return;
+	case RT_NET:
+		if (prop_type != PT_NPROP) {
+			zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
+			    B_TRUE);
+			long_usage(CMD_ADD, B_TRUE);
+			usage(B_FALSE, HELP_PROPS);
+			return;
+		}
+		pp = cmd->cmd_property_ptr[0];
+		if (pp->pv_type != PROP_VAL_COMPLEX) {
+			zerr(gettext("A %s value was expected here."),
+			    pvt_to_str(PROP_VAL_COMPLEX));
+			saw_error = B_TRUE;
+			return;
+		}
+
+		do_res_attr(&(in_progress_nwiftab.zone_nwif_attrp),
+		    pp->pv_complex);
+		return;
+	case RT_DEVICE:
+		if (prop_type != PT_NPROP) {
+			zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
+			    B_TRUE);
+			long_usage(CMD_ADD, B_TRUE);
+			usage(B_FALSE, HELP_PROPS);
+			return;
+		}
+		pp = cmd->cmd_property_ptr[0];
+		if (pp->pv_type != PROP_VAL_COMPLEX) {
+			zerr(gettext("A %s value was expected here."),
+			    pvt_to_str(PROP_VAL_COMPLEX));
+			saw_error = B_TRUE;
+			return;
+		}
+
+		do_res_attr(&(in_progress_devtab.zone_dev_attrp),
+		    pp->pv_complex);
+		return;
 	case RT_RCTL:
 		if (prop_type != PT_VALUE) {
 			zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
@@ -2520,8 +2683,9 @@
 		resource_scope = cmd->cmd_res_type;
 		end_op = CMD_ADD;
 		add_resource(cmd);
-	} else
+	} else {
 		add_property(cmd);
+	}
 }
 
 /*
@@ -2719,6 +2883,21 @@
 			    pp->pv_simple,
 			    sizeof (nwiftab->zone_nwif_physical));
 			break;
+		case PT_MAC:
+			(void) strlcpy(nwiftab->zone_nwif_mac,
+			    pp->pv_simple,
+			    sizeof (nwiftab->zone_nwif_mac));
+			break;
+		case PT_VLANID:
+			(void) strlcpy(nwiftab->zone_nwif_vlan_id,
+			    pp->pv_simple,
+			    sizeof (nwiftab->zone_nwif_vlan_id));
+			break;
+		case PT_GNIC:
+			(void) strlcpy(nwiftab->zone_nwif_gnic,
+			    pp->pv_simple,
+			    sizeof (nwiftab->zone_nwif_gnic));
+			break;
 		case PT_DEFROUTER:
 			(void) strlcpy(nwiftab->zone_nwif_defrouter,
 			    pp->pv_simple,
@@ -3401,6 +3580,7 @@
 	int err, res_type, prop_type;
 	property_value_ptr_t pp;
 	struct zone_rctlvaltab *rctlvaltab;
+	struct zone_res_attrtab *np;
 	complex_property_ptr_t cx;
 
 	res_type = resource_scope;
@@ -3461,6 +3641,56 @@
 			}
 		}
 		return;
+	case RT_NET:		/* FALLTHRU */
+	case RT_DEVICE:
+		if (prop_type != PT_NPROP) {
+			zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
+			    B_TRUE);
+			long_usage(CMD_REMOVE, B_TRUE);
+			usage(B_FALSE, HELP_PROPS);
+			return;
+		}
+		pp = cmd->cmd_property_ptr[0];
+		if (pp->pv_type != PROP_VAL_COMPLEX) {
+			zerr(gettext("A %s value was expected here."),
+			    pvt_to_str(PROP_VAL_COMPLEX));
+			saw_error = B_TRUE;
+			return;
+		}
+
+		np = alloca(sizeof (struct zone_res_attrtab));
+		for (cx = pp->pv_complex; cx != NULL; cx = cx->cp_next) {
+			switch (cx->cp_type) {
+			case PT_NAME:
+				(void) strlcpy(np->zone_res_attr_name,
+				    cx->cp_value,
+				    sizeof (np->zone_res_attr_name));
+				break;
+			case PT_VALUE:
+				(void) strlcpy(np->zone_res_attr_value,
+				    cx->cp_value,
+				    sizeof (np->zone_res_attr_value));
+				break;
+			default:
+				zone_perror(pt_to_str(prop_type),
+				    Z_NO_PROPERTY_TYPE, B_TRUE);
+				long_usage(CMD_REMOVE, B_TRUE);
+				usage(B_FALSE, HELP_PROPS);
+				return;
+			}
+		}
+		np->zone_res_attr_next = NULL;
+
+		if (res_type == RT_NET) {
+			err = zonecfg_remove_res_attr(
+			    &(in_progress_nwiftab.zone_nwif_attrp), np);
+		} else {				/* RT_DEVICE */
+			err = zonecfg_remove_res_attr(
+			    &(in_progress_devtab.zone_dev_attrp), np);
+		}
+		if (err != Z_OK)
+			zone_perror(pt_to_str(prop_type), err, B_TRUE);
+		return;
 	case RT_RCTL:
 		if (prop_type != PT_VALUE) {
 			zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
@@ -3513,18 +3743,6 @@
 			zone_perror(pt_to_str(prop_type), err, B_TRUE);
 		zonecfg_free_rctl_value_list(rctlvaltab);
 		return;
-	case RT_NET:
-		if (prop_type != PT_DEFROUTER) {
-			zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
-			    B_TRUE);
-			long_usage(CMD_REMOVE, B_TRUE);
-			usage(B_FALSE, HELP_PROPS);
-			return;
-		} else {
-			bzero(&in_progress_nwiftab.zone_nwif_defrouter,
-			    sizeof (in_progress_nwiftab.zone_nwif_defrouter));
-			return;
-		}
 	default:
 		zone_perror(rt_to_str(res_type), Z_NO_RESOURCE_TYPE, B_TRUE);
 		long_usage(CMD_REMOVE, B_TRUE);
@@ -3597,6 +3815,30 @@
 			return;
 		}
 		break;
+	case RT_NET:
+		switch (prop_type) {
+		case PT_ALLOWED_ADDRESS:
+			in_progress_nwiftab.zone_nwif_allowed_address[0] = '\0';
+			need_to_commit = B_TRUE;
+			return;
+		case PT_DEFROUTER:
+			in_progress_nwiftab.zone_nwif_defrouter[0] = '\0';
+			need_to_commit = B_TRUE;
+			return;
+		case PT_GNIC:
+			in_progress_nwiftab.zone_nwif_gnic[0] = '\0';
+			need_to_commit = B_TRUE;
+			return;
+		case PT_MAC:
+			in_progress_nwiftab.zone_nwif_mac[0] = '\0';
+			need_to_commit = B_TRUE;
+			return;
+		case PT_VLANID:
+			in_progress_nwiftab.zone_nwif_vlan_id[0] = '\0';
+			need_to_commit = B_TRUE;
+			return;
+		}
+		break;
 	default:
 		break;
 	}
@@ -4203,10 +4445,12 @@
 	 * A nasty expression but not that complicated:
 	 * 1. fs options are simple or list (tested below)
 	 * 2. rctl value's are complex or list (tested below)
+	 * 3. net attr's are complex (tested below)
 	 * Anything else should be simple.
 	 */
 	if (!(res_type == RT_FS && prop_type == PT_OPTIONS) &&
 	    !(res_type == RT_RCTL && prop_type == PT_VALUE) &&
+	    !(res_type == RT_NET && prop_type == PT_NPROP) &&
 	    (pp->pv_type != PROP_VAL_SIMPLE ||
 	    (prop_id = pp->pv_simple) == NULL)) {
 		zerr(gettext("A %s value was expected here."),
@@ -4466,6 +4710,21 @@
 			    prop_id,
 			    sizeof (in_progress_nwiftab.zone_nwif_physical));
 			break;
+		case PT_MAC:
+			(void) strlcpy(in_progress_nwiftab.zone_nwif_mac,
+			    prop_id,
+			    sizeof (in_progress_nwiftab.zone_nwif_mac));
+			break;
+		case PT_VLANID:
+			(void) strlcpy(in_progress_nwiftab.zone_nwif_vlan_id,
+			    prop_id,
+			    sizeof (in_progress_nwiftab.zone_nwif_vlan_id));
+			break;
+		case PT_GNIC:
+			(void) strlcpy(in_progress_nwiftab.zone_nwif_gnic,
+			    prop_id,
+			    sizeof (in_progress_nwiftab.zone_nwif_gnic));
+			break;
 		case PT_DEFROUTER:
 			if (validate_net_address_syntax(prop_id, B_TRUE)
 			    != Z_OK) {
@@ -4476,6 +4735,20 @@
 			    prop_id,
 			    sizeof (in_progress_nwiftab.zone_nwif_defrouter));
 			break;
+		case PT_NPROP:
+			if (pp->pv_type != PROP_VAL_COMPLEX) {
+				zerr(gettext("A %s value was expected here."),
+				    pvt_to_str(PROP_VAL_COMPLEX));
+				saw_error = B_TRUE;
+				return;
+			}
+			zonecfg_free_res_attr_list(
+			    in_progress_nwiftab.zone_nwif_attrp);
+			in_progress_nwiftab.zone_nwif_attrp = NULL;
+			if (!(pp->pv_type == PROP_VAL_LIST &&
+			    pp->pv_list == NULL))
+				add_property(cmd);
+			break;
 		default:
 			zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
 			    B_TRUE);
@@ -4491,6 +4764,20 @@
 			    prop_id,
 			    sizeof (in_progress_devtab.zone_dev_match));
 			break;
+		case PT_NPROP:
+			if (pp->pv_type != PROP_VAL_COMPLEX) {
+				zerr(gettext("A %s value was expected here."),
+				    pvt_to_str(PROP_VAL_COMPLEX));
+				saw_error = B_TRUE;
+				return;
+			}
+			zonecfg_free_res_attr_list(
+			    in_progress_devtab.zone_dev_attrp);
+			in_progress_devtab.zone_dev_attrp = NULL;
+			if (!(pp->pv_type == PROP_VAL_LIST &&
+			    pp->pv_list == NULL))
+				add_property(cmd);
+			break;
 		default:
 			zone_perror(pt_to_str(prop_type), Z_NO_PROPERTY_TYPE,
 			    B_TRUE);
@@ -5030,12 +5317,25 @@
 static void
 output_net(FILE *fp, struct zone_nwiftab *nwiftab)
 {
+	struct zone_res_attrtab *np;
+
 	(void) fprintf(fp, "%s:\n", rt_to_str(RT_NET));
 	output_prop(fp, PT_ADDRESS, nwiftab->zone_nwif_address, B_TRUE);
 	output_prop(fp, PT_ALLOWED_ADDRESS,
 	    nwiftab->zone_nwif_allowed_address, B_TRUE);
-	output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE);
 	output_prop(fp, PT_DEFROUTER, nwiftab->zone_nwif_defrouter, B_TRUE);
+	output_prop(fp, PT_GNIC, nwiftab->zone_nwif_gnic, B_TRUE);
+	output_prop(fp, PT_MAC, nwiftab->zone_nwif_mac, B_TRUE);
+	output_prop(fp, PT_PHYSICAL, nwiftab->zone_nwif_physical, B_TRUE);
+	output_prop(fp, PT_VLANID, nwiftab->zone_nwif_vlan_id, B_TRUE);
+
+	for (np = nwiftab->zone_nwif_attrp; np != NULL;
+	    np = np->zone_res_attr_next) {
+		fprintf(fp, "\t%s: (%s=%s,%s=\"%s\")\n",
+		    pt_to_str(PT_NPROP),
+		    pt_to_str(PT_NAME), np->zone_res_attr_name,
+		    pt_to_str(PT_VALUE), np->zone_res_attr_value);
+	}
 }
 
 static void
@@ -5078,8 +5378,18 @@
 static void
 output_dev(FILE *fp, struct zone_devtab *devtab)
 {
+	struct zone_res_attrtab *np;
+
 	(void) fprintf(fp, "%s:\n", rt_to_str(RT_DEVICE));
 	output_prop(fp, PT_MATCH, devtab->zone_dev_match, B_TRUE);
+
+	for (np = devtab->zone_dev_attrp; np != NULL;
+	    np = np->zone_res_attr_next) {
+		fprintf(fp, "\t%s: (%s=%s,%s=\"%s\")\n",
+		    pt_to_str(PT_NPROP),
+		    pt_to_str(PT_NAME), np->zone_res_attr_name,
+		    pt_to_str(PT_VALUE), np->zone_res_attr_value);
+	}
 }
 
 static void
@@ -6106,6 +6416,12 @@
 
 	if (save) {
 		if (ret_val == Z_OK) {
+			/*
+			 * If the zone doesn't yet have a debug ID, set one now.
+			 */
+			if (zonecfg_get_did(handle) == -1)
+				zonecfg_set_did(handle);
+
 			if ((ret_val = zonecfg_save(handle)) == Z_OK) {
 				need_to_commit = B_FALSE;
 				(void) strlcpy(revert_zone, zone,
