diff options
Diffstat (limited to 'usr/src/lib/libipadm/common/libipadm.c')
-rw-r--r-- | usr/src/lib/libipadm/common/libipadm.c | 27 |
1 files changed, 24 insertions, 3 deletions
diff --git a/usr/src/lib/libipadm/common/libipadm.c b/usr/src/lib/libipadm/common/libipadm.c index 4103ebbd85..21aeab72ba 100644 --- a/usr/src/lib/libipadm/common/libipadm.c +++ b/usr/src/lib/libipadm/common/libipadm.c @@ -97,7 +97,8 @@ static struct ipadm_error_info { { IPADM_IPC_ERROR, "Could not communicate with ipmgmtd" }, { IPADM_NOTSUP, "Operation not supported" }, { IPADM_OP_DISABLE_OBJ, "Operation not supported on disabled object" }, - { IPADM_EBADE, "Invalid data exchange with daemon" } + { IPADM_EBADE, "Invalid data exchange with daemon" }, + { IPADM_GZ_PERM, "Operation not permitted on from-gz interface"} }; #define IPADM_NUM_ERRORS (sizeof (ipadm_errors) / sizeof (*ipadm_errors)) @@ -186,7 +187,7 @@ ipadm_open(ipadm_handle_t *handle, uint32_t flags) return (IPADM_INVALID_ARG); *handle = NULL; - if (flags & ~(IPH_VRRP|IPH_LEGACY|IPH_INIT)) + if (flags & ~(IPH_VRRP|IPH_LEGACY|IPH_INIT|IPH_IPMGMTD)) return (IPADM_INVALID_ARG); if ((iph = calloc(1, sizeof (struct ipadm_handle))) == NULL) @@ -194,6 +195,7 @@ ipadm_open(ipadm_handle_t *handle, uint32_t flags) iph->iph_sock = -1; iph->iph_sock6 = -1; iph->iph_door_fd = -1; + iph->iph_rtsock = -1; iph->iph_flags = flags; (void) pthread_mutex_init(&iph->iph_lock, NULL); @@ -213,6 +215,7 @@ ipadm_open(ipadm_handle_t *handle, uint32_t flags) * dladm_open() for such zones. */ zoneid = getzoneid(); + iph->iph_zoneid = zoneid; if (zoneid != GLOBAL_ZONEID) { if (zone_getattr(zoneid, ZONE_ATTR_FLAGS, &zflags, sizeof (zflags)) < 0) { @@ -224,6 +227,14 @@ ipadm_open(ipadm_handle_t *handle, uint32_t flags) ipadm_close(iph); return (IPADM_DLADM_FAILURE); } + if (zoneid != GLOBAL_ZONEID) { + iph->iph_rtsock = socket(PF_ROUTE, SOCK_RAW, 0); + /* + * Failure to open rtsock is ignored as this is + * only used in non-global zones to initialize + * routing socket information. + */ + } } else { assert(zoneid != GLOBAL_ZONEID); iph->iph_dlh = NULL; @@ -256,6 +267,8 @@ ipadm_close(ipadm_handle_t iph) (void) close(iph->iph_sock); if (iph->iph_sock6 != -1) (void) close(iph->iph_sock6); + if (iph->iph_rtsock != -1) + (void) close(iph->iph_rtsock); if (iph->iph_door_fd != -1) (void) close(iph->iph_door_fd); dladm_close(iph->iph_dlh); @@ -494,7 +507,7 @@ i_ipadm_is_6to4(ipadm_handle_t iph, char *ifname) datalink_id_t linkid; if (iph->iph_dlh == NULL) { - assert(getzoneid() != GLOBAL_ZONEID); + assert(iph->iph_zoneid != GLOBAL_ZONEID); return (B_FALSE); } dlstatus = dladm_name2info(iph->iph_dlh, ifname, &linkid, NULL, @@ -682,6 +695,8 @@ i_ipadm_init_ifobj(ipadm_handle_t iph, const char *ifname, nvlist_t *ifnvl) 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)); /* @@ -705,6 +720,9 @@ i_ipadm_init_ifobj(ipadm_handle_t iph, const char *ifname, nvlist_t *ifnvl) */ 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) { /* @@ -736,6 +754,9 @@ i_ipadm_init_ifobj(ipadm_handle_t iph, const char *ifname, nvlist_t *ifnvl) 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); } |