Print this page
Commit IPMP changes

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/libipadm/common/libipadm.c
          +++ new/usr/src/lib/libipadm/common/libipadm.c
↓ open down ↓ 12 lines elided ↑ open up ↑
  13   13   * When distributing Covered Code, include this CDDL HEADER in each
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
       23 + * Copyright 2013 Nexenta Systems, Inc. All rights reserved.
  23   24   */
  24   25  
  25   26  #include <stdio.h>
  26   27  #include <stdlib.h>
  27   28  #include <string.h>
  28   29  #include <errno.h>
  29   30  #include <fcntl.h>
  30   31  #include <unistd.h>
  31   32  #include <stropts.h>
  32   33  #include <sys/sockio.h>
↓ open down ↓ 485 lines elided ↑ open up ↑
 518  519                      DLADM_OPT_ACTIVE);
 519  520                  if (dlstatus == DLADM_STATUS_OK &&
 520  521                      params.iptun_param_type == IPTUN_TYPE_6TO4) {
 521  522                          return (B_TRUE);
 522  523                  }
 523  524          }
 524  525          return (B_FALSE);
 525  526  }
 526  527  
 527  528  /*
 528      - * Returns B_TRUE if `ifname' represents an IPMP underlying interface.
 529      - */
 530      -boolean_t
 531      -i_ipadm_is_under_ipmp(ipadm_handle_t iph, const char *ifname)
 532      -{
 533      -        struct lifreq   lifr;
 534      -
 535      -        (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
 536      -        if (ioctl(iph->iph_sock, SIOCGLIFGROUPNAME, (caddr_t)&lifr) < 0) {
 537      -                if (ioctl(iph->iph_sock6, SIOCGLIFGROUPNAME,
 538      -                    (caddr_t)&lifr) < 0) {
 539      -                        return (B_FALSE);
 540      -                }
 541      -        }
 542      -        return (lifr.lifr_groupname[0] != '\0');
 543      -}
 544      -
 545      -/*
 546      - * Returns B_TRUE if `ifname' represents an IPMP meta-interface.
 547      - */
 548      -boolean_t
 549      -i_ipadm_is_ipmp(ipadm_handle_t iph, const char *ifname)
 550      -{
 551      -        uint64_t flags;
 552      -
 553      -        if (i_ipadm_get_flags(iph, ifname, AF_INET, &flags) != IPADM_SUCCESS &&
 554      -            i_ipadm_get_flags(iph, ifname, AF_INET6, &flags) != IPADM_SUCCESS)
 555      -                return (B_FALSE);
 556      -
 557      -        return ((flags & IFF_IPMP) != 0);
 558      -}
 559      -
 560      -/*
 561  529   * For a given interface name, ipadm_if_enabled() checks if v4
 562  530   * or v6 or both IP interfaces exist in the active configuration.
 563  531   */
 564  532  boolean_t
 565  533  ipadm_if_enabled(ipadm_handle_t iph, const char *ifname, sa_family_t af)
 566  534  {
 567  535          struct lifreq   lifr;
 568  536          int             s4 = iph->iph_sock;
 569  537          int             s6 = iph->iph_sock6;
 570  538  
↓ open down ↓ 112 lines elided ↑ open up ↑
 683  651   * Instantiate the interface object by retrieving the configuration from
 684  652   * `ifnvl'. The nvlist `ifnvl' contains all the persistent configuration
 685  653   * (interface properties and address objects on that interface) for the
 686  654   * given `ifname'.
 687  655   */
 688  656  ipadm_status_t
 689  657  i_ipadm_init_ifobj(ipadm_handle_t iph, const char *ifname, nvlist_t *ifnvl)
 690  658  {
 691  659          nvlist_t        *nvl = NULL;
 692  660          nvpair_t        *nvp;
 693      -        char            *afstr;
 694  661          ipadm_status_t  status;
 695  662          ipadm_status_t  ret_status = IPADM_SUCCESS;
 696  663          char            newifname[LIFNAMSIZ];
 697  664          char            *aobjstr;
 698      -        sa_family_t     af = AF_UNSPEC;
      665 +        char    *ifclass_str, *gif_name;
      666 +        uint16_t        *families;
      667 +        uint_t  nelem = 0;
      668 +        char **members;
      669 +        uint32_t        ipadm_flags;
 699  670          boolean_t       is_ngz = (iph->iph_zoneid != GLOBAL_ZONEID);
      671 +        boolean_t   init_from_gz = B_FALSE;
 700  672  
 701  673          (void) strlcpy(newifname, ifname, sizeof (newifname));
 702  674          /*
 703  675           * First plumb the given interface and then apply all the persistent
 704  676           * interface properties and then instantiate any persistent addresses
 705  677           * objects on that interface.
 706  678           */
 707  679          for (nvp = nvlist_next_nvpair(ifnvl, NULL); nvp != NULL;
 708  680              nvp = nvlist_next_nvpair(ifnvl, nvp)) {
      681 +
 709  682                  if (nvpair_value_nvlist(nvp, &nvl) != 0)
 710  683                          continue;
 711  684  
 712      -                if (nvlist_lookup_string(nvl, IPADM_NVP_FAMILY, &afstr) == 0) {
 713      -                        status = i_ipadm_plumb_if(iph, newifname, atoi(afstr),
 714      -                            IPADM_OPT_ACTIVE);
 715      -                        /*
 716      -                         * If the interface is already plumbed, we should
 717      -                         * ignore this error because there might be address
 718      -                         * address objects on that interface that needs to
 719      -                         * be enabled again.
 720      -                         */
 721      -                        if (status == IPADM_IF_EXISTS)
 722      -                                status = IPADM_SUCCESS;
 723  685  
      686 +                if (nvlist_lookup_uint16_array(nvl, IPADM_NVP_FAMILIES,
      687 +                    &families, &nelem) == 0) {
      688 +
      689 +                        ipadm_flags = IPADM_OPT_ACTIVE;
      690 +
      691 +                        if (nvlist_lookup_string(nvl, IPADM_NVP_IFCLASS, &ifclass_str) == 0 &&
      692 +                            atoi(ifclass_str) == IPADM_IF_CLASS_IPMP)
      693 +                                ipadm_flags |= IPADM_OPT_IPMP;
      694 +
      695 +                        while (nelem--) {
      696 +                                assert(families[nelem] == AF_INET ||
      697 +                                    families[nelem] == AF_INET6);
      698 +
      699 +                                status = i_ipadm_plumb_if(iph, newifname, families[nelem],
      700 +                                    ipadm_flags);
      701 +
      702 +                                if (status == IPADM_IF_EXISTS)
      703 +                                        status = IPADM_SUCCESS;
      704 +
      705 +                                /* plumbing can fail for ipmp, this is expected */
      706 +                                if (status != IPADM_SUCCESS && !(ipadm_flags & IPADM_OPT_IPMP))
      707 +                                        break;
      708 +                        }
      709 +                        /* does this interface belong to ipmp ? */
      710 +                        if (nvlist_lookup_string(nvl, IPADM_NVP_GIFNAME, &gif_name) == 0) {
      711 +                                (void) ipadm_create_if(iph, gif_name, AF_INET, IPADM_OPT_IPMP |
      712 +                                    IPADM_OPT_ACTIVE);
      713 +                                (void) ipadm_create_if(iph, gif_name, AF_INET6, IPADM_OPT_IPMP |
      714 +                                   IPADM_OPT_ACTIVE);
      715 +                                /** add itself to the group */
      716 +                                status = ipadm_add_ipmp_member(iph, gif_name, newifname, IPADM_OPT_ACTIVE);
      717 +                                if (status != IPADM_SUCCESS && status != IPADM_IF_EXISTS)
      718 +                                        break;
      719 +                        }
 724  720                          if (is_ngz)
 725      -                                af = atoi(afstr);
 726      -                } else if (nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME,
      721 +                                init_from_gz = B_TRUE;
      722 +                 } else if (nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME,
 727  723                      &aobjstr) == 0) {
 728  724                          /*
 729  725                           * For a static address, we need to search for
 730  726                           * the prefixlen in the nvlist `ifnvl'.
 731  727                           */
 732  728                          if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR) ||
 733  729                              nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) {
 734  730                                  status = i_ipadm_merge_prefixlen_from_nvl(ifnvl,
 735  731                                      nvl, aobjstr);
      732 +
 736  733                                  if (status != IPADM_SUCCESS)
 737  734                                          continue;
 738  735                          }
 739  736                          status = i_ipadm_init_addrobj(iph, nvl);
 740  737                          /*
 741  738                           * If this address is in use on some other interface,
 742  739                           * we want to record an error to be returned as
 743  740                           * a soft error and continue processing the rest of
 744  741                           * the addresses.
 745  742                           */
