diff options
Diffstat (limited to 'usr/src/lib/libdlpi/common')
-rw-r--r-- | usr/src/lib/libdlpi/common/libdlpi.c | 61 | ||||
-rw-r--r-- | usr/src/lib/libdlpi/common/libdlpi.h | 2 | ||||
-rw-r--r-- | usr/src/lib/libdlpi/common/libdlpi_impl.h | 3 | ||||
-rw-r--r-- | usr/src/lib/libdlpi/common/mapfile-vers | 5 |
4 files changed, 63 insertions, 8 deletions
diff --git a/usr/src/lib/libdlpi/common/libdlpi.c b/usr/src/lib/libdlpi/common/libdlpi.c index 1a639a5db9..aa97afee04 100644 --- a/usr/src/lib/libdlpi/common/libdlpi.c +++ b/usr/src/lib/libdlpi/common/libdlpi.c @@ -22,6 +22,9 @@ * Copyright 2009 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * Copyright (c) 2014, Joyent, Inc. + */ /* * Data-Link Provider Interface (Version 2) @@ -51,7 +54,7 @@ #include "libdlpi_impl.h" -static int i_dlpi_open(const char *, int *, uint_t, boolean_t); +static int i_dlpi_open(const char *, const char *, int *, uint_t, boolean_t); static int i_dlpi_style1_open(dlpi_impl_t *); static int i_dlpi_style2_open(dlpi_impl_t *); static int i_dlpi_checkstyle(dlpi_impl_t *, t_uscalar_t); @@ -130,7 +133,8 @@ dlpi_walk(dlpi_walkfunc_t *fn, void *arg, uint_t flags) } int -dlpi_open(const char *linkname, dlpi_handle_t *dhp, uint_t flags) +dlpi_open_zone(const char *linkname, const char *zonename, dlpi_handle_t *dhp, + uint_t flags) { int retval, on = 1; ifspec_t ifsp; @@ -164,6 +168,16 @@ dlpi_open(const char *linkname, dlpi_handle_t *dhp, uint_t flags) if (getenv("DLPI_DEVONLY") != NULL) dip->dli_oflags |= DLPI_DEVONLY; + if (zonename == NULL) { + dip->dli_zonename[0] = '\0'; + } else { + if (strlcpy(dip->dli_zonename, zonename, + sizeof (dip->dli_zonename)) >= sizeof (dip->dli_zonename)) { + free(dip); + return (DLPI_EZONENAMEINVAL); + } + } + /* Copy linkname provided to the function. */ if (strlcpy(dip->dli_linkname, linkname, sizeof (dip->dli_linkname)) >= sizeof (dip->dli_linkname)) { @@ -237,6 +251,12 @@ dlpi_open(const char *linkname, dlpi_handle_t *dhp, uint_t flags) return (DLPI_SUCCESS); } +int +dlpi_open(const char *linkname, dlpi_handle_t *dhp, uint_t flags) +{ + return (dlpi_open_zone(linkname, NULL, dhp, flags)); +} + void dlpi_close(dlpi_handle_t dh) { @@ -1013,6 +1033,15 @@ dlpi_iftype(uint_t dlpitype) * /dev - if DLPI_DEVONLY is specified, or if there is no * data-link with the specified name (could be /dev/ip) * + * If a zone's name has been specified, eg. via dlpi_open_zone, then we instead + * will check in: + * + * /dev/ipnet/zone/%z/ - if DLPI_DEVIPNET is specified + * /dev/net/zone/%z/ - if a data-link with the specified name exists. + * + * When a zone name is specified, all of the fallback procedures that we opt for + * in the normal case are not used. + * * In particular, if DLPI_DEVIPNET is not specified, this function is used to * open a data-link node, or "/dev/ip" node. It is usually be called firstly * with style1 being B_TRUE, and if that fails and the return value is not @@ -1040,7 +1069,8 @@ dlpi_iftype(uint_t dlpitype) * the second style-2 open attempt. */ static int -i_dlpi_open(const char *provider, int *fd, uint_t flags, boolean_t style1) +i_dlpi_open(const char *provider, const char *zonename, int *fd, uint_t flags, + boolean_t style1) { char path[MAXPATHLEN]; int oflags; @@ -1051,7 +1081,13 @@ i_dlpi_open(const char *provider, int *fd, uint_t flags, boolean_t style1) oflags |= O_EXCL; if (flags & DLPI_DEVIPNET) { - (void) snprintf(path, sizeof (path), "/dev/ipnet/%s", provider); + if (*zonename != '\0') { + (void) snprintf(path, sizeof (path), + "/dev/ipnet/zone/%s/%s", zonename, provider); + } else { + (void) snprintf(path, sizeof (path), "/dev/ipnet/%s", + provider); + } if ((*fd = open(path, oflags)) != -1) return (DLPI_SUCCESS); else @@ -1070,7 +1106,13 @@ i_dlpi_open(const char *provider, int *fd, uint_t flags, boolean_t style1) if (dlpi_parselink(provider, driver, &ppa) != DLPI_SUCCESS) goto fallback; - (void) snprintf(path, sizeof (path), "/dev/net/%s", provider); + if (*zonename != '\0') { + (void) snprintf(path, sizeof (path), + "/dev/net/zone/%s/%s", zonename, provider); + } else { + (void) snprintf(path, sizeof (path), "/dev/net/%s", + provider); + } if ((*fd = open(path, oflags)) != -1) return (DLPI_SUCCESS); @@ -1130,7 +1172,8 @@ i_dlpi_style1_open(dlpi_impl_t *dip) int retval, save_errno; int fd; - retval = i_dlpi_open(dip->dli_linkname, &fd, dip->dli_oflags, B_TRUE); + retval = i_dlpi_open(dip->dli_linkname, dip->dli_zonename, &fd, + dip->dli_oflags, B_TRUE); if (retval != DLPI_SUCCESS) return (retval); dip->dli_fd = fd; @@ -1153,7 +1196,8 @@ i_dlpi_style2_open(dlpi_impl_t *dip) int fd; int retval, save_errno; - retval = i_dlpi_open(dip->dli_provider, &fd, dip->dli_oflags, B_FALSE); + retval = i_dlpi_open(dip->dli_provider, dip->dli_zonename, &fd, + dip->dli_oflags, B_FALSE); if (retval != DLPI_SUCCESS) return (retval); dip->dli_fd = fd; @@ -1571,7 +1615,8 @@ static const char *libdlpi_errlist[] = { /* DLPI_ENOTENOTSUP */ "invalid DLPI notification type", /* DLPI_ENOTEINVAL */ "invalid DLPI notification id", /* DLPI_ENOTEIDINVAL */ - "DLPI_IPNETINFO not supported" /* DLPI_EIPNETINFONOTSUP */ + "DLPI_IPNETINFO not supported", /* DLPI_EIPNETINFONOTSUP */ + "invalid zone name" /* DLPI_EZONENAMEINVAL */ }; const char * diff --git a/usr/src/lib/libdlpi/common/libdlpi.h b/usr/src/lib/libdlpi/common/libdlpi.h index 993ac1b7a4..364413ee3a 100644 --- a/usr/src/lib/libdlpi/common/libdlpi.h +++ b/usr/src/lib/libdlpi/common/libdlpi.h @@ -93,6 +93,7 @@ enum { DLPI_ENOTENOTSUP, /* DLPI notification not supported by link */ DLPI_ENOTEIDINVAL, /* invalid DLPI notification id */ DLPI_EIPNETINFONOTSUP, /* DLPI_IPNETINFO not supported */ + DLPI_EZONENAMEINVAL, /* invalid zone name */ DLPI_ERRMAX /* Highest + 1 libdlpi error code */ }; @@ -184,6 +185,7 @@ typedef boolean_t dlpi_walkfunc_t(const char *, void *); extern void dlpi_walk(dlpi_walkfunc_t *, void *, uint_t); extern int dlpi_open(const char *, dlpi_handle_t *, uint_t); +extern int dlpi_open_zone(const char *, const char *, dlpi_handle_t *, uint_t); extern void dlpi_close(dlpi_handle_t); extern int dlpi_info(dlpi_handle_t, dlpi_info_t *, uint_t); extern int dlpi_bind(dlpi_handle_t, uint_t, uint_t *); diff --git a/usr/src/lib/libdlpi/common/libdlpi_impl.h b/usr/src/lib/libdlpi/common/libdlpi_impl.h index 70708ff5af..8969cce7cb 100644 --- a/usr/src/lib/libdlpi/common/libdlpi_impl.h +++ b/usr/src/lib/libdlpi/common/libdlpi_impl.h @@ -28,6 +28,7 @@ #include <libdlpi.h> #include <sys/sysmacros.h> +#include <sys/zone.h> #ifdef __cplusplus extern "C" { @@ -112,6 +113,8 @@ typedef struct dlpi_impl_s { /* full linkname including PPA */ char dli_provider[DLPI_LINKNAME_MAX]; /* only provider name */ + char dli_zonename[ZONENAME_MAX]; + /* optionally specified zone */ t_uscalar_t dli_style; /* style 1 or 2 */ uint_t dli_saplen; /* bound SAP length */ uint_t dli_sap; /* bound SAP value */ diff --git a/usr/src/lib/libdlpi/common/mapfile-vers b/usr/src/lib/libdlpi/common/mapfile-vers index ed3231dc92..c818e5e660 100644 --- a/usr/src/lib/libdlpi/common/mapfile-vers +++ b/usr/src/lib/libdlpi/common/mapfile-vers @@ -67,6 +67,11 @@ SYMBOL_VERSION SUNW_1.1 { # first release of libdlpi, Solaris 11 SYMBOL_VERSION SUNWprivate { global: + # + # dlpi_open_zone should be moved to a new public section once it is + # upstreamed into illumos-gate . + # + dlpi_open_zone; dlpi_parselink; dlpi_makelink; dlpi_style; |