Print this page
Commit IPMP changes

@@ -228,12 +228,13 @@
 
         /*
          * 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.
          */
         for (nvp = nvlist_next_nvpair(onvl, NULL); nvp != NULL;

@@ -257,13 +258,15 @@
                         break;
                 }
         }
         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);
 fail:
         nvlist_free(onvl);

@@ -1511,11 +1514,10 @@
 
         /* Persistent operation not allowed on a temporary object. */
         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
          * in.ndpd retrieving the address properties from ipmgmtd for given
          * address object and then setting them on auto-configured addresses,

@@ -2030,12 +2032,12 @@
                 status = ipadm_set_addr(&ipaddr, cidraddr, af);
                 free(cidraddr);
         } 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);
                 if (status != IPADM_SUCCESS)
                         return (status);

@@ -2176,17 +2178,17 @@
 
         if ((aname = strchr(ifname, '/')) != NULL)
                 *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);
 
         /*
          * If the ifname has logical interface number, extract it and assign

@@ -2364,14 +2366,10 @@
 static ipadm_status_t
 i_ipadm_get_db_addr(ipadm_handle_t iph, const char *ifname,
     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));
         garg.ia_cmd = IPMGMT_CMD_GETADDR;
         if (aobjname != NULL)

@@ -2378,20 +2376,11 @@
                 (void) strlcpy(garg.ia_aobjname, aobjname,
                     sizeof (garg.ia_aobjname));
         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));
 }
 
 /*
  * Adds the IP address contained in the 'ipaddr' argument to the physical
  * interface represented by 'ifname' after doing the required validation.

@@ -2430,13 +2419,13 @@
         if (!ipadm_check_auth())
                 return (IPADM_EAUTH);
 
         /* 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,
          * a default name will be generated and added to the daemon's
          * aobjmap.

@@ -2479,13 +2468,14 @@
          * down any interface configuration, so the namespace for the interface
          * is fully controlled by the GZ.
          */
         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);
         /* Plumb the IP interfaces if necessary */
         status = i_ipadm_create_if(iph, ifname, af, flags);
         if (status != IPADM_SUCCESS && status != IPADM_IF_EXISTS) {

@@ -2629,10 +2619,11 @@
         ipadm_status_t                  status = IPADM_SUCCESS;
         int                             sock;
         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;
         boolean_t                       default_prefixlen = B_FALSE;
         boolean_t                       is_boot;

@@ -2698,11 +2689,14 @@
                         goto ret;
                 }
         }
 
         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.
                  * No need to tear down the address.
                  */

@@ -3201,19 +3195,22 @@
         if (status != IPADM_SUCCESS)
                 return (status);
 
         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)))
                 return (IPADM_NOTSUP);
 
         i_ipadm_addrobj2lifname(ipaddr, lifname, sizeof (lifname));
+
         return (i_ipadm_get_flags(iph, lifname, ipaddr->ipadm_af, ifflags));
 }
 
 /*
  * Marks the address in the address object `aobjname' up. This operation is

@@ -3421,12 +3418,17 @@
         if (legacy && ipaddr->ipadm_atype != IPADM_ADDR_STATIC)
                 return (IPADM_NOTSUP);
 
         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);
         /*
          * For legacy case, interfaces are not implicitly plumbed. We need to

@@ -3446,20 +3448,14 @@
 
         /* Check if interface exists in the persistent configuration. */
         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)
                         return (status);
         }