↓ open down ↓ 1 lines elided ↑ open up ↑
 747  744                                  ret_status = IPADM_ALL_ADDRS_NOT_ENABLED;
 748  745                                  status = IPADM_SUCCESS;
 749  746                          }
 750  747                  } else {
 751  748                          assert(nvlist_exists(nvl, IPADM_NVP_PROTONAME));
 752  749                          status = i_ipadm_init_ifprop(iph, nvl);
 753  750                  }
 754  751                  if (status != IPADM_SUCCESS)
 755  752                          return (status);
 756  753          }
 757      -
 758      -        if (is_ngz && af != AF_UNSPEC)
      754 +        if (init_from_gz)
 759  755                  ret_status = ipadm_init_net_from_gz(iph, newifname, NULL);
      756 +
 760  757          return (ret_status);
 761  758  }
 762  759  
 763  760  /*
 764  761   * Retrieves the persistent configuration for the given interface(s) in `ifs'
 765  762   * by contacting the daemon and dumps the information in `allifs'.
 766  763   */
 767  764  ipadm_status_t
 768  765  i_ipadm_init_ifs(ipadm_handle_t iph, const char *ifs, nvlist_t **allifs)
 769  766  {
↓ open down ↓ 176 lines elided ↑ open up ↑
 946  943                                  (void) memcpy(*rbufp, darg.rbuf, darg.rsize);
 947  944                          }
 948  945                  }
 949  946                  /* munmap() the door buffer */
 950  947                  (void) munmap(darg.rbuf, darg.rsize);
 951  948          } else {
 952  949                  if (darg.rsize != rsize)
 953  950                          err = EBADE;
 954  951          }
 955  952          return (err);
      953 +}
      954 +
      955 +/*
      956 + * A helper that is used by i_ipadm_get_db_addr and i_ipadm_get_db_if
      957 + * to do a door_call to ipmgmtd, that should return persistent information
      958 + * about interfaces or/and addresses from ipadm DB
      959 + */
      960 +ipadm_status_t
      961 +i_ipadm_call_ipmgmtd(ipadm_handle_t iph, void *garg,
      962 +        size_t garg_size, nvlist_t **onvl)
      963 +{
      964 +        ipmgmt_get_rval_t       *rvalp;
      965 +        int                     err;
      966 +        size_t                  nvlsize;
      967 +        char                    *nvlbuf;
      968 +
      969 +        rvalp = malloc(sizeof (ipmgmt_get_rval_t));
      970 +        err = ipadm_door_call(iph, garg, garg_size, (void **)&rvalp,
      971 +            sizeof (*rvalp), B_TRUE);
      972 +        if (err == 0) {
      973 +                nvlsize = rvalp->ir_nvlsize;
      974 +                nvlbuf = (char *)rvalp + sizeof (ipmgmt_get_rval_t);
      975 +                err = nvlist_unpack(nvlbuf, nvlsize, onvl, NV_ENCODE_NATIVE);
      976 +        }
      977 +        free(rvalp);
      978 +
      979 +        return (ipadm_errno2status(err));
 956  980  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX