Print this page
Commit IPMP changes

*** 18,27 **** --- 18,28 ---- * * CDDL HEADER END */ /* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2013 Nexenta Systems, Inc. All rights reserved. */ #include <stdio.h> #include <stdlib.h> #include <string.h>
*** 523,565 **** } return (B_FALSE); } /* - * Returns B_TRUE if `ifname' represents an IPMP underlying interface. - */ - boolean_t - i_ipadm_is_under_ipmp(ipadm_handle_t iph, const char *ifname) - { - struct lifreq lifr; - - (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name)); - if (ioctl(iph->iph_sock, SIOCGLIFGROUPNAME, (caddr_t)&lifr) < 0) { - if (ioctl(iph->iph_sock6, SIOCGLIFGROUPNAME, - (caddr_t)&lifr) < 0) { - return (B_FALSE); - } - } - return (lifr.lifr_groupname[0] != '\0'); - } - - /* - * Returns B_TRUE if `ifname' represents an IPMP meta-interface. - */ - boolean_t - i_ipadm_is_ipmp(ipadm_handle_t iph, const char *ifname) - { - uint64_t flags; - - if (i_ipadm_get_flags(iph, ifname, AF_INET, &flags) != IPADM_SUCCESS && - i_ipadm_get_flags(iph, ifname, AF_INET6, &flags) != IPADM_SUCCESS) - return (B_FALSE); - - return ((flags & IFF_IPMP) != 0); - } - - /* * For a given interface name, ipadm_if_enabled() checks if v4 * or v6 or both IP interfaces exist in the active configuration. */ boolean_t ipadm_if_enabled(ipadm_handle_t iph, const char *ifname, sa_family_t af) --- 524,533 ----
*** 688,730 **** ipadm_status_t i_ipadm_init_ifobj(ipadm_handle_t iph, const char *ifname, nvlist_t *ifnvl) { nvlist_t *nvl = NULL; nvpair_t *nvp; - char *afstr; ipadm_status_t status; ipadm_status_t ret_status = IPADM_SUCCESS; char newifname[LIFNAMSIZ]; char *aobjstr; ! sa_family_t af = AF_UNSPEC; boolean_t is_ngz = (iph->iph_zoneid != GLOBAL_ZONEID); (void) strlcpy(newifname, ifname, sizeof (newifname)); /* * First plumb the given interface and then apply all the persistent * interface properties and then instantiate any persistent addresses * objects on that interface. */ for (nvp = nvlist_next_nvpair(ifnvl, NULL); nvp != NULL; nvp = nvlist_next_nvpair(ifnvl, nvp)) { if (nvpair_value_nvlist(nvp, &nvl) != 0) continue; ! if (nvlist_lookup_string(nvl, IPADM_NVP_FAMILY, &afstr) == 0) { ! status = i_ipadm_plumb_if(iph, newifname, atoi(afstr), ! IPADM_OPT_ACTIVE); ! /* ! * If the interface is already plumbed, we should ! * ignore this error because there might be address ! * address objects on that interface that needs to ! * be enabled again. ! */ if (status == IPADM_IF_EXISTS) status = IPADM_SUCCESS; if (is_ngz) ! af = atoi(afstr); } else if (nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME, &aobjstr) == 0) { /* * For a static address, we need to search for * the prefixlen in the nvlist `ifnvl'. --- 656,726 ---- ipadm_status_t i_ipadm_init_ifobj(ipadm_handle_t iph, const char *ifname, nvlist_t *ifnvl) { nvlist_t *nvl = NULL; nvpair_t *nvp; ipadm_status_t status; ipadm_status_t ret_status = IPADM_SUCCESS; char newifname[LIFNAMSIZ]; char *aobjstr; ! char *ifclass_str, *gif_name; ! uint16_t *families; ! uint_t nelem = 0; ! char **members; ! uint32_t ipadm_flags; boolean_t is_ngz = (iph->iph_zoneid != GLOBAL_ZONEID); + boolean_t init_from_gz = B_FALSE; (void) strlcpy(newifname, ifname, sizeof (newifname)); /* * First plumb the given interface and then apply all the persistent * interface properties and then instantiate any persistent addresses * objects on that interface. */ for (nvp = nvlist_next_nvpair(ifnvl, NULL); nvp != NULL; nvp = nvlist_next_nvpair(ifnvl, nvp)) { + if (nvpair_value_nvlist(nvp, &nvl) != 0) continue; ! ! if (nvlist_lookup_uint16_array(nvl, IPADM_NVP_FAMILIES, ! &families, &nelem) == 0) { ! ! ipadm_flags = IPADM_OPT_ACTIVE; ! ! if (nvlist_lookup_string(nvl, IPADM_NVP_IFCLASS, &ifclass_str) == 0 && ! atoi(ifclass_str) == IPADM_IF_CLASS_IPMP) ! ipadm_flags |= IPADM_OPT_IPMP; ! ! while (nelem--) { ! assert(families[nelem] == AF_INET || ! families[nelem] == AF_INET6); ! ! status = i_ipadm_plumb_if(iph, newifname, families[nelem], ! ipadm_flags); ! if (status == IPADM_IF_EXISTS) status = IPADM_SUCCESS; + /* plumbing can fail for ipmp, this is expected */ + if (status != IPADM_SUCCESS && !(ipadm_flags & IPADM_OPT_IPMP)) + break; + } + /* does this interface belong to ipmp ? */ + if (nvlist_lookup_string(nvl, IPADM_NVP_GIFNAME, &gif_name) == 0) { + (void) ipadm_create_if(iph, gif_name, AF_INET, IPADM_OPT_IPMP | + IPADM_OPT_ACTIVE); + (void) ipadm_create_if(iph, gif_name, AF_INET6, IPADM_OPT_IPMP | + IPADM_OPT_ACTIVE); + /** add itself to the group */ + status = ipadm_add_ipmp_member(iph, gif_name, newifname, IPADM_OPT_ACTIVE); + if (status != IPADM_SUCCESS && status != IPADM_IF_EXISTS) + break; + } if (is_ngz) ! init_from_gz = B_TRUE; } else if (nvlist_lookup_string(nvl, IPADM_NVP_AOBJNAME, &aobjstr) == 0) { /* * For a static address, we need to search for * the prefixlen in the nvlist `ifnvl'.
*** 731,740 **** --- 727,737 ---- */ if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR) || nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) { status = i_ipadm_merge_prefixlen_from_nvl(ifnvl, nvl, aobjstr); + if (status != IPADM_SUCCESS) continue; } status = i_ipadm_init_addrobj(iph, nvl); /*
*** 752,764 **** status = i_ipadm_init_ifprop(iph, nvl); } if (status != IPADM_SUCCESS) return (status); } ! ! if (is_ngz && af != AF_UNSPEC) ret_status = ipadm_init_net_from_gz(iph, newifname, NULL); return (ret_status); } /* * Retrieves the persistent configuration for the given interface(s) in `ifs' --- 749,761 ---- status = i_ipadm_init_ifprop(iph, nvl); } if (status != IPADM_SUCCESS) return (status); } ! if (init_from_gz) ret_status = ipadm_init_net_from_gz(iph, newifname, NULL); + return (ret_status); } /* * Retrieves the persistent configuration for the given interface(s) in `ifs'
*** 951,956 **** --- 948,980 ---- } else { if (darg.rsize != rsize) err = EBADE; } return (err); + } + + /* + * A helper that is used by i_ipadm_get_db_addr and i_ipadm_get_db_if + * to do a door_call to ipmgmtd, that should return persistent information + * about interfaces or/and addresses from ipadm DB + */ + ipadm_status_t + i_ipadm_call_ipmgmtd(ipadm_handle_t iph, void *garg, + size_t garg_size, nvlist_t **onvl) + { + ipmgmt_get_rval_t *rvalp; + int err; + size_t nvlsize; + char *nvlbuf; + + rvalp = malloc(sizeof (ipmgmt_get_rval_t)); + err = ipadm_door_call(iph, garg, garg_size, (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)); }