diff options
Diffstat (limited to 'usr/src/lib/libdlpi/common')
| -rw-r--r-- | usr/src/lib/libdlpi/common/libdlpi.c | 71 | ||||
| -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, 69 insertions, 12 deletions
| diff --git a/usr/src/lib/libdlpi/common/libdlpi.c b/usr/src/lib/libdlpi/common/libdlpi.c index 1a639a5db9..d07eea70e7 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) 2017, 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,11 +1081,19 @@ 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 ((*fd = open(path, oflags)) != -1) +		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 -			return (errno == ENOENT ? DLPI_ENOLINK : DL_SYSERR); +		} else { +			return (errno == ENOENT || errno == EISDIR ? +			    DLPI_ENOLINK : DL_SYSERR); +		}  	} else if (style1 && !(flags & DLPI_DEVONLY)) {  		char		driver[DLPI_LINKNAME_MAX];  		char		device[DLPI_LINKNAME_MAX]; @@ -1070,7 +1108,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); @@ -1118,7 +1162,7 @@ fallback:  	if ((*fd = open(path, oflags)) != -1)  		return (DLPI_SUCCESS); -	return (errno == ENOENT ? DLPI_ENOLINK : DL_SYSERR); +	return (errno == ENOENT || errno == EISDIR ? DLPI_ENOLINK : DL_SYSERR);  }  /* @@ -1130,7 +1174,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 +1198,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 +1617,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; | 
