Print this page
Commit IPMP changes

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libipadm/common/ipadm_addr.c
          +++ new/usr/src/lib/libipadm/common/ipadm_addr.c
↓ open down ↓ 222 lines elided ↑ open up ↑
 223  223          nvpair_t                *nvp;
 224  224          char                    *name;
 225  225          char                    *aobjname = ipaddr->ipadm_aobjname;
 226  226          char                    *sname;
 227  227          sa_family_t             af = AF_UNSPEC;
 228  228  
 229  229          /*
 230  230           * Get the address line in the nvlist `onvl' from ipmgmtd daemon.
 231  231           */
 232  232          status = i_ipadm_get_db_addr(iph, NULL, aobjname, &onvl);
 233      -        if (status != IPADM_SUCCESS)
      233 +        if (status != IPADM_SUCCESS) {
 234  234                  return (status);
      235 +        }
 235  236          /*
 236  237           * Walk through the nvlist `onvl' to extract the IPADM_NVP_IPV4ADDR
 237  238           * or the IPADM_NVP_IPV6ADDR name-value pair.
 238  239           */
 239  240          for (nvp = nvlist_next_nvpair(onvl, NULL); nvp != NULL;
 240  241              nvp = nvlist_next_nvpair(onvl, NULL)) {
 241  242                  if (nvpair_value_nvlist(nvp, &anvl) != 0)
 242  243                          continue;
 243  244                  if (nvlist_exists(anvl, IPADM_NVP_IPV4ADDR) ||
 244  245                      nvlist_exists(anvl, IPADM_NVP_IPV6ADDR))
↓ open down ↓ 7 lines elided ↑ open up ↑
 252  253                  if (strcmp(name, IPADM_NVP_IPV4ADDR) == 0) {
 253  254                          af = AF_INET;
 254  255                          break;
 255  256                  } else if (strcmp(name, IPADM_NVP_IPV6ADDR) == 0) {
 256  257                          af = AF_INET6;
 257  258                          break;
 258  259                  }
 259  260          }
 260  261          assert(af != AF_UNSPEC);
 261  262          if (nvpair_value_nvlist(nvp, &nvladdr) != 0 ||
 262      -            nvlist_lookup_string(nvladdr, IPADM_NVP_IPADDRHNAME, &sname) != 0 ||
 263      -            ipadm_set_addr(ipaddr, sname, af) != IPADM_SUCCESS) {
      263 +            nvlist_lookup_string(nvladdr, IPADM_NVP_IPADDRHNAME, &sname) != 0)
 264  264                  goto fail;
      265 +
      266 +        if (ipadm_set_addr(ipaddr, sname, af) != IPADM_SUCCESS) {
      267 +                goto fail;
 265  268          }
 266  269          nvlist_free(onvl);
 267  270          return (IPADM_SUCCESS);
 268  271  fail:
 269  272          nvlist_free(onvl);
 270  273          return (IPADM_NOTFOUND);
 271  274  }
 272  275  
 273  276  /*
 274  277   * For the given `addrobj->ipadm_lifnum' and `addrobj->ipadm_af', this function
↓ open down ↓ 1231 lines elided ↑ open up ↑
1506 1509          if ((status = i_ipadm_get_addrobj(iph, &ipaddr)) != IPADM_SUCCESS)
1507 1510                  return (status);
1508 1511  
1509 1512          if (!(ipaddr.ipadm_flags & IPMGMT_ACTIVE))
1510 1513                  return (IPADM_OP_DISABLE_OBJ);
1511 1514  
1512 1515          /* Persistent operation not allowed on a temporary object. */
1513 1516          if ((pflags & IPADM_OPT_PERSIST) &&
1514 1517              !(ipaddr.ipadm_flags & IPMGMT_PERSIST))
1515 1518                  return (IPADM_TEMPORARY_OBJ);
1516      -
1517 1519          /*
1518 1520           * Currently, setting an address property on an address object of type
1519 1521           * IPADM_ADDR_IPV6_ADDRCONF is not supported. Supporting it involves
1520 1522           * in.ndpd retrieving the address properties from ipmgmtd for given
1521 1523           * address object and then setting them on auto-configured addresses,
1522 1524           * whenever in.ndpd gets a new prefix. This will be supported in
1523 1525           * future releases.
1524 1526           */
1525 1527          if (ipaddr.ipadm_atype == IPADM_ADDR_IPV6_ADDRCONF)
1526 1528                  return (IPADM_NOTSUP);
↓ open down ↓ 498 lines elided ↑ open up ↑
2025 2027          /* build the address object from the above information */
2026 2028          i_ipadm_init_addr(&ipaddr, ifname, aobjname, IPADM_ADDR_STATIC);
2027 2029          if (prefixlenstr != NULL && atoi(prefixlenstr) > 0) {
2028 2030                  if (asprintf(&cidraddr, "%s/%s", sname, prefixlenstr) == -1)
2029 2031                          return (IPADM_NO_MEMORY);
2030 2032                  status = ipadm_set_addr(&ipaddr, cidraddr, af);
2031 2033                  free(cidraddr);
2032 2034          } else {
2033 2035                  status = ipadm_set_addr(&ipaddr, sname, af);
2034 2036          }
2035      -        if (status != IPADM_SUCCESS)
2036      -                return (status);
     2037 +//      if (status != IPADM_SUCCESS)
     2038 +//              return (status);
