All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH 00/12] Next series of mountd IPv6 support patches
@ 2010-09-13 17:20 Chuck Lever
  2010-09-13 17:20 ` [PATCH 01/12] libnfs.a: Fix API for getfh() & friends Chuck Lever
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:20 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

This series enables support for IPv6 addresses when receiving mountd
requests and processing export records.

The final series (later this week, or next) will enable mountd to
listen on IPv6 transports.

---

Chuck Lever (12):
      libexport.a: Enable IPv6 support in hostname.c
      mountd: Ensure cache downcall can handle IPv6 addresses
      mountd: Handle IPv6 addresses in kernel auth_unix_ip upcalls
      mountd: clean up cache API
      exportfs: Enable IPv6 support in matchhostname()
      mountd: Support IPv6 in mountlist_list()
      mountd: Handle memory exhaustion in mountlist_list()
      mountd: Add mountlist_freeall()
      mountd: support IPv6 in mountlist_del_all()
      mountd: Support IPv6 in mountd's svc routines
      mountd: add IPv6 support in auth_authenticate()
      libnfs.a: Fix API for getfh() & friends


 support/export/hostname.c |   31 +++++++--------
 support/include/nfslib.h  |    9 +++-
 support/nfs/getfh.c       |   64 ++++++++++++++++++++++++++++---
 utils/exportfs/exportfs.c |   23 +----------
 utils/mountd/auth.c       |   52 +++++++++++++------------
 utils/mountd/cache.c      |   57 +++++++++++++++++++++-------
 utils/mountd/mountd.c     |   92 +++++++++++++++++++++++++++++++--------------
 utils/mountd/mountd.h     |   11 ++++-
 utils/mountd/rmtab.c      |   72 +++++++++++++++++++++++------------
 9 files changed, 270 insertions(+), 141 deletions(-)

-- 
Chuck Lever

^ permalink raw reply	[flat|nested] 14+ messages in thread

* [PATCH 01/12] libnfs.a: Fix API for getfh() & friends
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
@ 2010-09-13 17:20 ` Chuck Lever
  2010-09-13 17:21 ` [PATCH 02/12] mountd: add IPv6 support in auth_authenticate() Chuck Lever
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:20 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

This is more of a clean-up than a behavioral change.

POSIX requires that a "struct sockaddr" is the same size as a "struct
sockaddr_in".  Therefore, a variable or field of type "struct sockaddr"
cannot contain an AF_INET6 address.  However, "struct sockaddr *" is
often used to reference a generic (ie non-address family specific)
socket address, generating some confusion about this.

The nfsctl_arg struct uses a struct sockaddr (not a pointer) to pass
the client's IP address to the kernel.  This means the legacy nfsctl()
kernel API can never support IPv6.  Fortunately for us, this legacy
interface was replaced by a text-based cache interface a few years
back.  We don't need to support non-AF_INET addresses here.

The getfh() functions in nfs-utils provide a handy C API for the
kernel's nfsctl interface.  The getfh() functions still take a struct
sockaddr *, though, and that can imply that a non-IPv4 address can be
passed via this API.  To make it abundantly clear that only IPv4
addresses can be used with this interface, change the synopses of
getfh() and friends to take a struct sockaddr_in * instead of a struct
sockaddr * .

This makes these functions conform with other places in mountd and
exportfs that already grok the difference between a struct sockaddr
and a struct sockaddr_in.

While we're here...

Introduce some nice documenting comments for the get_fh() functions,
and...

Since mountd will support IPv6 in the near future, assert that the
family of client addresses passed to this API is indeed AF_INET, in
order to prevent non-AF_INET addresses from ever being passed to the
legacy nfsctl() interface.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 support/include/nfslib.h |    9 ++++--
 support/nfs/getfh.c      |   64 ++++++++++++++++++++++++++++++++++++++++++----
 utils/mountd/mountd.c    |    7 ++---
 3 files changed, 67 insertions(+), 13 deletions(-)

diff --git a/support/include/nfslib.h b/support/include/nfslib.h
index af242d3..3db5bec 100644
--- a/support/include/nfslib.h
+++ b/support/include/nfslib.h
@@ -134,9 +134,12 @@ int			nfsaddclient(struct nfsctl_client *clp);
 int			nfsdelclient(struct nfsctl_client *clp);
 int			nfsexport(struct nfsctl_export *exp);
 int			nfsunexport(struct nfsctl_export *exp);
-struct nfs_fh_len *	getfh_old(struct sockaddr *addr, dev_t dev, ino_t ino);
-struct nfs_fh_len *	getfh(struct sockaddr *addr, const char *);
-struct nfs_fh_len *	getfh_size(struct sockaddr *addr, const char *, int size);
+
+struct nfs_fh_len *	getfh_old(const struct sockaddr_in *sin,
+					const dev_t dev, const ino_t ino);
+struct nfs_fh_len *	getfh(const struct sockaddr_in *sin, const char *path);
+struct nfs_fh_len *	getfh_size(const struct sockaddr_in *sin,
+					const char *path, int const size);
 
 void qword_print(FILE *f, char *str);
 void qword_printhex(FILE *f, char *str, int slen);
diff --git a/support/nfs/getfh.c b/support/nfs/getfh.c
index 81266fd..611459b 100644
--- a/support/nfs/getfh.c
+++ b/support/nfs/getfh.c
@@ -19,60 +19,112 @@
 #include <errno.h>
 #include "nfslib.h"
 
+/**
+ * getfh_old - ask the kernel for an NFSv2 file handle via nfsctl()
+ * @sin: pointer to IPv4 address of a client
+ * @dev: device number of device where requested object resides
+ * @ino: inode number of requested object
+ *
+ * Returns a pointer to an NFSv2 file handle, or NULL if some error
+ * occurred.  errno is set to reflect the specifics of the error.
+ */
 struct nfs_fh_len *
-getfh_old (struct sockaddr *addr, dev_t dev, ino_t ino)
+getfh_old(const struct sockaddr_in *sin, const dev_t dev, const ino_t ino)
 {
 	union nfsctl_res	res;
 	struct nfsctl_arg	arg;
 	static struct nfs_fh_len rfh;
 
+	if (sin->sin_family != AF_INET) {
+		errno = EAFNOSUPPORT;
+		return NULL;
+	}
+
+	memset(&arg, 0, sizeof(arg));
+	memset(&res, 0, sizeof(res));
+
 	arg.ca_version = NFSCTL_VERSION;
 	arg.ca_getfh.gf_version = 2;	/* obsolete */
 	arg.ca_getfh.gf_dev = dev;
 	arg.ca_getfh.gf_ino = ino;
-	memcpy(&arg.ca_getfh.gf_addr, addr, sizeof(struct sockaddr_in));
+	memcpy(&arg.ca_getfh.gf_addr, sin, sizeof(*sin));
 
 	if (nfsctl(NFSCTL_GETFH, &arg, &res) < 0)
 		return NULL;
 
+	memset(&rfh, 0, sizeof(rfh));
 	rfh.fh_size = 32;
 	memcpy(rfh.fh_handle, &res.cr_getfh, 32);
 	return &rfh;
 }
 
+/**
+ * getfh - ask the kernel for an NFSv2 file handle via nfsctl()
+ * @sin: pointer to IPv4 address of a client
+ * @path: pointer to a '\0'-terminated ASCII string containing an pathname
+ *
+ * Returns a pointer to an NFSv2 file handle, or NULL if some error
+ * occurred.  errno is set to reflect the specifics of the error.
+ */
 struct nfs_fh_len *
-getfh(struct sockaddr *addr, const char *path)
+getfh(const struct sockaddr_in *sin, const char *path)
 {
 	static union nfsctl_res res;
         struct nfsctl_arg       arg;
 	static struct nfs_fh_len rfh;
 
+	if (sin->sin_family != AF_INET) {
+		errno = EAFNOSUPPORT;
+		return NULL;
+	}
+
+	memset(&arg, 0, sizeof(arg));
+	memset(&res, 0, sizeof(res));
+
         arg.ca_version = NFSCTL_VERSION;
         arg.ca_getfd.gd_version = 2;    /* obsolete */
         strncpy(arg.ca_getfd.gd_path, path,
 		sizeof(arg.ca_getfd.gd_path) - 1);
 	arg.ca_getfd.gd_path[sizeof (arg.ca_getfd.gd_path) - 1] = '\0';
-        memcpy(&arg.ca_getfd.gd_addr, addr, sizeof(struct sockaddr_in));
+	memcpy(&arg.ca_getfd.gd_addr, sin, sizeof(*sin));
 
         if (nfsctl(NFSCTL_GETFD, &arg, &res) < 0)
                 return NULL;
 
+	memset(&rfh, 0, sizeof(rfh));
 	rfh.fh_size = 32;
 	memcpy(rfh.fh_handle, &res.cr_getfh, 32);
 	return &rfh;
 }
 
+/**
+ * getfh_size - ask the kernel for a file handle via nfsctl()
+ * @sin: pointer to IPv4 address of a client
+ * @path: pointer to a '\0'-terminated ASCII string containing an pathname
+ * @size: maximum size, in bytes, of the returned file handle
+ *
+ * Returns a pointer to an NFSv3 file handle, or NULL if some error
+ * occurred.  errno is set to reflect the specifics of the error.
+ */
 struct nfs_fh_len *
-getfh_size(struct sockaddr *addr, const char *path, int size)
+getfh_size(const struct sockaddr_in *sin, const char *path, const int size)
 {
         static union nfsctl_res res;
         struct nfsctl_arg       arg;
 
+	if (sin->sin_family != AF_INET) {
+		errno = EAFNOSUPPORT;
+		return NULL;
+	}
+
+	memset(&arg, 0, sizeof(arg));
+	memset(&res, 0, sizeof(res));
+
         arg.ca_version = NFSCTL_VERSION;
         strncpy(arg.ca_getfs.gd_path, path,
 		sizeof(arg.ca_getfs.gd_path) - 1);
 	arg.ca_getfs.gd_path[sizeof (arg.ca_getfs.gd_path) - 1] = '\0';
-        memcpy(&arg.ca_getfs.gd_addr, addr, sizeof(struct sockaddr_in));
+	memcpy(&arg.ca_getfs.gd_addr, sin, sizeof(*sin));
 	arg.ca_getfs.gd_maxlen = size;
 
         if (nfsctl(NFSCTL_GETFS, &arg, &res) < 0)
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index dc84404..78f26c2 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -484,14 +484,13 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
 			xtab_append(exp);
 
 		if (v3)
-			fh = getfh_size ((struct sockaddr *) sin, p, 64);
+			fh = getfh_size(sin, p, 64);
 		if (!v3 || (fh == NULL && errno == EINVAL)) {
 			/* We first try the new nfs syscall. */
-			fh = getfh ((struct sockaddr *) sin, p);
+			fh = getfh(sin, p);
 			if (fh == NULL && errno == EINVAL)
 				/* Let's try the old one. */
-				fh = getfh_old ((struct sockaddr *) sin,
-						stb.st_dev, stb.st_ino);
+				fh = getfh_old(sin, stb.st_dev, stb.st_ino);
 		}
 		if (fh == NULL && !did_export) {
 			exp->m_exported = 0;


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 02/12] mountd: add IPv6 support in auth_authenticate()
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
  2010-09-13 17:20 ` [PATCH 01/12] libnfs.a: Fix API for getfh() & friends Chuck Lever
