summaryrefslogtreecommitdiff
path: root/usr/src/lib
diff options
context:
space:
mode:
Diffstat (limited to 'usr/src/lib')
-rw-r--r--usr/src/lib/brand/native/zone/platform.xml3
-rw-r--r--usr/src/lib/brand/sn1/zone/platform.xml3
-rw-r--r--usr/src/lib/libbsm/common/adt.c4
-rw-r--r--usr/src/lib/libdlpi/common/libdlpi.c21
-rw-r--r--usr/src/lib/libinetcfg/common/inetcfg.c38
-rw-r--r--usr/src/lib/libinetutil/Makefile.com14
-rw-r--r--usr/src/lib/libinetutil/common/ifaddrlist.c68
-rw-r--r--usr/src/lib/libinetutil/common/ifaddrlistx.c168
-rw-r--r--usr/src/lib/libinetutil/common/inetutil.c (renamed from usr/src/lib/libinetutil/common/inetutil4.c)36
-rw-r--r--usr/src/lib/libinetutil/common/libinetutil.h55
-rw-r--r--usr/src/lib/libinetutil/common/mapfile-vers7
-rw-r--r--usr/src/lib/libipmp/Makefile6
-rw-r--r--usr/src/lib/libipmp/Makefile.com9
-rw-r--r--usr/src/lib/libipmp/common/ipmp.c20
-rw-r--r--usr/src/lib/libipmp/common/ipmp.h12
-rw-r--r--usr/src/lib/libipmp/common/ipmp_admin.c104
-rw-r--r--usr/src/lib/libipmp/common/ipmp_admin.h50
-rw-r--r--usr/src/lib/libipmp/common/ipmp_mpathd.c26
-rw-r--r--usr/src/lib/libipmp/common/ipmp_mpathd.h81
-rw-r--r--usr/src/lib/libipmp/common/ipmp_query.c498
-rw-r--r--usr/src/lib/libipmp/common/ipmp_query.h112
-rw-r--r--usr/src/lib/libipmp/common/ipmp_query_impl.h41
-rw-r--r--usr/src/lib/libipmp/common/llib-lipmp10
-rw-r--r--usr/src/lib/libipmp/common/mapfile-vers13
-rw-r--r--usr/src/lib/libnsl/nss/netdir_inet_sundry.c92
-rw-r--r--usr/src/lib/libsocket/inet/interface_id.c23
-rw-r--r--usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c4
27 files changed, 1159 insertions, 359 deletions
diff --git a/usr/src/lib/brand/native/zone/platform.xml b/usr/src/lib/brand/native/zone/platform.xml
index f7030ba0a1..69e86cefd2 100644
--- a/usr/src/lib/brand/native/zone/platform.xml
+++ b/usr/src/lib/brand/native/zone/platform.xml
@@ -20,7 +20,7 @@
CDDL HEADER END
- Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ Copyright 2009 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
DO NOT EDIT THIS FILE.
@@ -97,6 +97,7 @@
<device match="ipf" ip-type="exclusive" />
<device match="ipl" ip-type="exclusive" />
<device match="iplookup" ip-type="exclusive" />
+ <device match="ipmpstub" ip-type="exclusive" />
<device match="ipnat" ip-type="exclusive" />
<device match="ipscan" ip-type="exclusive" />
<device match="ipsecah" ip-type="exclusive" />
diff --git a/usr/src/lib/brand/sn1/zone/platform.xml b/usr/src/lib/brand/sn1/zone/platform.xml
index 1659d8851c..b3bb0d7962 100644
--- a/usr/src/lib/brand/sn1/zone/platform.xml
+++ b/usr/src/lib/brand/sn1/zone/platform.xml
@@ -20,7 +20,7 @@
CDDL HEADER END
- Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ Copyright 2009 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
DO NOT EDIT THIS FILE.
@@ -101,6 +101,7 @@
<device match="ipf" ip-type="exclusive" />
<device match="ipl" ip-type="exclusive" />
<device match="iplookup" ip-type="exclusive" />
+ <device match="ipmpstub" ip-type="exclusive" />
<device match="ipnat" ip-type="exclusive" />
<device match="ipscan" ip-type="exclusive" />
<device match="ipsecah" ip-type="exclusive" />
diff --git a/usr/src/lib/libbsm/common/adt.c b/usr/src/lib/libbsm/common/adt.c
index 23f78b6247..d9947622d4 100644
--- a/usr/src/lib/libbsm/common/adt.c
+++ b/usr/src/lib/libbsm/common/adt.c
@@ -20,7 +20,7 @@
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -2137,7 +2137,7 @@ adt_get_local_address(int family, struct ifaddrlist *al)
int ifal_count;
int i;
- if ((ifal_count = ifaddrlist(&ifal, family, errbuf)) <= 0) {
+ if ((ifal_count = ifaddrlist(&ifal, family, 0, errbuf)) <= 0) {
int serrno = errno;
(void) snprintf(msg, sizeof (msg), "adt_get_local_address "
diff --git a/usr/src/lib/libdlpi/common/libdlpi.c b/usr/src/lib/libdlpi/common/libdlpi.c
index 14c4451081..d546807342 100644
--- a/usr/src/lib/libdlpi/common/libdlpi.c
+++ b/usr/src/lib/libdlpi/common/libdlpi.c
@@ -19,7 +19,7 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -1109,7 +1109,7 @@ i_dlpi_open(const char *provider, int *fd, uint_t flags, boolean_t style1)
/* open libdladm handle rather than taking it as input */
if (dladm_open(&handle) != DLADM_STATUS_OK)
- return (DLPI_FAILURE);
+ goto fallback;
if (dladm_dev2linkid(handle, device, &linkid) ==
DLADM_STATUS_OK) {
@@ -1400,7 +1400,7 @@ i_dlpi_strgetmsg(dlpi_impl_t *dip, int msec, dlpi_msg_t *dlreplyp,
void *databuf, size_t *datalenp, size_t *totdatalenp)
{
int retval;
- int flags = 0;
+ int flags;
int fd = dip->dli_fd;
struct strbuf ctl, data;
struct pollfd pfd;
@@ -1437,16 +1437,17 @@ i_dlpi_strgetmsg(dlpi_impl_t *dip, int msec, dlpi_msg_t *dlreplyp,
start = gethrtime() / (NANOSEC / MILLISEC);
switch (poll(&pfd, 1, msec)) {
- default:
- if (pfd.revents & POLLHUP)
- return (DL_SYSERR);
- break;
- case 0:
- return (DLPI_ETIMEDOUT);
- case -1:
+ default:
+ if (pfd.revents & POLLHUP)
return (DL_SYSERR);
+ break;
+ case 0:
+ return (DLPI_ETIMEDOUT);
+ case -1:
+ return (DL_SYSERR);
}
+ flags = 0;
if ((retval = getmsg(fd, &ctl, &data, &flags)) < 0)
return (DL_SYSERR);
diff --git a/usr/src/lib/libinetcfg/common/inetcfg.c b/usr/src/lib/libinetcfg/common/inetcfg.c
index 38beca5574..e1f09a881a 100644
--- a/usr/src/lib/libinetcfg/common/inetcfg.c
+++ b/usr/src/lib/libinetcfg/common/inetcfg.c
@@ -19,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -743,7 +741,8 @@ icfg_set_flags(icfg_handle_t handle, uint64_t flags)
struct lifreq lifr;
uint64_t oflags;
int ret;
- int rtsock;
+ int rtsock = -1;
+ int aware = RTAW_UNDER_IPMP;
(void) strlcpy(lifr.lifr_name, handle->ifh_interface.if_name,
sizeof (lifr.lifr_name));
@@ -757,10 +756,16 @@ icfg_set_flags(icfg_handle_t handle, uint64_t flags)
/*
* Any time flags are changed on an interface that has IFF_UP set,
* you'll get a routing socket message. We care about the status,
- * though, only when the new flags are marked "up."
+ * though, only when the new flags are marked "up." Since we may be
+ * changing an IPMP test address, we enable RTAW_UNDER_IPMP.
*/
- rtsock = (flags & IFF_UP) ?
- socket(PF_ROUTE, SOCK_RAW, ICFG_FAMILY(handle)) : -1;
+ if (flags & IFF_UP) {
+ rtsock = socket(PF_ROUTE, SOCK_RAW, ICFG_FAMILY(handle));
+ if (rtsock != -1) {
+ (void) setsockopt(rtsock, SOL_ROUTE, RT_AWARE, &aware,
+ sizeof (aware));
+ }
+ }
lifr.lifr_flags = flags;
if (ioctl(handle->ifh_sock, SIOCSLIFFLAGS, (caddr_t)&lifr) < 0) {
@@ -993,7 +998,8 @@ icfg_set_addr(icfg_handle_t handle, const struct sockaddr *addr,
struct lifreq lifr;
uint64_t flags;
int ret;
- int rtsock;
+ int rtsock = -1;
+ int aware = RTAW_UNDER_IPMP;
(void) memset(&lifr.lifr_addr, 0, sizeof (lifr.lifr_addr));
if ((ret = to_sockaddr_storage(ICFG_FAMILY(handle), addr, addrlen,
@@ -1002,15 +1008,19 @@ icfg_set_addr(icfg_handle_t handle, const struct sockaddr *addr,
}
/*
- * Need to do check on duplicate address detection results if the
- * interface is up.
+ * Need to check duplicate address detection results if the address is
+ * up. Since this may be an IPMP test address, enable RTAW_UNDER_IPMP.
*/
- if ((ret = icfg_get_flags(handle, &flags)) != ICFG_SUCCESS) {
+ if ((ret = icfg_get_flags(handle, &flags)) != ICFG_SUCCESS)
return (ret);
- }
- rtsock = (flags & IFF_UP) ?
- socket(PF_ROUTE, SOCK_RAW, ICFG_FAMILY(handle)) : -1;
+ if (flags & IFF_UP) {
+ rtsock = socket(PF_ROUTE, SOCK_RAW, ICFG_FAMILY(handle));
+ if (rtsock != -1) {
+ (void) setsockopt(rtsock, SOL_ROUTE, RT_AWARE, &aware,
+ sizeof (aware));
+ }
+ }
(void) strlcpy(lifr.lifr_name, handle->ifh_interface.if_name,
sizeof (lifr.lifr_name));
diff --git a/usr/src/lib/libinetutil/Makefile.com b/usr/src/lib/libinetutil/Makefile.com
index 810f24bd71..cd3a0d6e33 100644
--- a/usr/src/lib/libinetutil/Makefile.com
+++ b/usr/src/lib/libinetutil/Makefile.com
@@ -19,15 +19,13 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
-LIBRARY = libinetutil.a
-VERS = .1
-OBJECTS = octet.o inetutil4.o ifspec.o ifaddrlist.o eh.o tq.o
+LIBRARY = libinetutil.a
+VERS = .1
+OBJECTS = octet.o inetutil.o ifspec.o ifaddrlist.o ifaddrlistx.o eh.o tq.o
include ../../Makefile.lib
@@ -38,9 +36,9 @@ LIBS = $(DYNLIB) $(LINTLIB)
SRCDIR = ../common
COMDIR = $(SRC)/common/net/dhcp
-SRCS = $(COMDIR)/octet.c $(SRCDIR)/inetutil4.c \
+SRCS = $(COMDIR)/octet.c $(SRCDIR)/inetutil.c \
$(SRCDIR)/ifspec.c $(SRCDIR)/eh.c $(SRCDIR)/tq.c \
- $(SRCDIR)/ifaddrlist.c
+ $(SRCDIR)/ifaddrlist.c $(SRCDIR)/ifaddrlistx.c
$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
LDLIBS += -lsocket -lc
diff --git a/usr/src/lib/libinetutil/common/ifaddrlist.c b/usr/src/lib/libinetutil/common/ifaddrlist.c
index 383dc2afb0..fa67a0fc37 100644
--- a/usr/src/lib/libinetutil/common/ifaddrlist.c
+++ b/usr/src/lib/libinetutil/common/ifaddrlist.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
@@ -38,9 +38,6 @@
* @(#) $Header: ifaddrlist.c,v 1.2 97/04/22 13:31:05 leres Exp $ (LBL)
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
-#include <alloca.h>
#include <errno.h>
#include <libinetutil.h>
#include <stdio.h>
@@ -54,9 +51,9 @@
* See <libinetutil.h> for a description of the programming interface.
*/
int
-ifaddrlist(struct ifaddrlist **ipaddrp, int family, char *errbuf)
+ifaddrlist(struct ifaddrlist **ipaddrp, int family, uint_t flags, char *errbuf)
{
- struct ifaddrlist *ifaddrlist, *al;
+ struct ifaddrlist *ifaddrlist = NULL, *al = NULL;
struct sockaddr_in *sin;
struct sockaddr_in6 *sin6;
struct lifconf lifc;
@@ -64,31 +61,28 @@ ifaddrlist(struct ifaddrlist **ipaddrp, int family, char *errbuf)
struct lifreq *lifrp;
int i, count, nlifr;
int fd;
- const char *iocstr;
+ const char *opstr;
+ (void) memset(&lifc, 0, sizeof (lifc));
if (family != AF_INET && family != AF_INET6) {
(void) strlcpy(errbuf, "invalid address family", ERRBUFSIZE);
return (-1);
}
- fd = socket(family, SOCK_DGRAM, 0);
- if (fd == -1) {
- (void) snprintf(errbuf, ERRBUFSIZE, "socket: %s",
- strerror(errno));
- return (-1);
+ if ((fd = socket(family, SOCK_DGRAM, 0)) == -1) {
+ opstr = "socket";
+ goto fail;
}
/*
* Get the number of network interfaces of type `family'.
*/
lifn.lifn_family = family;
- lifn.lifn_flags = 0;
+ lifn.lifn_flags = flags;
again:
if (ioctl(fd, SIOCGLIFNUM, &lifn) == -1) {
- (void) snprintf(errbuf, ERRBUFSIZE, "SIOCGLIFNUM: %s",
- strerror(errno));
- (void) close(fd);
- return (-1);
+ opstr = "SIOCGLIFNUM";
+ goto fail;
}
/*
@@ -97,16 +91,17 @@ again:
*/
lifn.lifn_count += 4;
+ lifc.lifc_flags = flags;
lifc.lifc_family = family;
lifc.lifc_len = lifn.lifn_count * sizeof (struct lifreq);
- lifc.lifc_buf = alloca(lifc.lifc_len);
- lifc.lifc_flags = 0;
+ if ((lifc.lifc_buf = realloc(lifc.lifc_buf, lifc.lifc_len)) == NULL) {
+ opstr = "realloc";
+ goto fail;
+ }
if (ioctl(fd, SIOCGLIFCONF, &lifc) == -1) {
- (void) snprintf(errbuf, ERRBUFSIZE, "SIOCGLIFCONF: %s",
- strerror(errno));
- (void) close(fd);
- return (-1);
+ opstr = "SIOCGLIFCONF";
+ goto fail;
}
/*
@@ -121,12 +116,9 @@ again:
/*
* Allocate the address list to return.
*/
- ifaddrlist = calloc(nlifr, sizeof (struct ifaddrlist));
- if (ifaddrlist == NULL) {
- (void) snprintf(errbuf, ERRBUFSIZE, "calloc: %s",
- strerror(errno));
- (void) close(fd);
- return (-1);
+ if ((ifaddrlist = calloc(nlifr, sizeof (struct ifaddrlist))) == NULL) {
+ opstr = "calloc";
+ goto fail;
}
/*
@@ -142,7 +134,7 @@ again:
if (ioctl(fd, SIOCGLIFFLAGS, lifrp) == -1) {
if (errno == ENXIO)
continue;
- iocstr = "SIOCGLIFFLAGS";
+ opstr = "SIOCGLIFFLAGS";
goto fail;
}
al->flags = lifrp->lifr_flags;
@@ -150,7 +142,7 @@ again:
if (ioctl(fd, SIOCGLIFINDEX, lifrp) == -1) {
if (errno == ENXIO)
continue;
- iocstr = "SIOCGLIFINDEX";
+ opstr = "SIOCGLIFINDEX";
goto fail;
}
al->index = lifrp->lifr_index;
@@ -158,7 +150,7 @@ again:
if (ioctl(fd, SIOCGLIFADDR, lifrp) == -1) {
if (errno == ENXIO)
continue;
- iocstr = "SIOCGLIFADDR";
+ opstr = "SIOCGLIFADDR";
goto fail;
}
@@ -174,6 +166,7 @@ again:
}
(void) close(fd);
+ free(lifc.lifc_buf);
if (count == 0) {
free(ifaddrlist);
*ipaddrp = NULL;
@@ -183,9 +176,14 @@ again:
*ipaddrp = ifaddrlist;
return (count);
fail:
- (void) snprintf(errbuf, ERRBUFSIZE, "%s: %s: %s", iocstr, al->device,
- strerror(errno));
-
+ if (al == NULL) {
+ (void) snprintf(errbuf, ERRBUFSIZE, "%s: %s", opstr,
+ strerror(errno));
+ } else {
+ (void) snprintf(errbuf, ERRBUFSIZE, "%s: %s: %s", opstr,
+ al->device, strerror(errno));
+ }
+ free(lifc.lifc_buf);
free(ifaddrlist);
(void) close(fd);
return (-1);
diff --git a/usr/src/lib/libinetutil/common/ifaddrlistx.c b/usr/src/lib/libinetutil/common/ifaddrlistx.c
new file mode 100644
index 0000000000..ce85c5521f
--- /dev/null
+++ b/usr/src/lib/libinetutil/common/ifaddrlistx.c
@@ -0,0 +1,168 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#include <errno.h>
+#include <libinetutil.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/sockio.h>
+
+/*
+ * Create a list of the addresses on physical interface `ifname' with at least
+ * one of the flags in `set' set and all of the flags in `clear' clear.
+ * Return the number of items in the list, or -1 on failure.
+ */
+int
+ifaddrlistx(const char *ifname, uint64_t set, uint64_t clear,
+ ifaddrlistx_t **ifaddrsp)
+{
+ struct lifconf lifc;
+ struct lifnum lifn;
+ struct lifreq *lifrp;
+ ifaddrlistx_t *ifaddrp, *ifaddrs = NULL;
+ int i, nlifr, naddr = 0;
+ char *cp;
+ uint_t flags;
+ int s4, s6 = -1;
+ boolean_t isv6;
+ int save_errno;
+ struct sockaddr_storage addr;
+
+ (void) memset(&lifc, 0, sizeof (lifc));
+ flags = LIFC_NOXMIT | LIFC_ALLZONES | LIFC_TEMPORARY | LIFC_UNDER_IPMP;
+
+ /*
+ * We need both IPv4 and IPv6 sockets to query both IPv4 and IPv6
+ * interfaces below.
+ */
+ if ((s4 = socket(AF_INET, SOCK_DGRAM, 0)) == -1 ||
+ (s6 = socket(AF_INET6, SOCK_DGRAM, 0)) == -1) {
+ goto fail;
+ }
+
+ /*
+ * Get the number of network interfaces of type `family'.
+ */
+ lifn.lifn_family = AF_UNSPEC;
+ lifn.lifn_flags = flags;
+again:
+ if (ioctl(s4, SIOCGLIFNUM, &lifn) == -1)
+ goto fail;
+
+ /*
+ * Pad the interface count to detect when additional interfaces have
+ * been configured between SIOCGLIFNUM and SIOCGLIFCONF.
+ */
+ lifn.lifn_count += 4;
+
+ lifc.lifc_flags = flags;
+ lifc.lifc_family = AF_UNSPEC;
+ lifc.lifc_len = lifn.lifn_count * sizeof (struct lifreq);
+ if ((lifc.lifc_buf = realloc(lifc.lifc_buf, lifc.lifc_len)) == NULL)
+ goto fail;
+
+ if (ioctl(s4, SIOCGLIFCONF, &lifc) == -1)
+ goto fail;
+
+ /*
+ * If every lifr_req slot is taken, then additional interfaces must
+ * have been plumbed between the SIOCGLIFNUM and the SIOCGLIFCONF.
+ * Recalculate to make sure we didn't miss any interfaces.
+ */
+ nlifr = lifc.lifc_len / sizeof (struct lifreq);
+ if (nlifr >= lifn.lifn_count)
+ goto again;
+
+ /*
+ * Populate the ifaddrlistx by querying each matching interface. If a
+ * query ioctl returns ENXIO, then the interface must have been
+ * removed after the SIOCGLIFCONF completed -- so we just ignore it.
+ */
+ for (lifrp = lifc.lifc_req, i = 0; i < nlifr; i++, lifrp++) {
+ if ((cp = strchr(lifrp->lifr_name, ':')) != NULL)
+ *cp = '\0';
+
+ if (strcmp(lifrp->lifr_name, ifname) != 0)
+ continue;
+
+ if (cp != NULL)
+ *cp = ':';
+
+ addr = lifrp->lifr_addr;
+ isv6 = addr.ss_family == AF_INET6;
+ if (ioctl(isv6 ? s6 : s4, SIOCGLIFFLAGS, lifrp) == -1) {
+ if (errno == ENXIO)
+ continue;
+ goto fail;
+ }
+
+ if (set != 0 && ((lifrp->lifr_flags & set) == 0) ||
+ (lifrp->lifr_flags & clear) != 0)
+ continue;
+
+ /*
+ * We've got a match; allocate a new record.
+ */
+ if ((ifaddrp = malloc(sizeof (ifaddrlistx_t))) == NULL)
+ goto fail;
+
+ (void) strlcpy(ifaddrp->ia_name, lifrp->lifr_name, LIFNAMSIZ);
+ ifaddrp->ia_flags = lifrp->lifr_flags;
+ ifaddrp->ia_addr = addr;
+ ifaddrp->ia_next = ifaddrs;
+ ifaddrs = ifaddrp;
+ naddr++;
+ }
+
+ (void) close(s4);
+ (void) close(s6);
+ free(lifc.lifc_buf);
+ *ifaddrsp = ifaddrs;
+ return (naddr);
+fail:
+ save_errno = errno;
+ (void) close(s4);
+ (void) close(s6);
+ free(lifc.lifc_buf);
+ ifaddrlistx_free(ifaddrs);
+ errno = save_errno;
+ return (-1);
+}
+
+/*
+ * Free the provided ifaddrlistx_t.
+ */
+void
+ifaddrlistx_free(ifaddrlistx_t *ifaddrp)
+{
+ ifaddrlistx_t *next_ifaddrp;
+
+ for (; ifaddrp != NULL; ifaddrp = next_ifaddrp) {
+ next_ifaddrp = ifaddrp->ia_next;
+ free(ifaddrp);
+ }
+}
diff --git a/usr/src/lib/libinetutil/common/inetutil4.c b/usr/src/lib/libinetutil/common/inetutil.c
index ff5607e192..195d080b79 100644
--- a/usr/src/lib/libinetutil/common/inetutil4.c
+++ b/usr/src/lib/libinetutil/common/inetutil.c
@@ -18,13 +18,12 @@
*
* CDDL HEADER END
*/
+
/*
- * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <unistd.h>
#include <netinet/in.h>
#include <libinetutil.h>
@@ -32,7 +31,7 @@
extern int getnetmaskbyaddr(const struct in_addr, struct in_addr *);
/*
- * Generic internet (v4) functions.
+ * Internet utility functions.
*/
/*
@@ -67,3 +66,32 @@ get_netmask4(const struct in_addr *n_addrp, struct in_addr *s_addrp)
else
s_addrp->s_addr = IN_CLASSE_NET;
}
+
+/*
+ * Checks if the IP addresses `ssp1' and `ssp2' are equal.
+ */
+boolean_t
+sockaddrcmp(const struct sockaddr_storage *ssp1,
+ const struct sockaddr_storage *ssp2)
+{
+ struct in_addr addr1, addr2;
+ const struct in6_addr *addr6p1, *addr6p2;
+
+ if (ssp1->ss_family != ssp2->ss_family)
+ return (B_FALSE);
+
+ if (ssp1 == ssp2)
+ return (B_TRUE);
+
+ switch (ssp1->ss_family) {
+ case AF_INET:
+ addr1 = ((const struct sockaddr_in *)ssp1)->sin_addr;
+ addr2 = ((const struct sockaddr_in *)ssp2)->sin_addr;
+ return (addr1.s_addr == addr2.s_addr);
+ case AF_INET6:
+ addr6p1 = &((const struct sockaddr_in6 *)ssp1)->sin6_addr;
+ addr6p2 = &((const struct sockaddr_in6 *)ssp2)->sin6_addr;
+ return (IN6_ARE_ADDR_EQUAL(addr6p1, addr6p2));
+ }
+ return (B_FALSE);
+}
diff --git a/usr/src/lib/libinetutil/common/libinetutil.h b/usr/src/lib/libinetutil/common/libinetutil.h
index b21d54f56c..0bece07e07 100644
--- a/usr/src/lib/libinetutil/common/libinetutil.h
+++ b/usr/src/lib/libinetutil/common/libinetutil.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,15 +20,13 @@
*/
/*
- * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _LIBINETUTIL_H
#define _LIBINETUTIL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Contains SMI-private API for general Internet functionality
*/
@@ -59,11 +56,14 @@ typedef struct {
extern boolean_t ifparse_ifspec(const char *, ifspec_t *);
extern void get_netmask4(const struct in_addr *, struct in_addr *);
+extern boolean_t sockaddrcmp(const struct sockaddr_storage *,
+ const struct sockaddr_storage *);
/*
* Extended version of the classic BSD ifaddrlist() interface:
*
- * int ifaddrlist(struct ifaddrlist **addrlistp, int af, char *errbuf);
+ * int ifaddrlist(struct ifaddrlist **addrlistp, int af, uint_t flags,
+ * char *errbuf);
*
* * addrlistp: Upon success, ifaddrlist() sets *addrlistp to a
* dynamically-allocated array of addresses.
@@ -71,6 +71,9 @@ extern void get_netmask4(const struct in_addr *, struct in_addr *);
* * af: Either AF_INET to obtain IPv4 addresses, or AF_INET6 to
* obtain IPv6 addresses.
*
+ * * flags: LIFC_* flags that control the classes of interfaces that
+ * will be visible.
+ *
* * errbuf: A caller-supplied buffer of ERRBUFSIZE. Upon failure,
* provides the reason for the failure.
*
@@ -89,9 +92,43 @@ struct ifaddrlist {
uint64_t flags; /* interface flags */
};
-#define ERRBUFSIZE 128 /* expected size of third argument */
+#define ERRBUFSIZE 128 /* expected size of fourth argument */
+
+extern int ifaddrlist(struct ifaddrlist **, int, uint_t, char *);
-extern int ifaddrlist(struct ifaddrlist **, int, char *);
+/*
+ * Similar to ifaddrlist(), but returns a linked-list of addresses for a
+ * *specific* interface name, and allows specific address flags to be matched
+ * against. A linked list is used rather than an array so that information
+ * can grow over time without affecting binary compatibility. Also, leaves
+ * error-handling up to the caller. Returns the number of ifaddrlistx's
+ * chained through ifaddrp.
+ *
+ * int ifaddrlistx(const char *ifname, uint64_t set, uint64_t clear,
+ * ifaddrlistx_t **ifaddrp);
+ *
+ * * ifname: Interface name to match against.
+ *
+ * * set: One or more flags that must be set on the address for
+ * it to be returned.
+ *
+ * * clear: Flags that must be clear on the address for it to be
+ * returned.
+ *
+ * * ifaddrp: Upon success, ifaddrlistx() sets *ifaddrp to the head
+ * of a dynamically-allocated array of ifaddrlistx structures.
+ *
+ * Once done, the caller must free `ifaddrp' by calling ifaddrlistx_free().
+ */
+typedef struct ifaddrlistx {
+ struct ifaddrlistx *ia_next;
+ char ia_name[LIFNAMSIZ];
+ uint64_t ia_flags;
+ struct sockaddr_storage ia_addr;
+} ifaddrlistx_t;
+
+extern int ifaddrlistx(const char *, uint64_t, uint64_t, ifaddrlistx_t **);
+extern void ifaddrlistx_free(ifaddrlistx_t *);
/*
* Timer queues
diff --git a/usr/src/lib/libinetutil/common/mapfile-vers b/usr/src/lib/libinetutil/common/mapfile-vers
index 51c168fcc4..c9a7829fdb 100644
--- a/usr/src/lib/libinetutil/common/mapfile-vers
+++ b/usr/src/lib/libinetutil/common/mapfile-vers
@@ -19,17 +19,17 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
SUNWprivate_1.1 {
global:
get_netmask4;
hexascii_to_octet;
ifaddrlist;
+ ifaddrlistx;
+ ifaddrlistx_free;
ifparse_ifspec;
iu_adjust_timer;
iu_cancel_timer;
@@ -48,6 +48,7 @@ SUNWprivate_1.1 {
iu_tq_destroy;
iu_unregister_event;
octet_to_hexascii;
+ sockaddrcmp;
local:
*;
};
diff --git a/usr/src/lib/libipmp/Makefile b/usr/src/lib/libipmp/Makefile
index 188c49c073..5d52f304dc 100644
--- a/usr/src/lib/libipmp/Makefile
+++ b/usr/src/lib/libipmp/Makefile
@@ -19,15 +19,13 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
include $(SRC)/lib/Makefile.lib
-HDRS = ipmp.h ipmp_mpathd.h ipmp_query.h ipmp_query_impl.h
+HDRS = ipmp.h ipmp_admin.h ipmp_mpathd.h ipmp_query.h ipmp_query_impl.h
HDRDIR = common
SUBDIRS = $(MACH)
diff --git a/usr/src/lib/libipmp/Makefile.com b/usr/src/lib/libipmp/Makefile.com
index bea02659a8..d3065ae37c 100644
--- a/usr/src/lib/libipmp/Makefile.com
+++ b/usr/src/lib/libipmp/Makefile.com
@@ -19,20 +19,19 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
LIBRARY = libipmp.a
VERS = .1
-OBJECTS = ipmp_query.o ipmp_mpathd.o ipmp.o
+OBJECTS = ipmp_admin.o ipmp_query.o ipmp_mpathd.o ipmp.o
include ../../Makefile.lib
+include ../../Makefile.rootfs
LIBS = $(DYNLIB) $(LINTLIB)
-LDLIBS += -lsocket -lc
+LDLIBS += -linetutil -lsocket -lc
SRCDIR = ../common
$(LINTLIB):= SRCS = $(SRCDIR)/$(LINTSRC)
diff --git a/usr/src/lib/libipmp/common/ipmp.c b/usr/src/lib/libipmp/common/ipmp.c
index b9a7984889..cf9c3c7c3c 100644
--- a/usr/src/lib/libipmp/common/ipmp.c
+++ b/usr/src/lib/libipmp/common/ipmp.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2003 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* IPMP general interfaces (PSARC/2002/615).
*/
@@ -34,6 +31,8 @@
#include <stdlib.h>
#include <locale.h>
#include <unistd.h>
+#include <string.h>
+#include <errno.h>
#include "ipmp_impl.h"
@@ -92,13 +91,15 @@ static char *errmsgs[IPMP_NERR] = {
"operation failed", /* 1 IPMP_FAILURE */
"minimum failover redundancy not met", /* 2 IPMP_EMINRED */
"failback disabled", /* 3 IPMP_EFBDISABLED */
- "unable to completely fail back", /* 4 IPMP_EFBPARTIAL */
+ "unknown IPMP data address", /* 4 IPMP_EUNKADDR */
"invalid argument", /* 5 IPMP_EINVAL */
"out of memory", /* 6 IPMP_ENOMEM */
"cannot contact in.mpathd", /* 7 IPMP_ENOMPATHD */
"unknown IPMP group", /* 8 IPMP_EUNKGROUP */
"interface is not using IPMP", /* 9 IPMP_EUNKIF */
- "unable to communicate with in.mpathd" /* 10 IPMP_EPROTO */
+ "unable to communicate with in.mpathd", /* 10 IPMP_EPROTO */
+ "interface has duplicate hardware address"
+ /* 11 IPMP_EHWADDRDUP */
};
/*
@@ -110,5 +111,8 @@ ipmp_errmsg(int error)
if (error >= IPMP_NERR || error < 0)
return (dgettext(TEXT_DOMAIN, "<unknown error>"));
+ if (error == IPMP_FAILURE)
+ return (strerror(errno));
+
return (dgettext(TEXT_DOMAIN, errmsgs[error]));
}
diff --git a/usr/src/lib/libipmp/common/ipmp.h b/usr/src/lib/libipmp/common/ipmp.h
index 0112615a84..2ca0a9b2b9 100644
--- a/usr/src/lib/libipmp/common/ipmp.h
+++ b/usr/src/lib/libipmp/common/ipmp.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,15 +19,13 @@
* CDDL HEADER END
*/
/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _IPMP_H
#define _IPMP_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* General IPMP-related definitions and functions.
*
@@ -50,13 +47,14 @@ enum {
IPMP_FAILURE, /* operation failed (check errno) */
IPMP_EMINRED, /* minimum failover redundancy not met */
IPMP_EFBDISABLED, /* failback disabled */
- IPMP_EFBPARTIAL, /* unable to completely fail back */
+ IPMP_EUNKADDR, /* unknown IPMP data address */
IPMP_EINVAL, /* invalid argument */
IPMP_ENOMEM, /* out of memory */
IPMP_ENOMPATHD, /* cannot contact in.mpathd */
IPMP_EUNKGROUP, /* unknown IPMP group */
IPMP_EUNKIF, /* interface is not using IPMP */
IPMP_EPROTO, /* unable to communicate with in.mpathd */
+ IPMP_EHWADDRDUP, /* interface has duplicate hardware address */
IPMP_NERR /* number of error codes */
};
diff --git a/usr/src/lib/libipmp/common/ipmp_admin.c b/usr/src/lib/libipmp/common/ipmp_admin.c
new file mode 100644
index 0000000000..8a282f5286
--- /dev/null
+++ b/usr/src/lib/libipmp/common/ipmp_admin.c
@@ -0,0 +1,104 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+/*
+ * IPMP administrative interfaces (see PSARC/2007/272).
+ */
+
+#include <assert.h>
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <sys/time.h>
+#include <sys/types.h>
+
+#include "ipmp_impl.h"
+#include "ipmp_mpathd.h"
+#include "ipmp_admin.h"
+
+static int
+ipmp_command(ipmp_handle_t handle, const void *req, uint_t reqsize)
+{
+ ipmp_state_t *statep = (ipmp_state_t *)handle;
+ mi_result_t result;
+ struct timeval end;
+ int save_errno;
+ int retval;
+
+ if (gettimeofday(&end, NULL) == -1)
+ return (IPMP_FAILURE);
+ end.tv_sec += IPMP_REQTIMEOUT;
+
+ assert(statep->st_fd == -1);
+ retval = ipmp_connect(&statep->st_fd);
+ if (retval != IPMP_SUCCESS)
+ return (retval);
+
+ retval = ipmp_write(statep->st_fd, req, reqsize);
+ if (retval != IPMP_SUCCESS)
+ goto out;
+
+ retval = ipmp_read(statep->st_fd, &result, sizeof (result), &end);
+ if (retval != IPMP_SUCCESS)
+ goto out;
+
+ errno = result.me_sys_error;
+ retval = result.me_mpathd_error;
+out:
+ save_errno = errno;
+ (void) close(statep->st_fd);
+ statep->st_fd = -1;
+ errno = save_errno;
+ return (retval);
+}
+
+int
+ipmp_offline(ipmp_handle_t handle, const char *ifname, uint_t minred)
+{
+ mi_offline_t mio;
+
+ mio.mio_command = MI_OFFLINE;
+ mio.mio_min_redundancy = minred;
+ (void) strlcpy(mio.mio_ifname, ifname, LIFNAMSIZ);
+ return (ipmp_command(handle, &mio, sizeof (mio)));
+}
+
+int
+ipmp_undo_offline(ipmp_handle_t handle, const char *ifname)
+{
+ mi_undo_offline_t miu;
+
+ miu.miu_command = MI_UNDO_OFFLINE;
+ (void) strlcpy(miu.miu_ifname, ifname, LIFNAMSIZ);
+ return (ipmp_command(handle, &miu, sizeof (miu)));
+}
+
+int
+ipmp_ping_daemon(ipmp_handle_t handle)
+{
+ mi_ping_t mip;
+
+ mip.mip_command = MI_PING;
+ return (ipmp_command(handle, &mip, sizeof (mip)));
+}
diff --git a/usr/src/lib/libipmp/common/ipmp_admin.h b/usr/src/lib/libipmp/common/ipmp_admin.h
new file mode 100644
index 0000000000..fa0986f7fa
--- /dev/null
+++ b/usr/src/lib/libipmp/common/ipmp_admin.h
@@ -0,0 +1,50 @@
+/*
+ * CDDL HEADER START
+ *
+ * The contents of this file are subject to the terms of the
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
+ *
+ * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+ * or http://www.opensolaris.org/os/licensing.
+ * See the License for the specific language governing permissions
+ * and limitations under the License.
+ *
+ * When distributing Covered Code, include this CDDL HEADER in each
+ * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+ * If applicable, add the following below this CDDL HEADER, with the
+ * fields enclosed by brackets "[]" replaced with your own identifying
+ * information: Portions Copyright [yyyy] [name of copyright owner]
+ *
+ * CDDL HEADER END
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
+ * Use is subject to license terms.
+ */
+
+#ifndef _IPMP_ADMIN_H
+#define _IPMP_ADMIN_H
+
+#include <ipmp.h>
+#include <sys/types.h>
+
+/*
+ * IPMP administrative interfaces.
+ *
+ * These interfaces may only be used within ON or after signing a contract
+ * with ON. For documentation, refer to PSARC/2007/272.
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern int ipmp_offline(ipmp_handle_t, const char *, uint_t);
+extern int ipmp_undo_offline(ipmp_handle_t, const char *);
+extern int ipmp_ping_daemon(ipmp_handle_t);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _IPMP_ADMIN_H */
diff --git a/usr/src/lib/libipmp/common/ipmp_mpathd.c b/usr/src/lib/libipmp/common/ipmp_mpathd.c
index ee1d35de33..e24de71017 100644
--- a/usr/src/lib/libipmp/common/ipmp_mpathd.c
+++ b/usr/src/lib/libipmp/common/ipmp_mpathd.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -18,14 +17,11 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
- */
-/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Low-level interfaces for communicating with in.mpathd(1M).
*
@@ -66,16 +62,16 @@ ipmp_connect(int *fdp)
return (IPMP_FAILURE);
/*
- * Enable TCP_ANONPRIVBIND so the kernel will choose our source port.
- * Since we're using loopback sockets, requiring use of privileged
- * source ports is sufficient for security.
+ * If we have sufficient privilege, enable TCP_ANONPRIVBIND so the
+ * kernel will choose a privileged source port (since in.mpathd only
+ * accepts requests on loopback, this is sufficient for security).
+ * If not, drive on since MI_QUERY and MI_PING commands are allowed
+ * from non-privileged ports.
*/
- if (setsockopt(fd, IPPROTO_TCP, TCP_ANONPRIVBIND, &on,
- sizeof (on)) == -1)
- goto fail;
+ (void) setsockopt(fd, IPPROTO_TCP, TCP_ANONPRIVBIND, &on, sizeof (on));
/*
- * Bind to a privileged port chosen by the kernel.
+ * Bind to a port chosen by the kernel.
*/
(void) memset(&sin, 0, sizeof (struct sockaddr_in));
sin.sin_port = htons(0);
diff --git a/usr/src/lib/libipmp/common/ipmp_mpathd.h b/usr/src/lib/libipmp/common/ipmp_mpathd.h
index 61ae71b78f..7df3b4fd92 100644
--- a/usr/src/lib/libipmp/common/ipmp_mpathd.h
+++ b/usr/src/lib/libipmp/common/ipmp_mpathd.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -18,26 +17,17 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
- */
-/*
- * Copyright 1999-2002 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _IPMP_MPATHD_H
#define _IPMP_MPATHD_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
* Definitions for the messaging protocol between in.mpathd and libipmp.
- * This interface is loosely documented in PSARC/2000/306.
- *
- * PLEASE NOTE: Although this interface is officially consolidation-private,
- * we will be reclassifying it as project-private in the future, and
- * transitioning any existing consumers to use higher-level libipmp routines.
- *
- * Put another way: treat this as if it was project-private!
+ * This interface is project-private to the IPMP subsystem.
*/
#include <sys/types.h>
@@ -49,33 +39,41 @@ extern "C" {
#endif
#define MPATHD_PORT 5999
-#define MPATHD_PATH "/usr/lib/inet/in.mpathd"
+#define MPATHD_PATH "/lib/inet/in.mpathd"
/*
* Supported commands.
*/
enum {
- MI_PING = 0, /* sanity test */
+ MI_PING = 0, /* ping in.mpathd */
MI_OFFLINE = 1, /* offline the interface */
MI_UNDO_OFFLINE = 2, /* undo the offline */
- MI_SETOINDEX = 3, /* set original interface index */
- MI_QUERY = 4, /* query ipmp-related information */
+ MI_QUERY = 3, /* query ipmp-related information */
MI_NCMD /* total number of commands */
};
/*
* Types of information which can be requested and received (except for
- * IPMP_IFLIST, which can only be received).
+ * IPMP_IFLIST and IPMP_ADDRLIST, which can only be received).
*/
typedef enum {
IPMP_GROUPLIST = 1,
IPMP_GROUPINFO = 2,
IPMP_IFINFO = 3,
IPMP_IFLIST = 4,
- IPMP_SNAP = 5
+ IPMP_SNAP = 5,
+ IPMP_ADDRLIST = 6,
+ IPMP_ADDRINFO = 7
} ipmp_infotype_t;
/*
+ * Daemon ping request.
+ */
+typedef struct mi_ping {
+ uint32_t mip_command;
+} mi_ping_t;
+
+/*
* Interface offline request; `mio_ifname' is the interface to offline;
* `mio_min_redundancy' is the minimum amount of usable interfaces after
* offline that must exist for the operation to succeed.
@@ -83,7 +81,6 @@ typedef enum {
typedef struct mi_offline {
uint32_t mio_command;
char mio_ifname[LIFNAMSIZ];
- char mio_move_to_if[LIFNAMSIZ]; /* currently unused */
uint32_t mio_min_redundancy;
} mi_offline_t;
@@ -97,24 +94,12 @@ typedef struct mi_undo_offline {
} mi_undo_offline_t;
/*
- * Set original interface index request: `mis_lifname' is the name of the
- * logical interface that is having its index reset; `mis_new_pifname' is the
- * name of the interface whose index will be associated with `mis_lifname';
- * `mis_iftype' is the interface type.
- */
-typedef struct mi_setoindex {
- uint32_t mis_command;
- char mis_lifname[LIFNAMSIZ];
- char mis_new_pifname[LIFNAMSIZ];
- uint32_t mis_iftype;
-} mi_setoindex_t;
-
-/*
* Retrieve IPMP-related information: `miq_inforeq' is the type of information
- * being request (see above for the list of types). If the request is for
- * either IPMP_GROUPINFO or IPMP_IFINFO, then either `miq_grname' or
- * `miq_ifname' should be set (respectively) to indicate the name of the
- * group or interface to retrieve the information for.
+ * being request (see above for the list of types). If the request type is
+ * IPMP_GROUPINFO, then `miq_grname' indicates the group. If the request type
+ * is IPMP_IFINFO, then `miq_ifname' indicates the interface. If the request
+ * type is IPMP_ADDRINFO then `miq_grname' indicates the group and `miq_addr'
+ * indicates the address.
*/
typedef struct mi_query {
uint32_t miq_command;
@@ -123,6 +108,7 @@ typedef struct mi_query {
char miqu_ifname[LIFNAMSIZ];
char miqu_grname[LIFGRNAMSIZ];
} miq_infodata;
+ struct sockaddr_storage miq_addr;
} mi_query_t;
#define miq_ifname miq_infodata.miqu_ifname
#define miq_grname miq_infodata.miqu_grname
@@ -132,10 +118,10 @@ typedef struct mi_query {
* requirement for receiving any command.
*/
union mi_commands {
- uint32_t mi_command;
+ uint32_t mi_command;
+ mi_ping_t mi_pcmd;
mi_offline_t mi_ocmd;
mi_undo_offline_t mi_ucmd;
- mi_setoindex_t mi_scmd;
mi_query_t mi_qcmd;
};
@@ -147,18 +133,7 @@ typedef struct mi_result {
uint32_t me_mpathd_error; /* Mpathd error */
} mi_result_t;
-/*
- * Legacy values for me_mpathd_error; the daemon now returns the IPMP
- * error codes defined in <ipmp.h>, which are compatible with these error
- * codes. These will be removed in the future.
- */
-enum {
- MPATHD_SUCCESS = 0, /* operation succeeded */
- MPATHD_SYS_ERROR = 1, /* check me_sys_error for the errno */
- MPATHD_MIN_RED_ERROR = 2, /* minimum redundancy not met */
- MPATHD_FAILBACK_DISABLED = 3, /* failback administratively disabled */
- MPATHD_FAILBACK_PARTIAL = 4 /* unable to completely failback */
-};
+#define IPMP_REQTIMEOUT 5 /* seconds */
extern int ipmp_connect(int *);
extern int ipmp_read(int, void *, size_t, const struct timeval *);
diff --git a/usr/src/lib/libipmp/common/ipmp_query.c b/usr/src/lib/libipmp/common/ipmp_query.c
index 8a7dc7ee69..a0af2da578 100644
--- a/usr/src/lib/libipmp/common/ipmp_query.c
+++ b/usr/src/lib/libipmp/common/ipmp_query.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -18,20 +17,18 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
- */
-/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/*
- * IPMP query interfaces (PSARC/2002/615).
+ * IPMP query interfaces (see PSARC/2002/615 and PSARC/2007/272).
*/
#include <assert.h>
#include <errno.h>
+#include <libinetutil.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
@@ -41,13 +38,19 @@
#include "ipmp_mpathd.h"
#include "ipmp_query_impl.h"
-#define IPMP_REQTIMEOUT 5 /* seconds */
-
static ipmp_ifinfo_t *ipmp_ifinfo_clone(ipmp_ifinfo_t *);
+static ipmp_addrinfo_t *ipmp_addrinfo_clone(ipmp_addrinfo_t *);
+static ipmp_addrlist_t *ipmp_addrlist_clone(ipmp_addrlist_t *);
static ipmp_grouplist_t *ipmp_grouplist_clone(ipmp_grouplist_t *);
static ipmp_groupinfo_t *ipmp_groupinfo_clone(ipmp_groupinfo_t *);
+static ipmp_iflist_t *ipmp_iflist_create(uint_t, char (*)[LIFNAMSIZ]);
+static void ipmp_freeiflist(ipmp_iflist_t *);
+static ipmp_addrlist_t *ipmp_addrlist_create(uint_t, struct sockaddr_storage *);
+static void ipmp_freeaddrlist(ipmp_addrlist_t *);
static ipmp_groupinfo_t *ipmp_snap_getgroupinfo(ipmp_snap_t *, const char *);
static ipmp_ifinfo_t *ipmp_snap_getifinfo(ipmp_snap_t *, const char *);
+static ipmp_addrinfo_t *ipmp_snap_getaddrinfo(ipmp_snap_t *, const char *,
+ struct sockaddr_storage *);
static int ipmp_snap_take(ipmp_state_t *, ipmp_snap_t **);
static boolean_t ipmp_checktlv(ipmp_infotype_t, size_t, void *);
static int ipmp_querydone(ipmp_state_t *, int);
@@ -62,7 +65,7 @@ static int ipmp_querydone(ipmp_state_t *, int);
*/
static int
ipmp_sendquery(ipmp_state_t *statep, ipmp_infotype_t type, const char *name,
- struct timeval *endtp)
+ const void *addr, struct timeval *endtp)
{
mi_query_t query;
mi_result_t result;
@@ -72,6 +75,11 @@ ipmp_sendquery(ipmp_state_t *statep, ipmp_infotype_t type, const char *name,
query.miq_inforeq = type;
switch (type) {
+ case IPMP_ADDRINFO:
+ (void) strlcpy(query.miq_grname, name, LIFGRNAMSIZ);
+ query.miq_addr = *(struct sockaddr_storage *)addr;
+ break;
+
case IPMP_GROUPINFO:
(void) strlcpy(query.miq_grname, name, LIFGRNAMSIZ);
break;
@@ -138,6 +146,61 @@ ipmp_readinfo(ipmp_state_t *statep, ipmp_infotype_t infotype, void **infop,
}
/*
+ * Using `statep', read in the remaining IPMP group information TLVs from
+ * in.mpathd into `grinfop' before the current time becomes `endtp'. Returns
+ * an IPMP error code. On failure, `grinfop' will have its original contents.
+ */
+static int
+ipmp_readgroupinfo_lists(ipmp_state_t *statep, ipmp_groupinfo_t *grinfop,
+ const struct timeval *endtp)
+{
+ int retval;
+ ipmp_iflist_t *iflistp;
+ ipmp_addrlist_t *adlistp;
+
+ retval = ipmp_readinfo(statep, IPMP_IFLIST, (void **)&iflistp, endtp);
+ if (retval != IPMP_SUCCESS)
+ return (retval);
+
+ retval = ipmp_readinfo(statep, IPMP_ADDRLIST, (void **)&adlistp, endtp);
+ if (retval != IPMP_SUCCESS) {
+ ipmp_freeiflist(iflistp);
+ return (retval);
+ }
+
+ grinfop->gr_iflistp = iflistp;
+ grinfop->gr_adlistp = adlistp;
+ return (IPMP_SUCCESS);
+}
+
+/*
+ * Using `statep', read in the remaining IPMP interface information TLVs from
+ * in.mpathd into `ifinfop' before the current time becomes `endtp'. Returns
+ * an IPMP error code. On failure, `ifinfop' will have its original contents.
+ */
+static int
+ipmp_readifinfo_lists(ipmp_state_t *statep, ipmp_ifinfo_t *ifinfop,
+ const struct timeval *endtp)
+{
+ int retval;
+ ipmp_addrlist_t *tlist4p, *tlist6p;
+
+ retval = ipmp_readinfo(statep, IPMP_ADDRLIST, (void **)&tlist4p, endtp);
+ if (retval != IPMP_SUCCESS)
+ return (retval);
+
+ retval = ipmp_readinfo(statep, IPMP_ADDRLIST, (void **)&tlist6p, endtp);
+ if (retval != IPMP_SUCCESS) {
+ ipmp_freeaddrlist(tlist4p);
+ return (retval);
+ }
+
+ ifinfop->if_targinfo4.it_targlistp = tlist4p;
+ ifinfop->if_targinfo6.it_targlistp = tlist6p;
+ return (IPMP_SUCCESS);
+}
+
+/*
* Complete the query operation started in ipmp_sendquery(). The interface is
* designed to be easy to use in the `return' statement of a function, and
* thus returns the passed in `retval' and preserves `errno'.
@@ -169,7 +232,7 @@ ipmp_getgrouplist(ipmp_handle_t handle, ipmp_grouplist_t **grlistpp)
return (*grlistpp != NULL ? IPMP_SUCCESS : IPMP_ENOMEM);
}
- retval = ipmp_sendquery(statep, IPMP_GROUPLIST, NULL, &end);
+ retval = ipmp_sendquery(statep, IPMP_GROUPLIST, NULL, NULL, &end);
if (retval != IPMP_SUCCESS)
return (retval);
@@ -196,7 +259,6 @@ ipmp_getgroupinfo(ipmp_handle_t handle, const char *name,
ipmp_groupinfo_t **grinfopp)
{
ipmp_state_t *statep = handle;
- ipmp_iflist_t *iflistp;
int retval;
struct timeval end;
ipmp_groupinfo_t *grinfop;
@@ -210,7 +272,7 @@ ipmp_getgroupinfo(ipmp_handle_t handle, const char *name,
return (*grinfopp != NULL ? IPMP_SUCCESS : IPMP_ENOMEM);
}
- retval = ipmp_sendquery(statep, IPMP_GROUPINFO, name, &end);
+ retval = ipmp_sendquery(statep, IPMP_GROUPINFO, name, NULL, &end);
if (retval != IPMP_SUCCESS)
return (retval);
@@ -218,11 +280,9 @@ ipmp_getgroupinfo(ipmp_handle_t handle, const char *name,
if (retval != IPMP_SUCCESS)
return (ipmp_querydone(statep, retval));
- retval = ipmp_readinfo(statep, IPMP_IFLIST, (void **)&iflistp, &end);
+ retval = ipmp_readgroupinfo_lists(statep, *grinfopp, &end);
if (retval != IPMP_SUCCESS)
free(*grinfopp);
- else
- (*grinfopp)->gr_iflistp = iflistp;
return (ipmp_querydone(statep, retval));
}
@@ -233,7 +293,8 @@ ipmp_getgroupinfo(ipmp_handle_t handle, const char *name,
void
ipmp_freegroupinfo(ipmp_groupinfo_t *grinfop)
{
- free(grinfop->gr_iflistp);
+ ipmp_freeaddrlist(grinfop->gr_adlistp);
+ ipmp_freeiflist(grinfop->gr_iflistp);
free(grinfop);
}
@@ -259,11 +320,18 @@ ipmp_getifinfo(ipmp_handle_t handle, const char *name, ipmp_ifinfo_t **ifinfopp)
return (*ifinfopp != NULL ? IPMP_SUCCESS : IPMP_ENOMEM);
}
- retval = ipmp_sendquery(statep, IPMP_IFINFO, name, &end);
+ retval = ipmp_sendquery(statep, IPMP_IFINFO, name, NULL, &end);
if (retval != IPMP_SUCCESS)
return (retval);
retval = ipmp_readinfo(statep, IPMP_IFINFO, (void **)ifinfopp, &end);
+ if (retval != IPMP_SUCCESS)
+ return (ipmp_querydone(statep, retval));
+
+ retval = ipmp_readifinfo_lists(statep, *ifinfopp, &end);
+ if (retval != IPMP_SUCCESS)
+ free(*ifinfopp);
+
return (ipmp_querydone(statep, retval));
}
@@ -273,10 +341,52 @@ ipmp_getifinfo(ipmp_handle_t handle, const char *name, ipmp_ifinfo_t **ifinfopp)
void
ipmp_freeifinfo(ipmp_ifinfo_t *ifinfop)
{
+ ipmp_freeaddrlist(ifinfop->if_targinfo4.it_targlistp);
+ ipmp_freeaddrlist(ifinfop->if_targinfo6.it_targlistp);
free(ifinfop);
}
/*
+ * Using `handle', get the address information associated with address `addrp'
+ * on group `grname' and store the results in a dynamically allocated buffer
+ * pointed to by `*adinfopp'. Returns an IPMP error code.
+ */
+int
+ipmp_getaddrinfo(ipmp_handle_t handle, const char *grname,
+ struct sockaddr_storage *addrp, ipmp_addrinfo_t **adinfopp)
+{
+ ipmp_state_t *statep = handle;
+ ipmp_addrinfo_t *adinfop;
+ int retval;
+ struct timeval end;
+
+ if (statep->st_snap != NULL) {
+ adinfop = ipmp_snap_getaddrinfo(statep->st_snap, grname, addrp);
+ if (adinfop == NULL)
+ return (IPMP_EUNKADDR);
+
+ *adinfopp = ipmp_addrinfo_clone(adinfop);
+ return (*adinfopp != NULL ? IPMP_SUCCESS : IPMP_ENOMEM);
+ }
+
+ retval = ipmp_sendquery(statep, IPMP_ADDRINFO, grname, addrp, &end);
+ if (retval != IPMP_SUCCESS)
+ return (retval);
+
+ retval = ipmp_readinfo(statep, IPMP_ADDRINFO, (void **)adinfopp, &end);
+ return (ipmp_querydone(statep, retval));
+}
+
+/*
+ * Free the address information pointed to by `adinfop'.
+ */
+void
+ipmp_freeaddrinfo(ipmp_addrinfo_t *adinfop)
+{
+ free(adinfop);
+}
+
+/*
* Check if `buf' has a NUL byte in its first `bufsize' bytes.
*/
static boolean_t
@@ -300,12 +410,25 @@ ipmp_checktlv(ipmp_infotype_t type, size_t len, void *value)
ipmp_ifinfo_t *ifinfop;
ipmp_grouplist_t *grlistp;
ipmp_groupinfo_t *grinfop;
+ ipmp_addrlist_t *adlistp;
unsigned int i;
switch (type) {
+ case IPMP_ADDRINFO:
+ if (len != sizeof (ipmp_addrinfo_t))
+ return (B_FALSE);
+ break;
+
+ case IPMP_ADDRLIST:
+ adlistp = (ipmp_addrlist_t *)value;
+ if (len < IPMP_ADDRLIST_SIZE(0) ||
+ len < IPMP_ADDRLIST_SIZE(adlistp->al_naddr))
+ return (B_FALSE);
+ break;
+
case IPMP_IFLIST:
iflistp = (ipmp_iflist_t *)value;
- if (len < IPMP_IFLIST_MINSIZE ||
+ if (len < IPMP_IFLIST_SIZE(0) ||
len < IPMP_IFLIST_SIZE(iflistp->il_nif))
return (B_FALSE);
@@ -326,7 +449,7 @@ ipmp_checktlv(ipmp_infotype_t type, size_t len, void *value)
case IPMP_GROUPLIST:
grlistp = (ipmp_grouplist_t *)value;
- if (len < IPMP_GROUPLIST_MINSIZE ||
+ if (len < IPMP_GROUPLIST_SIZE(0) ||
len < IPMP_GROUPLIST_SIZE(grlistp->gl_ngroup))
return (B_FALSE);
@@ -357,9 +480,8 @@ ipmp_checktlv(ipmp_infotype_t type, size_t len, void *value)
}
/*
- * Create a group list with signature `sig' containing `ngroup' groups named
- * by `groups'. Returns a pointer to the new group list on success, or NULL
- * on failure.
+ * Create a group list; arguments match ipmp_grouplist_t fields. Returns a
+ * pointer to the new group list on success, or NULL on failure.
*/
ipmp_grouplist_t *
ipmp_grouplist_create(uint64_t sig, unsigned int ngroup,
@@ -392,13 +514,80 @@ ipmp_grouplist_clone(ipmp_grouplist_t *grlistp)
}
/*
- * Create an interface information structure for interface `name' and
- * associate `group', `state' and `type' with it. Returns a pointer to the
- * interface information on success, or NULL on failure.
+ * Create target information; arguments match ipmp_targinfo_t fields. Returns
+ * a pointer to the new target info on success, or NULL on failure.
+ */
+ipmp_targinfo_t *
+ipmp_targinfo_create(const char *name, struct sockaddr_storage *testaddrp,
+ ipmp_if_targmode_t targmode, uint_t ntarg, struct sockaddr_storage *targs)
+{
+ ipmp_targinfo_t *targinfop;
+
+ targinfop = malloc(sizeof (ipmp_targinfo_t));
+ if (targinfop == NULL)
+ return (NULL);
+
+ targinfop->it_testaddr = *testaddrp;
+ targinfop->it_targmode = targmode;
+ targinfop->it_targlistp = ipmp_addrlist_create(ntarg, targs);
+ if (targinfop->it_targlistp == NULL) {
+ ipmp_freetarginfo(targinfop);
+ return (NULL);
+ }
+ (void) strlcpy(targinfop->it_name, name, LIFNAMSIZ);
+
+ return (targinfop);
+}
+
+/*
+ * Free the target information pointed to by `targinfop'.
+ */
+void
+ipmp_freetarginfo(ipmp_targinfo_t *targinfop)
+{
+ free(targinfop->it_targlistp);
+ free(targinfop);
+}
+
+/*
+ * Create an interface list; arguments match ipmp_iflist_t fields. Returns a
+ * pointer to the new interface list on success, or NULL on failure.
+ */
+static ipmp_iflist_t *
+ipmp_iflist_create(uint_t nif, char (*ifs)[LIFNAMSIZ])
+{
+ unsigned int i;
+ ipmp_iflist_t *iflistp;
+
+ iflistp = malloc(IPMP_IFLIST_SIZE(nif));
+ if (iflistp == NULL)
+ return (NULL);
+
+ iflistp->il_nif = nif;
+ for (i = 0; i < nif; i++)
+ (void) strlcpy(iflistp->il_ifs[i], ifs[i], LIFNAMSIZ);
+
+ return (iflistp);
+}
+
+/*
+ * Free the interface list pointed to by `iflistp'.
+ */
+static void
+ipmp_freeiflist(ipmp_iflist_t *iflistp)
+{
+ free(iflistp);
+}
+
+/*
+ * Create an interface; arguments match ipmp_ifinfo_t fields. Returns a
+ * pointer to the new interface on success, or NULL on failure.
*/
ipmp_ifinfo_t *
ipmp_ifinfo_create(const char *name, const char *group, ipmp_if_state_t state,
- ipmp_if_type_t type)
+ ipmp_if_type_t type, ipmp_if_linkstate_t linkstate,
+ ipmp_if_probestate_t probestate, ipmp_if_flags_t flags,
+ ipmp_targinfo_t *targinfo4p, ipmp_targinfo_t *targinfo6p)
{
ipmp_ifinfo_t *ifinfop;
@@ -408,8 +597,25 @@ ipmp_ifinfo_create(const char *name, const char *group, ipmp_if_state_t state,
(void) strlcpy(ifinfop->if_name, name, LIFNAMSIZ);
(void) strlcpy(ifinfop->if_group, group, LIFGRNAMSIZ);
- ifinfop->if_state = state;
- ifinfop->if_type = type;
+
+ ifinfop->if_state = state;
+ ifinfop->if_type = type;
+ ifinfop->if_linkstate = linkstate;
+ ifinfop->if_probestate = probestate;
+ ifinfop->if_flags = flags;
+ ifinfop->if_targinfo4 = *targinfo4p;
+ ifinfop->if_targinfo6 = *targinfo6p;
+
+ ifinfop->if_targinfo4.it_targlistp =
+ ipmp_addrlist_clone(targinfo4p->it_targlistp);
+ ifinfop->if_targinfo6.it_targlistp =
+ ipmp_addrlist_clone(targinfo6p->it_targlistp);
+
+ if (ifinfop->if_targinfo4.it_targlistp == NULL ||
+ ifinfop->if_targinfo6.it_targlistp == NULL) {
+ ipmp_freeifinfo(ifinfop);
+ return (NULL);
+ }
return (ifinfop);
}
@@ -422,40 +628,41 @@ ipmp_ifinfo_t *
ipmp_ifinfo_clone(ipmp_ifinfo_t *ifinfop)
{
return (ipmp_ifinfo_create(ifinfop->if_name, ifinfop->if_group,
- ifinfop->if_state, ifinfop->if_type));
+ ifinfop->if_state, ifinfop->if_type, ifinfop->if_linkstate,
+ ifinfop->if_probestate, ifinfop->if_flags, &ifinfop->if_targinfo4,
+ &ifinfop->if_targinfo6));
}
/*
- * Create a group named `name' with signature `sig', in state `state', and
- * with the `nif' interfaces named by `ifs' as members. Returns a pointer
+ * Create a group; arguments match ipmp_groupinfo_t fields. Returns a pointer
* to the new group on success, or NULL on failure.
*/
ipmp_groupinfo_t *
-ipmp_groupinfo_create(const char *name, uint64_t sig, ipmp_group_state_t state,
- unsigned int nif, char (*ifs)[LIFNAMSIZ])
+ipmp_groupinfo_create(const char *name, uint64_t sig, uint_t fdt,
+ ipmp_group_state_t state, uint_t nif, char (*ifs)[LIFNAMSIZ],
+ const char *grifname, const char *m4ifname, const char *m6ifname,
+ const char *bcifname, uint_t naddr, struct sockaddr_storage *addrs)
{
ipmp_groupinfo_t *grinfop;
- ipmp_iflist_t *iflistp;
- unsigned int i;
grinfop = malloc(sizeof (ipmp_groupinfo_t));
if (grinfop == NULL)
return (NULL);
- iflistp = malloc(IPMP_IFLIST_SIZE(nif));
- if (iflistp == NULL) {
- free(grinfop);
+ grinfop->gr_sig = sig;
+ grinfop->gr_fdt = fdt;
+ grinfop->gr_state = state;
+ grinfop->gr_iflistp = ipmp_iflist_create(nif, ifs);
+ grinfop->gr_adlistp = ipmp_addrlist_create(naddr, addrs);
+ if (grinfop->gr_iflistp == NULL || grinfop->gr_adlistp == NULL) {
+ ipmp_freegroupinfo(grinfop);
return (NULL);
}
-
- grinfop->gr_sig = sig;
- grinfop->gr_state = state;
- grinfop->gr_iflistp = iflistp;
(void) strlcpy(grinfop->gr_name, name, LIFGRNAMSIZ);
-
- iflistp->il_nif = nif;
- for (i = 0; i < nif; i++)
- (void) strlcpy(iflistp->il_ifs[i], ifs[i], LIFNAMSIZ);
+ (void) strlcpy(grinfop->gr_ifname, grifname, LIFNAMSIZ);
+ (void) strlcpy(grinfop->gr_m4ifname, m4ifname, LIFNAMSIZ);
+ (void) strlcpy(grinfop->gr_m6ifname, m6ifname, LIFNAMSIZ);
+ (void) strlcpy(grinfop->gr_bcifname, bcifname, LIFNAMSIZ);
return (grinfop);
}
@@ -467,9 +674,86 @@ ipmp_groupinfo_create(const char *name, uint64_t sig, ipmp_group_state_t state,
ipmp_groupinfo_t *
ipmp_groupinfo_clone(ipmp_groupinfo_t *grinfop)
{
+ ipmp_addrlist_t *adlistp = grinfop->gr_adlistp;
+
return (ipmp_groupinfo_create(grinfop->gr_name, grinfop->gr_sig,
- grinfop->gr_state, grinfop->gr_iflistp->il_nif,
- grinfop->gr_iflistp->il_ifs));
+ grinfop->gr_fdt, grinfop->gr_state, grinfop->gr_iflistp->il_nif,
+ grinfop->gr_iflistp->il_ifs, grinfop->gr_ifname,
+ grinfop->gr_m4ifname, grinfop->gr_m6ifname, grinfop->gr_bcifname,
+ adlistp->al_naddr, adlistp->al_addrs));
+}
+
+/*
+ * Create an address list; arguments match ipmp_addrlist_t fields. Returns
+ * a pointer to the new address list on success, or NULL on failure.
+ */
+static ipmp_addrlist_t *
+ipmp_addrlist_create(uint_t naddr, struct sockaddr_storage *addrs)
+{
+ unsigned int i;
+ ipmp_addrlist_t *adlistp;
+
+ adlistp = malloc(IPMP_ADDRLIST_SIZE(naddr));
+ if (adlistp == NULL)
+ return (NULL);
+
+ adlistp->al_naddr = naddr;
+ for (i = 0; i < naddr; i++)
+ adlistp->al_addrs[i] = addrs[i];
+
+ return (adlistp);
+}
+
+/*
+ * Clone the address list named by `adlistp'. Returns a pointer to the clone
+ * on success, or NULL on failure.
+ */
+static ipmp_addrlist_t *
+ipmp_addrlist_clone(ipmp_addrlist_t *adlistp)
+{
+ return (ipmp_addrlist_create(adlistp->al_naddr, adlistp->al_addrs));
+}
+
+/*
+ * Free the address list pointed to by `adlistp'.
+ */
+static void
+ipmp_freeaddrlist(ipmp_addrlist_t *adlistp)
+{
+ free(adlistp);
+}
+
+/*
+ * Create an address; arguments match ipmp_addrinfo_t fields. Returns a
+ * pointer to the new address on success, or NULL on failure.
+ */
+ipmp_addrinfo_t *
+ipmp_addrinfo_create(struct sockaddr_storage *addrp, ipmp_addr_state_t state,
+ const char *group, const char *binding)
+{
+ ipmp_addrinfo_t *adinfop;
+
+ adinfop = malloc(sizeof (ipmp_addrinfo_t));
+ if (adinfop == NULL)
+ return (NULL);
+
+ adinfop->ad_addr = *addrp;
+ adinfop->ad_state = state;
+ (void) strlcpy(adinfop->ad_group, group, LIFGRNAMSIZ);
+ (void) strlcpy(adinfop->ad_binding, binding, LIFNAMSIZ);
+
+ return (adinfop);
+}
+
+/*
+ * Clone the address information named by `adinfop'. Returns a pointer to
+ * the clone on success, or NULL on failure.
+ */
+ipmp_addrinfo_t *
+ipmp_addrinfo_clone(ipmp_addrinfo_t *adinfop)
+{
+ return (ipmp_addrinfo_create(&adinfop->ad_addr, adinfop->ad_state,
+ adinfop->ad_group, adinfop->ad_binding));
}
/*
@@ -523,8 +807,10 @@ ipmp_snap_create(void)
snap->sn_grlistp = NULL;
snap->sn_grinfolistp = NULL;
snap->sn_ifinfolistp = NULL;
+ snap->sn_adinfolistp = NULL;
snap->sn_ngroup = 0;
snap->sn_nif = 0;
+ snap->sn_naddr = 0;
return (snap);
}
@@ -536,6 +822,7 @@ void
ipmp_snap_free(ipmp_snap_t *snap)
{
ipmp_ifinfolist_t *iflp, *ifnext;
+ ipmp_addrinfolist_t *adlp, *adnext;
ipmp_groupinfolist_t *grlp, *grnext;
ipmp_freegrouplist(snap->sn_grlistp);
@@ -552,6 +839,12 @@ ipmp_snap_free(ipmp_snap_t *snap)
free(iflp);
}
+ for (adlp = snap->sn_adinfolistp; adlp != NULL; adlp = adnext) {
+ adnext = adlp->adl_next;
+ ipmp_freeaddrinfo(adlp->adl_adinfop);
+ free(adlp);
+ }
+
free(snap);
}
@@ -612,6 +905,34 @@ ipmp_snap_addifinfo(ipmp_snap_t *snap, ipmp_ifinfo_t *ifinfop)
}
/*
+ * Add the address information in `adinfop' to the snapshot named by `snap'.
+ * Returns an IPMP error code.
+ */
+int
+ipmp_snap_addaddrinfo(ipmp_snap_t *snap, ipmp_addrinfo_t *adinfop)
+{
+ ipmp_addrinfolist_t *adlp;
+
+ /*
+ * Any duplicate addresses should've already been weeded by in.mpathd.
+ */
+ if (ipmp_snap_getaddrinfo(snap, adinfop->ad_group,
+ &adinfop->ad_addr) != NULL)
+ return (IPMP_EPROTO);
+
+ adlp = malloc(sizeof (ipmp_addrinfolist_t));
+ if (adlp == NULL)
+ return (IPMP_ENOMEM);
+
+ adlp->adl_adinfop = adinfop;
+ adlp->adl_next = snap->sn_adinfolistp;
+ snap->sn_adinfolistp = adlp;
+ snap->sn_naddr++;
+
+ return (IPMP_SUCCESS);
+}
+
+/*
* Retrieve the information for the group `name' in snapshot `snap'.
* Returns a pointer to the group information on success, or NULL on failure.
*/
@@ -647,6 +968,26 @@ ipmp_snap_getifinfo(ipmp_snap_t *snap, const char *name)
}
/*
+ * Retrieve the information for the address `addrp' on group `grname' in
+ * snapshot `snap'. Returns a pointer to the address information on success,
+ * or NULL on failure.
+ */
+static ipmp_addrinfo_t *
+ipmp_snap_getaddrinfo(ipmp_snap_t *snap, const char *grname,
+ struct sockaddr_storage *addrp)
+{
+ ipmp_addrinfolist_t *adlp;
+
+ for (adlp = snap->sn_adinfolistp; adlp != NULL; adlp = adlp->adl_next) {
+ if (strcmp(grname, adlp->adl_adinfop->ad_group) == 0 &&
+ sockaddrcmp(addrp, &adlp->adl_adinfop->ad_addr))
+ break;
+ }
+
+ return (adlp != NULL ? adlp->adl_adinfop : NULL);
+}
+
+/*
* Using `statep', take a snapshot of the IPMP subsystem and if successful
* return it in a dynamically allocated snapshot pointed to by `*snapp'.
* Returns an IPMP error code.
@@ -656,7 +997,6 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
{
ipmp_snap_t *snap, *osnap;
ipmp_infotype_t type;
- ipmp_iflist_t *iflistp;
int retval;
size_t len;
void *infop;
@@ -666,7 +1006,7 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
if (snap == NULL)
return (IPMP_ENOMEM);
- retval = ipmp_sendquery(statep, IPMP_SNAP, NULL, &end);
+ retval = ipmp_sendquery(statep, IPMP_SNAP, NULL, NULL, &end);
if (retval != IPMP_SUCCESS) {
ipmp_snap_free(snap);
return (retval);
@@ -679,12 +1019,11 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
}
/*
- * Using the information in the passed `osnap' snapshot, build up our
- * own snapshot. If we receive more than one grouplist, or more than
- * the expected number of interfaces or groups, then bail out. Note
- * that there's only so much we can do to check that the information
- * sent by in.mpathd makes sense. We know there will always be at
- * least one TLV (IPMP_GROUPLIST).
+ * Using the information in the `osnap' snapshot, build up our own
+ * snapshot. We know there will always be at least one TLV (for
+ * IPMP_GROUPLIST). If we receive anything illogical (e.g., more than
+ * the expected number of interfaces), then bail out. However, to a
+ * large extent we have to trust the information sent by in.mpathd.
*/
do {
infop = NULL;
@@ -711,7 +1050,32 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
retval = IPMP_EPROTO;
break;
}
+
+ /*
+ * Read in V4 and V6 targlist TLVs that follow.
+ */
+ retval = ipmp_readifinfo_lists(statep, infop, &end);
+ if (retval != IPMP_SUCCESS)
+ break;
+
retval = ipmp_snap_addifinfo(snap, infop);
+ if (retval != IPMP_SUCCESS) {
+ ipmp_freeifinfo(infop);
+ infop = NULL;
+ }
+ break;
+
+ case IPMP_ADDRINFO:
+ if (snap->sn_naddr == osnap->sn_naddr) {
+ retval = IPMP_EPROTO;
+ break;
+ }
+
+ retval = ipmp_snap_addaddrinfo(snap, infop);
+ /*
+ * NOTE: since we didn't call ipmp_read*info_lists(),
+ * no need to use ipmp_freeaddrinfo() on failure.
+ */
break;
case IPMP_GROUPINFO:
@@ -721,18 +1085,17 @@ ipmp_snap_take(ipmp_state_t *statep, ipmp_snap_t **snapp)
}
/*
- * An IPMP_IFLIST TLV always follows the
- * IPMP_GROUPINFO TLV; read it in.
+ * Read in IPMP groupinfo list TLVs that follow.
*/
- retval = ipmp_readinfo(statep, IPMP_IFLIST,
- (void **)&iflistp, &end);
+ retval = ipmp_readgroupinfo_lists(statep, infop, &end);
if (retval != IPMP_SUCCESS)
break;
- ((ipmp_groupinfo_t *)infop)->gr_iflistp = iflistp;
retval = ipmp_snap_addgroupinfo(snap, infop);
- if (retval != IPMP_SUCCESS)
- free(iflistp);
+ if (retval != IPMP_SUCCESS) {
+ ipmp_freegroupinfo(infop);
+ infop = NULL;
+ }
break;
default:
@@ -747,7 +1110,8 @@ fail:
return (ipmp_querydone(statep, retval));
}
} while (snap->sn_grlistp == NULL || snap->sn_nif < osnap->sn_nif ||
- snap->sn_ngroup < osnap->sn_ngroup);
+ snap->sn_ngroup < osnap->sn_ngroup ||
+ snap->sn_naddr < osnap->sn_naddr);
free(osnap);
*snapp = snap;
diff --git a/usr/src/lib/libipmp/common/ipmp_query.h b/usr/src/lib/libipmp/common/ipmp_query.h
index d92554887a..160f561dd2 100644
--- a/usr/src/lib/libipmp/common/ipmp_query.h
+++ b/usr/src/lib/libipmp/common/ipmp_query.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -18,17 +17,14 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
- */
-/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _IPMP_QUERY_H
#define _IPMP_QUERY_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <sys/types.h>
#include <sys/socket.h> /* needed by <net/if.h> */
#include <net/if.h> /* for LIF*NAMSIZ */
@@ -38,7 +34,7 @@
* IPMP query interfaces.
*
* These interfaces may only be used within ON or after signing a contract
- * with ON. For documentation, refer to PSARC/2002/615.
+ * with ON. For documentation, refer to PSARC/2002/615 and PSARC/2007/272.
*/
#ifdef __cplusplus
@@ -46,6 +42,43 @@ extern "C" {
#endif
/*
+ * Assorted enumerations used in the data types described below.
+ */
+typedef enum ipmp_if_probestate {
+ IPMP_PROBE_OK, /* probes detect no problems */
+ IPMP_PROBE_FAILED, /* probes detect failure */
+ IPMP_PROBE_UNKNOWN, /* probe detection unavailable */
+ IPMP_PROBE_DISABLED /* probe detection disabled */
+} ipmp_if_probestate_t;
+
+typedef enum ipmp_if_linkstate {
+ IPMP_LINK_UP, /* link detects up */
+ IPMP_LINK_DOWN, /* link detects down */
+ IPMP_LINK_UNKNOWN /* link detection unavailable */
+} ipmp_if_linkstate_t;
+
+typedef enum ipmp_if_flags {
+ IPMP_IFFLAG_INACTIVE = 0x1,
+ IPMP_IFFLAG_HWADDRDUP = 0x2,
+ IPMP_IFFLAG_ACTIVE = 0x4,
+ IPMP_IFFLAG_DOWN = 0x8
+} ipmp_if_flags_t;
+
+typedef enum ipmp_addr_state {
+ IPMP_ADDR_UP, /* address is up */
+ IPMP_ADDR_DOWN /* address is down */
+} ipmp_addr_state_t;
+
+typedef enum ipmp_if_targmode {
+ IPMP_TARG_DISABLED, /* use of targets is disabled */
+ IPMP_TARG_ROUTES, /* route-learned targets */
+ IPMP_TARG_MULTICAST /* multicast-learned targets */
+} ipmp_if_targmode_t;
+
+#define IPMP_LIST_SIZE(listtype, elsize, nel) \
+ ((sizeof (ipmp_ ## listtype ## _t) - (elsize)) + ((nel) * (elsize)))
+
+/*
* Data type describing a list of IPMP groups.
*/
typedef struct ipmp_grouplist {
@@ -54,8 +87,8 @@ typedef struct ipmp_grouplist {
char gl_groups[1][LIFGRNAMSIZ];
} ipmp_grouplist_t;
-#define IPMP_GROUPLIST_MINSIZE (sizeof (ipmp_grouplist_t) - LIFGRNAMSIZ)
-#define IPMP_GROUPLIST_SIZE(ngr) (IPMP_GROUPLIST_MINSIZE + (ngr) * LIFGRNAMSIZ)
+#define IPMP_GROUPLIST_SIZE(ngr) \
+ IPMP_LIST_SIZE(grouplist, LIFGRNAMSIZ, ngr)
/*
* Data type describing a list of interfaces.
@@ -65,8 +98,19 @@ typedef struct ipmp_iflist {
char il_ifs[1][LIFNAMSIZ];
} ipmp_iflist_t;
-#define IPMP_IFLIST_MINSIZE (sizeof (ipmp_iflist_t) - LIFNAMSIZ)
-#define IPMP_IFLIST_SIZE(nif) (IPMP_IFLIST_MINSIZE + (nif) * LIFNAMSIZ)
+#define IPMP_IFLIST_SIZE(nif) \
+ IPMP_LIST_SIZE(iflist, LIFNAMSIZ, nif)
+
+/*
+ * Data type describing a list of addresses.
+ */
+typedef struct ipmp_addrlist {
+ unsigned int al_naddr;
+ struct sockaddr_storage al_addrs[1];
+} ipmp_addrlist_t;
+
+#define IPMP_ADDRLIST_SIZE(naddr) \
+ IPMP_LIST_SIZE(addrlist, sizeof (struct sockaddr_storage), naddr)
/*
* Data type describing the state of an IPMP group.
@@ -76,18 +120,49 @@ typedef struct ipmp_groupinfo {
uint64_t gr_sig;
ipmp_group_state_t gr_state;
ipmp_iflist_t *gr_iflistp;
+ ipmp_addrlist_t *gr_adlistp;
+ char gr_ifname[LIFNAMSIZ];
+ char gr_m4ifname[LIFNAMSIZ];
+ char gr_m6ifname[LIFNAMSIZ];
+ char gr_bcifname[LIFNAMSIZ];
+ unsigned int gr_fdt;
} ipmp_groupinfo_t;
/*
+ * Data type describing IPMP target information for a particular interface.
+ */
+typedef struct ipmp_targinfo {
+ char it_name[LIFNAMSIZ];
+ struct sockaddr_storage it_testaddr;
+ ipmp_if_targmode_t it_targmode;
+ ipmp_addrlist_t *it_targlistp;
+} ipmp_targinfo_t;
+
+/*
* Data type describing the IPMP-related state of an interface.
*/
typedef struct ipmp_ifinfo {
- char if_name[LIFNAMSIZ];
- char if_group[LIFGRNAMSIZ];
- ipmp_if_state_t if_state;
- ipmp_if_type_t if_type;
+ char if_name[LIFNAMSIZ];
+ char if_group[LIFGRNAMSIZ];
+ ipmp_if_state_t if_state;
+ ipmp_if_type_t if_type;
+ ipmp_if_linkstate_t if_linkstate;
+ ipmp_if_probestate_t if_probestate;
+ ipmp_if_flags_t if_flags;
+ ipmp_targinfo_t if_targinfo4;
+ ipmp_targinfo_t if_targinfo6;
} ipmp_ifinfo_t;
+/*
+ * Data type describing an IPMP data address.
+ */
+typedef struct ipmp_addrinfo {
+ struct sockaddr_storage ad_addr;
+ ipmp_addr_state_t ad_state;
+ char ad_group[LIFGRNAMSIZ];
+ char ad_binding[LIFNAMSIZ];
+} ipmp_addrinfo_t;
+
typedef enum {
IPMP_QCONTEXT_LIVE,
IPMP_QCONTEXT_SNAP
@@ -100,6 +175,9 @@ extern int ipmp_getgroupinfo(ipmp_handle_t, const char *, ipmp_groupinfo_t **);
extern void ipmp_freegroupinfo(ipmp_groupinfo_t *);
extern int ipmp_getifinfo(ipmp_handle_t, const char *, ipmp_ifinfo_t **);
extern void ipmp_freeifinfo(ipmp_ifinfo_t *);
+extern int ipmp_getaddrinfo(ipmp_handle_t, const char *,
+ struct sockaddr_storage *, ipmp_addrinfo_t **);
+extern void ipmp_freeaddrinfo(ipmp_addrinfo_t *);
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libipmp/common/ipmp_query_impl.h b/usr/src/lib/libipmp/common/ipmp_query_impl.h
index 03ecb5cd84..6ac5c3ca27 100644
--- a/usr/src/lib/libipmp/common/ipmp_query_impl.h
+++ b/usr/src/lib/libipmp/common/ipmp_query_impl.h
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -18,17 +17,14 @@
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
- */
-/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ *
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#ifndef _IPMP_QUERY_IMPL_H
#define _IPMP_QUERY_IMPL_H
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <ipmp_query.h>
/*
@@ -58,14 +54,24 @@ typedef struct ipmp_ifinfolist {
} ipmp_ifinfolist_t;
/*
+ * List of ipmp_addrinfo_t structures.
+ */
+typedef struct ipmp_addrinfolist {
+ struct ipmp_addrinfolist *adl_next;
+ ipmp_addrinfo_t *adl_adinfop;
+} ipmp_addrinfolist_t;
+
+/*
* Snapshot of IPMP state.
*/
typedef struct ipmp_snap {
ipmp_grouplist_t *sn_grlistp;
ipmp_groupinfolist_t *sn_grinfolistp;
ipmp_ifinfolist_t *sn_ifinfolistp;
+ ipmp_addrinfolist_t *sn_adinfolistp;
unsigned int sn_ngroup;
unsigned int sn_nif;
+ unsigned int sn_naddr;
} ipmp_snap_t;
/*
@@ -74,17 +80,28 @@ typedef struct ipmp_snap {
extern ipmp_snap_t *ipmp_snap_create(void);
extern void ipmp_snap_free(ipmp_snap_t *);
extern int ipmp_snap_addifinfo(ipmp_snap_t *, ipmp_ifinfo_t *);
+extern int ipmp_snap_addaddrinfo(ipmp_snap_t *, ipmp_addrinfo_t *);
extern int ipmp_snap_addgroupinfo(ipmp_snap_t *, ipmp_groupinfo_t *);
/*
- * IPMP structure creation routines.
+ * IPMP structure creation/destruction routines.
*/
extern ipmp_ifinfo_t *ipmp_ifinfo_create(const char *, const char *,
- ipmp_if_state_t, ipmp_if_type_t);
-extern ipmp_groupinfo_t *ipmp_groupinfo_create(const char *, uint64_t,
- ipmp_group_state_t, unsigned int, char (*)[LIFNAMSIZ]);
+ ipmp_if_state_t, ipmp_if_type_t, ipmp_if_linkstate_t, ipmp_if_probestate_t,
+ ipmp_if_flags_t, ipmp_targinfo_t *, ipmp_targinfo_t *);
+extern ipmp_groupinfo_t *ipmp_groupinfo_create(const char *, uint64_t, uint_t,
+ ipmp_group_state_t, uint_t, char (*)[LIFNAMSIZ], const char *,
+ const char *, const char *, const char *, uint_t,
+ struct sockaddr_storage *);
extern ipmp_grouplist_t *ipmp_grouplist_create(uint64_t, unsigned int,
char (*)[LIFGRNAMSIZ]);
+extern ipmp_addrinfo_t *ipmp_addrinfo_create(struct sockaddr_storage *,
+ ipmp_addr_state_t, const char *, const char *);
+extern ipmp_targinfo_t *ipmp_targinfo_create(const char *,
+ struct sockaddr_storage *, ipmp_if_targmode_t, uint_t,
+ struct sockaddr_storage *);
+extern void ipmp_freetarginfo(ipmp_targinfo_t *);
+
#ifdef __cplusplus
}
diff --git a/usr/src/lib/libipmp/common/llib-lipmp b/usr/src/lib/libipmp/common/llib-lipmp
index a16011745a..a22eec5d66 100644
--- a/usr/src/lib/libipmp/common/llib-lipmp
+++ b/usr/src/lib/libipmp/common/llib-lipmp
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,15 +19,14 @@
* CDDL HEADER END
*/
/*
- * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
/* LINTLIBRARY */
/* PROTOLIB1 */
#include <ipmp.h>
+#include <ipmp_admin.h>
#include <ipmp_mpathd.h>
#include <ipmp_query_impl.h>
diff --git a/usr/src/lib/libipmp/common/mapfile-vers b/usr/src/lib/libipmp/common/mapfile-vers
index a4052bfcd3..8c93248338 100644
--- a/usr/src/lib/libipmp/common/mapfile-vers
+++ b/usr/src/lib/libipmp/common/mapfile-vers
@@ -19,32 +19,39 @@
# CDDL HEADER END
#
#
-# Copyright 2006 Sun Microsystems, Inc. All rights reserved.
+# Copyright 2009 Sun Microsystems, Inc. All rights reserved.
# Use is subject to license terms.
#
-# ident "%Z%%M% %I% %E% SMI"
-#
SUNWprivate_1.1 {
global:
+ ipmp_addrinfo_create;
ipmp_close;
ipmp_errmsg;
+ ipmp_freeaddrinfo;
ipmp_freegroupinfo;
ipmp_freegrouplist;
ipmp_freeifinfo;
+ ipmp_freetarginfo;
+ ipmp_getaddrinfo;
ipmp_getgroupinfo;
ipmp_getgrouplist;
ipmp_getifinfo;
ipmp_groupinfo_create;
ipmp_grouplist_create;
ipmp_ifinfo_create;
+ ipmp_offline;
ipmp_open;
+ ipmp_ping_daemon;
ipmp_read;
ipmp_setqcontext;
+ ipmp_snap_addaddrinfo;
ipmp_snap_addgroupinfo;
ipmp_snap_addifinfo;
ipmp_snap_create;
ipmp_snap_free;
+ ipmp_targinfo_create;
+ ipmp_undo_offline;
ipmp_write;
ipmp_writetlv;
local:
diff --git a/usr/src/lib/libnsl/nss/netdir_inet_sundry.c b/usr/src/lib/libnsl/nss/netdir_inet_sundry.c
index 742e7408b2..4e9473a8cf 100644
--- a/usr/src/lib/libnsl/nss/netdir_inet_sundry.c
+++ b/usr/src/lib/libnsl/nss/netdir_inet_sundry.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -21,7 +20,7 @@
*/
/*
- * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* lib/libnsl/nss/netdir_inet_sundry.c
@@ -39,8 +38,6 @@
* Copied mostly from erstwhile lib/nametoaddr/tcpip/tcpip.c.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include "mt.h"
#include <stdlib.h>
#include <stdio.h>
@@ -69,9 +66,6 @@
#include <syslog.h>
#include <values.h>
#include <limits.h>
-#ifdef DEBUG
-#include <stdio.h>
-#endif
#include <nss_dbdefs.h>
#include "nss.h"
@@ -151,8 +145,8 @@ __inet_taddr2uaddr(struct netconfig *tp, struct netbuf *addr)
/* LINTED pointer cast */
sa6 = (struct sockaddr_in6 *)(addr->buf);
myport = ntohs(sa6->sin6_port);
- if (inet_ntop(AF_INET6, (void *)sa6->sin6_addr.s6_addr,
- tmp, sizeof (tmp)) == 0) {
+ if (inet_ntop(AF_INET6, sa6->sin6_addr.s6_addr, tmp,
+ sizeof (tmp)) == NULL) {
_nderror = ND_BADARG;
return (NULL);
}
@@ -400,7 +394,7 @@ getifnum:
continue;
if_info[n_ifs].if_address =
- ((struct sockaddr_in *)&lifr->lifr_addr)->sin_addr;
+ ((struct sockaddr_in *)&lifr->lifr_addr)->sin_addr;
if (nss_ioctl(AF_INET, SIOCGLIFFLAGS, lifr) < 0)
continue;
@@ -413,7 +407,7 @@ getifnum:
continue;
if_info[n_ifs].if_netmask =
- ((struct sockaddr_in *)&lifr->lifr_addr)->sin_addr;
+ ((struct sockaddr_in *)&lifr->lifr_addr)->sin_addr;
n_ifs++;
}
free(buf);
@@ -528,21 +522,12 @@ get_best_match(struct in_addr addr)
if_addr = ntohl(ifn->if_address.s_addr); /* host order */
/*
- * Checking if the interface selected is FAILED or DEPRECATED.
- * In case IFF_FAILED or IFF_DEPRECATED flag for the interface
- * is set, we move on to the next interface in the list.
- * Refer IPMP(IP Multi Pathing) for more details.
- */
-
- if ((ifn->if_flags & (IFF_FAILED | IFF_DEPRECATED)) != 0)
- continue;
-
- /*
* set initial count to first bit set in netmask, with
* zero being the number of the least significant bit.
*/
- for (count = 0, mask = netmask; mask && ((mask & 1) == 0);
- count++, mask >>= 1);
+ count = 0;
+ for (mask = netmask; mask && ((mask & 1) == 0); mask >>= 1)
+ count++;
/*
* Set limit so that we don't try to match prefixes shorter
@@ -570,12 +555,6 @@ get_best_match(struct in_addr addr)
* (2) the best partial subnet match
* (3) the first non-loopback && non-PPP interface
* (4) the first non-loopback interface (PPP is OK)
- *
- * While checking for condition (3) and (4), we also look
- * if the interface we are returning is neither FAILED
- * nor DEPRECATED. In case there are no interface
- * available, which are neither FAILED nor DEPRECRATED,
- * we return 0.
*/
found = FALSE;
while (netmask && count < subnet_count) {
@@ -607,8 +586,7 @@ get_best_match(struct in_addr addr)
*/
if (bestmatch == NULL) {
for (ifn = if_info; ifn < (if_info + n_ifs); ifn++) {
- if ((ifn->if_flags & (IFF_LOOPBACK |
- IFF_FAILED | IFF_DEPRECATED)) == 0) {
+ if ((ifn->if_flags & IFF_LOOPBACK) == 0) {
bestmatch = ifn;
/*
@@ -619,10 +597,6 @@ get_best_match(struct in_addr addr)
* list...
*/
if ((ifn->if_flags & IFF_POINTOPOINT) == 0) {
-#ifdef DEBUG
- (void) printf("found !loopback && !non-PPP interface: %s\n",
- inet_ntoa(ifn->if_address));
-#endif
break;
}
}
@@ -701,9 +675,9 @@ select_server_addr(union any_in_addr *dst_addr, int family,
}
/* open a UDP socket */
- if ((tmp_fd = _so_socket(family, SOCK_DGRAM, 0,
- NULL, SOV_SOCKBSD)) < 0) {
- syslog(LOG_ERR, "selsect_server_addr:connect failed\n");
+ tmp_fd = _so_socket(family, SOCK_DGRAM, 0, NULL, SOV_SOCKBSD);
+ if (tmp_fd < 0) {
+ syslog(LOG_ERR, "select_server_addr: connect failed\n");
return (FALSE);
}
@@ -716,15 +690,16 @@ select_server_addr(union any_in_addr *dst_addr, int family,
* message, as it'll try to send the probe packet out and will
* receive ICMP unreachable.
*/
- if (family == AF_INET)
+ if (family == AF_INET) {
src_addr->addr.s_addr = INADDR_ANY;
- else
+ } else {
/*
* Since in6addr_any is not in the scope
* use the following hack
*/
(void) memset(src_addr->addr6.s6_addr,
- 0, sizeof (struct in6_addr));
+ 0, sizeof (struct in6_addr));
+ }
(void) close(tmp_fd);
free(sock);
return (FALSE);
@@ -732,7 +707,7 @@ select_server_addr(union any_in_addr *dst_addr, int family,
/* get the local sock info */
if (_so_getsockname(tmp_fd, sock, &sock_len, SOV_DEFAULT) < 0) {
- syslog(LOG_ERR, "selsect_server_addr:getsockname failed\n");
+ syslog(LOG_ERR, "select_server_addr: getsockname failed\n");
(void) close(tmp_fd);
free(sock);
return (FALSE);
@@ -799,11 +774,6 @@ inet_netdir_mergeaddr(struct netconfig *tp, char *ruaddr, char *uaddr)
clientaddr.s_addr = inet_addr(ruaddr);
-#ifdef DEBUG
- (void) printf("client's address is %s and %s\n",
- ruaddr, inet_ntoa(clientaddr));
-#endif
-
/* We know cp is not NULL due to the check above */
*cp = '.'; /* Put the dot back in the IP addr */
@@ -895,28 +865,22 @@ inet_netdir_mergeaddr(struct netconfig *tp, char *ruaddr, char *uaddr)
FALSE)
return (NULL);
server_addr.sin6_addr = out_addr.addr6;
+ } else {
+ (void) memcpy(&server_addr, &sa, sizeof (server_addr));
}
- else
- (void) memcpy(&server_addr, &sa,
- sizeof (struct sockaddr_in6));
-#ifdef DEBUG
- printf("%s\n", inet_ntop(af, out_addr.addr6.s6_addr,
- tmp, sizeof (tmp)));
-#endif
-
- if (inet_ntop(af, server_addr.sin6_addr.s6_addr,
- tmp, sizeof (tmp)) == NULL) {
+
+ if (inet_ntop(af, server_addr.sin6_addr.s6_addr, tmp,
+ sizeof (tmp)) == NULL) {
_nderror = ND_NOHOST;
return (NULL);
}
/* now extract the port info */
if ((dot = strrchr(uaddr, '.')) != 0) {
+ char *p = --dot;
- char *p;
-
- p = --dot;
- while (*p-- != '.');
+ while (*p-- != '.')
+ ;
p++;
(void) strcat(tmp + strlen(tmp), p);
_nderror = ND_OK;
@@ -1051,7 +1015,7 @@ bindresvport(struct netconfig *nconf, int fd, struct netbuf *addr)
* this, if the caller has set this option before calling
* bindresvport(), it will be unset. Better be safe...
*/
- *optval = 0;
+ *optval = 0;
resp.flags = 0;
resp.opt.buf = (char *)reqbuf;
resp.opt.maxlen = sizeof (reqbuf);
diff --git a/usr/src/lib/libsocket/inet/interface_id.c b/usr/src/lib/libsocket/inet/interface_id.c
index 2a512b025f..88854fe9da 100644
--- a/usr/src/lib/libsocket/inet/interface_id.c
+++ b/usr/src/lib/libsocket/inet/interface_id.c
@@ -2,9 +2,8 @@
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
- * Common Development and Distribution License, Version 1.0 only
- * (the "License"). You may not use this file except in compliance
- * with the License.
+ * Common Development and Distribution License (the "License").
+ * You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or http://www.opensolaris.org/os/licensing.
@@ -20,12 +19,10 @@
* CDDL HEADER END
*/
/*
- * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
+ * Copyright 2009 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
-#pragma ident "%Z%%M% %I% %E% SMI"
-
#include <stdio.h>
#include <ctype.h>
#include <string.h>
@@ -120,6 +117,9 @@ if_indextoname(uint32_t ifindex, char *ifname)
int numifs;
size_t bufsize;
boolean_t found;
+ uint_t flags;
+
+ flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES | LIFC_UNDER_IPMP;
/* A interface index of 0 is invalid */
if (ifindex == 0) {
@@ -137,14 +137,19 @@ if_indextoname(uint32_t ifindex, char *ifname)
/* Prepare to send a SIOCGLIFNUM request message */
lifn.lifn_family = AF_UNSPEC;
- lifn.lifn_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
+ lifn.lifn_flags = flags;
if (ioctl(s, SIOCGLIFNUM, (char *)&lifn) < 0) {
int save_err = errno;
(void) close(s);
errno = save_err;
return (NULL);
}
- numifs = lifn.lifn_count;
+
+ /*
+ * NOTE: "+ 10" sleaze mitigates new IP interfaces showing up between
+ * the SIOCGLIFNUM and the SIOCGLIFCONF.
+ */
+ numifs = lifn.lifn_count + 10;
/*
* Provide enough buffer to obtain the interface
@@ -161,7 +166,7 @@ if_indextoname(uint32_t ifindex, char *ifname)
return (NULL);
}
lifc.lifc_family = AF_UNSPEC;
- lifc.lifc_flags = LIFC_NOXMIT | LIFC_TEMPORARY | LIFC_ALLZONES;
+ lifc.lifc_flags = flags;
lifc.lifc_len = bufsize;
lifc.lifc_buf = buf;
if (ioctl(s, SIOCGLIFCONF, (char *)&lifc) < 0) {
diff --git a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
index dabc2e0929..62ebedf522 100644
--- a/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
+++ b/usr/src/lib/smbsrv/libsmbns/common/smbns_dyndns.c
@@ -1936,7 +1936,7 @@ dyndns_update_core(char *fqdn)
return (-1);
do {
- if (ni.ni_nic.nic_sysflags & (IFF_STANDBY | IFF_PRIVATE))
+ if (ni.ni_nic.nic_sysflags & IFF_PRIVATE)
continue;
addr.s_addr = ni.ni_nic.nic_ip;
@@ -2003,7 +2003,7 @@ dyndns_clear_rev_zone(char *fqdn)
return (-1);
do {
- if (ni.ni_nic.nic_sysflags & (IFF_STANDBY | IFF_PRIVATE))
+ if (ni.ni_nic.nic_sysflags & IFF_PRIVATE)
continue;
addr.s_addr = ni.ni_nic.nic_ip;