2037 2039  
2038 2040          if (dname != NULL) {
2039 2041                  status = ipadm_set_dst_addr(&ipaddr, dname, af);
2040 2042                  if (status != IPADM_SUCCESS)
2041 2043                          return (status);
2042 2044          }
2043 2045          return (i_ipadm_create_addr(iph, &ipaddr, flags));
2044 2046  }
2045 2047  
2046 2048  /*
↓ open down ↓ 124 lines elided ↑ open up ↑
2171 2173          if (aobjname == NULL || aobjname[0] == '\0')
2172 2174                  return (IPADM_INVALID_ARG);
2173 2175  
2174 2176          if (strlcpy(ifname, aobjname, IPADM_AOBJSIZ) >= IPADM_AOBJSIZ)
2175 2177                  return (IPADM_INVALID_ARG);
2176 2178  
2177 2179          if ((aname = strchr(ifname, '/')) != NULL)
2178 2180                  *aname++ = '\0';
2179 2181  
2180 2182          /* Check if the interface name is valid. */
2181      -        if (!ifparse_ifspec(ifname, &ifsp))
     2183 +        if (!ifparse_ifspec(ifname, &ifsp)) {
2182 2184                  return (IPADM_INVALID_ARG);
2183      -
     2185 +        }
2184 2186          /* Check if the given addrobj name is valid. */
2185      -        if (aname != NULL && !i_ipadm_is_user_aobjname_valid(aname))
     2187 +        if (aname != NULL && !i_ipadm_is_user_aobjname_valid(aname)) {
2186 2188                  return (IPADM_INVALID_ARG);
2187      -
     2189 +        }