@ 2010-09-13 17:21 ` Chuck Lever
  2010-09-13 17:21 ` [PATCH 03/12] mountd: Support IPv6 in mountd's svc routines Chuck Lever
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:21 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Make the entire auth_authenticate() code path address-family agnostic.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mountd/auth.c   |   52 +++++++++++++++++++++++++------------------------
 utils/mountd/mountd.c |   14 +++++++------
 utils/mountd/mountd.h |    5 +++--
 utils/mountd/rmtab.c  |    3 ++-
 4 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/utils/mountd/auth.c b/utils/mountd/auth.c
index 04487e5..ccc849a 100644
--- a/utils/mountd/auth.c
+++ b/utils/mountd/auth.c
@@ -15,6 +15,8 @@
 #include <arpa/inet.h>
 #include <errno.h>
 #include <unistd.h>
+
+#include "sockaddr.h"
 #include "misc.h"
 #include "nfslib.h"
 #include "exportfs.h"
@@ -111,13 +113,14 @@ auth_reload()
 }
 
 static char *
-get_client_hostname(struct sockaddr_in *caller, struct addrinfo *ai,
+get_client_hostname(const struct sockaddr *caller, struct addrinfo *ai,
 		enum auth_error *error)
 {
+	char buf[INET6_ADDRSTRLEN];
 	char *n;
 
 	if (use_ipaddr)
-		return strdup(inet_ntoa(caller->sin_addr));
+		return strdup(host_ntop(caller, buf, sizeof(buf)));
 	n = client_compose(ai);
 	*error = unknown_host;
 	if (!n)
@@ -130,8 +133,8 @@ get_client_hostname(struct sockaddr_in *caller, struct addrinfo *ai,
 
 /* return static nfs_export with details filled in */
 static nfs_export *
-auth_authenticate_newcache(struct sockaddr_in *caller,
-			   char *path, struct addrinfo *ai,
+auth_authenticate_newcache(const struct sockaddr *caller,
+			   const char *path, struct addrinfo *ai,
 			   enum auth_error *error)
 {
 	nfs_export *exp;
@@ -144,7 +147,7 @@ auth_authenticate_newcache(struct sockaddr_in *caller,
 		return NULL;
 
 	my_client.m_naddr = 1;
-	set_addrlist_in(&my_client, 0, caller);
+	set_addrlist(&my_client, 0, caller);
 	my_exp.m_client = &my_client;
 
 	exp = NULL;
@@ -168,9 +171,8 @@ auth_authenticate_newcache(struct sockaddr_in *caller,
 }
 
 static nfs_export *
-auth_authenticate_internal(struct sockaddr_in *caller,
-			   char *path, struct addrinfo *ai,
-			   enum auth_error *error)
+auth_authenticate_internal(const struct sockaddr *caller, const char *path,
+		struct addrinfo *ai, enum auth_error *error)
 {
 	nfs_export *exp;
 
@@ -190,7 +192,7 @@ auth_authenticate_internal(struct sockaddr_in *caller,
 		return NULL;
 	}
 	if (!(exp->m_export.e_flags & NFSEXP_INSECURE_PORT) &&
-		     ntohs(caller->sin_port) >= IPPORT_RESERVED) {
+		     nfs_get_port(caller) >= IPPORT_RESERVED) {
 		*error = illegal_port;
 		return NULL;
 	}
@@ -200,18 +202,19 @@ auth_authenticate_internal(struct sockaddr_in *caller,
 }
 
 nfs_export *
-auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
+auth_authenticate(const char *what, const struct sockaddr *caller,
+		const char *path)
 {
 	nfs_export	*exp = NULL;
 	char		epath[MAXPATHLEN+1];
 	char		*p = NULL;
+	char		buf[INET6_ADDRSTRLEN];
 	struct addrinfo *ai = NULL;
-	struct in_addr	addr = caller->sin_addr;
 	enum auth_error	error = bad_path;
 
-	if (path [0] != '/') {
-		xlog(L_WARNING, "bad path in %s request from %s: \"%s\"",
-		     what, inet_ntoa(addr), path);
+	if (path[0] != '/') {
+		xlog(L_WARNING, "Bad path in %s request from %s: \"%s\"",
+			     what, host_ntop(caller, buf, sizeof(buf)), path);
 		return exp;
 	}
 
@@ -219,14 +222,13 @@ auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
 	epath[sizeof (epath) - 1] = '\0';
 	auth_fixpath(epath); /* strip duplicate '/' etc */
 
-	ai = client_resolve((struct sockaddr *)caller);
+	ai = client_resolve(caller);
 	if (ai == NULL)
 		return exp;
 
 	/* Try the longest matching exported pathname. */
 	while (1) {
-		exp = auth_authenticate_internal(caller, epath,
-						 ai, &error);
+		exp = auth_authenticate_internal(caller, epath, ai, &error);
 		if (exp || (error != not_exported && error != no_entry))
 			break;
 		/* We have to treat the root, "/", specially. */
@@ -239,12 +241,12 @@ auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
 	switch (error) {
 	case bad_path:
 		xlog(L_WARNING, "bad path in %s request from %s: \"%s\"",
-		     what, inet_ntoa(addr), path);
+		     what, host_ntop(caller, buf, sizeof(buf)), path);
 		break;
 
 	case unknown_host:
 		xlog(L_WARNING, "refused %s request from %s for %s (%s): unmatched host",
-		     what, inet_ntoa(addr), path, epath);
+		     what, host_ntop(caller, buf, sizeof(buf)), path, epath);
 		break;
 
 	case no_entry:
@@ -258,17 +260,17 @@ auth_authenticate(char *what, struct sockaddr_in *caller, char *path)
 		break;
 
 	case illegal_port:
-		xlog(L_WARNING, "refused %s request from %s for %s (%s): illegal port %d",
-		     what, ai->ai_canonname, path, epath, ntohs(caller->sin_port));
+		xlog(L_WARNING, "refused %s request from %s for %s (%s): illegal port %u",
+		     what, ai->ai_canonname, path, epath, nfs_get_port(caller));
 		break;
 
 	case success:
-		xlog(L_NOTICE, "authenticated %s request from %s:%d for %s (%s)",
-		     what, ai->ai_canonname, ntohs(caller->sin_port), path, epath);
+		xlog(L_NOTICE, "authenticated %s request from %s:%u for %s (%s)",
+		     what, ai->ai_canonname, nfs_get_port(caller), path, epath);
 		break;
 	default:
-		xlog(L_NOTICE, "%s request from %s:%d for %s (%s) gave %d",
-		     what, ai->ai_canonname, ntohs(caller->sin_port),
+		xlog(L_NOTICE, "%s request from %s:%u for %s (%s) gave %d",
+		     what, ai->ai_canonname, nfs_get_port(caller),
 			path, epath, error);
 	}
 
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index 78f26c2..c8ea3f7 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -237,9 +237,9 @@ mount_umnt_1_svc(struct svc_req *rqstp, dirpath *argp, void *UNUSED(resp))
 		p = rpath;
 	}
 
-	if (!(exp = auth_authenticate("unmount", sin, p))) {
+	exp = auth_authenticate("unmount", (struct sockaddr *)sin, p);
+	if (exp == NULL)
 		return 1;
-	}
 
 	mountlist_del(inet_ntoa(sin->sin_addr), p);
 	return 1;
@@ -313,10 +313,10 @@ mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res)
 	}
 
 	/* Now authenticate the intruder... */
-	exp = auth_authenticate("pathconf", sin, p);
-	if (!exp) {
+	exp = auth_authenticate("pathconf", (struct sockaddr *)sin, p);
+	if (exp == NULL)
 		return 1;
-	} else if (stat(p, &stb) < 0) {
+	else if (stat(p, &stb) < 0) {
 		xlog(L_WARNING, "can't stat exported dir %s: %s",
 				p, strerror(errno));
 		return 1;
@@ -415,8 +415,8 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
 	}
 
 	/* Now authenticate the intruder... */
-	exp = auth_authenticate("mount", sin, p);
-	if (!exp) {
+	exp = auth_authenticate("mount", (struct sockaddr *)sin, p);
+	if (exp == NULL) {
 		*error = NFSERR_ACCES;
 		return NULL;
 	}
diff --git a/utils/mountd/mountd.h b/utils/mountd/mountd.h
index 31bacb5..96e9bf1 100644
--- a/utils/mountd/mountd.h
+++ b/utils/mountd/mountd.h
@@ -41,8 +41,9 @@ bool_t		mount_mnt_3_svc(struct svc_req *, dirpath *, mountres3 *);
 void		mount_dispatch(struct svc_req *, SVCXPRT *);
 void		auth_init(char *export_file);
 unsigned int	auth_reload(void);
-nfs_export *	auth_authenticate(char *what, struct sockaddr_in *sin,
-					char *path);
+nfs_export *	auth_authenticate(const char *what,
+					const struct sockaddr *caller,
+					const char *path);
 void		auth_export(nfs_export *exp);
 
 void		mountlist_add(char *host, const char *path);
diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c
index ba0fcf6..d23712b 100644
--- a/utils/mountd/rmtab.c
+++ b/utils/mountd/rmtab.c
@@ -157,7 +157,8 @@ mountlist_del_all(struct sockaddr_in *sin)
 
 	while ((rep = getrmtabent(1, NULL)) != NULL) {
 		if (strcmp(rep->r_client, hostname) == 0 &&
-		    (exp = auth_authenticate("umountall", sin, rep->r_path)))
+		    (exp = auth_authenticate("umountall",
+				(struct sockaddr *)sin, rep->r_path)))
 			continue;
 		fputrmtabent(fp, rep, NULL);
 	}


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 03/12] mountd: Support IPv6 in mountd's svc routines
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
  2010-09-13 17:20 ` [PATCH 01/12] libnfs.a: Fix API for getfh() & friends Chuck Lever
  2010-09-13 17:21 ` [PATCH 02/12] mountd: add IPv6 support in auth_authenticate() Chuck Lever
@ 2010-09-13 17:21 ` Chuck Lever
  2010-09-13 17:21 ` [PATCH 04/12] mountd: support IPv6 in mountlist_del_all() Chuck Lever
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:21 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Replace IPv4-specific code with use of our generic hostname helpers
in the routines that handle incoming MNT RPC requests.

These functions will support IPv6 without additional changes, once
IPv6 is enabled in the generic hostname helpers.

As part of this update, I've modified all of mountd's _svc routines
to use a debug message format that is consistent with statd.  It may
be overkill for some of these; if so we can pull them out later.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mountd/mountd.c |   79 +++++++++++++++++++++++++++++++++++++------------
 1 files changed, 59 insertions(+), 20 deletions(-)

diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index c8ea3f7..19dc4ee 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -192,18 +192,28 @@ sig_hup (int sig)
 }
 
 bool_t
-mount_null_1_svc(struct svc_req *UNUSED(rqstp), void *UNUSED(argp), 
+mount_null_1_svc(struct svc_req *rqstp, void *UNUSED(argp), 
 	void *UNUSED(resp))
 {
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
+	char buf[INET6_ADDRSTRLEN];
+
+	xlog(D_CALL, "Received NULL request from %s",
+		host_ntop(sap, buf, sizeof(buf)));
+
 	return 1;
 }
 
 bool_t
 mount_mnt_1_svc(struct svc_req *rqstp, dirpath *path, fhstatus *res)
 {
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
+	char buf[INET6_ADDRSTRLEN];
 	struct nfs_fh_len *fh;
 
-	xlog(D_CALL, "MNT1(%s) called", *path);
+	xlog(D_CALL, "Received MNT1(%s) request from %s", *path,
+		host_ntop(sap, buf, sizeof(buf)));
+
 	fh = get_rootfh(rqstp, path, NULL, &res->fhs_status, 0);
 	if (fh)
 		memcpy(&res->fhstatus_u.fhs_fhandle, fh->fh_handle, 32);
@@ -213,9 +223,12 @@ mount_mnt_1_svc(struct svc_req *rqstp, dirpath *path, fhstatus *res)
 bool_t
 mount_dump_1_svc(struct svc_req *rqstp, void *UNUSED(argp), mountlist *res)
 {
-	struct sockaddr_in *addr = nfs_getrpccaller_in(rqstp->rq_xprt);
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
+	char buf[INET6_ADDRSTRLEN];
+
+	xlog(D_CALL, "Received DUMP request from %s",
+		host_ntop(sap, buf, sizeof(buf)));
 
-	xlog(D_CALL, "dump request from %s.", inet_ntoa(addr->sin_addr));
 	*res = mountlist_list();
 
 	return 1;
@@ -224,10 +237,11 @@ mount_dump_1_svc(struct svc_req *rqstp, void *UNUSED(argp), mountlist *res)
 bool_t
 mount_umnt_1_svc(struct svc_req *rqstp, dirpath *argp, void *UNUSED(resp))
 {
-	struct sockaddr_in *sin = nfs_getrpccaller_in(rqstp->rq_xprt);
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
 	nfs_export	*exp;
 	char		*p = *argp;
 	char		rpath[MAXPATHLEN+1];
+	char		buf[INET6_ADDRSTRLEN];
 
 	if (*p == '\0')
 		p = "/";
@@ -237,11 +251,14 @@ mount_umnt_1_svc(struct svc_req *rqstp, dirpath *argp, void *UNUSED(resp))
 		p = rpath;
 	}
 
-	exp = auth_authenticate("unmount", (struct sockaddr *)sin, p);
+	xlog(D_CALL, "Received UMNT(%s) request from %s", p,
+		host_ntop(sap, buf, sizeof(buf)));
+
+	exp = auth_authenticate("unmount", sap, p);
 	if (exp == NULL)
 		return 1;
 
-	mountlist_del(inet_ntoa(sin->sin_addr), p);
+	mountlist_del(host_ntop(sap, buf, sizeof(buf)), p);
 	return 1;
 }
 
@@ -249,6 +266,12 @@ bool_t
 mount_umntall_1_svc(struct svc_req *rqstp, void *UNUSED(argp), 
 	void *UNUSED(resp))
 {
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
+	char		buf[INET6_ADDRSTRLEN];
+
+	xlog(D_CALL, "Received UMNTALL request from %s",
+		host_ntop(sap, buf, sizeof(buf)));
+
 	/* Reload /etc/xtab if necessary */
 	auth_reload();
 
@@ -259,9 +282,12 @@ mount_umntall_1_svc(struct svc_req *rqstp, void *UNUSED(argp),
 bool_t
 mount_export_1_svc(struct svc_req *rqstp, void *UNUSED(argp), exports *resp)
 {
-	struct sockaddr_in *addr = nfs_getrpccaller_in(rqstp->rq_xprt);
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
+	char buf[INET6_ADDRSTRLEN];
+
+	xlog(D_CALL, "Received EXPORT request from %s.",
+		host_ntop(sap, buf, sizeof(buf)));
 
-	xlog(D_CALL, "export request from %s.", inet_ntoa(addr->sin_addr));
 	*resp = get_exportlist();
 		
 	return 1;
@@ -270,9 +296,12 @@ mount_export_1_svc(struct svc_req *rqstp, void *UNUSED(argp), exports *resp)
 bool_t
 mount_exportall_1_svc(struct svc_req *rqstp, void *UNUSED(argp), exports *resp)
 {
-	struct sockaddr_in *addr = nfs_getrpccaller_in(rqstp->rq_xprt);
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
+	char buf[INET6_ADDRSTRLEN];
+
+	xlog(D_CALL, "Received EXPORTALL request from %s.",
+		host_ntop(sap, buf, sizeof(buf)));
 
-	xlog(D_CALL, "exportall request from %s.", inet_ntoa(addr->sin_addr));
 	*resp = get_exportlist();
 
 	return 1;
@@ -292,11 +321,12 @@ mount_exportall_1_svc(struct svc_req *rqstp, void *UNUSED(argp), exports *resp)
 bool_t
 mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res)
 {
-	struct sockaddr_in *sin = nfs_getrpccaller_in(rqstp->rq_xprt);
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
 	struct stat	stb;
 	nfs_export	*exp;
 	char		rpath[MAXPATHLEN+1];
 	char		*p = *path;
+	char buf[INET6_ADDRSTRLEN];
 
 	memset(res, 0, sizeof(*res));
 
@@ -312,8 +342,11 @@ mount_pathconf_2_svc(struct svc_req *rqstp, dirpath *path, ppathcnf *res)
 		p = rpath;
 	}
 
+	xlog(D_CALL, "Received PATHCONF(%s) request from %s", p,
+		host_ntop(sap, buf, sizeof(buf)));
+
 	/* Now authenticate the intruder... */
-	exp = auth_authenticate("pathconf", (struct sockaddr *)sin, p);
+	exp = auth_authenticate("pathconf", sap, p);
 	if (exp == NULL)
 		return 1;
 	else if (stat(p, &stb) < 0) {
@@ -376,11 +409,15 @@ static void set_authflavors(struct mountres3_ok *ok, nfs_export *exp)
 bool_t
 mount_mnt_3_svc(struct svc_req *rqstp, dirpath *path, mountres3 *res)
 {
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
 	struct mountres3_ok *ok = &res->mountres3_u.mountinfo;
+	char buf[INET6_ADDRSTRLEN];
 	nfs_export *exp;
 	struct nfs_fh_len *fh;
 
-	xlog(D_CALL, "MNT3(%s) called", *path);
+	xlog(D_CALL, "Received MNT3(%s) request from %s", *path,
+		host_ntop(sap, buf, sizeof(buf)));
+
 	fh = get_rootfh(rqstp, path, &exp, &res->fhs_status, 1);
 	if (!fh)
 		return 1;
@@ -395,12 +432,13 @@ static struct nfs_fh_len *
 get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
 		mountstat3 *error, int v3)
 {
-	struct sockaddr_in *sin = nfs_getrpccaller_in(rqstp->rq_xprt);
+	struct sockaddr *sap = nfs_getrpccaller(rqstp->rq_xprt);
 	struct stat	stb, estb;
 	nfs_export	*exp;
 	struct nfs_fh_len *fh;
 	char		rpath[MAXPATHLEN+1];
 	char		*p = *path;
+	char		buf[INET6_ADDRSTRLEN];
 
 	if (*p == '\0')
 		p = "/";
@@ -415,7 +453,7 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
 	}
 
 	/* Now authenticate the intruder... */
-	exp = auth_authenticate("mount", (struct sockaddr *)sin, p);
+	exp = auth_authenticate("mount", sap, p);
 	if (exp == NULL) {
 		*error = NFSERR_ACCES;
 		return NULL;
@@ -484,13 +522,14 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
 			xtab_append(exp);
 
 		if (v3)
-			fh = getfh_size(sin, p, 64);
+			fh = getfh_size((struct sockaddr_in *)sap, p, 64);
 		if (!v3 || (fh == NULL && errno == EINVAL)) {
 			/* We first try the new nfs syscall. */
-			fh = getfh(sin, p);
+			fh = getfh((struct sockaddr_in *)sap, p);
 			if (fh == NULL && errno == EINVAL)
 				/* Let's try the old one. */
-				fh = getfh_old(sin, stb.st_dev, stb.st_ino);
+				fh = getfh_old((struct sockaddr_in *)sap,
+						stb.st_dev, stb.st_ino);
 		}
 		if (fh == NULL && !did_export) {
 			exp->m_exported = 0;
@@ -504,7 +543,7 @@ get_rootfh(struct svc_req *rqstp, dirpath *path, nfs_export **expret,
 		}
 	}
 	*error = NFS_OK;
-	mountlist_add(inet_ntoa(sin->sin_addr), p);
+	mountlist_add(host_ntop(sap, buf, sizeof(buf)), p);
 	if (expret)
 		*expret = exp;
 	return fh;


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 04/12] mountd: support IPv6 in mountlist_del_all()
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
                   ` (2 preceding siblings ...)
  2010-09-13 17:21 ` [PATCH 03/12] mountd: Support IPv6 in mountd's svc routines Chuck Lever
@ 2010-09-13 17:21 ` Chuck Lever
  2010-09-13 17:21 ` [PATCH 05/12] mountd: Add mountlist_freeall() Chuck Lever
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:21 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Replace IPv4-specific code in the mountlist_del_all() path with code
that is address family agnostic.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mountd/mountd.c |    2 +-
 utils/mountd/mountd.h |    2 +-
 utils/mountd/rmtab.c  |   12 +++++-------
 3 files changed, 7 insertions(+), 9 deletions(-)

diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index 19dc4ee..98b396d 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -275,7 +275,7 @@ mount_umntall_1_svc(struct svc_req *rqstp, void *UNUSED(argp),
 	/* Reload /etc/xtab if necessary */
 	auth_reload();
 
-	mountlist_del_all(nfs_getrpccaller_in(rqstp->rq_xprt));
+	mountlist_del_all(nfs_getrpccaller(rqstp->rq_xprt));
 	return 1;
 }
 
diff --git a/utils/mountd/mountd.h b/utils/mountd/mountd.h
index 96e9bf1..0d31ca7 100644
--- a/utils/mountd/mountd.h
+++ b/utils/mountd/mountd.h
@@ -48,7 +48,7 @@ void		auth_export(nfs_export *exp);
 
 void		mountlist_add(char *host, const char *path);
 void		mountlist_del(char *host, const char *path);
-void		mountlist_del_all(struct sockaddr_in *sin);
+void		mountlist_del_all(const struct sockaddr *sap);
 mountlist	mountlist_list(void);
 
 
diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c
index d23712b..b2c04e7 100644
--- a/utils/mountd/rmtab.c
+++ b/utils/mountd/rmtab.c
@@ -131,21 +131,20 @@ mountlist_del(char *hname, const char *path)
 }
 
 void
-mountlist_del_all(struct sockaddr_in *sin)
+mountlist_del_all(const struct sockaddr *sap)
 {
 	char		*hostname;
 	struct rmtabent	*rep;
-	nfs_export	*exp;
 	FILE		*fp;
 	int		lockid;
 
 	if ((lockid = xflock(_PATH_RMTABLCK, "w")) < 0)
 		return;
-	hostname = host_canonname((struct sockaddr *)sin);
+	hostname = host_canonname(sap);
 	if (hostname == NULL) {
-		char buf[INET_ADDRSTRLEN];
+		char buf[INET6_ADDRSTRLEN];
 		xlog(L_ERROR, "can't get hostname of %s",
-			host_ntop((struct sockaddr *)sin, buf, sizeof(buf)));
+			host_ntop(sap, buf, sizeof(buf)));
 		goto out_unlock;
 	}
 
@@ -157,8 +156,7 @@ mountlist_del_all(struct sockaddr_in *sin)
 
 	while ((rep = getrmtabent(1, NULL)) != NULL) {
 		if (strcmp(rep->r_client, hostname) == 0 &&
-		    (exp = auth_authenticate("umountall",
-				(struct sockaddr *)sin, rep->r_path)))
+		    auth_authenticate("umountall", sap, rep->r_path) != NULL)
 			continue;
 		fputrmtabent(fp, rep, NULL);
 	}


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 05/12] mountd: Add mountlist_freeall()
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
                   ` (3 preceding siblings ...)
  2010-09-13 17:21 ` [PATCH 04/12] mountd: support IPv6 in mountlist_del_all() Chuck Lever
@ 2010-09-13 17:21 ` Chuck Lever
  2010-09-13 17:22 ` [PATCH 06/12] mountd: Handle memory exhaustion in mountlist_list() Chuck Lever
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:21 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

I'm about to add a second bit of logic that needs to free all
mountlist records, so introduce a helper for freeing them.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mountd/rmtab.c |   19 +++++++++++++------
 1 files changed, 13 insertions(+), 6 deletions(-)

diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c
index b2c04e7..854d519 100644
--- a/utils/mountd/rmtab.c
+++ b/utils/mountd/rmtab.c
@@ -173,6 +173,18 @@ out_unlock:
 	xfunlock(lockid);
 }
 
+static void
+mountlist_freeall(mountlist list)
+{
+	while (list != NULL) {
+		mountlist m = list;
+		list = m->ml_next;
+		xfree(m->ml_hostname);
+		xfree(m->ml_directory);
+		xfree(m);
+	}
+}
+
 mountlist
 mountlist_list(void)
 {
@@ -194,12 +206,7 @@ mountlist_list(void)
 		return NULL;
 	}
 	if (stb.st_mtime != last_mtime) {
-		while (mlist) {
-			mlist = (m = mlist)->ml_next;
-			xfree(m->ml_hostname);
-			xfree(m->ml_directory);
-			xfree(m);
-		}
+		mountlist_freeall(mlist);
 		last_mtime = stb.st_mtime;
 
 		setrmtabent("r");


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 06/12] mountd: Handle memory exhaustion in mountlist_list()
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
                   ` (4 preceding siblings ...)
  2010-09-13 17:21 ` [PATCH 05/12] mountd: Add mountlist_freeall() Chuck Lever
@ 2010-09-13 17:22 ` Chuck Lever
  2010-09-13 17:22 ` [PATCH 07/12] mountd: Support IPv6 " Chuck Lever
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:22 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

I'm about to replace inet_aton(3)/gethostbyaddr(3) with
host_pton()/host_canonname() in mountlist_list().

Since host_canonname() returns a string allocated with strdup(3)
instead of xstrdup(), mountlist_list() must now deal with memory
exhaustion properly.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mountd/rmtab.c |   32 ++++++++++++++++++++++++--------
 1 files changed, 24 insertions(+), 8 deletions(-)

diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c
index 854d519..cd6abc8 100644
--- a/utils/mountd/rmtab.c
+++ b/utils/mountd/rmtab.c
@@ -16,7 +16,7 @@
 #include <netinet/in.h>
 #include <arpa/inet.h>
 #include <netdb.h>
-#include "xmalloc.h"
+
 #include "misc.h"
 #include "exportfs.h"
 #include "xio.h"
@@ -179,9 +179,9 @@ mountlist_freeall(mountlist list)
 	while (list != NULL) {
 		mountlist m = list;
 		list = m->ml_next;
-		xfree(m->ml_hostname);
-		xfree(m->ml_directory);
-		xfree(m);
+		free(m->ml_hostname);
+		free(m->ml_directory);
+		free(m);
 	}
 }
 
@@ -211,16 +211,32 @@ mountlist_list(void)
 
 		setrmtabent("r");
 		while ((rep = getrmtabent(1, NULL)) != NULL) {
-			m = (mountlist) xmalloc(sizeof(*m));
+			m = calloc(1, sizeof(*m));
+			if (m == NULL) {
+				mountlist_freeall(mlist);
+				mlist = NULL;
+				xlog(L_ERROR, "%s: memory allocation failed",
+						__func__);
+				break;
+			}
 
 			if (reverse_resolve &&
 			   inet_aton((const char *) rep->r_client, &addr) &&
 			   (he = gethostbyaddr(&addr, sizeof(addr), AF_INET)))
-				m->ml_hostname = xstrdup(he->h_name);
+				m->ml_hostname = strdup(he->h_name);
 			else
-				m->ml_hostname = xstrdup(rep->r_client);
+				m->ml_hostname = strdup(rep->r_client);
+
+			m->ml_directory = strdup(rep->r_path);
+
+			if (m->ml_hostname == NULL || m->ml_directory == NULL) {
+				mountlist_freeall(mlist);
+				mlist = NULL;
+				xlog(L_ERROR, "%s: memory allocation failed",
+						__func__);
+				break;
+			}
 
- 			m->ml_directory = xstrdup(rep->r_path);
 			m->ml_next = mlist;
 			mlist = m;
 		}


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 07/12] mountd: Support IPv6 in mountlist_list()
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
                   ` (5 preceding siblings ...)
  2010-09-13 17:22 ` [PATCH 06/12] mountd: Handle memory exhaustion in mountlist_list() Chuck Lever
@ 2010-09-13 17:22 ` Chuck Lever
  2010-09-13 17:22 ` [PATCH 08/12] exportfs: Enable IPv6 support in matchhostname() Chuck Lever
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:22 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Replace inet_aton(3) and gethostbyaddr(3) calls in mountlist_list()
with calls to the new host_foo() DNS helpers.

The new functions will support IPv6 without additional changes, once
IPv6 is enabled in the generic hostname helpers.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mountd/rmtab.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

diff --git a/utils/mountd/rmtab.c b/utils/mountd/rmtab.c
index cd6abc8..d339296 100644
--- a/utils/mountd/rmtab.c
+++ b/utils/mountd/rmtab.c
@@ -194,8 +194,6 @@ mountlist_list(void)
 	struct rmtabent		*rep;
 	struct stat		stb;
 	int			lockid;
-	struct in_addr		addr;
-	struct hostent		*he;
 
 	if ((lockid = xflock(_PATH_RMTABLCK, "r")) < 0)
 		return NULL;
@@ -220,11 +218,15 @@ mountlist_list(void)
 				break;
 			}
 
-			if (reverse_resolve &&
-			   inet_aton((const char *) rep->r_client, &addr) &&
-			   (he = gethostbyaddr(&addr, sizeof(addr), AF_INET)))
-				m->ml_hostname = strdup(he->h_name);
-			else
+			if (reverse_resolve) {
+				struct addrinfo *ai;
+				ai = host_pton(rep->r_client);
+				if (ai != NULL) {
+					m->ml_hostname = host_canonname(ai->ai_addr);
+					freeaddrinfo(ai);
+				}
+			}
+			if (m->ml_hostname == NULL)
 				m->ml_hostname = strdup(rep->r_client);
 
 			m->ml_directory = strdup(rep->r_path);


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 08/12] exportfs: Enable IPv6 support in matchhostname()
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
                   ` (6 preceding siblings ...)
  2010-09-13 17:22 ` [PATCH 07/12] mountd: Support IPv6 " Chuck Lever
@ 2010-09-13 17:22 ` Chuck Lever
  2010-09-13 17:22 ` [PATCH 09/12] mountd: clean up cache API Chuck Lever
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:22 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

To gain IPv6 support in matchhostname(), simply replace the socket
address comparison helpers with the generic versions that can handle
IPv4 and IPv6.

host_addrinfo() (called by matchhostname()) returns IPv6 addresses
only if IPv6 support is enabled.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/exportfs/exportfs.c |   23 ++---------------------
 1 files changed, 2 insertions(+), 21 deletions(-)

diff --git a/utils/exportfs/exportfs.c b/utils/exportfs/exportfs.c
index 8496d82..b78957f 100644
--- a/utils/exportfs/exportfs.c
+++ b/utils/exportfs/exportfs.c
@@ -26,6 +26,7 @@
 #include <netdb.h>
 #include <errno.h>
 
+#include "sockaddr.h"
 #include "misc.h"
 #include "nfslib.h"
 #include "exportfs.h"
@@ -443,26 +444,6 @@ is_hostname(const char *sp)
 	return true;
 }
 
-static _Bool
-compare_sockaddrs4(const struct sockaddr *sa1, const struct sockaddr *sa2)
-{
-	const struct sockaddr_in *sin1 = (const struct sockaddr_in *)sa1;
-	const struct sockaddr_in *sin2 = (const struct sockaddr_in *)sa2;
-	return sin1->sin_addr.s_addr == sin2->sin_addr.s_addr;
-}
-
-static _Bool
-compare_sockaddrs(const struct sockaddr *sa1, const struct sockaddr *sa2)
-{
-	if (sa1->sa_family == sa2->sa_family)
-		switch (sa1->sa_family) {
-		case AF_INET:
-			return compare_sockaddrs4(sa1, sa2);
-		}
-
-	return false;
-}
-
 static int
 matchhostname(const char *hostname1, const char *hostname2)
 {
@@ -493,7 +474,7 @@ matchhostname(const char *hostname1, const char *hostname2)
 
 	for (ai1 = results1; ai1 != NULL; ai1 = ai1->ai_next)
 		for (ai2 = results2; ai2 != NULL; ai2 = ai2->ai_next)
-			if (compare_sockaddrs(ai1->ai_addr, ai2->ai_addr)) {
+			if (nfs_compare_sockaddr(ai1->ai_addr, ai2->ai_addr)) {
 				result = 1;
 				break;
 			}


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 09/12] mountd: clean up cache API
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
                   ` (7 preceding siblings ...)
  2010-09-13 17:22 ` [PATCH 08/12] exportfs: Enable IPv6 support in matchhostname() Chuck Lever
@ 2010-09-13 17:22 ` Chuck Lever
  2010-09-13 17:22 ` [PATCH 10/12] mountd: Handle IPv6 addresses in kernel auth_unix_ip upcalls Chuck Lever
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:22 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Clean up: Squelch compiler warnings and document public parts of
cache API.

cache.c: At top level:
cache.c:67: warning: no previous prototype for ‘auth_unix_ip’
cache.c:123: warning: no previous prototype for ‘auth_unix_gid’
cache.c:217: warning: no previous prototype for ‘get_uuid’
cache.c:247: warning: no previous prototype for ‘uuid_by_path’
cache.c:326: warning: no previous prototype for ‘nfsd_fh’
cache.c:745: warning: no previous prototype for ‘nfsd_export’
cache.c:820: warning: no previous prototype for ‘cache_open’
cache.c:832: warning: no previous prototype for ‘cache_set_fds’
cache.c:841: warning: no previous prototype for ‘cache_process_req’
cache.c:921: warning: no previous prototype for ‘cache_export’
cache.c:953: warning: no previous prototype for ‘cache_get_filehandle’

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mountd/cache.c  |   49 +++++++++++++++++++++++++++++++++++++++----------
 utils/mountd/mountd.c |    4 ----
 utils/mountd/mountd.h |    4 ++++
 3 files changed, 43 insertions(+), 14 deletions(-)

diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index 2909ad3..ab873d5 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -37,6 +37,11 @@
 #include "blkid/blkid.h"
 #endif
 
+/*
+ * Invoked by RPC service loop
+ */
+void	cache_set_fds(fd_set *fdset);
+int	cache_process_req(fd_set *readfds);
 
 enum nfsd_fsid {
 	FSID_DEV = 0,
@@ -57,14 +62,14 @@ enum nfsd_fsid {
  * Record is terminated with newline.
  *
  */
-int cache_export_ent(char *domain, struct exportent *exp, char *p);
+static int cache_export_ent(char *domain, struct exportent *exp, char *p);
 
 
 char *lbuf  = NULL;
 int lbuflen = 0;
 extern int use_ipaddr;
 
-void auth_unix_ip(FILE *f)
+static void auth_unix_ip(FILE *f)
 {
 	/* requests are
 	 *  class IP-ADDR
@@ -120,7 +125,7 @@ void auth_unix_ip(FILE *f)
 	free(client);
 }
 
-void auth_unix_gid(FILE *f)
+static void auth_unix_gid(FILE *f)
 {
 	/* Request are
 	 *  uid
@@ -214,7 +219,7 @@ static const char *get_uuid_blkdev(char *path)
 #define get_uuid_blkdev(path) (NULL)
 #endif
 
-int get_uuid(const char *val, int uuidlen, char *u)
+static int get_uuid(const char *val, int uuidlen, char *u)
 {
 	/* extract hex digits from uuidstr and compose a uuid
 	 * of the given length (max 16), xoring bytes to make
@@ -244,7 +249,7 @@ int get_uuid(const char *val, int uuidlen, char *u)
 	return 1;
 }
 
-int uuid_by_path(char *path, int type, int uuidlen, char *uuid)
+static int uuid_by_path(char *path, int type, int uuidlen, char *uuid)
 {
 	/* get a uuid for the filesystem found at 'path'.
 	 * There are several possible ways of generating the
@@ -323,7 +328,7 @@ static char *next_mnt(void **v, char *p)
 	return me->mnt_dir;
 }
 
-void nfsd_fh(FILE *f)
+static void nfsd_fh(FILE *f)
 {
 	/* request are:
 	 *  domain fsidtype fsid
@@ -742,7 +747,7 @@ lookup_export(char *dom, char *path, struct addrinfo *ai)
 	return found;
 }
 
-void nfsd_export(FILE *f)
+static void nfsd_export(FILE *f)
 {
 	/* requests are:
 	 *  domain path
@@ -817,6 +822,11 @@ struct {
 };
 
 extern int manage_gids;
+
+/**
+ * cache_open - prepare communications channels with kernel RPC caches
+ *
+ */
 void cache_open(void) 
 {
 	int i;
@@ -829,6 +839,10 @@ void cache_open(void)
 	}
 }
 
+/**
+ * cache_set_fds - prepare cache file descriptors for one iteration of the service loop
+ * @fdset: pointer to fd_set to prepare
+ */
 void cache_set_fds(fd_set *fdset)
 {
 	int i;
@@ -838,6 +852,10 @@ void cache_set_fds(fd_set *fdset)
 	}
 }
 
+/**
+ * cache_process_req - process any active cache file descriptors during service loop iteration
+ * @fdset: pointer to fd_set to examine for activity
+ */
 int cache_process_req(fd_set *readfds) 
 {
 	int i;
@@ -860,7 +878,7 @@ int cache_process_req(fd_set *readfds)
  * % echo $domain $path $[now+30*60] $options $anonuid $anongid $fsid > /proc/net/rpc/nfsd.export/channel
  */
 
-int cache_export_ent(char *domain, struct exportent *exp, char *path)
+static int cache_export_ent(char *domain, struct exportent *exp, char *path)
 {
 	int err;
 	FILE *f = fopen("/proc/net/rpc/nfsd.export/channel", "w");
@@ -918,6 +936,11 @@ int cache_export_ent(char *domain, struct exportent *exp, char *path)
 	return err;
 }
 
+/**
+ * cache_export - Inform kernel of a new nfs_export
+ * @exp: target nfs_export
+ * @path: NUL-terminated C string containing export path
+ */
 int cache_export(nfs_export *exp, char *path)
 {
 	char buf[INET_ADDRSTRLEN];
@@ -943,7 +966,14 @@ int cache_export(nfs_export *exp, char *path)
 	return err;
 }
 
-/* Get a filehandle.
+/**
+ * cache_get_filehandle - given an nfs_export, get its root filehandle
+ * @exp: target nfs_export
+ * @len: length of requested file handle
+ * @p: NUL-terminated C string containing export path
+ *
+ * Returns pointer to NFS file handle of root directory of export
+ *
  * { 
  *   echo $domain $path $length 
  *   read filehandle <&0
@@ -977,4 +1007,3 @@ cache_get_filehandle(nfs_export *exp, int len, char *p)
 	fh.fh_size = qword_get(&bp, (char *)fh.fh_handle, NFS3_FHSIZE);
 	return &fh;
 }
-
diff --git a/utils/mountd/mountd.c b/utils/mountd/mountd.c
index 98b396d..982b06e 100644
--- a/utils/mountd/mountd.c
+++ b/utils/mountd/mountd.c
@@ -28,10 +28,6 @@
 #include "rpcmisc.h"
 #include "pseudoflavors.h"
 
-extern void	cache_open(void);
-extern struct nfs_fh_len *cache_get_filehandle(nfs_export *exp, int len, char *p);
-extern int cache_export(nfs_export *exp, char *path);
-
 extern void my_svc_run(void);
 
 static void		usage(const char *, int exitcode);
diff --git a/utils/mountd/mountd.h b/utils/mountd/mountd.h
index 0d31ca7..4c184d2 100644
--- a/utils/mountd/mountd.h
+++ b/utils/mountd/mountd.h
@@ -51,5 +51,9 @@ void		mountlist_del(char *host, const char *path);
 void		mountlist_del_all(const struct sockaddr *sap);
 mountlist	mountlist_list(void);
 
+void		cache_open(void);
+struct nfs_fh_len *
+		cache_get_filehandle(nfs_export *exp, int len, char *p);
+int		cache_export(nfs_export *exp, char *path);
 
 #endif /* MOUNTD_H */


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 10/12] mountd: Handle IPv6 addresses in kernel auth_unix_ip upcalls
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
                   ` (8 preceding siblings ...)
  2010-09-13 17:22 ` [PATCH 09/12] mountd: clean up cache API Chuck Lever
@ 2010-09-13 17:22 ` Chuck Lever
  2010-09-13 17:22 ` [PATCH 11/12] mountd: Ensure cache downcall can handle IPv6 addresses Chuck Lever
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:22 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mountd/cache.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index ab873d5..0e8a2f4 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -80,7 +80,7 @@ static void auth_unix_ip(FILE *f)
 	 */
 	char *cp;
 	char class[20];
-	char ipaddr[20];
+	char ipaddr[INET6_ADDRSTRLEN];
 	char *client = NULL;
 	struct addrinfo *tmp = NULL;
 	struct addrinfo *ai = NULL;
@@ -95,7 +95,7 @@ static void auth_unix_ip(FILE *f)
 	    strcmp(class, "nfsd") != 0)
 		return;
 
-	if (qword_get(&cp, ipaddr, 20) <= 0)
+	if (qword_get(&cp, ipaddr, sizeof(ipaddr)) <= 0)
 		return;
 
 	tmp = host_pton(ipaddr);
@@ -953,7 +953,7 @@ int cache_export(nfs_export *exp, char *path)
 
 
 	qword_print(f, "nfsd");
-	qword_print(f, 
+	qword_print(f,
 		host_ntop(get_addrlist(exp->m_client, 0), buf, sizeof(buf)));
 	qword_printint(f, time(0)+30*60);
 	qword_print(f, exp->m_client->m_hostname);


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 11/12] mountd: Ensure cache downcall can handle IPv6 addresses
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
                   ` (9 preceding siblings ...)
  2010-09-13 17:22 ` [PATCH 10/12] mountd: Handle IPv6 addresses in kernel auth_unix_ip upcalls Chuck Lever
@ 2010-09-13 17:22 ` Chuck Lever
  2010-09-13 17:23 ` [PATCH 12/12] libexport.a: Enable IPv6 support in hostname.c Chuck Lever
       [not found] ` <20100913171844.19017.13446.stgit-x+BlCsqV7M/wdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:22 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 utils/mountd/cache.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/utils/mountd/cache.c b/utils/mountd/cache.c
index 0e8a2f4..f70f4d6 100644
--- a/utils/mountd/cache.c
+++ b/utils/mountd/cache.c
@@ -943,7 +943,7 @@ static int cache_export_ent(char *domain, struct exportent *exp, char *path)
  */
 int cache_export(nfs_export *exp, char *path)
 {
-	char buf[INET_ADDRSTRLEN];
+	char buf[INET6_ADDRSTRLEN];
 	int err;
 	FILE *f;
 


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* [PATCH 12/12] libexport.a: Enable IPv6 support in hostname.c
  2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
                   ` (10 preceding siblings ...)
  2010-09-13 17:22 ` [PATCH 11/12] mountd: Ensure cache downcall can handle IPv6 addresses Chuck Lever
@ 2010-09-13 17:23 ` Chuck Lever
       [not found] ` <20100913171844.19017.13446.stgit-x+BlCsqV7M/wdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
  12 siblings, 0 replies; 14+ messages in thread
From: Chuck Lever @ 2010-09-13 17:23 UTC (permalink / raw)
  To: steved; +Cc: linux-nfs

If --enable-ipv6 is specified when building nfs-utils, libexport's
host_foo() helpers can now return both IPv4 and IPv6 addresses.

This means IPv6 presentation addresses and IPv6 DNS resolution
results are handled properly in the mountd cache and /etc/exports,
but does not yet enable IPv6 mountd listeners.

Signed-off-by: Chuck Lever <chuck.lever@oracle.com>
---

 support/export/hostname.c |   31 +++++++++++++++----------------
 1 files changed, 15 insertions(+), 16 deletions(-)

diff --git a/support/export/hostname.c b/support/export/hostname.c
index 232e040..3c55ce7 100644
--- a/support/export/hostname.c
+++ b/support/export/hostname.c
@@ -34,16 +34,6 @@
 #define AI_ADDRCONFIG	0
 #endif
 
-#ifdef HAVE_GETNAMEINFO
-static socklen_t
-sockaddr_size(const struct sockaddr *sap)
-{
-	if (sap->sa_family != AF_INET)
-		return 0;
-	return (socklen_t)sizeof(struct sockaddr_in);
-}
-#endif	/* HAVE_GETNAMEINFO */
-
 /**
  * host_ntop - generate presentation address given a sockaddr
  * @sap: pointer to socket address
@@ -56,7 +46,7 @@ sockaddr_size(const struct sockaddr *sap)
 char *
 host_ntop(const struct sockaddr *sap, char *buf, const size_t buflen)
 {
-	socklen_t salen = sockaddr_size(sap);
+	socklen_t salen = nfs_sockaddr_length(sap);
 	int error;
 
 	memset(buf, 0, buflen);
@@ -117,7 +107,7 @@ host_pton(const char *paddr)
 		.ai_family	= AF_UNSPEC,
 	};
 	struct sockaddr_in sin;
-	int error;
+	int error, inet4;
 
 	/*
 	 * Although getaddrinfo(3) is easier to use and supports
@@ -129,12 +119,17 @@ host_pton(const char *paddr)
 	 * have a real AF_INET presentation address, before invoking
 	 * getaddrinfo(3) to generate the full addrinfo list.
 	 */
+	inet4 = 1;
 	if (inet_pton(AF_INET, paddr, &sin.sin_addr) == 0)
-		return NULL;
+		inet4 = 0;
 
 	error = getaddrinfo(paddr, NULL, &hint, &ai);
 	switch (error) {
 	case 0:
+		if (!inet4 && ai->ai_addr->sa_family == AF_INET) {
+			freeaddrinfo(ai);
+			break;
+		}
 		return ai;
 	case EAI_NONAME:
 		if (paddr == NULL)
@@ -168,7 +163,11 @@ host_addrinfo(const char *hostname)
 {
 	struct addrinfo *ai = NULL;
 	struct addrinfo hint = {
+#ifdef IPV6_SUPPORTED
+		.ai_family	= AF_UNSPEC,
+#else
 		.ai_family	= AF_INET,
+#endif
 		/* don't return duplicates */
 		.ai_protocol	= (int)IPPROTO_UDP,
 		.ai_flags	= AI_ADDRCONFIG | AI_CANONNAME,
@@ -208,7 +207,7 @@ __attribute_malloc__
 char *
 host_canonname(const struct sockaddr *sap)
 {
-	socklen_t salen = sockaddr_size(sap);
+	socklen_t salen = nfs_sockaddr_length(sap);
 	char buf[NI_MAXHOST];
 	int error;
 
@@ -298,8 +297,8 @@ __attribute_malloc__
 struct addrinfo *
 host_numeric_addrinfo(const struct sockaddr *sap)
 {
-	socklen_t salen = sockaddr_size(sap);
-	char buf[INET_ADDRSTRLEN];
+	socklen_t salen = nfs_sockaddr_length(sap);
+	char buf[INET6_ADDRSTRLEN];
 	struct addrinfo *ai;
 	int error;
 


^ permalink raw reply related	[flat|nested] 14+ messages in thread

* Re: [PATCH 00/12] Next series of mountd IPv6 support patches
       [not found] ` <20100913171844.19017.13446.stgit-x+BlCsqV7M/wdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
@ 2010-09-16 21:29   ` Steve Dickson
  0 siblings, 0 replies; 14+ messages in thread
From: Steve Dickson @ 2010-09-16 21:29 UTC (permalink / raw)
  To: Chuck Lever; +Cc: linux-nfs



On 09/13/2010 01:20 PM, Chuck Lever wrote:
> This series enables support for IPv6 addresses when receiving mountd
> requests and processing export records.
> 
> The final series (later this week, or next) will enable mountd to
> listen on IPv6 transports.
> 
> ---
> 
> Chuck Lever (12):
>       libexport.a: Enable IPv6 support in hostname.c
>       mountd: Ensure cache downcall can handle IPv6 addresses
>       mountd: Handle IPv6 addresses in kernel auth_unix_ip upcalls
>       mountd: clean up cache API
>       exportfs: Enable IPv6 support in matchhostname()
>       mountd: Support IPv6 in mountlist_list()
>       mountd: Handle memory exhaustion in mountlist_list()
>       mountd: Add mountlist_freeall()
>       mountd: support IPv6 in mountlist_del_all()
>       mountd: Support IPv6 in mountd's svc routines
>       mountd: add IPv6 support in auth_authenticate()
>       libnfs.a: Fix API for getfh() & friends
> 
> 
>  support/export/hostname.c |   31 +++++++--------
>  support/include/nfslib.h  |    9 +++-
>  support/nfs/getfh.c       |   64 ++++++++++++++++++++++++++++---
>  utils/exportfs/exportfs.c |   23 +----------
>  utils/mountd/auth.c       |   52 +++++++++++++------------
>  utils/mountd/cache.c      |   57 +++++++++++++++++++++-------
>  utils/mountd/mountd.c     |   92 +++++++++++++++++++++++++++++++--------------
>  utils/mountd/mountd.h     |   11 ++++-
>  utils/mountd/rmtab.c      |   72 +++++++++++++++++++++++------------
>  9 files changed, 270 insertions(+), 141 deletions(-)
> 
All 12 patches committed... 

steved. 

^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2010-09-16 21:29 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-09-13 17:20 [PATCH 00/12] Next series of mountd IPv6 support patches Chuck Lever
2010-09-13 17:20 ` [PATCH 01/12] libnfs.a: Fix API for getfh() & friends Chuck Lever
2010-09-13 17:21 ` [PATCH 02/12] mountd: add IPv6 support in auth_authenticate() Chuck Lever
2010-09-13 17:21 ` [PATCH 03/12] mountd: Support IPv6 in mountd's svc routines Chuck Lever
2010-09-13 17:21 ` [PATCH 04/12] mountd: support IPv6 in mountlist_del_all() Chuck Lever
2010-09-13 17:21 ` [PATCH 05/12] mountd: Add mountlist_freeall() Chuck Lever
2010-09-13 17:22 ` [PATCH 06/12] mountd: Handle memory exhaustion in mountlist_list() Chuck Lever
2010-09-13 17:22 ` [PATCH 07/12] mountd: Support IPv6 " Chuck Lever
2010-09-13 17:22 ` [PATCH 08/12] exportfs: Enable IPv6 support in matchhostname() Chuck Lever
2010-09-13 17:22 ` [PATCH 09/12] mountd: clean up cache API Chuck Lever
2010-09-13 17:22 ` [PATCH 10/12] mountd: Handle IPv6 addresses in kernel auth_unix_ip upcalls Chuck Lever
2010-09-13 17:22 ` [PATCH 11/12] mountd: Ensure cache downcall can handle IPv6 addresses Chuck Lever
2010-09-13 17:23 ` [PATCH 12/12] libexport.a: Enable IPv6 support in hostname.c Chuck Lever
     [not found] ` <20100913171844.19017.13446.stgit-x+BlCsqV7M/wdl/1UfZZQIVfYA8g3rJ/@public.gmane.org>
2010-09-16 21:29   ` [PATCH 00/12] Next series of mountd IPv6 support patches Steve Dickson

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.