Print this page
7388 Support DHCP Client FQDN. Allow IAID/DUID for all v4.
*** 19,28 ****
--- 19,29 ----
* CDDL HEADER END
*/
/*
* Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2016, Chris Fraire <cfraire@me.com>.
*/
/*
* Main door handler functions used by ipmgmtd to process the different door
* call requests, issued by the library libipadm.so.
*** 223,234 ****
i_ipmgmt_nvl2aobjnode(nvlist_t *nvl, ipmgmt_aobjmap_t *nodep)
{
char *aobjname = NULL, *ifname = NULL;
int32_t lnum;
nvlist_t *nvladdr;
- struct sockaddr_storage addr;
- uint_t n;
sa_family_t af = AF_UNSPEC;
ipadm_addr_type_t addrtype = IPADM_ADDR_NONE;
int err = 0;
/*
--- 224,233 ----
*** 242,261 ****
return (err);
}
if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR)) {
af = AF_INET;
addrtype = IPADM_ADDR_STATIC;
! } else if (nvlist_exists(nvl, IPADM_NVP_DHCP)) {
af = AF_INET;
addrtype = IPADM_ADDR_DHCP;
} else if (nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) {
af = AF_INET6;
addrtype = IPADM_ADDR_STATIC;
} else if (nvlist_lookup_nvlist(nvl, IPADM_NVP_INTFID, &nvladdr) == 0) {
! struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)&addr;
uint8_t *addr6;
uint32_t plen;
af = AF_INET6;
addrtype = IPADM_ADDR_IPV6_ADDRCONF;
if (nvlist_lookup_uint32(nvladdr, IPADM_NVP_PREFIXLEN,
&plen) != 0)
--- 241,286 ----
return (err);
}
if (nvlist_exists(nvl, IPADM_NVP_IPV4ADDR)) {
af = AF_INET;
addrtype = IPADM_ADDR_STATIC;
! } else if (nvlist_lookup_nvlist(nvl, IPADM_NVP_DHCP, &nvladdr) == 0) {
! char *reqhost;
! boolean_t primary;
!
af = AF_INET;
addrtype = IPADM_ADDR_DHCP;
+
+ if (nvlist_lookup_boolean_value(nvladdr, IPADM_NVP_PRIMARY,
+ &primary) != 0)
+ return (EINVAL);
+ nodep->ipmgmt_am_primary = primary;
+
+ /*
+ * ipmgmt_am_reqhost comes through in `nvl' for purposes of updating
+ * the cached representation, but it is persisted as a stand-alone
+ * DB line; so remove it after copying it.
+ */
+ if (!nvlist_exists(nvl, IPADM_NVP_REQHOST)) {
+ *nodep->ipmgmt_am_reqhost = '\0';
+ } else {
+ if ((err = nvlist_lookup_string(nvl, IPADM_NVP_REQHOST,
+ &reqhost)) != 0)
+ return (err);
+
+ (void) strlcpy(nodep->ipmgmt_am_reqhost, reqhost,
+ sizeof (nodep->ipmgmt_am_reqhost));
+ (void) nvlist_remove(nvl, IPADM_NVP_REQHOST, DATA_TYPE_STRING);
+ }
} else if (nvlist_exists(nvl, IPADM_NVP_IPV6ADDR)) {
af = AF_INET6;
addrtype = IPADM_ADDR_STATIC;
} else if (nvlist_lookup_nvlist(nvl, IPADM_NVP_INTFID, &nvladdr) == 0) {
! struct sockaddr_in6 sin6 = {0};
uint8_t *addr6;
uint32_t plen;
+ uint_t n;
af = AF_INET6;
addrtype = IPADM_ADDR_IPV6_ADDRCONF;
if (nvlist_lookup_uint32(nvladdr, IPADM_NVP_PREFIXLEN,
&plen) != 0)
*** 262,290 ****
return (EINVAL);
if (plen != 0) {
if (nvlist_lookup_uint8_array(nvladdr,
IPADM_NVP_IPNUMADDR, &addr6, &n) != 0)
return (EINVAL);
! bcopy(addr6, &sin6->sin6_addr, n);
! } else {
! bzero(&sin6->sin6_addr, sizeof (sin6->sin6_addr));
}
}
/*
! * populate the `*nodep' with retrieved values.
*/
(void) strlcpy(nodep->am_ifname, ifname, sizeof (nodep->am_ifname));
(void) strlcpy(nodep->am_aobjname, aobjname,
sizeof (nodep->am_aobjname));
nodep->am_lnum = lnum;
nodep->am_family = af;
nodep->am_atype = addrtype;
- if (addrtype == IPADM_ADDR_IPV6_ADDRCONF) {
- nodep->am_linklocal = B_TRUE;
- nodep->am_ifid = addr;
- }
nodep->am_next = NULL;
/*
* Do not store logical interface number in persistent store as it
* takes different value on reboot. So remove it from `nvl'.
--- 287,312 ----
return (EINVAL);
if (plen != 0) {
if (nvlist_lookup_uint8_array(nvladdr,
IPADM_NVP_IPNUMADDR, &addr6, &n) != 0)
return (EINVAL);
! bcopy(addr6, &sin6.sin6_addr, n);
}
+
+ nodep->ipmgmt_am_linklocal = B_TRUE;
+ nodep->ipmgmt_am_ifid = sin6;
}
/*
! * populate the non-addrtype-specific `*nodep' with retrieved values.
*/
(void) strlcpy(nodep->am_ifname, ifname, sizeof (nodep->am_ifname));
(void) strlcpy(nodep->am_aobjname, aobjname,
sizeof (nodep->am_aobjname));
nodep->am_lnum = lnum;
nodep->am_family = af;
nodep->am_atype = addrtype;
nodep->am_next = NULL;
/*
* Do not store logical interface number in persistent store as it
* takes different value on reboot. So remove it from `nvl'.
*** 295,313 ****
return (0);
}
/*
* Handles the door command IPMGMT_CMD_SETADDR. It adds a new address object
! * node to the list `aobjmap' and then persists the address information in the
! * DB.
*/
static void
ipmgmt_setaddr_handler(void *argp)
{
ipmgmt_setaddr_arg_t *sargp = argp;
ipmgmt_retval_t rval;
! ipmgmt_aobjmap_t node;
nvlist_t *nvl = NULL;
char *nvlbuf;
size_t nvlsize = sargp->ia_nvlsize;
uint32_t flags = sargp->ia_flags;
int err = 0;
--- 317,335 ----
return (0);
}
/*
* Handles the door command IPMGMT_CMD_SETADDR. It adds a new address object
! * node to the list `aobjmap' and optionally persists the address
! * information in the DB.
*/
static void
ipmgmt_setaddr_handler(void *argp)
{
ipmgmt_setaddr_arg_t *sargp = argp;
ipmgmt_retval_t rval;
! ipmgmt_aobjmap_t node = {0};
nvlist_t *nvl = NULL;
char *nvlbuf;
size_t nvlsize = sargp->ia_nvlsize;
uint32_t flags = sargp->ia_flags;
int err = 0;
*** 319,333 ****
if ((err = i_ipmgmt_nvl2aobjnode(nvl, &node)) != 0)
goto ret;
if (flags & IPMGMT_INIT)
node.am_flags = (IPMGMT_ACTIVE|IPMGMT_PERSIST);
else
! node.am_flags = flags;
if ((err = ipmgmt_aobjmap_op(&node, ADDROBJ_ADD)) != 0)
goto ret;
}
! if (flags & IPMGMT_PERSIST) {
ipadm_dbwrite_cbarg_t cb;
cb.dbw_nvl = nvl;
cb.dbw_flags = 0;
err = ipmgmt_db_walk(ipmgmt_db_add, &cb, IPADM_DB_WRITE);
--- 341,355 ----
if ((err = i_ipmgmt_nvl2aobjnode(nvl, &node)) != 0)
goto ret;
if (flags & IPMGMT_INIT)
node.am_flags = (IPMGMT_ACTIVE|IPMGMT_PERSIST);
else
! node.am_flags = flags & ~IPMGMT_PROPS_ONLY;
if ((err = ipmgmt_aobjmap_op(&node, ADDROBJ_ADD)) != 0)
goto ret;
}
! if ((flags & IPMGMT_PERSIST) && !(flags & IPMGMT_PROPS_ONLY)) {
ipadm_dbwrite_cbarg_t cb;
cb.dbw_nvl = nvl;
cb.dbw_flags = 0;
err = ipmgmt_db_walk(ipmgmt_db_add, &cb, IPADM_DB_WRITE);
*** 337,347 ****
rval.ir_err = err;
(void) door_return((char *)&rval, sizeof (rval), NULL, 0);
}
/*
! * Handles the door commands that modify the `aobjmap' structure.
*
* IPMGMT_CMD_ADDROBJ_LOOKUPADD - places a stub address object in `aobjmap'
* after ensuring that the namespace is not taken. If required, also
* generates an `aobjname' for address object for the library to use.
* IPMGMT_CMD_ADDROBJ_ADD - add/update address object in `aobjmap'
--- 359,369 ----
rval.ir_err = err;
(void) door_return((char *)&rval, sizeof (rval), NULL, 0);
}
/*
! * Handles the door commands that read or modify the `aobjmap' structure.
*
* IPMGMT_CMD_ADDROBJ_LOOKUPADD - places a stub address object in `aobjmap'
* after ensuring that the namespace is not taken. If required, also
* generates an `aobjname' for address object for the library to use.
* IPMGMT_CMD_ADDROBJ_ADD - add/update address object in `aobjmap'
*** 439,449 ****
* Other logical interfaces were created for
* prefixes and dhcpv6 addresses and do not
* have am_ifid set.
*/
if (head->am_atype != IPADM_ADDR_IPV6_ADDRCONF ||
! head->am_linklocal) {
break;
}
}
if (head == NULL) {
err = ENOENT;
--- 461,471 ----
* Other logical interfaces were created for
* prefixes and dhcpv6 addresses and do not
* have am_ifid set.
*/
if (head->am_atype != IPADM_ADDR_IPV6_ADDRCONF ||
! head->ipmgmt_am_linklocal) {
break;
}
}
if (head == NULL) {
err = ENOENT;
*** 454,466 ****
sizeof (aobjrval.ir_ifname));
aobjrval.ir_lnum = head->am_lnum;
aobjrval.ir_family = head->am_family;
aobjrval.ir_flags = head->am_flags;
aobjrval.ir_atype = head->am_atype;
! if (head->am_atype == IPADM_ADDR_IPV6_ADDRCONF &&
! head->am_linklocal)
! aobjrval.ir_ifid = head->am_ifid;
(void) pthread_rwlock_unlock(&aobjmap.aobjmap_rwlock);
break;
case IPMGMT_CMD_LIF2ADDROBJ:
rsize = sizeof (ipmgmt_aobjop_rval_t);
rvalp = &aobjrval;
--- 476,487 ----
sizeof (aobjrval.ir_ifname));
aobjrval.ir_lnum = head->am_lnum;
aobjrval.ir_family = head->am_family;
aobjrval.ir_flags = head->am_flags;
aobjrval.ir_atype = head->am_atype;
! (void) memcpy(&aobjrval.ir_atype_cache, &head->am_atype_cache,
! sizeof (aobjrval.ir_atype_cache));
(void) pthread_rwlock_unlock(&aobjmap.aobjmap_rwlock);
break;
case IPMGMT_CMD_LIF2ADDROBJ:
rsize = sizeof (ipmgmt_aobjop_rval_t);
rvalp = &aobjrval;
*** 485,494 ****
--- 506,517 ----
}
(void) strlcpy(aobjrval.ir_aobjname, head->am_aobjname,
sizeof (aobjrval.ir_aobjname));
aobjrval.ir_atype = head->am_atype;
aobjrval.ir_flags = head->am_flags;
+ (void) memcpy(&aobjrval.ir_atype_cache, &head->am_atype_cache,
+ sizeof (aobjrval.ir_atype_cache));
(void) pthread_rwlock_unlock(&aobjmap.aobjmap_rwlock);
break;
default:
rsize = sizeof (ipmgmt_retval_t);
rvalp = &rval;