--- old/usr/src/lib/libipadm/common/ipadm_addr.c	Sat Jul  5 09:39:27 2014
+++ new/usr/src/lib/libipadm/common/ipadm_addr.c	Sat Jul  5 09:39:27 2014
@@ -230,8 +230,9 @@
 	 * Get the address line in the nvlist `onvl' from ipmgmtd daemon.
 	 */
 	status = i_ipadm_get_db_addr(iph, NULL, aobjname, &onvl);
-	if (status != IPADM_SUCCESS)
+	if (status != IPADM_SUCCESS) {
 		return (status);
+	}
 	/*
 	 * Walk through the nvlist `onvl' to extract the IPADM_NVP_IPV4ADDR
 	 * or the IPADM_NVP_IPV6ADDR name-value pair.
@@ -259,9 +260,11 @@
 	}
 	assert(af != AF_UNSPEC);
 	if (nvpair_value_nvlist(nvp, &nvladdr) != 0 ||
-	    nvlist_lookup_string(nvladdr, IPADM_NVP_IPADDRHNAME, &sname) != 0 ||
-	    ipadm_set_addr(ipaddr, sname, af) != IPADM_SUCCESS) {
+	    nvlist_lookup_string(nvladdr, IPADM_NVP_IPADDRHNAME, &sname) != 0)
 		goto fail;
+
+	if (ipadm_set_addr(ipaddr, sname, af) != IPADM_SUCCESS) {
+		goto fail;
 	}
 	nvlist_free(onvl);
 	return (IPADM_SUCCESS);
@@ -1513,7 +1516,6 @@
 	if ((pflags & IPADM_OPT_PERSIST) &&
 	    !(ipaddr.ipadm_flags & IPMGMT_PERSIST))
 		return (IPADM_TEMPORARY_OBJ);
-
 	/*
 	 * Currently, setting an address property on an address object of type
 	 * IPADM_ADDR_IPV6_ADDRCONF is not supported. Supporting it involves
@@ -2032,8 +2034,8 @@
 	} else {
 		status = ipadm_set_addr(&ipaddr, sname, af);
 	}
-	if (status != IPADM_SUCCESS)
-		return (status);
+//	if (status != IPADM_SUCCESS)
+//		return (status);
 
 	if (dname != NULL) {
 		status = ipadm_set_dst_addr(&ipaddr, dname, af);
@@ -2178,13 +2180,13 @@
 		*aname++ = '\0';
 
 	/* Check if the interface name is valid. */
-	if (!ifparse_ifspec(ifname, &ifsp))
+	if (!ifparse_ifspec(ifname, &ifsp)) {
 		return (IPADM_INVALID_ARG);
-
+	}
 	/* Check if the given addrobj name is valid. */
-	if (aname != NULL && !i_ipadm_is_user_aobjname_valid(aname))
+	if (aname != NULL && !i_ipadm_is_user_aobjname_valid(aname)) {
 		return (IPADM_INVALID_ARG);
-
+	}
 	if ((newaddr = calloc(1, sizeof (struct ipadm_addrobj_s))) == NULL)
 		return (IPADM_NO_MEMORY);
 
@@ -2366,10 +2368,6 @@
     const char *aobjname, nvlist_t **onvl)
 {
 	ipmgmt_getaddr_arg_t	garg;
-	ipmgmt_get_rval_t	*rvalp;
-	int			err;
-	size_t			nvlsize;
-	char			*nvlbuf;
 
 	/* Populate the door_call argument structure */
 	bzero(&garg, sizeof (garg));
@@ -2380,16 +2378,7 @@
 	if (ifname != NULL)
 		(void) strlcpy(garg.ia_ifname, ifname, sizeof (garg.ia_ifname));
 
-	rvalp = malloc(sizeof (ipmgmt_get_rval_t));
-	err = ipadm_door_call(iph, &garg, sizeof (garg), (void **)&rvalp,
-	    sizeof (*rvalp), B_TRUE);
-	if (err == 0) {
-		nvlsize = rvalp->ir_nvlsize;
-		nvlbuf = (char *)rvalp + sizeof (ipmgmt_get_rval_t);
-		err = nvlist_unpack(nvlbuf, nvlsize, onvl, NV_ENCODE_NATIVE);
-	}
-	free(rvalp);
-	return (ipadm_errno2status(err));
+	return (i_ipadm_call_ipmgmtd(iph, (void *) &garg, sizeof (garg), onvl));
 }
 
 /*
@@ -2432,9 +2421,9 @@
 
 	/* Validate the addrobj. This also fills in addr->ipadm_ifname. */
 	status = i_ipadm_validate_create_addr(iph, addr, flags);
