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));
}