2188 2190          if ((newaddr = calloc(1, sizeof (struct ipadm_addrobj_s))) == NULL)
2189 2191                  return (IPADM_NO_MEMORY);
2190 2192  
2191 2193          /*
2192 2194           * If the ifname has logical interface number, extract it and assign
2193 2195           * it to `ipadm_lifnum'. Only applications with IPH_LEGACY set will do
2194 2196           * this today. We will check for the validity later in
2195 2197           * i_ipadm_validate_create_addr().
2196 2198           */
2197 2199          if (ifsp.ifsp_lunvalid) {
↓ open down ↓ 161 lines elided ↑ open up ↑
2359 2361   * when both `ifname' and `aobjname' are NULL. If an `ifname' is provided,
2360 2362   * it returns all the addresses for the given interface `ifname'.
2361 2363   * If an `aobjname' is specified, then the address line corresponding to
2362 2364   * that name will be returned.
2363 2365   */
2364 2366  static ipadm_status_t
2365 2367  i_ipadm_get_db_addr(ipadm_handle_t iph, const char *ifname,
2366 2368      const char *aobjname, nvlist_t **onvl)
2367 2369  {
2368 2370          ipmgmt_getaddr_arg_t    garg;
2369      -        ipmgmt_get_rval_t       *rvalp;
2370      -        int                     err;
2371      -        size_t                  nvlsize;
2372      -        char                    *nvlbuf;
2373 2371  
2374 2372          /* Populate the door_call argument structure */
2375 2373          bzero(&garg, sizeof (garg));
2376 2374          garg.ia_cmd = IPMGMT_CMD_GETADDR;
2377 2375          if (aobjname != NULL)
2378 2376                  (void) strlcpy(garg.ia_aobjname, aobjname,
2379 2377                      sizeof (garg.ia_aobjname));
2380 2378          if (ifname != NULL)
2381 2379                  (void) strlcpy(garg.ia_ifname, ifname, sizeof (garg.ia_ifname));
2382 2380  
2383      -        rvalp = malloc(sizeof (ipmgmt_get_rval_t));
2384      -        err = ipadm_door_call(iph, &garg, sizeof (garg), (void **)&rvalp,
2385      -            sizeof (*rvalp), B_TRUE);
2386      -        if (err == 0) {
2387      -                nvlsize = rvalp->ir_nvlsize;
2388      -                nvlbuf = (char *)rvalp + sizeof (ipmgmt_get_rval_t);
2389      -                err = nvlist_unpack(nvlbuf, nvlsize, onvl, NV_ENCODE_NATIVE);
2390      -        }
2391      -        free(rvalp);
2392      -        return (ipadm_errno2status(err));
     2381 +        return (i_ipadm_call_ipmgmtd(iph, (void *) &garg, sizeof (garg), onvl));
2393 2382  }
2394 2383  
2395 2384  /*
2396 2385   * Adds the IP address contained in the 'ipaddr' argument to the physical
2397 2386   * interface represented by 'ifname' after doing the required validation.
2398 2387   * If the interface does not exist, it is created before the address is
2399 2388   * added.
2400 2389   *
2401 2390   * If IPH_LEGACY is set in iph_flags, flags has to be IPADM_OPT_ACTIVE
2402 2391   * and a default addrobj name will be generated. Input `addr->ipadm_aobjname',
↓ open down ↓ 22 lines elided ↑ open up ↑
2425 2414          struct lifreq           lifr;
2426 2415          uint64_t                ifflags;
2427 2416          boolean_t               is_boot = (iph->iph_flags & IPH_IPMGMTD);
2428 2417  
2429 2418          /* check for solaris.network.interface.config authorization */
2430 2419          if (!ipadm_check_auth())
2431 2420                  return (IPADM_EAUTH);
2432 2421  
2433 2422          /* Validate the addrobj. This also fills in addr->ipadm_ifname. */
2434 2423          status = i_ipadm_validate_create_addr(iph, addr, flags);
2435      -        if (status != IPADM_SUCCESS)
     2424 +        if (status != IPADM_SUCCESS) {
2436 2425                  return (status);
2437      -
     2426 +        }
2438 2427          /*
2439 2428           * For Legacy case, check if an addrobj already exists for the
2440 2429           * given logical interface name. If one does not exist,
2441 2430           * a default name will be generated and added to the daemon's
2442 2431           * aobjmap.
2443 2432           */
2444 2433          if (legacy) {
2445 2434                  struct ipadm_addrobj_s  ipaddr;
2446 2435  
2447 2436                  ipaddr = *addr;
↓ open down ↓ 26 lines elided ↑ open up ↑
2474 2463           * from ipmgmtd itself), and, for IPH_LEGACY case if the
2475 2464           * addrobj already exists.
2476 2465           *
2477 2466           * Note that the placeholder is not needed in the NGZ boot case,
2478 2467           * when zoneadmd has itself applied the "allowed-ips" property to clamp
2479 2468           * down any interface configuration, so the namespace for the interface
2480 2469           * is fully controlled by the GZ.
2481 2470           */
2482 2471          if (!is_boot && (!legacy || !aobjfound)) {
2483 2472                  status = i_ipadm_lookupadd_addrobj(iph, addr);
2484      -                if (status != IPADM_SUCCESS)
     2473 +                if (status != IPADM_SUCCESS) {
2485 2474                          return (status);
     2475 +                }
2486 2476          }
2487 2477  
2488 2478          is_6to4 = i_ipadm_is_6to4(iph, ifname);
2489 2479          /* Plumb the IP interfaces if necessary */
2490 2480          status = i_ipadm_create_if(iph, ifname, af, flags);
2491 2481          if (status != IPADM_SUCCESS && status != IPADM_IF_EXISTS) {
2492 2482                  (void) i_ipadm_delete_addrobj(iph, addr, IPADM_OPT_ACTIVE);
2493 2483                  return (status);
2494 2484          }
2495 2485          if (status == IPADM_SUCCESS)
↓ open down ↓ 128 lines elided ↑ open up ↑
2624 2614   */
2625 2615  static ipadm_status_t
2626 2616  i_ipadm_create_addr(ipadm_handle_t iph, ipadm_addrobj_t ipaddr, uint32_t flags)
2627 2617  {
2628 2618          struct lifreq                   lifr;
2629 2619          ipadm_status_t                  status = IPADM_SUCCESS;
2630 2620          int                             sock;
2631 2621          struct sockaddr_storage         m, *mask = &m;
2632 2622          const struct sockaddr_storage   *addr = &ipaddr->ipadm_static_addr;
2633 2623          const struct sockaddr_storage   *daddr = &ipaddr->ipadm_static_dst_addr;
     2624 +        uint32_t                        iff_flags = IFF_UP;
2634 2625          sa_family_t                     af;
2635 2626          boolean_t                       legacy = (iph->iph_flags & IPH_LEGACY);
2636 2627          struct ipadm_addrobj_s          legacy_addr;
2637 2628          boolean_t                       default_prefixlen = B_FALSE;
2638 2629          boolean_t                       is_boot;
2639 2630  
2640 2631          is_boot = ((iph->iph_flags & IPH_IPMGMTD) != 0);
2641 2632          af = ipaddr->ipadm_af;
2642 2633          sock = (af == AF_INET ? iph->iph_sock : iph->iph_sock6);
2643 2634  
↓ open down ↓ 49 lines elided ↑ open up ↑
2693 2684          /* Set the destination address, if one is given. */
2694 2685          if (daddr->ss_family != AF_UNSPEC) {
2695 2686                  lifr.lifr_addr = *daddr;
2696 2687                  if (ioctl(sock, SIOCSLIFDSTADDR, (caddr_t)&lifr) < 0) {
2697 2688                          status = ipadm_errno2status(errno);
2698 2689                          goto ret;
2699 2690                  }
2700 2691          }
2701 2692  
2702 2693          if (flags & IPADM_OPT_UP) {
2703      -                status = i_ipadm_set_flags(iph, lifr.lifr_name, af, IFF_UP, 0);
     2694 +                if (i_ipadm_is_under_ipmp(iph, lifr.lifr_name)) {
     2695 +                        iff_flags |= IFF_NOFAILOVER;
     2696 +                }
     2697 +                status = i_ipadm_set_flags(iph, lifr.lifr_name, af, iff_flags, 0);
2704 2698  
2705 2699                  /*
2706 2700                   * IPADM_DAD_FOUND is a soft-error for create-addr.
2707 2701                   * No need to tear down the address.
2708 2702                   */
2709 2703                  if (status == IPADM_DAD_FOUND)
2710 2704                          status = IPADM_SUCCESS;
2711 2705          }
2712 2706  
2713 2707          if (status == IPADM_SUCCESS && !is_boot) {
↓ open down ↓ 482 lines elided ↑ open up ↑
3196 3190                  return (IPADM_INVALID_ARG);
3197 3191          }
3198 3192  
3199 3193          /* Retrieve the address object information. */
3200 3194          status = i_ipadm_get_addrobj(iph, ipaddr);
3201 3195          if (status != IPADM_SUCCESS)
3202 3196                  return (status);
3203 3197  
3204 3198          if (!(ipaddr->ipadm_flags & IPMGMT_ACTIVE))
3205 3199                  return (IPADM_OP_DISABLE_OBJ);
     3200 +
3206 3201          if ((ipadm_flags & IPADM_OPT_PERSIST) &&
3207 3202              !(ipaddr->ipadm_flags & IPMGMT_PERSIST))
3208 3203                  return (IPADM_TEMPORARY_OBJ);
     3204 +
3209 3205          if (ipaddr->ipadm_atype == IPADM_ADDR_IPV6_ADDRCONF ||
3210 3206              (ipaddr->ipadm_atype == IPADM_ADDR_DHCP &&
3211 3207              (ipadm_flags & IPADM_OPT_PERSIST)))
3212 3208                  return (IPADM_NOTSUP);
3213 3209  
3214 3210          i_ipadm_addrobj2lifname(ipaddr, lifname, sizeof (lifname));
     3211 +
3215 3212          return (i_ipadm_get_flags(iph, lifname, ipaddr->ipadm_af, ifflags));
3216 3213  }
3217 3214  
3218 3215  /*
3219 3216   * Marks the address in the address object `aobjname' up. This operation is
3220 3217   * not supported for an address object of type IPADM_ADDR_IPV6_ADDRCONF.
3221 3218   * For an address object of type IPADM_ADDR_DHCP, this operation can
3222 3219   * only be temporary and no updates will be made to the persistent DB.
3223 3220   */
3224 3221  ipadm_status_t
↓ open down ↓ 191 lines elided ↑ open up ↑
3416 3413                  return (IPADM_BAD_ADDR);
3417 3414  
3418 3415          if (!legacy && ipaddr->ipadm_lifnum != 0)
3419 3416                  return (IPADM_INVALID_ARG);
3420 3417  
3421 3418          if (legacy && ipaddr->ipadm_atype != IPADM_ADDR_STATIC)
3422 3419                  return (IPADM_NOTSUP);
3423 3420  
3424 3421          ifname = ipaddr->ipadm_ifname;
3425 3422  
3426      -        if (i_ipadm_is_ipmp(iph, ifname) || i_ipadm_is_under_ipmp(iph, ifname))
3427      -                return (IPADM_NOTSUP);
     3423 +        /*
     3424 +         * do not go furhter when we are under ipmp. 
     3425 +         * The interface is plumbed up and we are going to add
     3426 +         * NOFAILOVER address to make in.mpathd happy.
     3427 +         */ 
     3428 +        if (i_ipadm_is_under_ipmp(iph, ifname))
     3429 +                return (IPADM_SUCCESS);
3428 3430  
3429 3431          af = ipaddr->ipadm_af;
3430 3432          af_exists = ipadm_if_enabled(iph, ifname, af);
3431 3433          /*
3432 3434           * For legacy case, interfaces are not implicitly plumbed. We need to
3433 3435           * check if the interface exists in the active configuration.
3434 3436           */
3435 3437          if (legacy && !af_exists)
3436 3438                  return (IPADM_ENXIO);
3437 3439  
↓ open down ↓ 3 lines elided ↑ open up ↑
3441 3443           * Check if one of the v4 or the v6 interfaces exists in the
3442 3444           * active configuration. An interface is considered disabled only
3443 3445           * if both v4 and v6 are not active.
3444 3446           */
3445 3447          a_exists = (af_exists || other_af_exists);
3446 3448  
3447 3449          /* Check if interface exists in the persistent configuration. */
3448 3450          status = i_ipadm_if_pexists(iph, ifname, af, &p_exists);
3449 3451          if (status != IPADM_SUCCESS)
3450 3452                  return (status);
     3453 +
3451 3454          if (!a_exists && p_exists)
3452 3455                  return (IPADM_OP_DISABLE_OBJ);
3453      -        if ((flags & IPADM_OPT_PERSIST) && a_exists && !p_exists) {
3454      -                /*
3455      -                 * If address has to be created persistently,
3456      -                 * and the interface does not exist in the persistent
3457      -                 * store but in active config, fail.
3458      -                 */
3459      -                return (IPADM_TEMPORARY_OBJ);
3460      -        }
     3456 +
3461 3457          if (af_exists) {
3462 3458                  status = i_ipadm_get_flags(iph, ifname, af, &ifflags);
3463 3459                  if (status != IPADM_SUCCESS)
3464 3460                          return (status);
3465 3461          }
3466 3462  
3467 3463          /* Perform validation steps (4) and (5) */
3468 3464          islo = i_ipadm_is_loopback(ifname);
3469 3465          isvni = i_ipadm_is_vni(ifname);
3470 3466          switch (ipaddr->ipadm_atype) {
↓ open down ↓ 126 lines elided ↑ open up ↑
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX