summaryrefslogtreecommitdiffstats
path: root/sys/nfsserver
diff options
context:
space:
mode:
authoralfred <alfred@FreeBSD.org>2002-07-15 19:40:23 +0000
committeralfred <alfred@FreeBSD.org>2002-07-15 19:40:23 +0000
commitdf766765ba15b2a418b09b713353a763a1c12909 (patch)
tree08c1766490b20ea5dcdd86157dd05bf33f410b18 /sys/nfsserver
parentc559b8902789e64b5a4b1e482f230e933cda7198 (diff)
downloadFreeBSD-src-df766765ba15b2a418b09b713353a763a1c12909.zip
FreeBSD-src-df766765ba15b2a418b09b713353a763a1c12909.tar.gz
Add IPv6 support.
Submitted by: Jean-Luc Richier <Jean-Luc.Richier@imag.fr>
Diffstat (limited to 'sys/nfsserver')
-rw-r--r--sys/nfsserver/nfs.h7
-rw-r--r--sys/nfsserver/nfs_srvcache.c5
-rw-r--r--sys/nfsserver/nfs_srvsock.c4
-rw-r--r--sys/nfsserver/nfs_srvsubs.c21
-rw-r--r--sys/nfsserver/nfs_syscalls.c33
5 files changed, 56 insertions, 14 deletions
diff --git a/sys/nfsserver/nfs.h b/sys/nfsserver/nfs.h
index 18768af..cbdb54f 100644
--- a/sys/nfsserver/nfs.h
+++ b/sys/nfsserver/nfs.h
@@ -195,13 +195,6 @@ union nethostaddr {
struct sockaddr *had_nam;
};
-#define nu_inetaddr nu_haddr.had_inetaddr
-#define nu_nam nu_haddr.had_nam
-/* Bits for nu_flag */
-#define NU_INETADDR 0x1
-#define NU_NAM 0x2
-#define NU_NETFAM(u) (((u)->nu_flag & NU_INETADDR) ? AF_INET : AF_ISO)
-
struct nfsrv_rec {
STAILQ_ENTRY(nfsrv_rec) nr_link;
struct sockaddr *nr_address;
diff --git a/sys/nfsserver/nfs_srvcache.c b/sys/nfsserver/nfs_srvcache.c
index 2222ffa..1986c0b 100644
--- a/sys/nfsserver/nfs_srvcache.c
+++ b/sys/nfsserver/nfs_srvcache.c
@@ -71,7 +71,7 @@ static u_long nfsrvhash;
#define FALSE 0
#define NETFAMILY(rp) \
- (((rp)->rc_flag & RC_INETADDR) ? AF_INET : AF_ISO)
+ (((rp)->rc_flag & RC_NAM) ? (rp)->rc_nam->sa_family : AF_INET)
/*
* Static array that defines which nfs rpc's are nonidempotent
@@ -240,7 +240,8 @@ loop:
rp->rc_flag |= RC_INETADDR;
rp->rc_inetaddr = saddr->sin_addr.s_addr;
break;
- case AF_ISO:
+/* case AF_INET6: */
+/* case AF_ISO: */
default:
rp->rc_flag |= RC_NAM;
rp->rc_nam = dup_sockaddr(nd->nd_nam, 1);
diff --git a/sys/nfsserver/nfs_srvsock.c b/sys/nfsserver/nfs_srvsock.c
index 2143544..1feffa9 100644
--- a/sys/nfsserver/nfs_srvsock.c
+++ b/sys/nfsserver/nfs_srvsock.c
@@ -154,13 +154,13 @@ nfs_rephead(int siz, struct nfsrv_descript *nd, int err,
* If this is a big reply, use a cluster else
* try and leave leading space for the lower level headers.
*/
+ mreq->m_len = 6 * NFSX_UNSIGNED;
siz += RPC_REPLYSIZ;
if ((max_hdr + siz) >= MINCLSIZE) {
MCLGET(mreq, M_TRYWAIT);
} else
- mreq->m_data += max_hdr;
+ mreq->m_data += min(max_hdr, M_TRAILINGSPACE(mreq));
tl = mtod(mreq, u_int32_t *);
- mreq->m_len = 6 * NFSX_UNSIGNED;
bpos = ((caddr_t)tl) + mreq->m_len;
*tl++ = txdr_unsigned(nd->nd_retxid);
*tl++ = nfsrv_rpc_reply;
diff --git a/sys/nfsserver/nfs_srvsubs.c b/sys/nfsserver/nfs_srvsubs.c
index 5f37b1f..19a74d7 100644
--- a/sys/nfsserver/nfs_srvsubs.c
+++ b/sys/nfsserver/nfs_srvsubs.c
@@ -46,6 +46,8 @@ __FBSDID("$FreeBSD$");
* copy data between mbuf chains and uio lists.
*/
+#include "opt_inet6.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/kernel.h>
@@ -1051,7 +1053,9 @@ nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp,
#ifdef MNT_EXNORESPORT
if (!(exflags & (MNT_EXNORESPORT|MNT_EXPUBLIC))) {
saddr = (struct sockaddr_in *)nam;
- if (saddr->sin_family == AF_INET &&
+ if ((saddr->sin_family == AF_INET ||
+ saddr->sin_family == AF_INET6) &&
+ /* same code for INET and INET6: sin*_port at same offet */
ntohs(saddr->sin_port) >= IPPORT_RESERVED) {
vput(*vpp);
*vpp = NULL;
@@ -1117,6 +1121,21 @@ netaddr_match(int family, union nethostaddr *haddr, struct sockaddr *nam)
inetaddr->sin_addr.s_addr == haddr->had_inetaddr)
return (1);
break;
+#ifdef INET6
+ case AF_INET6:
+ {
+ register struct sockaddr_in6 *inet6addr1, *inet6addr2;
+
+ inet6addr1 = (struct sockaddr_in6 *)nam;
+ inet6addr2 = (struct sockaddr_in6 *)haddr->had_nam;
+ /* XXX - should test sin6_scope_id ? */
+ if (inet6addr1->sin6_family == AF_INET6 &&
+ IN6_ARE_ADDR_EQUAL(&inet6addr1->sin6_addr,
+ &inet6addr2->sin6_addr))
+ return (1);
+ break;
+ }
+#endif
default:
break;
};
diff --git a/sys/nfsserver/nfs_syscalls.c b/sys/nfsserver/nfs_syscalls.c
index fb60d36..f123dcc 100644
--- a/sys/nfsserver/nfs_syscalls.c
+++ b/sys/nfsserver/nfs_syscalls.c
@@ -40,6 +40,8 @@
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
+#include "opt_inet6.h"
+
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/sysproto.h>
@@ -64,6 +66,10 @@ __FBSDID("$FreeBSD$");
#include <netinet/in.h>
#include <netinet/tcp.h>
+#ifdef INET6
+#include <net/if.h>
+#include <netinet6/in6_var.h>
+#endif
#include <nfs/xdr_subs.h>
#include <nfs/rpcv2.h>
#include <nfs/nfsproto.h>
@@ -109,6 +115,10 @@ static int nfssvc_nfsd(struct nfsd_srvargs *, caddr_t, struct thread *);
* - adds a socket to the selection list
* - remains in the kernel as an nfsd
* - remains in the kernel as an nfsiod
+ * For INET6 we suppose that nfsd provides only IN6P_BINDV6ONLY sockets
+ * and that mountd provides
+ * - sockaddr with no IPv4-mapped addresses
+ * - mask for both INET and INET6 families if there is IPv4-mapped overlap
*/
#ifndef _SYS_SYSPROTO_H_
struct nfssvc_args {
@@ -230,8 +240,7 @@ nfssvc_addsock(struct file *fp, struct sockaddr *mynam, struct thread *td)
val = 1;
sosetopt(so, &sopt);
}
- if (so->so_proto->pr_domain->dom_family == AF_INET &&
- so->so_proto->pr_protocol == IPPROTO_TCP) {
+ if (so->so_proto->pr_protocol == IPPROTO_TCP) {
struct sockopt sopt;
int val;
@@ -385,13 +394,33 @@ nfssvc_nfsd(struct nfsd_srvargs *nsd, caddr_t argp, struct thread *td)
struct sockaddr_in *sin;
sin = (struct sockaddr_in *)nam;
+ /*
+ * INET/INET6 - same code:
+ * sin_port and sin6_port are at same offset
+ */
port = ntohs(sin->sin_port);
if (port >= IPPORT_RESERVED &&
nd->nd_procnum != NFSPROC_NULL) {
+#if defined(INET6) && defined(KLD_MODULE)
+ /* do not use ip6_sprintf: the nfs module should work without INET6 */
+ char b6[INET6_ADDRSTRLEN];
+#define ip6_sprintf(a) \
+ (sprintf(b6, "%x:%x:%x:%x:%x:%x:%x:%x", \
+ (a)->s6_addr16[0], (a)->s6_addr16[1], \
+ (a)->s6_addr16[2], (a)->s6_addr16[3], \
+ (a)->s6_addr16[4], (a)->s6_addr16[5], \
+ (a)->s6_addr16[6], (a)->s6_addr16[7]), \
+ b6)
+#endif
nd->nd_procnum = NFSPROC_NOOP;
nd->nd_repstat = (NFSERR_AUTHERR | AUTH_TOOWEAK);
cacherep = RC_DOIT;
printf("NFS request from unprivileged port (%s:%d)\n",
+#ifdef INET6
+ sin->sin_family == AF_INET6 ?
+ ip6_sprintf(&satosin6(sin)->sin6_addr) :
+#undef ip6_sprintf
+#endif
inet_ntoa(sin->sin_addr), port);
}
}
OpenPOWER on IntegriCloud