-	if (status != IPADM_SUCCESS)
+	if (status != IPADM_SUCCESS) {
 		return (status);
-
+	}
 	/*
 	 * For Legacy case, check if an addrobj already exists for the
 	 * given logical interface name. If one does not exist,
@@ -2481,8 +2470,9 @@
 	 */
 	if (!is_boot && (!legacy || !aobjfound)) {
 		status = i_ipadm_lookupadd_addrobj(iph, addr);
-		if (status != IPADM_SUCCESS)
+		if (status != IPADM_SUCCESS) {
 			return (status);
+		}
 	}
 
 	is_6to4 = i_ipadm_is_6to4(iph, ifname);
@@ -2631,6 +2621,7 @@
 	struct sockaddr_storage		m, *mask = &m;
 	const struct sockaddr_storage	*addr = &ipaddr->ipadm_static_addr;
 	const struct sockaddr_storage	*daddr = &ipaddr->ipadm_static_dst_addr;
+	uint32_t			iff_flags = IFF_UP;
 	sa_family_t			af;
 	boolean_t			legacy = (iph->iph_flags & IPH_LEGACY);
 	struct ipadm_addrobj_s		legacy_addr;
@@ -2700,7 +2691,10 @@
 	}
 
 	if (flags & IPADM_OPT_UP) {
-		status = i_ipadm_set_flags(iph, lifr.lifr_name, af, IFF_UP, 0);
+		if (i_ipadm_is_under_ipmp(iph, lifr.lifr_name)) {
+			iff_flags |= IFF_NOFAILOVER;
+		}
+		status = i_ipadm_set_flags(iph, lifr.lifr_name, af, iff_flags, 0);
 
 		/*
 		 * IPADM_DAD_FOUND is a soft-error for create-addr.
@@ -3203,9 +3197,11 @@
 
 	if (!(ipaddr->ipadm_flags & IPMGMT_ACTIVE))
 		return (IPADM_OP_DISABLE_OBJ);
+
 	if ((ipadm_flags & IPADM_OPT_PERSIST) &&
 	    !(ipaddr->ipadm_flags & IPMGMT_PERSIST))
 		return (IPADM_TEMPORARY_OBJ);
+
 	if (ipaddr->ipadm_atype == IPADM_ADDR_IPV6_ADDRCONF ||
 	    (ipaddr->ipadm_atype == IPADM_ADDR_DHCP &&
 	    (ipadm_flags & IPADM_OPT_PERSIST)))
@@ -3212,6 +3208,7 @@
 		return (IPADM_NOTSUP);
 
 	i_ipadm_addrobj2lifname(ipaddr, lifname, sizeof (lifname));
+
 	return (i_ipadm_get_flags(iph, lifname, ipaddr->ipadm_af, ifflags));
 }
 
@@ -3423,8 +3420,13 @@
 
 	ifname = ipaddr->ipadm_ifname;
 
-	if (i_ipadm_is_ipmp(iph, ifname) || i_ipadm_is_under_ipmp(iph, ifname))
-		return (IPADM_NOTSUP);
+	/*
+	 * do not go furhter when we are under ipmp. 
+	 * The interface is plumbed up and we are going to add
+	 * NOFAILOVER address to make in.mpathd happy.
+	 */ 
+	if (i_ipadm_is_under_ipmp(iph, ifname))
+		return (IPADM_SUCCESS);
 
 	af = ipaddr->ipadm_af;
 	af_exists = ipadm_if_enabled(iph, ifname, af);
@@ -3448,16 +3450,10 @@
 	status = i_ipadm_if_pexists(iph, ifname, af, &p_exists);
 	if (status != IPADM_SUCCESS)
 		return (status);
+
 	if (!a_exists && p_exists)
 		return (IPADM_OP_DISABLE_OBJ);
-	if ((flags & IPADM_OPT_PERSIST) && a_exists && !p_exists) {
-		/*
-		 * If address has to be created persistently,
-		 * and the interface does not exist in the persistent
-		 * store but in active config, fail.
-		 */
-		return (IPADM_TEMPORARY_OBJ);
-	}
+
 	if (af_exists) {
 		status = i_ipadm_get_flags(iph, ifname, af, &ifflags);
 		if (status != IPADM_SUCCESS)
