[Midnightbsd-cvs] src: src/sys:

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Wed Oct 1 12:44:44 EDT 2008


Log Message:
-----------


Modified Files:
--------------
    src/sys:
        Makefile (r1.6 -> r1.7)
    src/sys/netatalk:
        COPYRIGHT (r1.1.1.1 -> r1.2)
        aarp.c (r1.1.1.1 -> r1.2)
        aarp.h (r1.1.1.1 -> r1.2)
        at.h (r1.1.1.1 -> r1.2)
        at_control.c (r1.1.1.1 -> r1.2)
        at_extern.h (r1.1.1.1 -> r1.2)
        at_proto.c (r1.1.1.1 -> r1.2)
        at_rmx.c (r1.1.1.1 -> r1.2)
        at_var.h (r1.1.1.1 -> r1.2)
        ddp.h (r1.1.1.1 -> r1.2)
        ddp_input.c (r1.1.1.1 -> r1.2)
        ddp_output.c (r1.1.1.1 -> r1.2)
        ddp_pcb.c (r1.1.1.1 -> r1.2)
        ddp_pcb.h (r1.1.1.1 -> r1.2)
        ddp_usrreq.c (r1.1.1.1 -> r1.2)
        ddp_var.h (r1.1.1.1 -> r1.2)
    src/sys/netatm:
        atm_aal5.c (r1.1.1.1 -> r1.2)
        atm_cm.c (r1.1.1.1 -> r1.2)
        atm_if.c (r1.1.1.1 -> r1.2)
        atm_proto.c (r1.1.1.1 -> r1.2)
        atm_signal.c (r1.1.1.2 -> r1.2)
        atm_socket.c (r1.1.1.1 -> r1.2)
        atm_sys.h (r1.1.1.1 -> r1.2)
        atm_usrreq.c (r1.1.1.1 -> r1.2)
        atm_var.h (r1.1.1.1 -> r1.2)
    src/sys/netatm/ipatm:
        ipatm_event.c (r1.1.1.1 -> r1.2)
        ipatm_if.c (r1.1.1.1 -> r1.2)
        ipatm_load.c (r1.1.1.1 -> r1.2)
        ipatm_vcm.c (r1.1.1.1 -> r1.2)
    src/sys/netatm/spans:
        spans_proto.c (r1.1.1.1 -> r1.2)
    src/sys/netatm/uni:
        sscf_uni_lower.c (r1.1.1.1 -> r1.2)
        uniarp.c (r1.1.1.1 -> r1.2)
        uniarp_timer.c (r1.1.1.1 -> r1.2)
        unisig_decode.h (r1.1.1.1 -> r1.2)
        unisig_encode.c (r1.1.1.2 -> r1.2)
        unisig_proto.c (r1.1.1.1 -> r1.2)
    src/sys/netnatm:
        natm.c (r1.1.1.1 -> r1.2)
        natm.h (r1.1.1.1 -> r1.2)
        natm_pcb.c (r1.1.1.1 -> r1.2)
        natm_proto.c (r1.1.1.1 -> r1.2)
    src/sys/netncp:
        ncp_conn.c (r1.1.1.2 -> r1.2)
        ncp_mod.c (r1.1.1.1 -> r1.2)
        ncp_rq.c (r1.1.1.1 -> r1.2)
        ncp_sock.c (r1.1.1.1 -> r1.2)
        ncp_subr.h (r1.1.1.1 -> r1.2)
    src/sys/netsmb:
        netbios.h (r1.1.1.1 -> r1.2)
        smb_conn.c (r1.1.1.1 -> r1.2)
        smb_crypt.c (r1.1.1.1 -> r1.2)
        smb_dev.c (r1.1.1.2 -> r1.2)
        smb_iod.c (r1.1.1.1 -> r1.2)
        smb_rq.c (r1.1.1.1 -> r1.2)
        smb_rq.h (r1.1.1.1 -> r1.2)
        smb_smb.c (r1.1.1.1 -> r1.2)
        smb_subr.c (r1.1.1.2 -> r1.2)
        smb_subr.h (r1.1.1.1 -> r1.2)
        smb_trantcp.c (r1.1.1.1 -> r1.2)
    src/sys/nfs:
        nfs_common.c (r1.1.1.1 -> r1.2)
        nfs_common.h (r1.1.1.1 -> r1.2)
        nfsproto.h (r1.1.1.1 -> r1.2)
    src/sys/nfs4client:
        nfs4_dev.c (r1.1.1.2 -> r1.2)
        nfs4_subs.c (r1.1.1.2 -> r1.2)
        nfs4_vfs_subs.c (r1.1.1.2 -> r1.2)
        nfs4_vfsops.c (r1.1.1.2 -> r1.2)
        nfs4_vn_subs.c (r1.1.1.2 -> r1.2)
        nfs4_vnops.c (r1.1.1.2 -> r1.2)
    src/sys/nfsserver:
        nfs.h (r1.1.1.1 -> r1.2)
        nfs_serv.c (r1.2 -> r1.3)
        nfs_srvcache.c (r1.1.1.1 -> r1.2)
        nfs_srvsock.c (r1.2 -> r1.3)
        nfs_srvsubs.c (r1.2 -> r1.3)
        nfs_syscalls.c (r1.1.1.1 -> r1.2)
        nfsm_subs.h (r1.1.1.1 -> r1.2)
        nfsrvcache.h (r1.1.1.1 -> r1.2)
    src/sys/pccard:
        cardinfo.h (r1.1.1.1 -> r1.2)
    src/sys/sys:
        md5.h (r1.3 -> r1.4)

Removed Files:
-------------
    src/sys/netkey:
        key.c
        key.h
        key_debug.c
        key_debug.h
        key_var.h
        keydb.c
        keydb.h
        keysock.c
        keysock.h
    src/sys/pccard:
        driver.h
        i82365.h
        meciareg.h
        pccard_nbk.h
        pcic_pci.h
        pcicvar.h
        slot.h

-------------- next part --------------
Index: nfsproto.h
===================================================================
RCS file: /home/cvs/src/sys/nfs/nfsproto.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/nfs/nfsproto.h -L sys/nfs/nfsproto.h -u -r1.1.1.1 -r1.2
--- sys/nfs/nfsproto.h
+++ sys/nfs/nfsproto.h
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsproto.h  8.2 (Berkeley) 3/30/95
- * $FreeBSD: src/sys/nfs/nfsproto.h,v 1.11 2005/01/07 01:45:50 imp Exp $
+ * $FreeBSD: src/sys/nfs/nfsproto.h,v 1.12 2006/11/28 19:33:28 rees Exp $
  */
 
 #ifndef _NFS_NFSPROTO_H_
@@ -508,6 +508,7 @@
 	uint32_t	fa4_rdev_major;
 	uint32_t	fa4_rdev_minor;
 	struct timespec	fa4_atime;
+	struct timespec	fa4_btime;
 	struct timespec	fa4_ctime;
 	struct timespec	fa4_mtime;
 	uint64_t	fa4_maxread;
@@ -533,21 +534,22 @@
 #define FA4V_GID	0x00000040
 #define FA4V_RDEV	0x00000080
 #define FA4V_ATIME	0x00000100
-#define FA4V_CTIME	0x00000200
-#define FA4V_MTIME	0x00000400
-#define FA4V_MAXREAD	0x00000800
-#define FA4V_MAXWRITE	0x00001000
-#define FA4V_TYPE	0x00002000
-#define FA4V_FFREE	0x00004000
-#define FA4V_FTOTAL	0x00008000
-#define FA4V_MAXNAME	0x00010000
-#define FA4V_SAVAIL	0x00020000
-#define FA4V_SFREE	0x00040000
-#define FA4V_STOTAL	0x00080000
-#define FA4V_CHANGEID	0x00100000
-#define FA4V_LEASE_TIME	0x00200000
-#define FA4V_MAXFILESIZE 0x00400000
-#define FA4V_ACL	0x00800000
+#define FA4V_BTIME	0x00000200
+#define FA4V_CTIME	0x00000400
+#define FA4V_MTIME	0x00000800
+#define FA4V_MAXREAD	0x00001000
+#define FA4V_MAXWRITE	0x00002000
+#define FA4V_TYPE	0x00004000
+#define FA4V_FFREE	0x00008000
+#define FA4V_FTOTAL	0x00010000
+#define FA4V_MAXNAME	0x00020000
+#define FA4V_SAVAIL	0x00040000
+#define FA4V_SFREE	0x00080000
+#define FA4V_STOTAL	0x00100000
+#define FA4V_CHANGEID	0x00200000
+#define FA4V_LEASE_TIME	0x00400000
+#define FA4V_MAXFILESIZE 0x00800000
+#define FA4V_ACL	0x01000000
 
 /* Offsets into bitmask */
 #define FA4_SUPPORTED_ATTRS	0
Index: nfs_common.h
===================================================================
RCS file: /home/cvs/src/sys/nfs/nfs_common.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/nfs/nfs_common.h -L sys/nfs/nfs_common.h -u -r1.1.1.1 -r1.2
--- sys/nfs/nfs_common.h
+++ sys/nfs/nfs_common.h
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsm_subs.h	8.2 (Berkeley) 3/30/95
- * $FreeBSD: src/sys/nfs/nfs_common.h,v 1.37.2.1 2005/10/09 03:21:56 delphij Exp $
+ * $FreeBSD: src/sys/nfs/nfs_common.h,v 1.38 2005/07/14 20:08:26 ps Exp $
  */
 
 
Index: nfs_common.c
===================================================================
RCS file: /home/cvs/src/sys/nfs/nfs_common.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/nfs/nfs_common.c -L sys/nfs/nfs_common.c -u -r1.1.1.1 -r1.2
--- sys/nfs/nfs_common.c
+++ sys/nfs/nfs_common.c
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfs/nfs_common.c,v 1.117.2.1 2005/10/09 03:21:56 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/nfs/nfs_common.c,v 1.118 2005/07/14 20:08:26 ps Exp $");
 
 /*
  * These functions support the macros and help fiddle mbuf chains for
Index: ncp_rq.c
===================================================================
RCS file: /home/cvs/src/sys/netncp/ncp_rq.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netncp/ncp_rq.c -L sys/netncp/ncp_rq.c -u -r1.1.1.1 -r1.2
--- sys/netncp/ncp_rq.c
+++ sys/netncp/ncp_rq.c
@@ -33,7 +33,7 @@
  */ 
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netncp/ncp_rq.c,v 1.14 2005/01/07 01:45:49 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netncp/ncp_rq.c,v 1.15 2005/07/29 13:22:37 imura Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -151,8 +151,18 @@
  */
 
 static int
-ncp_rq_pathstrhelp(struct mbchain *mbp, c_caddr_t src, caddr_t dst, size_t len)
+ncp_rq_pathstrhelp(struct mbchain *mbp, c_caddr_t src, caddr_t dst,
+    size_t *srclen, size_t *dstlen)
 {
+	int len;
+
+	if (*srclen < *dstlen) {
+		*dstlen = *srclen;
+		len = (int)*srclen;
+	} else {
+		*srclen = *dstlen;
+		len = (int)*dstlen;
+	}
 	ncp_pathcopy(src, dst, len, mbp->mb_udata);
 	return 0;
 }
Index: ncp_subr.h
===================================================================
RCS file: /home/cvs/src/sys/netncp/ncp_subr.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netncp/ncp_subr.h -L sys/netncp/ncp_subr.h -u -r1.1.1.1 -r1.2
--- sys/netncp/ncp_subr.h
+++ sys/netncp/ncp_subr.h
@@ -29,7 +29,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/netncp/ncp_subr.h,v 1.9 2005/01/07 01:45:49 imp Exp $
+ * $FreeBSD: src/sys/netncp/ncp_subr.h,v 1.10 2006/11/06 13:42:06 rwatson Exp $
  */
 #ifndef _NETNCP_NCP_SUBR_H_
 #define _NETNCP_NCP_SUBR_H_
@@ -84,7 +84,7 @@
 
 #define checkbad(fn) {error=(fn);if(error) goto bad;}
 
-#define	ncp_suser(cred)	suser_cred(cred, 0)
+#define	ncp_suser(cred)	priv_check_cred(cred, PRIV_NETNCP, 0)
 
 #define ncp_isowner(conn,cred) ((cred)->cr_uid == (conn)->nc_owner->cr_uid)
 
Index: ncp_mod.c
===================================================================
RCS file: /home/cvs/src/sys/netncp/ncp_mod.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netncp/ncp_mod.c -L sys/netncp/ncp_mod.c -u -r1.1.1.1 -r1.2
--- sys/netncp/ncp_mod.c
+++ sys/netncp/ncp_mod.c
@@ -32,11 +32,12 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netncp/ncp_mod.c,v 1.15 2005/01/07 01:45:48 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netncp/ncp_mod.c,v 1.16 2006/11/06 13:42:06 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/conf.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/kernel.h>
 #include <sys/module.h>
Index: ncp_sock.c
===================================================================
RCS file: /home/cvs/src/sys/netncp/ncp_sock.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netncp/ncp_sock.c -L sys/netncp/ncp_sock.c -u -r1.1.1.1 -r1.2
--- sys/netncp/ncp_sock.c
+++ sys/netncp/ncp_sock.c
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netncp/ncp_sock.c,v 1.15 2005/01/07 01:45:49 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netncp/ncp_sock.c,v 1.19 2007/06/05 00:00:55 jeff Exp $");
 
 #include <sys/param.h>
 #include <sys/errno.h>
@@ -139,10 +139,9 @@
 	auio.uio_td = td;
 	flags = MSG_DONTWAIT;
 
-/*	error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, &auio,
-	    (struct mbuf **)0, (struct mbuf **)0, &flags);*/
-	error = so->so_proto->pr_usrreqs->pru_soreceive(so, 0, &auio,
-	    mp, (struct mbuf **)0, &flags);
+/*	error = soreceive(so, 0, &auio, (struct mbuf **)0, (struct mbuf **)0,
+	    &flags);*/
+	error = soreceive(so, 0, &auio, mp, (struct mbuf **)0, &flags);
 	*rlen = len - auio.uio_resid;
 /*	if (!error) {
 	    *rlen=iov.iov_len;
@@ -163,17 +162,16 @@
 	struct ncp_conn *conn = rqp->nr_conn;
 	struct mbuf *m;
 	int error, flags=0;
-	int sendwait;
 
 	for (;;) {
 		m = m_copym(top, 0, M_COPYALL, M_TRYWAIT);
 /*		NCPDDEBUG(m);*/
-		error = so->so_proto->pr_usrreqs->pru_sosend(so, to, 0, m, 0, flags, td);
+		error = sosend(so, to, 0, m, 0, flags, td);
 		if (error == 0 || error == EINTR || error == ENETDOWN)
 			break;
 		if (rqp->rexmit == 0) break;
 		rqp->rexmit--;
-		tsleep(&sendwait, PWAIT, "ncprsn", conn->li.timeout * hz);
+		pause("ncprsn", conn->li.timeout * hz);
 		error = ncp_chkintr(conn, td);
 		if (error == EINTR) break;
 	}
@@ -186,10 +184,28 @@
 int
 ncp_poll(struct socket *so, int events)
 {
-    struct thread *td = curthread;
-    struct ucred *cred = NULL;
+	struct thread *td = curthread;
+	int revents;
 
-    return so->so_proto->pr_usrreqs->pru_sopoll(so, events, cred, td);
+	/* Fake up enough state to look like we are in poll(2). */
+	mtx_lock(&sellock);
+	thread_lock(td);
+	td->td_flags |= TDF_SELECT;
+	thread_unlock(td);
+	mtx_unlock(&sellock);
+	TAILQ_INIT(&td->td_selq);
+
+	revents = sopoll(so, events, NULL, td);
+
+	/* Tear down the fake poll(2) state. */
+	mtx_lock(&sellock);
+	clear_selinfo_list(td);
+	thread_lock(td);
+	td->td_flags &= ~TDF_SELECT;
+	thread_unlock(td);
+	mtx_unlock(&sellock);
+
+	return (revents);
 }
 
 int
@@ -197,7 +213,7 @@
 		 int events)
 {
 	struct timeval atv, rtv, ttv;
-	int ncoll, timo, error = 0;
+	int ncoll, timo, error, revents;
 
 	if (tv) {
 		atv = *tv;
@@ -213,22 +229,24 @@
 
 retry:
 	ncoll = nselcoll;
-	mtx_lock_spin(&sched_lock);
+	thread_lock(td);
 	td->td_flags |= TDF_SELECT;
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(td);
 	mtx_unlock(&sellock);
 
 	TAILQ_INIT(&td->td_selq);
-	error = ncp_poll(so, events);
+	revents = sopoll(so, events, NULL, td);
 	mtx_lock(&sellock);
-	if (error) {
+	if (revents) {
 		error = 0;
 		goto done;
 	}
 	if (tv) {
 		getmicrouptime(&rtv);
-		if (timevalcmp(&rtv, &atv, >=))
+		if (timevalcmp(&rtv, &atv, >=)) {
+			error = EWOULDBLOCK;
 			goto done;
+		}
 		ttv = atv;
 		timevalsub(&ttv, &rtv);
 		timo = tvtohz(&ttv);
@@ -239,12 +257,12 @@
 	 * the process, test TDF_SELECT and rescan file descriptors if
 	 * necessary.
 	 */
-	mtx_lock_spin(&sched_lock);
+	thread_lock(td);
 	if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) {
-		mtx_unlock_spin(&sched_lock);
+		thread_unlock(td);
 		goto retry;
 	}
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(td);
 
 	if (timo > 0)
 		error = cv_timedwait(&selwait, &sellock, timo);
@@ -256,9 +274,9 @@
 done:
 	clear_selinfo_list(td);
 
-	mtx_lock_spin(&sched_lock);
+	thread_lock(td);
 	td->td_flags &= ~TDF_SELECT;
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(td);
 	mtx_unlock(&sellock);
 
 done_noproclock:
@@ -443,8 +461,8 @@
 		auio.uio_resid = len = 1000000;
 		auio.uio_td = curthread;
 		flags = MSG_DONTWAIT;
-		error = so->so_proto->pr_usrreqs->pru_soreceive(so,
-		    (struct sockaddr**)&sa, &auio, &m, (struct mbuf**)0, &flags);
+		error = soreceive(so, (struct sockaddr**)&sa, &auio, &m,
+		    (struct mbuf**)0, &flags);
 		if (error) break;
 		len -= auio.uio_resid;
 		NCPSDEBUG("got watch dog %d\n",len);
@@ -452,7 +470,7 @@
 		buf = mtod(m, char*);
 		if (buf[1] != '?') break;
 		buf[1] = 'Y';
-		error = so->so_proto->pr_usrreqs->pru_sosend(so, (struct sockaddr*)sa, 0, m, 0, 0, curthread);
+		error = sosend(so, (struct sockaddr*)sa, 0, m, 0, 0, curthread);
 		NCPSDEBUG("send watch dog %d\n",error);
 		break;
 	}
Index: ncp_conn.c
===================================================================
RCS file: /home/cvs/src/sys/netncp/ncp_conn.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/netncp/ncp_conn.c -L sys/netncp/ncp_conn.c -u -r1.1.1.2 -r1.2
--- sys/netncp/ncp_conn.c
+++ sys/netncp/ncp_conn.c
@@ -33,12 +33,13 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netncp/ncp_conn.c,v 1.26.2.1 2006/02/14 21:55:15 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netncp/ncp_conn.c,v 1.30 2007/05/27 17:14:33 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/lock.h>
 #include <sys/sysctl.h>
@@ -73,7 +74,7 @@
 SYSCTL_PROC(_net_ncp, OID_AUTO, conn_stat, CTLFLAG_RD|CTLTYPE_OPAQUE,
 	    NULL, 0, ncp_sysctl_connstat, "S,connstat", "Connections list");
 
-MALLOC_DEFINE(M_NCPDATA, "NCP data", "NCP private data");
+MALLOC_DEFINE(M_NCPDATA, "ncp_data", "NCP private data");
 
 int
 ncp_conn_init(void)
@@ -222,10 +223,10 @@
 
 	if (cap->saddr.sa_family != AF_INET && cap->saddr.sa_family != AF_IPX)
 		return EPROTONOSUPPORT;
-	isroot = ncp_suser(cred) == 0;
 	/*
-	 * Only root can change ownership
+	 * Only root can change ownership.
 	 */
+	isroot = ncp_suser(cred) == 0;
 	if (cap->owner != NCP_DEFAULT_OWNER && !isroot)
 		return EPERM;
 	if (cap->group != NCP_DEFAULT_GROUP &&
@@ -233,6 +234,7 @@
 		return EPERM;
 	if (cap->owner != NCP_DEFAULT_OWNER) {
 		owner = crget();
+		crcopy(owner, cred);
 		owner->cr_uid = cap->owner;
 	} else
 		owner = crhold(cred);
@@ -242,7 +244,7 @@
 	lockinit(&ncp->nc_lock, PZERO, "ncplck", 0, 0);
 	ncp_conn_cnt++;
 	ncp->nc_id = ncp_next_ref++;
-	ncp->nc_owner = cred;
+	ncp->nc_owner = owner;
 	ncp->seq = 0;
 	ncp->connid = 0xFFFF;
 	ncp->li = *cap;
Index: ipatm_event.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/ipatm/ipatm_event.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/ipatm/ipatm_event.c -L sys/netatm/ipatm/ipatm_event.c -u -r1.1.1.1 -r1.2
--- sys/netatm/ipatm/ipatm_event.c
+++ sys/netatm/ipatm/ipatm_event.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/ipatm/ipatm_event.c,v 1.10 2005/01/07 01:45:37 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/ipatm/ipatm_event.c,v 1.11 2007/06/23 00:02:19 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -82,7 +82,7 @@
 	 * Back-off to ipvcc control block
 	 */
 	ivp = (struct ipvcc *)
-			((caddr_t)tip - (int)(&((struct ipvcc *)0)->iv_time));
+		((caddr_t)tip - offsetof(struct ipvcc, iv_time));
 
 	/*
 	 * Process timeout based on protocol state
Index: ipatm_vcm.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/ipatm/ipatm_vcm.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/ipatm/ipatm_vcm.c -L sys/netatm/ipatm/ipatm_vcm.c -u -r1.1.1.1 -r1.2
--- sys/netatm/ipatm/ipatm_vcm.c
+++ sys/netatm/ipatm/ipatm_vcm.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/ipatm/ipatm_vcm.c,v 1.19 2005/06/10 16:49:20 brooks Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/ipatm/ipatm_vcm.c,v 1.20 2006/01/22 01:07:11 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -341,9 +341,7 @@
  *
  */
 int
-ipatm_openpvc(pvp, sivp)
-	struct ipatmpvc	*pvp;
-	struct ipvcc	**sivp;
+ipatm_openpvc(struct ipatmpvc *pvp, struct ipvcc **sivp)
 {
 	struct ipvcc	*ivp = NULL;	/* XXX pacify gcc-3.1 */
 	Atm_attributes	*ap;
@@ -600,11 +598,8 @@
  *
  */
 int
-ipatm_createsvc(ifp, daf, dst, sivp)
-	struct ifnet		*ifp;
-	u_short			daf;
-	caddr_t			dst;
-	struct ipvcc		**sivp;
+ipatm_createsvc(struct ifnet *ifp, u_short daf, caddr_t dst,
+    struct ipvcc **sivp)
 {
 	struct atm_nif	*nip = IFP2ANIF(ifp);
 	struct ip_nif	*inp;
@@ -779,8 +774,7 @@
  *
  */
 int
-ipatm_opensvc(ivp)
-	struct ipvcc	*ivp;
+ipatm_opensvc(struct ipvcc *ivp)
 {
 	struct ip_nif	*inp = ivp->iv_ipnif;
 	Atm_attributes	*ap;
@@ -865,8 +859,7 @@
  *
  */
 int
-ipatm_retrysvc(ivp)
-	struct ipvcc	*ivp;
+ipatm_retrysvc(struct ipvcc *ivp)
 {
 	struct ip_nif	*inp = ivp->iv_ipnif;
 
@@ -895,8 +888,7 @@
  *
  */
 void
-ipatm_activate(ivp)
-	struct ipvcc	*ivp;
+ipatm_activate(struct ipvcc *ivp)
 {
 
 	/*
@@ -955,11 +947,8 @@
  *
  */
 int
-ipatm_incoming(tok, cop, ap, tokp)
-	void		*tok;
-	Atm_connection	*cop;
-	Atm_attributes	*ap;
-	void		**tokp;
+ipatm_incoming(void *tok, Atm_connection *cop, Atm_attributes *ap,
+    void **tokp)
 {
 	struct atm_nif	*nip = ap->nif;
 	struct ip_nif	*inp;
@@ -1127,9 +1116,7 @@
  *
  */
 int
-ipatm_closevc(ivp, code)
-	struct ipvcc	*ivp;
-	int		code;
+ipatm_closevc(struct ipvcc *ivp, int code)
 {
 	struct ip_nif	*inp = ivp->iv_ipnif;
 	int	s, err;
@@ -1238,9 +1225,7 @@
  *
  */
 int
-ipatm_chknif(in, inp)
-	struct in_addr	in;
-	struct ip_nif	*inp;
+ipatm_chknif(struct in_addr in, struct ip_nif *inp)
 {
 	struct in_ifaddr	*ia;
 	u_long	i;
@@ -1296,9 +1281,7 @@
  *
  */
 struct ipvcc *
-ipatm_iptovc(dst, nip)
-	struct sockaddr_in	*dst;
-	struct atm_nif		*nip;
+ipatm_iptovc(struct sockaddr_in *dst, struct atm_nif *nip)
 {
 	struct ip_nif	*inp;
 	struct ipvcc	*ivp;
@@ -1344,4 +1327,3 @@
 
 	return (ivp);
 }
-
Index: ipatm_load.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/ipatm/ipatm_load.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/ipatm/ipatm_load.c -L sys/netatm/ipatm/ipatm_load.c -u -r1.1.1.1 -r1.2
--- sys/netatm/ipatm/ipatm_load.c
+++ sys/netatm/ipatm/ipatm_load.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/ipatm/ipatm_load.c,v 1.22 2005/06/10 16:49:20 brooks Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/ipatm/ipatm_load.c,v 1.23 2005/10/30 19:44:39 rwatson Exp $");
 
 #ifndef ATM_IP_MODULE
 #include "opt_atm.h"
@@ -524,7 +524,7 @@
 		 */
 		if ((err = atm_cm_listen(NULL, &ipatm_endpt,
 				(void *)(intptr_t)i, &ipatm_listeners[i].attr,
-				&ipatm_listeners[i].conn)) != 0)
+				&ipatm_listeners[i].conn, -1)) != 0)
 			goto done;
 	}
 
Index: ipatm_if.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/ipatm/ipatm_if.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/ipatm/ipatm_if.c -L sys/netatm/ipatm/ipatm_if.c -u -r1.1.1.1 -r1.2
--- sys/netatm/ipatm/ipatm_if.c
+++ sys/netatm/ipatm/ipatm_if.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/ipatm/ipatm_if.c,v 1.17 2005/01/07 01:45:37 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/ipatm/ipatm_if.c,v 1.18 2005/10/31 15:41:26 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -60,7 +60,7 @@
 #include <netatm/ipatm/ipatm_var.h>
 #include <netatm/ipatm/ipatm_serv.h>
 
-static MALLOC_DEFINE(M_IPATM_NIF, "ipatm nif", "IP/ATM network interfaces");
+static MALLOC_DEFINE(M_IPATM_NIF, "ipatm_nif", "IP/ATM network interfaces");
 
 /*
  * Local functions
Index: nfs4_vfsops.c
===================================================================
RCS file: /home/cvs/src/sys/nfs4client/nfs4_vfsops.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/nfs4client/nfs4_vfsops.c -L sys/nfs4client/nfs4_vfsops.c -u -r1.1.1.2 -r1.2
--- sys/nfs4client/nfs4_vfsops.c
+++ sys/nfs4client/nfs4_vfsops.c
@@ -1,4 +1,3 @@
-/* $FreeBSD: src/sys/nfs4client/nfs4_vfsops.c,v 1.20.2.3 2006/01/27 18:22:53 rees Exp $ */
 /* $Id: nfs_vfsops.c,v 1.38 2003/11/05 14:59:01 rees Exp $ */
 
 /*-
@@ -60,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfs4client/nfs4_vfsops.c,v 1.20.2.3 2006/01/27 18:22:53 rees Exp $");
+__FBSDID("$FreeBSD: src/sys/nfs4client/nfs4_vfsops.c,v 1.27 2007/01/25 14:18:40 bde Exp $");
 
 #include "opt_bootp.h"
 #include "opt_nfsroot.h"
@@ -115,33 +114,33 @@
 SYSCTL_STRUCT(_vfs_nfs4, NFS_NFSSTATS, nfsstats, CTLFLAG_RD,
 	&nfsstats, nfsstats, "S,nfsstats");
 
-static void	nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp);
+static void	nfs4_decode_args(struct nfsmount *nmp, struct nfs_args *argp);
 static void	nfs4_daemon(void *arg);
 static int	mountnfs(struct nfs_args *, struct mount *,
 		    struct sockaddr *, char *, struct vnode **,
 		    struct ucred *cred);
 static int	nfs4_do_setclientid(struct nfsmount *nmp, struct ucred *cred);
-static vfs_mount_t nfs_mount;
-static vfs_cmount_t nfs_cmount;
-static vfs_unmount_t nfs_unmount;
-static vfs_root_t nfs_root;
-static vfs_statfs_t nfs_statfs;
-static vfs_sync_t nfs_sync;
+static vfs_mount_t nfs4_mount;
+static vfs_cmount_t nfs4_cmount;
+static vfs_unmount_t nfs4_unmount;
+static vfs_root_t nfs4_root;
+static vfs_statfs_t nfs4_statfs;
+static vfs_sync_t nfs4_sync;
 
 /*
  * nfs vfs operations.
  */
-static struct vfsops nfs_vfsops = {
+static struct vfsops nfs4_vfsops = {
 	.vfs_init =		nfs4_init,
-	.vfs_mount =		nfs_mount,
-	.vfs_cmount =		nfs_cmount,
-	.vfs_root =		nfs_root,
-	.vfs_statfs =		nfs_statfs,
-	.vfs_sync =		nfs_sync,
+	.vfs_mount =		nfs4_mount,
+	.vfs_cmount =		nfs4_cmount,
+	.vfs_root =		nfs4_root,
+	.vfs_statfs =		nfs4_statfs,
+	.vfs_sync =		nfs4_sync,
 	.vfs_uninit =		nfs4_uninit,
-	.vfs_unmount =		nfs_unmount,
+	.vfs_unmount =		nfs4_unmount,
 };
-VFS_SET(nfs_vfsops, nfs4, VFCF_NETWORK);
+VFS_SET(nfs4_vfsops, nfs4, VFCF_NETWORK);
 
 static struct nfs_rpcops nfs4_rpcops = {
 	nfs4_readrpc,
@@ -184,7 +183,7 @@
  * nfs statfs call
  */
 static int
-nfs_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
+nfs4_statfs(struct mount *mp, struct statfs *sbp, struct thread *td)
 {
 	struct vnode *vp;
 	struct nfs_statfs *sfp;
@@ -200,7 +199,7 @@
 #ifndef nolint
 	sfp = NULL;
 #endif
-	error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np);
+	error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np, LK_EXCLUSIVE);
 	if (error)
 		return (error);
 	vp = NFSTOV(np);
@@ -238,19 +237,25 @@
 }
 
 static void
-nfs_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
+nfs4_decode_args(struct nfsmount *nmp, struct nfs_args *argp)
 {
 	int s;
 	int adjsock;
 	int maxio;
 
 	s = splnet();
+
 	/*
 	 * Silently clear NFSMNT_NOCONN if it's a TCP mount, it makes
-	 * no sense in that context.
+	 * no sense in that context.  Also, set appropriate retransmit
+	 * and soft timeout behavior.
 	 */
-	if (argp->sotype == SOCK_STREAM)
+	if (argp->sotype == SOCK_STREAM) {
 		nmp->nm_flag &= ~NFSMNT_NOCONN;
+		nmp->nm_flag |= NFSMNT_DUMBTIMR;
+		nmp->nm_timeo = NFS_MAXTIMEO;
+		nmp->nm_retry = NFS_RETRANS_TCP;
+	}
 
 	nmp->nm_flag &= ~NFSMNT_RDIRPLUS;
 
@@ -368,9 +373,8 @@
 		nfs_safedisconnect(nmp);
 		if (nmp->nm_sotype == SOCK_DGRAM) {
 			while (nfs4_connect(nmp)) {
-				printf("nfs_args: retrying connect\n");
-				(void) tsleep((caddr_t)&lbolt,
-					      PSOCK, "nfscon", 0);
+				printf("nfs4_decode_args: retrying connect\n");
+				(void)tsleep(&lbolt, PSOCK, "nfscon", 0);
 			}
 		}
 	}
@@ -387,24 +391,21 @@
  */
 /* ARGSUSED */
 static int
-nfs_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
+nfs4_cmount(struct mntarg *ma, void *data, int flags, struct thread *td)
 {
 	struct nfs_args args;
 	int error;
 
-	error = copyin(data, (caddr_t)&args, sizeof (struct nfs_args));
+	error = copyin(data, &args, sizeof(struct nfs_args));
 	if (error)
 		return (error);
-
 	ma = mount_arg(ma, "nfs_args", &args, sizeof args);
-
 	error = kernel_mount(ma, flags);
-
-	 return (error);
+	return (error);
 }
 
 static int
-nfs_mount(struct mount *mp, struct thread *td)
+nfs4_mount(struct mount *mp, struct thread *td)
 {
 	int error;
 	struct nfs_args args;
@@ -414,8 +415,8 @@
 	size_t len;
 
 	if (mp->mnt_flag & MNT_ROOTFS) {
-		printf("NFSv4: nfs_mountroot not supported\n");
-		return EINVAL;
+		printf("nfs4_mountroot not supported\n");
+		return (EINVAL);
 	}
 	error = vfs_copyopt(mp->mnt_optnew, "nfs_args", &args, sizeof args);
 	if (error)
@@ -436,7 +437,7 @@
 		    ~(NFSMNT_NFSV3 | NFSMNT_NFSV4 | NFSMNT_NOLOCKD)) |
 		    (nmp->nm_flag &
 			(NFSMNT_NFSV3 | NFSMNT_NFSV4 | NFSMNT_NOLOCKD));
-		nfs_decode_args(nmp, &args);
+		nfs4_decode_args(nmp, &args);
 		return (0);
 	}
 
@@ -563,6 +564,8 @@
 
 	vfs_getnewfsid(mp);
 	nmp->nm_mountp = mp;
+	mtx_init(&nmp->nm_mtx, "NFS4mount lock", NULL, MTX_DEF);			
+
 	nmp->nm_maxfilesize = 0xffffffffLL;
 	nmp->nm_timeo = NFS_TIMEO;
 	nmp->nm_retry = NFS_RETRANS;
@@ -583,7 +586,7 @@
 
 	argp->flags |= (NFSMNT_NFSV3 | NFSMNT_NFSV4);
 
-	nfs_decode_args(nmp, argp);
+	nfs4_decode_args(nmp, argp);
 
 	if ((error = nfs4_connect(nmp)))
 		goto bad;
@@ -652,6 +655,7 @@
 	if (mrep != NULL)
 		m_freem(mrep);
 bad:
+	mtx_destroy(&nmp->nm_mtx);
 	nfs4_disconnect(nmp);
 	uma_zfree(nfsmount_zone, nmp);
 	FREE(nam, M_SONAME);
@@ -663,7 +667,7 @@
  * unmount system call
  */
 static int
-nfs_unmount(struct mount *mp, int mntflags, struct thread *td)
+nfs4_unmount(struct mount *mp, int mntflags, struct thread *td)
 {
 	struct nfsmount *nmp;
 	int error, flags = 0;
@@ -698,6 +702,7 @@
 	/* XXX there's a race condition here for SMP */
 	wakeup(&nfs4_daemonproc);
 
+	mtx_destroy(&nmp->nm_mtx);
 	uma_zfree(nfsmount_zone, nmp);
 	return (0);
 }
@@ -706,7 +711,7 @@
  * Return root of a filesystem
  */
 static int
-nfs_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
+nfs4_root(struct mount *mp, int flags, struct vnode **vpp, struct thread *td)
 {
 	struct vnode *vp;
 	struct nfsmount *nmp;
@@ -714,7 +719,8 @@
 	int error;
 
 	nmp = VFSTONFS(mp);
-	error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np);
+	error = nfs_nget(mp, (nfsfh_t *)nmp->nm_fh, nmp->nm_fhsize, &np,
+	    LK_EXCLUSIVE);
 	if (error)
 		return (error);
 	vp = NFSTOV(np);
@@ -729,9 +735,8 @@
 /*
  * Flush out the buffer cache
  */
-/* ARGSUSED */
 static int
-nfs_sync(struct mount *mp, int waitfor, struct thread *td)
+nfs4_sync(struct mount *mp, int waitfor, struct thread *td)
 {
 	struct vnode *vp, *mvp;
 	int error, allerror = 0;
Index: nfs4_vnops.c
===================================================================
RCS file: /home/cvs/src/sys/nfs4client/nfs4_vnops.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/nfs4client/nfs4_vnops.c -L sys/nfs4client/nfs4_vnops.c -u -r1.1.1.2 -r1.2
--- sys/nfs4client/nfs4_vnops.c
+++ sys/nfs4client/nfs4_vnops.c
@@ -1,4 +1,3 @@
-/* $FreeBSD: src/sys/nfs4client/nfs4_vnops.c,v 1.31 2005/04/25 05:11:19 jeff Exp $ */
 /* $Id: nfs_vnops.c,v 1.45 2003/11/05 14:59:02 rees Exp $ */
 
 /*-
@@ -60,7 +59,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfs4client/nfs4_vnops.c,v 1.31 2005/04/25 05:11:19 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/nfs4client/nfs4_vnops.c,v 1.37 2007/06/01 01:12:44 jeff Exp $");
 
 /*
  * vnode op calls for Sun NFS version 2 and 3
@@ -220,14 +219,15 @@
 
 SYSCTL_DECL(_vfs_nfs4);
 
-static int	nfsaccess_cache_timeout = NFS_MAXATTRTIMO;
+static int	nfs4_access_cache_timeout = NFS_MAXATTRTIMO;
 SYSCTL_INT(_vfs_nfs4, OID_AUTO, access_cache_timeout, CTLFLAG_RW,
-	   &nfsaccess_cache_timeout, 0, "NFS ACCESS cache timeout");
+	   &nfs4_access_cache_timeout, 0, "NFS ACCESS cache timeout");
 
+#if 0
 static int	nfsv3_commit_on_close = 0;
 SYSCTL_INT(_vfs_nfs4, OID_AUTO, nfsv3_commit_on_close, CTLFLAG_RW,
 	   &nfsv3_commit_on_close, 0, "write+commit on close, else only write");
-#if 0
+
 SYSCTL_INT(_vfs_nfs4, OID_AUTO, access_cache_hits, CTLFLAG_RD,
 	   &nfsstats.accesscache_hits, 0, "NFS ACCESS cache hit count");
 
@@ -239,7 +239,7 @@
 			 | NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE	\
 			 | NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP)
 static int
-nfs3_access_otw(struct vnode *vp, int wmode, struct thread *td,
+nfs4_v3_access_otw(struct vnode *vp, int wmode, struct thread *td,
     struct ucred *cred)
 {
 	const int v3 = 1;
@@ -337,7 +337,7 @@
 				mode |= NFSV3ACCESS_LOOKUP;
 		}
 		/* XXX safety belt, only make blanket request if caching */
-		if (nfsaccess_cache_timeout > 0) {
+		if (nfs4_access_cache_timeout > 0) {
 			wmode = NFSV3ACCESS_READ | NFSV3ACCESS_MODIFY |
 			    NFSV3ACCESS_EXTEND | NFSV3ACCESS_EXECUTE |
 			    NFSV3ACCESS_DELETE | NFSV3ACCESS_LOOKUP;
@@ -349,20 +349,20 @@
 		 * Does our cached result allow us to give a definite yes to
 		 * this request?
 		 */
-		if ((time_second < (np->n_modestamp + nfsaccess_cache_timeout)) &&
-		    (ap->a_cred->cr_uid == np->n_modeuid) &&
-		    ((np->n_mode & mode) == mode)) {
+		if (time_second < np->n_modestamp + nfs4_access_cache_timeout &&
+		    ap->a_cred->cr_uid == np->n_modeuid &&
+		    (np->n_mode & mode) == mode) {
 			nfsstats.accesscache_hits++;
 		} else {
 			/*
 			 * Either a no, or a don't know.  Go to the wire.
 			 */
 			nfsstats.accesscache_misses++;
-		        error = nfs3_access_otw(vp, wmode, ap->a_td,ap->a_cred);
-			if (!error) {
-				if ((np->n_mode & mode) != mode) {
+		        error = nfs4_v3_access_otw(vp, wmode, ap->a_td,
+			    ap->a_cred);
+			if (error == 0) {
+				if ((np->n_mode & mode) != mode)
 					error = EACCES;
-				}
 			}
 		}
 		return (error);
@@ -497,7 +497,7 @@
 	if (vp == NULL) {
 		/* New file */
 		error = nfs_nget(dvp->v_mount, &getfh.fh_val,
-		    getfh.fh_len, &np);
+				 getfh.fh_len, &np, LK_EXCLUSIVE);
 		if (error != 0)
 			goto nfsmout;
 
@@ -1031,7 +1031,7 @@
 		if (NFS_CMPFH(np, fhp, fhsize))
 			return (EISDIR);
 
-		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
+		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
 		if (error)
 			return (error);
 
@@ -1047,7 +1047,7 @@
 	if (flags & ISDOTDOT) {
 		VOP_UNLOCK(dvp, 0, td);
 
-		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
+		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
 		vn_lock(dvp, LK_EXCLUSIVE | LK_RETRY, td);
 		if (error)
 			return (error);
@@ -1058,7 +1058,7 @@
 		VREF(dvp);
 		newvp = dvp;
 	} else {
-		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np);
+		error = nfs_nget(dvp->v_mount, fhp, fhsize, &np, LK_EXCLUSIVE);
 		if (error)
 			return (error);
 		newvp = NFSTOV(np);
@@ -1431,7 +1431,7 @@
 	nfsm_v4dissect_getattr(&cp, &ga);
 	nfsm_v4dissect_getfh(&cp, &gfh);	
 	
-	error = nfs_nget(dvp->v_mount, &gfh.fh_val, gfh.fh_len, &np);
+	error = nfs_nget(dvp->v_mount, &gfh.fh_val, gfh.fh_len, &np, LK_EXCLUSIVE);
 	if (error != 0)
 		goto nfsmout;
 
@@ -1924,7 +1924,7 @@
 	if (np->n_direofoffset > 0 && uio->uio_offset >= np->n_direofoffset &&
 	    (np->n_flag & NMODIFIED) == 0) {
 		if (VOP_GETATTR(vp, &vattr, ap->a_cred, uio->uio_td) == 0 &&
-			np->n_mtime.tv_sec == vattr.va_mtime.tv_sec) {
+			!NFS_TIMESPEC_COMPARE(&np->n_mtime, &vattr.va_mtime)) {
 			nfsstats.direofcache_hits++;
 			return (0);
 		}
@@ -2336,7 +2336,7 @@
 			VREF(dvp);
 			newvp = dvp;
 		} else {
-			error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np);
+			error = nfs_nget(dvp->v_mount, nfhp, fhlen, &np, LK_EXCLUSIVE);
 			if (error) {
 				m_freem(mrep);
 				return (error);
@@ -2444,17 +2444,11 @@
 {
 	struct buf *bp = ap->a_bp;
 	struct ucred *cr;
-	struct thread *td;
 	int error = 0;
 
 	KASSERT(!(bp->b_flags & B_DONE), ("nfs4_strategy: buffer %p unexpectedly marked B_DONE", bp));
 	KASSERT(BUF_REFCNT(bp) > 0, ("nfs4_strategy: buffer %p not locked", bp));
 
-	if (bp->b_flags & B_ASYNC)
-		td = NULL;
-	else
-		td = curthread;	/* XXX */
-
 	if (bp->b_iocmd == BIO_READ)
 		cr = bp->b_rcred;
 	else
@@ -2466,8 +2460,8 @@
 	 * otherwise just do it ourselves.
 	 */
 	if ((bp->b_flags & B_ASYNC) == 0 ||
-		nfs_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, td))
-		error = nfs_doio(ap->a_vp, bp, cr, td);
+		nfs_asyncio(VFSTONFS(ap->a_vp->v_mount), bp, NOCRED, curthread))
+		error = nfs_doio(ap->a_vp, bp, cr, curthread);
 	return (error);
 }
 
@@ -2834,7 +2828,7 @@
 	bp->b_iocmd = BIO_WRITE;
 
 	bufobj_wref(bp->b_bufobj);
-	curthread->td_proc->p_stats->p_ru.ru_oublock++;
+	curthread->td_ru.ru_oublock++;
 	splx(s);
 
 	/*
@@ -2880,4 +2874,5 @@
 	.bop_write	=	nfs4_bwrite,
 	.bop_strategy	=	bufstrategy,
 	.bop_sync	=	bufsync,
+	.bop_bdflush	=	bufbdflush,
 };
Index: nfs4_vn_subs.c
===================================================================
RCS file: /home/cvs/src/sys/nfs4client/nfs4_vn_subs.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/nfs4client/nfs4_vn_subs.c -L sys/nfs4client/nfs4_vn_subs.c -u -r1.1.1.2 -r1.2
--- sys/nfs4client/nfs4_vn_subs.c
+++ sys/nfs4client/nfs4_vn_subs.c
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/nfs4client/nfs4_vn_subs.c,v 1.4 2005/01/07 01:45:50 imp Exp $ */
+/* $FreeBSD: src/sys/nfs4client/nfs4_vn_subs.c,v 1.5 2006/11/28 19:33:28 rees Exp $ */
 /* $Id: nfs4_vn_subs.c,v 1.9 2003/11/05 14:59:00 rees Exp $ */
 
 /*-
@@ -121,6 +121,8 @@
                 vap->va_fileid = nfs_v4fileid4_to_fileid(fap->fa4_fileid);
         if (fap->fa4_valid & FA4V_ATIME)
                 vap->va_atime = fap->fa4_atime;
+        if (fap->fa4_valid & FA4V_BTIME)
+                vap->va_birthtime = fap->fa4_btime;
         if (fap->fa4_valid & FA4V_CTIME)
                 vap->va_ctime = fap->fa4_ctime;
         vap->va_flags = 0;
Index: nfs4_subs.c
===================================================================
RCS file: /home/cvs/src/sys/nfs4client/nfs4_subs.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/nfs4client/nfs4_subs.c -L sys/nfs4client/nfs4_subs.c -u -r1.1.1.2 -r1.2
--- sys/nfs4client/nfs4_subs.c
+++ sys/nfs4client/nfs4_subs.c
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/nfs4client/nfs4_subs.c,v 1.5 2005/01/07 01:45:50 imp Exp $ */
+/* $FreeBSD: src/sys/nfs4client/nfs4_subs.c,v 1.6 2006/11/28 19:33:28 rees Exp $ */
 /* $Id: nfs4_subs.c,v 1.52 2003/11/05 14:58:59 rees Exp $ */
 
 /*-
@@ -129,8 +129,10 @@
 	FA4_SET(FA4_OWNER, __getattr_bm);
 	FA4_SET(FA4_OWNER_GROUP, __getattr_bm);
 	FA4_SET(FA4_FILEID, __getattr_bm);
-	FA4_SET(FA4_TIME_MODIFY, __getattr_bm);
 	FA4_SET(FA4_TIME_ACCESS, __getattr_bm);
+	FA4_SET(FA4_TIME_CREATE, __getattr_bm);
+	FA4_SET(FA4_TIME_METADATA, __getattr_bm);
+	FA4_SET(FA4_TIME_MODIFY, __getattr_bm);
 
 	FA4_SET(FA4_TYPE, __readdir_bm);
 	FA4_SET(FA4_FSID, __readdir_bm);
@@ -1343,6 +1345,11 @@
 		len += 3 * NFSX_UNSIGNED;
 	}
 	if (FA4_ISSET(FA4_TIME_CREATE, bmval)) {
+		NFSM_MTOTIME(fa->fa4_btime);
+		fa->fa4_valid |= FA4V_BTIME;
+		len += 3 * NFSX_UNSIGNED;
+	}
+	if (FA4_ISSET(FA4_TIME_METADATA, bmval)) {
 		NFSM_MTOTIME(fa->fa4_ctime);
 		fa->fa4_valid |= FA4V_CTIME;
 		len += 3 * NFSX_UNSIGNED;
Index: nfs4_dev.c
===================================================================
RCS file: /home/cvs/src/sys/nfs4client/nfs4_dev.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/nfs4client/nfs4_dev.c -L sys/nfs4client/nfs4_dev.c -u -r1.1.1.2 -r1.2
--- sys/nfs4client/nfs4_dev.c
+++ sys/nfs4client/nfs4_dev.c
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/nfs4client/nfs4_dev.c,v 1.7 2005/01/07 01:45:50 imp Exp $ */
+/* $FreeBSD: src/sys/nfs4client/nfs4_dev.c,v 1.9 2006/05/13 00:16:35 cel Exp $ */
 /* $Id: nfs4_dev.c,v 1.10 2003/11/05 14:58:59 rees Exp $ */
 
 /*-
@@ -49,7 +49,7 @@
 #define NFS4DEV_NAME "nfs4"
 #define CDEV_MINOR 1
 
-MALLOC_DEFINE(M_NFS4DEV, "NFS4 dev", "NFS4 device");
+MALLOC_DEFINE(M_NFS4DEV, "nfs4_dev", "NFS4 device");
 
 struct nfs4dev_upcall {
   	/* request msg */
@@ -152,11 +152,12 @@
 		return EINVAL;
 	}
 
-	if (m->msg_len == 0 || m->msg_len > NFS4DEV_MSG_MAX_DATALEN) {
+	if (m->msg_len < sizeof(*m) - NFS4DEV_MSG_MAX_DATALEN ||
+		m->msg_len > NFS4DEV_MSG_MAX_DATALEN) {
 	  	NFS4DEV_DEBUG("bad message length\n");
 		return EINVAL;
 	}
-	  	
+
 	/* match the reply with a request */
 	mtx_lock(&nfs4dev_waitq_mtx);
 	TAILQ_FOREACH(u, &nfs4dev_waitq, up_entry) {
@@ -197,8 +198,10 @@
 
 	return 0;
 bad:
-	u->up_error = error;
-	wakeup(u);
+	if (u) {
+		u->up_error = error;
+		wakeup(u);
+	}
 	return error;
 }
 
Index: nfs4_vfs_subs.c
===================================================================
RCS file: /home/cvs/src/sys/nfs4client/nfs4_vfs_subs.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/nfs4client/nfs4_vfs_subs.c -L sys/nfs4client/nfs4_vfs_subs.c -u -r1.1.1.2 -r1.2
--- sys/nfs4client/nfs4_vfs_subs.c
+++ sys/nfs4client/nfs4_vfs_subs.c
@@ -1,4 +1,4 @@
-/* $FreeBSD: src/sys/nfs4client/nfs4_vfs_subs.c,v 1.4 2005/01/07 01:45:50 imp Exp $ */
+/* $FreeBSD: src/sys/nfs4client/nfs4_vfs_subs.c,v 1.5 2007/01/25 13:07:25 bde Exp $ */
 /* $Id: nfs4_vfs_subs.c,v 1.5 2003/11/05 14:59:00 rees Exp $ */
 
 /*-
@@ -65,24 +65,6 @@
 
 #include <nfsclient/nfsnode.h>
 
-static int	nfs_iosize(struct nfsmount *nmp);
-
-static int
-nfs_iosize(struct nfsmount *nmp)
-{
-	int iosize;
-
-	/*
-	 * Calculate the size used for io buffers.  Use the larger
-	 * of the two sizes to minimise nfs requests but make sure
-	 * that it is at least one VM page to avoid wasting buffer
-	 * space.
-	 */
-	iosize = max(nmp->nm_rsize, nmp->nm_wsize);
-	if (iosize < PAGE_SIZE) iosize = PAGE_SIZE;
-	return iosize;
-}
-
 void
 nfs4_vfsop_fsinfo(struct nfsv4_fattr *fap, struct nfsmount *nmp)
 {
Index: spans_proto.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/spans/spans_proto.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/spans/spans_proto.c -L sys/netatm/spans/spans_proto.c -u -r1.1.1.1 -r1.2
--- sys/netatm/spans/spans_proto.c
+++ sys/netatm/spans/spans_proto.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/spans/spans_proto.c,v 1.14 2005/01/07 01:45:38 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/spans/spans_proto.c,v 1.15 2007/06/23 00:02:19 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -214,7 +214,7 @@
 	 * Back-off to SPANS control block
 	 */
 	spp = (struct spans *)
-		((caddr_t)tip - (int)(&((struct spans *)0)->sp_time));
+		((caddr_t)tip - offsetof(struct spans, sp_time));
 
 	ATM_DEBUG2("spans_timer: spp=%p,state=%d\n",
 			spp, spp->sp_state);
@@ -363,8 +363,8 @@
 	/*
 	 * Get VCCB and SPANS control block addresses
 	 */
-	svp = (struct spans_vccb *) ((caddr_t)tip -
-			(int)(&((struct vccb *)0)->vc_time));
+	svp = (struct spans_vccb *)
+		((caddr_t)tip - offsetof(struct vccb, vc_time));
 	spp = (struct spans *)svp->sv_pif->pif_siginst;
 
 	ATM_DEBUG3("spans_vctimer: svp=%p, sstate=%d, ustate=%d\n",
Index: nfsm_subs.h
===================================================================
RCS file: /home/cvs/src/sys/nfsserver/nfsm_subs.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/nfsserver/nfsm_subs.h -L sys/nfsserver/nfsm_subs.h -u -r1.1.1.1 -r1.2
--- sys/nfsserver/nfsm_subs.h
+++ sys/nfsserver/nfsm_subs.h
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsm_subs.h	8.2 (Berkeley) 3/30/95
- * $FreeBSD: src/sys/nfsserver/nfsm_subs.h,v 1.37 2005/01/07 01:45:51 imp Exp $
+ * $FreeBSD: src/sys/nfsserver/nfsm_subs.h,v 1.39 2007/03/17 18:18:08 jeff Exp $
  */
 
 #ifndef _NFSSERVER_NFSM_SUBS_H_
@@ -74,6 +74,7 @@
 
 int	nfsm_srvstrsiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
 int	nfsm_srvnamesiz_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
+int	nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos);
 int	nfsm_srvmtofh_xx(fhandle_t *f, struct nfsrv_descript *nfsd,
 	    struct mbuf **md, caddr_t *dpos);
 int	nfsm_srvsattr_xx(struct vattr *a, struct mbuf **md, caddr_t *dpos);
@@ -101,7 +102,7 @@
 #define	nfsm_srvpathsiz(s) \
 do { \
 	int t1; \
-	t1 = nfsm_srvnamesiz_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
+	t1 = nfsm_srvnamesiz0_xx(&(s), NFS_MAXPATHLEN, &md, &dpos); \
 	if (t1) { \
 		error = t1; \
 		nfsm_reply(0); \
@@ -160,7 +161,7 @@
 	    caddr_t *bpos);
 void	nfsm_srvpostop_fh_xx(fhandle_t *f, struct mbuf **mb, caddr_t *bpos);
 void	nfsm_clget_xx(u_int32_t **tl, struct mbuf *mb, struct mbuf **mp,
-	    char **bp, char **be, caddr_t bpos, int droplock);
+	    char **bp, char **be, caddr_t bpos);
 
 #define nfsm_srvfhtom(f, v3) \
 	nfsm_srvfhtom_xx((f), (v3), &mb, &bpos)
@@ -178,9 +179,6 @@
 	nfsm_srvfattr(nfsd, (a), (f))
 
 #define nfsm_clget \
-	nfsm_clget_xx(&tl, mb, &mp, &bp, &be, bpos, 1)
-
-#define nfsm_clget_nolock \
-	nfsm_clget_xx(&tl, mb, &mp, &bp, &be, bpos, 0)
+	nfsm_clget_xx(&tl, mb, &mp, &bp, &be, bpos)
 
 #endif
Index: nfs.h
===================================================================
RCS file: /home/cvs/src/sys/nfsserver/nfs.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/nfsserver/nfs.h -L sys/nfsserver/nfs.h -u -r1.1.1.1 -r1.2
--- sys/nfsserver/nfs.h
+++ sys/nfsserver/nfs.h
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfs.h	8.4 (Berkeley) 5/1/95
- * $FreeBSD: src/sys/nfsserver/nfs.h,v 1.78 2005/04/17 16:25:36 rwatson Exp $
+ * $FreeBSD: src/sys/nfsserver/nfs.h,v 1.82.2.1 2007/11/25 19:15:53 rwatson Exp $
  */
 
 #ifndef _NFSSERVER_NFS_H_
@@ -258,7 +258,7 @@
 	u_int32_t		nd_retxid;	/* Reply xid */
 	struct timeval		nd_starttime;	/* Time RPC initiated */
 	fhandle_t		nd_fh;		/* File handle */
-	struct ucred		nd_cr;		/* Credentials */
+	struct ucred		*nd_cr;		/* Credentials */
 };
 
 /* Bits for "nd_flag" */
@@ -337,6 +337,7 @@
 void	nfsm_adj(struct mbuf *, int, int);
 int	nfsm_mbuftouio(struct mbuf **, struct uio *, int, caddr_t *);
 void	nfsrv_initcache(void);
+void	nfsrv_destroycache(void);
 void	nfsrv_timer(void *);
 int	nfsrv_dorec(struct nfssvc_sock *, struct nfsd *,
 	    struct nfsrv_descript **);
@@ -346,7 +347,6 @@
 void	nfsrv_init(int);
 int	nfsrv_errmap(struct nfsrv_descript *, int);
 void	nfsrvw_sort(gid_t *, int);
-void	nfsrv_setcred(struct ucred *, struct ucred *);
 void	nfsrv_wakenfsd(struct nfssvc_sock *slp);
 int	nfsrv_writegather(struct nfsrv_descript **, struct nfssvc_sock *,
 	    struct thread *, struct mbuf **);
@@ -357,7 +357,7 @@
 	    struct thread *td, struct mbuf **mrq);
 int	nfsrv_create(struct nfsrv_descript *nfsd, struct nfssvc_sock *slp,
 	    struct thread *td, struct mbuf **mrq);
-int	nfsrv_fhtovp(fhandle_t *, int, struct vnode **, struct ucred *,
+int	nfsrv_fhtovp(fhandle_t *, int, struct vnode **, int *, struct ucred *,
 	    struct nfssvc_sock *, struct sockaddr *, int *, int);
 int	nfsrv_setpublicfs(struct mount *, struct netexport *,
 	    struct export_args *);
Index: nfs_syscalls.c
===================================================================
RCS file: /home/cvs/src/sys/nfsserver/nfs_syscalls.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/nfsserver/nfs_syscalls.c -L sys/nfsserver/nfs_syscalls.c -u -r1.1.1.1 -r1.2
--- sys/nfsserver/nfs_syscalls.c
+++ sys/nfsserver/nfs_syscalls.c
@@ -33,10 +33,9 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_syscalls.c,v 1.103 2005/03/26 11:29:02 delphij Exp $");
+__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_syscalls.c,v 1.116.2.1 2007/10/12 03:59:18 mohans Exp $");
 
 #include "opt_inet6.h"
-#include "opt_mac.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -46,9 +45,9 @@
 #include <sys/file.h>
 #include <sys/filedesc.h>
 #include <sys/vnode.h>
-#include <sys/mac.h>
 #include <sys/malloc.h>
 #include <sys/mount.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/bio.h>
 #include <sys/buf.h>
@@ -74,11 +73,10 @@
 #include <nfsserver/nfsm_subs.h>
 #include <nfsserver/nfsrvcache.h>
 
-static MALLOC_DEFINE(M_NFSSVC, "NFS srvsock", "Nfs server structure");
-
-MALLOC_DEFINE(M_NFSRVDESC, "NFSV3 srvdesc", "NFS server socket descriptor");
-MALLOC_DEFINE(M_NFSD, "NFS daemon", "Nfs server daemon structure");
+static MALLOC_DEFINE(M_NFSSVC, "nfss_srvsock", "Nfs server structure");
 
+MALLOC_DEFINE(M_NFSRVDESC, "nfss_srvdesc", "NFS server socket descriptor");
+MALLOC_DEFINE(M_NFSD, "nfss_daemon", "Nfs server daemon structure");
 
 #define	TRUE	1
 #define	FALSE	0
@@ -102,6 +100,8 @@
 static void	nfsrv_zapsock(struct nfssvc_sock *slp);
 static int	nfssvc_nfsd(struct thread *);
 
+extern u_long sb_max_adj;
+
 /*
  * NFS server system calls
  */
@@ -123,9 +123,6 @@
 	caddr_t argp;
 };
 #endif
-/*
- * MPSAFE
- */
 int
 nfssvc(struct thread *td, struct nfssvc_args *uap)
 {
@@ -136,15 +133,9 @@
 
 	KASSERT(!mtx_owned(&Giant), ("nfssvc(): called with Giant"));
 
-#ifdef MAC
-	error = mac_check_system_nfsd(td->td_ucred);
-	if (error)
-		return (error);
-#endif
-	error = suser(td);
+	error = priv_check(td, PRIV_NFS_DAEMON);
 	if (error)
 		return (error);
-	NET_LOCK_GIANT();
 	NFSD_LOCK();
 	while (nfssvc_sockhead_flag & SLP_INIT) {
 		 nfssvc_sockhead_flag |= SLP_WANTINIT;
@@ -155,12 +146,12 @@
 	if (uap->flag & NFSSVC_ADDSOCK) {
 		error = copyin(uap->argp, (caddr_t)&nfsdarg, sizeof(nfsdarg));
 		if (error)
-			goto done2;
+			return (error);
 		if ((error = fget(td, nfsdarg.sock, &fp)) != 0)
-			goto done2;
+			return (error);
 		if (fp->f_type != DTYPE_SOCKET) {
 			fdrop(fp, td);
-			goto done2;
+			return (error);	/* XXXRW: Should be EINVAL? */
 		}
 		/*
 		 * Get the client address for connected sockets.
@@ -172,7 +163,7 @@
 					    nfsdarg.namelen);
 			if (error) {
 				fdrop(fp, td);
-				goto done2;
+				return (error);
 			}
 		}
 		error = nfssvc_addsock(fp, nam, td);
@@ -184,8 +175,6 @@
 	}
 	if (error == EINTR || error == ERESTART)
 		error = 0;
-done2:
-	NET_UNLOCK_GIANT();
 	return (error);
 }
 
@@ -200,8 +189,6 @@
 	struct socket *so;
 	int error, s;
 
-	NET_ASSERT_GIANT();
-
 	so = fp->f_data;
 #if 0
 	/*
@@ -221,10 +208,7 @@
 		}
 	}
 #endif
-	if (so->so_type == SOCK_STREAM)
-		siz = NFS_MAXPACKET + sizeof (u_long);
-	else
-		siz = NFS_MAXPACKET;
+	siz = sb_max_adj;
 	error = soreserve(so, siz, siz);
 	if (error) {
 		if (mynam != NULL)
@@ -315,8 +299,6 @@
 	int procrastinate;
 	u_quad_t cur_usec;
 
-	NET_ASSERT_GIANT();
-
 #ifndef nolint
 	cacherep = RC_DOIT;
 	writes_todo = 0;
@@ -390,6 +372,8 @@
 		}
 		if (error || (slp->ns_flag & SLP_VALID) == 0) {
 			if (nd) {
+				if (nd->nd_cr != NULL)
+					crfree(nd->nd_cr);
 				free((caddr_t)nd, M_NFSRVDESC);
 				nd = NULL;
 			}
@@ -426,27 +410,31 @@
 			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", \
+#ifdef INET6
+			    char b6[INET6_ADDRSTRLEN];
+#if defined(KLD_MODULE)
+	/* Do not use ip6_sprintf: the nfs module should work without INET6. */
+#define ip6_sprintf(buf, a) \
+	 (sprintf((buf), "%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)
+	 (buf))
+#endif
 #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) :
+				sin->sin_family == AF_INET6 ?
+				    ip6_sprintf(b6, &satosin6(sin)->sin6_addr) :
+#if defined(KLD_MODULE)
 #undef ip6_sprintf
 #endif
-				   inet_ntoa(sin->sin_addr), port);
+#endif
+				    inet_ntoa(sin->sin_addr), port);
 			}
 		    }
 
@@ -463,6 +451,7 @@
 			    procrastinate = nfsrvw_procrastinate_v3;
 			else
 			    procrastinate = nfsrvw_procrastinate;
+			NFSD_UNLOCK();
 			if (writes_todo || (!(nd->nd_flag & ND_NFSV3) &&
 			    nd->nd_procnum == NFSPROC_WRITE &&
 			    procrastinate > 0 && !notstarted))
@@ -471,6 +460,7 @@
 			else
 			    error = (*(nfsrv3_procs[nd->nd_procnum]))(nd,
 				slp, nfsd->nfsd_td, &mreq);
+			NFSD_LOCK();
 			if (mreq == NULL)
 				break;
 			if (error != 0 && error != NFSERR_RETVOID) {
@@ -522,6 +512,8 @@
 			if (slp->ns_so->so_proto->pr_flags & PR_CONNREQUIRED)
 				nfs_slpunlock(slp);
 			if (error == EINTR || error == ERESTART) {
+				if (nd->nd_cr != NULL)
+					crfree(nd->nd_cr);
 				free((caddr_t)nd, M_NFSRVDESC);
 				nfsrv_slpderef(slp);
 				s = splnet();
@@ -535,6 +527,8 @@
 			break;
 		    };
 		    if (nd) {
+			if (nd->nd_cr != NULL)
+				crfree(nd->nd_cr);
 			FREE((caddr_t)nd, M_NFSRVDESC);
 			nd = NULL;
 		    }
@@ -559,16 +553,10 @@
 			nfsd->nfsd_slp = NULL;
 			nfsrv_slpderef(slp);
 		}
-		KASSERT(!(debug_mpsafenet == 0 && !mtx_owned(&Giant)),
-		    ("nfssvc_nfsd(): debug.mpsafenet=0 && !Giant"));
-		KASSERT(!(debug_mpsafenet == 1 && mtx_owned(&Giant)),
-		    ("nfssvc_nfsd(): debug.mpsafenet=1 && Giant"));
+		mtx_assert(&Giant, MA_NOTOWNED);
 	}
 done:
-	KASSERT(!(debug_mpsafenet == 0 && !mtx_owned(&Giant)),
-	    ("nfssvc_nfsd(): debug.mpsafenet=0 && !Giant"));
-	KASSERT(!(debug_mpsafenet == 1 && mtx_owned(&Giant)),
-	    ("nfssvc_nfsd(): debug.mpsafenet=1 && Giant"));
+	mtx_assert(&Giant, MA_NOTOWNED);
 	TAILQ_REMOVE(&nfsd_head, nfsd, nfsd_chain);
 	splx(s);
 	free((caddr_t)nfsd, M_NFSD);
@@ -594,7 +582,6 @@
 	struct nfsrv_rec *rec;
 	int s;
 
-	NET_ASSERT_GIANT();
 	NFSD_LOCK_ASSERT();
 
 	/*
@@ -630,6 +617,8 @@
 		for (nwp = LIST_FIRST(&slp->ns_tq); nwp; nwp = nnwp) {
 			nnwp = LIST_NEXT(nwp, nd_tq);
 			LIST_REMOVE(nwp, nd_tq);
+			if (nwp->nd_cr != NULL)
+				crfree(nwp->nd_cr);
 			free((caddr_t)nwp, M_NFSRVDESC);
 		}
 		LIST_INIT(&slp->ns_tq);
@@ -705,16 +694,13 @@
 {
 	struct nfssvc_sock *slp, *nslp;
 
-	NET_ASSERT_GIANT();
 	NFSD_LOCK_ASSERT();
 
 	if (nfssvc_sockhead_flag & SLP_INIT)
 		panic("nfsd init");
 	nfssvc_sockhead_flag |= SLP_INIT;
 	if (terminating) {
-		for (slp = TAILQ_FIRST(&nfssvc_sockhead); slp != NULL;
-		    slp = nslp) {
-			nslp = TAILQ_NEXT(slp, ns_chain);
+		TAILQ_FOREACH_SAFE(slp, &nfssvc_sockhead, ns_chain, nslp) {
 			if (slp->ns_flag & SLP_VALID)
 				nfsrv_zapsock(slp);
 			TAILQ_REMOVE(&nfssvc_sockhead, slp, ns_chain);
Index: nfs_srvsock.c
===================================================================
RCS file: /home/cvs/src/sys/nfsserver/nfs_srvsock.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/nfsserver/nfs_srvsock.c -L sys/nfsserver/nfs_srvsock.c -u -r1.2 -r1.3
--- sys/nfsserver/nfs_srvsock.c
+++ sys/nfsserver/nfs_srvsock.c
@@ -33,12 +33,14 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvsock.c,v 1.94 2005/01/19 22:53:40 ps Exp $");
+__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvsock.c,v 1.104 2007/08/06 14:26:02 rwatson Exp $");
 
 /*
  * Socket operations for use by nfs
  */
 
+#include "opt_mac.h"
+
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
@@ -49,6 +51,7 @@
 #include <sys/mutex.h>
 #include <sys/proc.h>
 #include <sys/protosw.h>
+#include <sys/refcount.h>
 #include <sys/signalvar.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
@@ -65,6 +68,8 @@
 #include <nfs/xdr_subs.h>
 #include <nfsserver/nfsm_subs.h>
 
+#include <security/mac/mac_framework.h>
+
 #define	TRUE	1
 #define	FALSE	0
 
@@ -140,13 +145,9 @@
 	caddr_t bpos;
 	struct mbuf *mb;
 
-	/* XXXRW: not 100% clear the lock is needed here. */
-	NFSD_LOCK_ASSERT();
-
 	nd->nd_repstat = err;
 	if (err && (nd->nd_flag & ND_NFSV3) == 0)	/* XXX recheck */
 		siz = 0;
-	NFSD_UNLOCK();
 	MGETHDR(mreq, M_TRYWAIT, MT_DATA);
 	mb = mreq;
 	/*
@@ -159,7 +160,6 @@
 		MCLGET(mreq, M_TRYWAIT);
 	} else
 		mreq->m_data += min(max_hdr, M_TRAILINGSPACE(mreq));
-	NFSD_LOCK();
 	tl = mtod(mreq, u_int32_t *);
 	bpos = ((caddr_t)tl) + mreq->m_len;
 	*tl++ = txdr_unsigned(nd->nd_retxid);
@@ -241,18 +241,13 @@
 	struct mbuf *n = NULL;
 	int off = 0;
 
-	/* XXXRW: may not need lock? */
-	NFSD_LOCK_ASSERT();
-
 	++nfs_realign_test;
 	while ((m = *pm) != NULL) {
 		if ((m->m_len & 0x3) || (mtod(m, intptr_t) & 0x3)) {
-			NFSD_UNLOCK();
 			MGET(n, M_TRYWAIT, MT_DATA);
 			if (m->m_len >= MINCLSIZE) {
 				MCLGET(n, M_TRYWAIT);
 			}
-			NFSD_LOCK();
 			n->m_len = 0;
 			break;
 		}
@@ -361,17 +356,13 @@
 		}
 		nfsm_adv(nfsm_rndup(len));
 		tl = nfsm_dissect_nonblock(u_int32_t *, 3 * NFSX_UNSIGNED);
-		/*
-		 * XXX: This credential should be managed using crget(9)
-		 * and related calls.  Right now, this tramples on any
-		 * extensible data in the ucred, fails to initialize the
-		 * mutex, and worse.  This must be fixed before FreeBSD
-		 * 5.3-RELEASE.
-		 */
-		bzero((caddr_t)&nd->nd_cr, sizeof (struct ucred));
-		nd->nd_cr.cr_ref = 1;
-		nd->nd_cr.cr_uid = fxdr_unsigned(uid_t, *tl++);
-		nd->nd_cr.cr_gid = fxdr_unsigned(gid_t, *tl++);
+		nd->nd_cr->cr_uid = nd->nd_cr->cr_ruid =
+		    nd->nd_cr->cr_svuid = fxdr_unsigned(uid_t, *tl++);
+		nd->nd_cr->cr_groups[0] = nd->nd_cr->cr_rgid =
+		    nd->nd_cr->cr_svgid = fxdr_unsigned(gid_t, *tl++);
+#ifdef MAC
+		mac_associate_nfsd_label(nd->nd_cr);
+#endif
 		len = fxdr_unsigned(int, *tl);
 		if (len < 0 || len > RPCAUTH_UNIXGIDS) {
 			m_freem(mrep);
@@ -380,12 +371,12 @@
 		tl = nfsm_dissect_nonblock(u_int32_t *, (len + 2) * NFSX_UNSIGNED);
 		for (i = 1; i <= len; i++)
 		    if (i < NGROUPS)
-			nd->nd_cr.cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
+			nd->nd_cr->cr_groups[i] = fxdr_unsigned(gid_t, *tl++);
 		    else
 			tl++;
-		nd->nd_cr.cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
-		if (nd->nd_cr.cr_ngroups > 1)
-		    nfsrvw_sort(nd->nd_cr.cr_groups, nd->nd_cr.cr_ngroups);
+		nd->nd_cr->cr_ngroups = (len >= NGROUPS) ? NGROUPS : (len + 1);
+		if (nd->nd_cr->cr_ngroups > 1)
+		    nfsrvw_sort(nd->nd_cr->cr_groups, nd->nd_cr->cr_ngroups);
 		len = fxdr_unsigned(int, *++tl);
 		if (len < 0 || len > RPCAUTH_MAXSIZ) {
 			m_freem(mrep);
@@ -422,12 +413,6 @@
 	struct uio auio;
 	int flags, error;
 
-	/*
-	 * XXXRW: For now, assert Giant here since the NFS server upcall
-	 * will perform socket operations requiring Giant in a non-mpsafe
-	 * kernel.
-	 */
-	NET_ASSERT_GIANT();
 	NFSD_UNLOCK_ASSERT();
 
 	/* XXXRW: Unlocked read. */
@@ -466,8 +451,7 @@
 		auio.uio_resid = 1000000000;
 		flags = MSG_DONTWAIT;
 		NFSD_UNLOCK();
-		error = so->so_proto->pr_usrreqs->pru_soreceive
-			(so, &nam, &auio, &mp, NULL, &flags);
+		error = soreceive(so, &nam, &auio, &mp, NULL, &flags);
 		NFSD_LOCK();
 		if (error || mp == NULL) {
 			if (error == EWOULDBLOCK)
@@ -503,8 +487,7 @@
 			auio.uio_resid = 1000000000;
 			flags = MSG_DONTWAIT;
 			NFSD_UNLOCK();
-			error = so->so_proto->pr_usrreqs->pru_soreceive
-				(so, &nam, &auio, &mp, NULL, &flags);
+			error = soreceive(so, &nam, &auio, &mp, NULL, &flags);
 			if (mp) {
 				struct nfsrv_rec *rec;
 				rec = malloc(sizeof(struct nfsrv_rec),
@@ -517,8 +500,8 @@
 					NFSD_LOCK();
 					continue;
 				}
-				NFSD_LOCK();
 				nfs_realign(&mp, 10 * NFSX_UNSIGNED);
+				NFSD_LOCK();
 				rec->nr_address = nam;
 				rec->nr_packet = mp;
 				STAILQ_INSERT_TAIL(&slp->ns_rec, rec, nr_link);
@@ -702,6 +685,7 @@
 	    STAILQ_FIRST(&slp->ns_rec) == NULL)
 		return (ENOBUFS);
 	rec = STAILQ_FIRST(&slp->ns_rec);
+	KASSERT(rec->nr_packet != NULL, ("nfsrv_dorec: missing mbuf"));
 	STAILQ_REMOVE_HEAD(&slp->ns_rec, nr_link);
 	nam = rec->nr_address;
 	m = rec->nr_packet;
@@ -709,6 +693,7 @@
 	NFSD_UNLOCK();
 	MALLOC(nd, struct nfsrv_descript *, sizeof (struct nfsrv_descript),
 		M_NFSRVDESC, M_WAITOK);
+	nd->nd_cr = crget();
 	NFSD_LOCK();
 	nd->nd_md = nd->nd_mrep = m;
 	nd->nd_nam2 = nam;
@@ -718,6 +703,8 @@
 		if (nam) {
 			FREE(nam, M_SONAME);
 		}
+		if (nd->nd_cr != NULL)
+			crfree(nd->nd_cr);
 		free((caddr_t)nd, M_NFSRVDESC);
 		return (error);
 	}
@@ -768,7 +755,6 @@
 	struct sockaddr *sendnam;
 	int error, soflags, flags;
 
-	NET_ASSERT_GIANT();
 	NFSD_UNLOCK_ASSERT();
 
 	soflags = so->so_proto->pr_flags;
@@ -781,8 +767,7 @@
 	else
 		flags = 0;
 
-	error = so->so_proto->pr_usrreqs->pru_sosend(so, sendnam, 0, top, 0,
-						     flags, curthread/*XXX*/);
+	error = sosend(so, sendnam, 0, top, 0, flags, curthread/*XXX*/);
 	if (error == ENOBUFS && so->so_type == SOCK_DGRAM)
 		error = 0;
 
Index: nfs_serv.c
===================================================================
RCS file: /home/cvs/src/sys/nfsserver/nfs_serv.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/nfsserver/nfs_serv.c -L sys/nfsserver/nfs_serv.c -u -r1.2 -r1.3
--- sys/nfsserver/nfs_serv.c
+++ sys/nfsserver/nfs_serv.c
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_serv.c,v 1.156.2.2 2006/03/13 03:06:49 jeff Exp $");
+__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_serv.c,v 1.174.2.1 2007/10/26 21:46:31 jhb Exp $");
 
 /*
  * nfs version 2 and 3 server calls to vnode ops
@@ -80,6 +80,7 @@
 #include <sys/socketvar.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
+#include <sys/priv.h>
 #include <sys/dirent.h>
 #include <sys/stat.h>
 #include <sys/kernel.h>
@@ -134,12 +135,9 @@
 SYSCTL_INT(_vfs_nfsrv, OID_AUTO, commit_miss, CTLFLAG_RW, &nfs_commit_miss, 0, "");
 
 struct nfsrvstats nfsrvstats;
-SYSCTL_STRUCT(_vfs_nfsrv, NFS_NFSRVSTATS, nfsrvstats, CTLFLAG_RD,
+SYSCTL_STRUCT(_vfs_nfsrv, NFS_NFSRVSTATS, nfsrvstats, CTLFLAG_RW,
 	&nfsrvstats, nfsrvstats, "S,nfsrvstats");
 
-static int	nfsrv_access_withgiant(struct vnode *vp, int flags,
-		    struct ucred *cred, int rdonly, struct thread *td,
-		    int override);
 static int	nfsrv_access(struct vnode *, int, struct ucred *, int,
 		    struct thread *, int);
 static void	nfsrvw_coalesce(struct nfsrv_descript *,
@@ -161,6 +159,32 @@
 }
 
 /*
+ * Takes two vfslocked integers and returns with at most one
+ * reference to giant.  The return value indicates whether giant
+ * is held by either lock.  This simplifies nfsrv ops by allowing
+ * them to track only one vfslocked var.
+ */
+static __inline int
+nfsrv_lockedpair(int vfs1, int vfs2)
+{
+
+	if (vfs1 && vfs2)
+		VFS_UNLOCK_GIANT(vfs2);
+
+	return (vfs1 | vfs2);
+}
+
+static __inline int
+nfsrv_lockedpair_nd(int vfs1, struct nameidata *nd)
+{
+	int vfs2;
+
+	vfs2 = NDHASGIANT(nd);
+
+	return nfsrv_lockedpair(vfs1, vfs2);
+}
+
+/*
  * nfs v3 access service
  */
 int
@@ -170,7 +194,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct vnode *vp = NULL;
 	nfsfh_t nfh;
 	fhandle_t *fhp;
@@ -181,8 +205,7 @@
 	struct vattr vattr, *vap = &vattr;
 	u_long testmode, nfsmode;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	if (!v3)
@@ -190,7 +213,8 @@
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
 	tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);
 		nfsm_srvpostop_attr(1, NULL);
@@ -198,10 +222,8 @@
 		goto nfsmout;
 	}
 	nfsmode = fxdr_unsigned(u_int32_t, *tl);
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if ((nfsmode & NFSV3ACCESS_READ) &&
-		nfsrv_access_withgiant(vp, VREAD, cred, rdonly, td, 0))
+		nfsrv_access(vp, VREAD, cred, rdonly, td, 0))
 		nfsmode &= ~NFSV3ACCESS_READ;
 	if (vp->v_type == VDIR)
 		testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND |
@@ -209,33 +231,26 @@
 	else
 		testmode = (NFSV3ACCESS_MODIFY | NFSV3ACCESS_EXTEND);
 	if ((nfsmode & testmode) &&
-		nfsrv_access_withgiant(vp, VWRITE, cred, rdonly, td, 0))
+		nfsrv_access(vp, VWRITE, cred, rdonly, td, 0))
 		nfsmode &= ~testmode;
 	if (vp->v_type == VDIR)
 		testmode = NFSV3ACCESS_LOOKUP;
 	else
 		testmode = NFSV3ACCESS_EXECUTE;
 	if ((nfsmode & testmode) &&
-		nfsrv_access_withgiant(vp, VEXEC, cred, rdonly, td, 0))
+		nfsrv_access(vp, VEXEC, cred, rdonly, td, 0))
 		nfsmode &= ~testmode;
 	getret = VOP_GETATTR(vp, vap, cred, td);
 	vput(vp);
-	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
-	NFSD_LOCK();
 	nfsm_reply(NFSX_POSTOPATTR(1) + NFSX_UNSIGNED);
 	nfsm_srvpostop_attr(getret, vap);
 	tl = nfsm_build(u_int32_t *, NFSX_UNSIGNED);
 	*tl = txdr_unsigned(nfsmode);
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	if (vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp)
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -249,7 +264,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct nfs_fattr *fp;
 	struct vattr va;
 	struct vattr *vap = &va;
@@ -259,25 +274,22 @@
 	caddr_t bpos;
 	int error = 0, rdonly;
 	struct mbuf *mb, *mreq;
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, cred, slp, nam,
+	    &rdonly, TRUE);
 	if (error) {
 		nfsm_reply(0);
 		error = 0;
 		goto nfsmout;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	error = VOP_GETATTR(vp, vap, cred, td);
 	vput(vp);
-	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
-	NFSD_LOCK();
 	nfsm_reply(NFSX_FATTR(nfsd->nd_flag & ND_NFSV3));
 	if (error) {
 		error = 0;
@@ -289,14 +301,9 @@
 	/* fall through */
 
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	if (vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp)
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -310,7 +317,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct vattr va, preat;
 	struct vattr *vap = &va;
 	struct nfsv2_sattr *sp;
@@ -323,23 +330,22 @@
 	int error = 0, rdonly, preat_ret = 1, postat_ret = 1;
 	int v3 = (nfsd->nd_flag & ND_NFSV3), gcheck = 0;
 	struct mbuf *mb, *mreq;
-	struct timespec guard;
+	struct timespec guard = { 0, 0 };
 	struct mount *mp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int tvfslocked;
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
 	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
 		error = ESTALE;
 		goto out;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	VATTR_NULL(vap);
 	if (v3) {
 		nfsm_srvsattr(vap);
@@ -383,7 +389,9 @@
 	/*
 	 * Now that we have all the fields, lets do it.
 	 */
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &tvfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
+	vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
 		if (v3)
@@ -396,8 +404,6 @@
 	 * vp now an active resource, pay careful attention to cleanup
 	 */
 	if (v3) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		error = preat_ret = VOP_GETATTR(vp, &preat, cred, td);
 		if (!error && gcheck &&
 			(preat.va_ctime.tv_sec != guard.tv_sec ||
@@ -405,19 +411,14 @@
 			error = NFSERR_NOT_SYNC;
 		if (error) {
 			vput(vp);
-			mtx_unlock(&Giant);	/* VFS */
 			vp = NULL;
-			NFSD_LOCK();
 			nfsm_reply(NFSX_WCCDATA(v3));
 			if (v3)
 				nfsm_srvwcc_data(preat_ret, &preat, postat_ret, vap);
 			error = 0;
 			goto nfsmout;
 		}
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 	}
-	NFSD_LOCK_ASSERT();
 
 	/*
 	 * If the size is being changed write acces is required, otherwise
@@ -436,23 +437,13 @@
 			td, 0)) != 0)
 			goto out;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	error = VOP_SETATTR(vp, vap, cred, td);
 	postat_ret = VOP_GETATTR(vp, vap, cred, td);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 	if (!error)
 		error = postat_ret;
 out:
-	NFSD_LOCK_ASSERT();
-	if (vp != NULL) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp != NULL)
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
 
 	vp = NULL;
 	nfsm_reply(NFSX_WCCORFATTR(v3));
@@ -467,14 +458,10 @@
 	/* fall through */
 
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (vp)
 		vput(vp);
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -488,7 +475,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct nfs_fattr *fp;
 	struct nameidata nd, ind, *ndp = &nd;
 	struct vnode *vp, *dirp = NULL;
@@ -499,11 +486,12 @@
 	int v3 = (nfsd->nd_flag & ND_NFSV3), pubflag;
 	struct mbuf *mb, *mreq;
 	struct vattr va, dirattr, *vap = &va;
-
-	NFSD_LOCK_ASSERT();
+	int tvfslocked;
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
+	vfslocked = 0;
 
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
@@ -513,24 +501,21 @@
 
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = LOOKUP;
-	nd.ni_cnd.cn_flags = LOCKLEAF | SAVESTART;
+	nd.ni_cnd.cn_flags = LOCKLEAF | SAVESTART | MPSAFE;
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirattr, &dirattr_ret, td, pubflag);
+	vfslocked = NDHASGIANT(&nd);
 
 	/*
 	 * namei failure, only dirp to cleanup.  Clear out garbarge from
 	 * structure in case macros jump to nfsmout.
 	 */
 
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (error) {
 		if (dirp) {
 			vrele(dirp);
 			dirp = NULL;
 		}
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		nfsm_reply(NFSX_POSTOPATTR(v3));
 		if (v3)
 			nfsm_srvpostop_attr(dirattr_ret, &dirattr);
@@ -566,9 +551,14 @@
 			    nfs_pub.np_index;
 			ind.ni_startdir = nd.ni_vp;
 			VREF(ind.ni_startdir);
-
+			ind.ni_cnd.cn_flags &= ~GIANTHELD;
+			tvfslocked = VFS_LOCK_GIANT(ind.ni_startdir->v_mount);
+			if (tvfslocked)
+				nd.ni_cnd.cn_flags |= GIANTHELD;
 			error = lookup(&ind);
 			ind.ni_dvp = NULL;
+			vfslocked = nfsrv_lockedpair_nd(vfslocked, &ind);
+			ind.ni_cnd.cn_flags &= ~GIANTHELD;
 
 			if (error == 0) {
 				/*
@@ -605,8 +595,6 @@
 	 */
 
 	if (error) {
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		nfsm_reply(NFSX_POSTOPATTR(v3));
 		if (v3)
 			nfsm_srvpostop_attr(dirattr_ret, &dirattr);
@@ -621,7 +609,7 @@
 	vp = ndp->ni_vp;
 	bzero((caddr_t)fhp, sizeof(nfh));
 	fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
-	error = VFS_VPTOFH(vp, &fhp->fh_fid);
+	error = VOP_VPTOFH(vp, &fhp->fh_fid);
 	if (!error)
 		error = VOP_GETATTR(vp, vap, cred, td);
 
@@ -631,8 +619,6 @@
 	ndp->ni_vp = NULL;
 	ndp->ni_startdir = NULL;
 	dirp = NULL;
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 	nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPORFATTR(v3) + NFSX_POSTOPATTR(v3));
 	if (error) {
 		if (v3)
@@ -650,20 +636,16 @@
 	}
 
 nfsmout:
-	NFSD_LOCK_ASSERT();
 	if (ndp->ni_vp || dirp || ndp->ni_startdir) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		if (ndp->ni_vp)
 			vput(ndp->ni_vp);
 		if (dirp)
 			vrele(dirp);
 		if (ndp->ni_startdir)
 			vrele(ndp->ni_startdir);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 	}
 	NDFREE(&nd, NDF_ONLY_PNBUF);
+	VFS_UNLOCK_GIANT(vfslocked);
 	return (error);
 }
 
@@ -677,7 +659,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct iovec iv[(NFS_MAXPATHLEN+MLEN-1)/MLEN];
 	struct iovec *ivp = iv;
 	struct mbuf *mp;
@@ -691,10 +673,10 @@
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	struct uio io, *uiop = &io;
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 #ifndef nolint
 	mp = NULL;
 #endif
@@ -703,7 +685,6 @@
 	nfsm_srvmtofh(fhp);
 	len = 0;
 	i = 0;
-	NFSD_UNLOCK();
 	while (len < NFS_MAXPATHLEN) {
 		MGET(nmp, M_TRYWAIT, MT_DATA);
 		MCLGET(nmp, M_TRYWAIT);
@@ -731,8 +712,8 @@
 	uiop->uio_rw = UIO_READ;
 	uiop->uio_segflg = UIO_SYSSPACE;
 	uiop->uio_td = NULL;
-	NFSD_LOCK();
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
 		if (v3)
@@ -740,8 +721,6 @@
 		error = 0;
 		goto nfsmout;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (vp->v_type != VLNK) {
 		if (v3)
 			error = EINVAL;
@@ -751,9 +730,7 @@
 		error = VOP_READLINK(vp, uiop, cred);
 	getret = VOP_GETATTR(vp, &attr, cred, td);
 	vput(vp);
-	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
-	NFSD_LOCK();
 	nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_UNSIGNED);
 	if (v3)
 		nfsm_srvpostop_attr(getret, &attr);
@@ -771,16 +748,11 @@
 	mb->m_next = mp3;
 	mp3 = NULL;
 nfsmout:
-	NFSD_LOCK_ASSERT();
 	if (mp3)
 		m_freem(mp3);
-	if (vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp)
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -794,7 +766,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct iovec *iv;
 	struct iovec *iv2;
 	struct mbuf *m;
@@ -814,10 +786,11 @@
 	struct nfsheur *nh;
 	off_t off;
 	int ioflag = 0;
+	int vfslocked;
 
-	NFSD_LOCK_ASSERT();
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
 	if (v3) {
@@ -835,7 +808,8 @@
 	 * as well.
 	 */
 
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
 	if (error) {
 		vp = NULL;
 		nfsm_reply(2 * NFSX_UNSIGNED);
@@ -851,12 +825,10 @@
 		else
 			error = (vp->v_type == VDIR) ? EISDIR : EACCES;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (!error) {
-		if ((error = nfsrv_access_withgiant(vp, VREAD, cred, rdonly,
+		if ((error = nfsrv_access(vp, VREAD, cred, rdonly,
 		    td, 1)) != 0)
-			error = nfsrv_access_withgiant(vp, VEXEC, cred,
+			error = nfsrv_access(vp, VEXEC, cred,
 			    rdonly, td, 1);
 	}
 	getret = VOP_GETATTR(vp, vap, cred, td);
@@ -864,17 +836,13 @@
 		error = getret;
 	if (error) {
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
 		vp = NULL;
-		NFSD_LOCK();
 		nfsm_reply(NFSX_POSTOPATTR(v3));
 		if (v3)
 			nfsm_srvpostop_attr(getret, vap);
 		error = 0;
 		goto nfsmout;
 	}
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 
 	/*
 	 * Calculate byte count to read
@@ -954,7 +922,6 @@
 		tl += (NFSX_V2FATTR / sizeof (u_int32_t));
 	}
 	len = left = nfsm_rndup(cnt);
-	NFSD_UNLOCK();
 	if (cnt > 0) {
 		/*
 		 * Generate the mbuf list with the uio_iov ref. to it.
@@ -1000,7 +967,6 @@
 		uiop->uio_resid = len;
 		uiop->uio_rw = UIO_READ;
 		uiop->uio_segflg = UIO_SYSSPACE;
-		mtx_lock(&Giant);	/* VFS */
 		error = VOP_READ(vp, uiop, IO_NODELOCKED | ioflag, cred);
 		off = uiop->uio_offset;
 		nh->nh_nextr = off;
@@ -1010,8 +976,6 @@
 				error = getret;
 			m_freem(mreq);
 			vput(vp);
-			mtx_unlock(&Giant);	/* VFS */
-			NFSD_LOCK();
 			vp = NULL;
 			nfsm_reply(NFSX_POSTOPATTR(v3));
 			if (v3)
@@ -1019,15 +983,10 @@
 			error = 0;
 			goto nfsmout;
 		}
-	} else {
+	} else
 		uiop->uio_resid = 0;
-		mtx_lock(&Giant);	/* VFS */
-	}
-	mtx_assert(&Giant, MA_OWNED);	/* VFS */
 	vput(vp);
-	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
-	NFSD_LOCK();
 	nfsm_srvfillattr(vap, fp);
 	tlen = len - uiop->uio_resid;
 	cnt = cnt < tlen ? cnt : tlen;
@@ -1043,14 +1002,9 @@
 	}
 	*tl = txdr_unsigned(cnt);
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	if (vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp)
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -1064,7 +1018,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct iovec *ivp;
 	int i, cnt;
 	struct mbuf *mp;
@@ -1085,10 +1039,11 @@
 	struct uio io, *uiop = &io;
 	off_t off;
 	struct mount *mntp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int tvfslocked;
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 	if (mrep == NULL) {
 		*mrq = NULL;
 		error = 0;
@@ -1100,11 +1055,9 @@
 		error = ESTALE;
 		goto ereply;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mntp);
 	(void) vn_start_write(NULL, &mntp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mntp);		/* The write holds a ref. */
 	if (v3) {
 		tl = nfsm_dissect_nonblock(u_int32_t *, 5 * NFSX_UNSIGNED);
 		off = fxdr_hyper(tl);
@@ -1158,7 +1111,9 @@
 		error = 0;
 		goto nfsmout;
 	}
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &tvfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
+	vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
 	if (error) {
 		vp = NULL;
 		nfsm_reply(2 * NFSX_UNSIGNED);
@@ -1167,13 +1122,8 @@
 		error = 0;
 		goto nfsmout;
 	}
-	if (v3) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (v3)
 		forat_ret = VOP_GETATTR(vp, &forat, cred, td);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
 	if (vp->v_type != VREG) {
 		if (v3)
 			error = EINVAL;
@@ -1183,11 +1133,7 @@
 	if (!error)
 		error = nfsrv_access(vp, VWRITE, cred, rdonly, td, 1);
 	if (error) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		vp = NULL;
 		nfsm_reply(NFSX_WCCDATA(v3));
 		if (v3)
@@ -1196,7 +1142,6 @@
 		goto nfsmout;
 	}
 
-	NFSD_UNLOCK();
 	if (len > 0) {
 	    MALLOC(ivp, struct iovec *, cnt * sizeof (struct iovec), M_TEMP,
 		M_WAITOK);
@@ -1230,23 +1175,17 @@
 	    uiop->uio_segflg = UIO_SYSSPACE;
 	    uiop->uio_td = NULL;
 	    uiop->uio_offset = off;
-	    mtx_lock(&Giant);	/* VFS */
 	    error = VOP_WRITE(vp, uiop, ioflags, cred);
 	    /* XXXRW: unlocked write. */
 	    nfsrvstats.srvvop_writes++;
 	    FREE((caddr_t)iv, M_TEMP);
-	} else
-	    mtx_lock(&Giant);	/* VFS */
-	mtx_assert(&Giant, MA_OWNED);	/* VFS */
+	}
 	aftat_ret = VOP_GETATTR(vp, vap, cred, td);
 	vput(vp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 	vp = NULL;
 	if (!error)
 		error = aftat_ret;
 ereply:
-	NFSD_LOCK_ASSERT();
 	nfsm_reply(NFSX_PREOPATTR(v3) + NFSX_POSTOPORFATTR(v3) +
 		2 * NFSX_UNSIGNED + NFSX_WRITEVERF(v3));
 	if (v3) {
@@ -1280,14 +1219,10 @@
 	}
 	error = 0;
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (vp)
 		vput(vp);
 	vn_finished_write(mntp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -1342,8 +1277,8 @@
 	struct uio io, *uiop = &io;
 	u_quad_t cur_usec;
 	struct mount *mntp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int mvfslocked;
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 #ifndef nolint
@@ -1357,7 +1292,7 @@
 	    mrep = nfsd->nd_mrep;
 	    md = nfsd->nd_md;
 	    dpos = nfsd->nd_dpos;
-	    cred = &nfsd->nd_cr;
+	    cred = nfsd->nd_cr;
 	    v3 = (nfsd->nd_flag & ND_NFSV3);
 	    LIST_INIT(&nfsd->nd_coalesce);
 	    nfsd->nd_mreq = NULL;
@@ -1414,7 +1349,6 @@
 	    }
 	    if (len > NFS_MAXDATA || len < 0  || i < len) {
 nfsmout:
-		NFSD_LOCK_ASSERT();
 		m_freem(mrep);
 		error = EIO;
 		nfsm_writereply(2 * NFSX_UNSIGNED);
@@ -1464,7 +1398,7 @@
 		     */
 		    for(; nfsd && NFSW_CONTIG(owp, nfsd); nfsd = wp) {
 			wp = LIST_NEXT(nfsd, nd_hash);
-			if (nfsrv_samecred(&owp->nd_cr, &nfsd->nd_cr))
+			if (nfsrv_samecred(owp->nd_cr, nfsd->nd_cr))
 			    nfsrvw_coalesce(owp, nfsd);
 		    }
 		} else {
@@ -1493,19 +1427,14 @@
 		splx(s);
 		mrep = nfsd->nd_mrep;
 		nfsd->nd_mrep = NULL;
-		cred = &nfsd->nd_cr;
+		cred = nfsd->nd_cr;
 		v3 = (nfsd->nd_flag & ND_NFSV3);
 		forat_ret = aftat_ret = 1;
-		error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &vp, cred, slp,
-		    nfsd->nd_nam, &rdonly, TRUE);
+		error = nfsrv_fhtovp(&nfsd->nd_fh, 1, &vp, &vfslocked, cred,
+		    slp, nfsd->nd_nam, &rdonly, TRUE);
 		if (!error) {
-		    if (v3) {
-			NFSD_UNLOCK();
-			mtx_lock(&Giant);	/* VFS */
+		    if (v3)
 			forat_ret = VOP_GETATTR(vp, &forat, cred, td);
-			mtx_unlock(&Giant);	/* VFS */
-			NFSD_LOCK();
-		    }
 		    if (vp->v_type != VREG) {
 			if (v3)
 			    error = EINVAL;
@@ -1515,10 +1444,8 @@
 		} else {
 		    vp = NULL;
 		}
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		if (!error)
-		    error = nfsrv_access_withgiant(vp, VWRITE, cred, rdonly,
+		    error = nfsrv_access(vp, VWRITE, cred, rdonly,
 			td, 1);
 		if (nfsd->nd_stable == NFSV3WRITE_UNSTABLE)
 		    ioflags = IO_NODELOCKED;
@@ -1552,12 +1479,14 @@
 			}
 			mp = mp->m_next;
 		    }
+		    mvfslocked = 0;
 		    if (!error) {
 			if (vn_start_write(vp, &mntp, V_NOWAIT) != 0) {
 			    VOP_UNLOCK(vp, 0, td);
 			    error = vn_start_write(NULL, &mntp, V_WAIT);
 			    vn_lock(vp, LK_EXCLUSIVE | LK_RETRY, td);
 			}
+		        mvfslocked = VFS_LOCK_GIANT(mntp);
 		    }
 		    if (!error) {
 			error = VOP_WRITE(vp, uiop, ioflags, cred);
@@ -1565,6 +1494,7 @@
 			nfsrvstats.srvvop_writes++;
 			vn_finished_write(mntp);
 		    }
+		    VFS_UNLOCK_GIANT(mvfslocked);
 		    FREE((caddr_t)iov, M_TEMP);
 		}
 		m_freem(mrep);
@@ -1573,9 +1503,7 @@
 		    vput(vp);
 		    vp = NULL;
 		}
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-
+		VFS_UNLOCK_GIANT(vfslocked);
 		/*
 		 * Loop around generating replies for all write rpcs that have
 		 * now been completed.
@@ -1669,8 +1597,6 @@
         struct mbuf *mp;
 	struct nfsrv_descript *p;
 
-	NFSD_LOCK_ASSERT();
-
 	NFS_DPF(WG, ("C%03x-%03x",
 		     nfsd->nd_retxid & 0xfff, owp->nd_retxid & 0xfff));
         LIST_REMOVE(nfsd, nd_hash);
@@ -1718,7 +1644,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct nfs_fattr *fp;
 	struct vattr va, dirfor, diraft;
 	struct vattr *vap = &va;
@@ -1736,10 +1662,11 @@
 	u_quad_t tempsize;
 	u_char cverf[NFSX_V3CREATEVERF];
 	struct mount *mp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int tvfslocked;
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 #ifndef nolint
 	rdev = 0;
 #endif
@@ -1749,18 +1676,16 @@
 	nfsm_srvmtofh(fhp);
 	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
 		error = ESTALE;
-		goto ereply_locked;
+		goto ereply;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	nfsm_srvnamesiz(len);
 
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
-	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART;
+	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE;
 
 	/*
 	 * Call namei and do initial cleanup to get a few things
@@ -1773,12 +1698,9 @@
 	 */
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
+	vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
 	if (dirp && !v3) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		vrele(dirp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		dirp = NULL;
 	}
 	if (error) {
@@ -1853,8 +1775,6 @@
 	 * The only possible error we can have at this point is EEXIST.
 	 * nd.ni_vp will also be non-NULL in that case.
 	 */
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (nd.ni_vp == NULL) {
 		if (vap->va_mode == (mode_t)VNOVAL)
 			vap->va_mode = 0;
@@ -1901,7 +1821,6 @@
 			 */
 			vput(nd.ni_dvp);
 			nd.ni_dvp = NULL;
-
 			/*
 			 * Setup for lookup.
 			 *
@@ -1912,9 +1831,13 @@
 			nd.ni_cnd.cn_flags &= ~(LOCKPARENT);
 			nd.ni_cnd.cn_thread = td;
 			nd.ni_cnd.cn_cred = cred;
-
+			tvfslocked = VFS_LOCK_GIANT(nd.ni_startdir->v_mount);
+			if (tvfslocked)
+				nd.ni_cnd.cn_flags |= GIANTHELD;
 			error = lookup(&nd);
 			nd.ni_dvp = NULL;
+			vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
+			nd.ni_cnd.cn_flags &= ~GIANTHELD;
 			if (error)
 				goto ereply;
 
@@ -1927,7 +1850,7 @@
 		}
 	} else {
 		if (vap->va_size != -1) {
-			error = nfsrv_access_withgiant(nd.ni_vp, VWRITE,
+			error = nfsrv_access(nd.ni_vp, VWRITE,
 			    cred, (nd.ni_cnd.cn_flags & RDONLY), td, 0);
 			if (!error) {
 				tempsize = vap->va_size;
@@ -1942,7 +1865,7 @@
 	if (!error) {
 		bzero((caddr_t)fhp, sizeof(nfh));
 		fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
-		error = VFS_VPTOFH(nd.ni_vp, &fhp->fh_fid);
+		error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
 		if (!error)
 			error = VOP_GETATTR(nd.ni_vp, vap, cred, td);
 	}
@@ -1971,11 +1894,6 @@
 		}
 	}
 ereply:
-	NFSD_UNLOCK_ASSERT();
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
-ereply_locked:
-	NFSD_LOCK_ASSERT();
 	nfsm_reply(NFSX_SRVFH(v3) + NFSX_FATTR(v3) + NFSX_WCCDATA(v3));
 	if (v3) {
 		if (!error) {
@@ -1992,9 +1910,6 @@
 	error = 0;
 
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (nd.ni_dvp) {
 		if (nd.ni_dvp == nd.ni_vp)
 			vrele(nd.ni_dvp);
@@ -2011,8 +1926,7 @@
 		vrele(dirp);
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return (error);
 }
 
@@ -2026,7 +1940,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct vattr va, dirfor, diraft;
 	struct vattr *vap = &va;
 	u_int32_t *tl;
@@ -2041,10 +1955,11 @@
 	fhandle_t *fhp;
 	struct mount *mp = NULL;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
-
-	NFSD_LOCK_ASSERT();
+	int tvfslocked;
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 	if (!v3)
 		panic("nfsrv_mknod: v3 proc called on a v2 connection");
 	ndclear(&nd);
@@ -2055,16 +1970,14 @@
 		error = ESTALE;
 		goto ereply;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	nfsm_srvnamesiz(len);
 
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
-	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART;
+	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | SAVESTART | MPSAFE;
 
 	/*
 	 * Handle nfs_namei() call.  If an error occurs, the nd structure
@@ -2074,6 +1987,7 @@
 
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
+	vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
 	if (error) {
 		nfsm_reply(NFSX_WCCDATA(1));
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
@@ -2083,8 +1997,6 @@
 	tl = nfsm_dissect_nonblock(u_int32_t *, NFSX_UNSIGNED);
 	vtyp = nfsv3tov_type(*tl);
 	if (vtyp != VCHR && vtyp != VBLK && vtyp != VSOCK && vtyp != VFIFO) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		error = NFSERR_BADTYPE;
 		goto out;
 	}
@@ -2101,16 +2013,12 @@
 	 * Iff doesn't exist, create it.
 	 */
 	if (nd.ni_vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		error = EEXIST;
 		goto out;
 	}
 	vap->va_type = vtyp;
 	if (vap->va_mode == (mode_t)VNOVAL)
 		vap->va_mode = 0;
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (vtyp == VSOCK) {
 		vrele(nd.ni_startdir);
 		nd.ni_startdir = NULL;
@@ -2138,9 +2046,13 @@
 		nd.ni_cnd.cn_flags &= ~(LOCKPARENT);
 		nd.ni_cnd.cn_thread = td;
 		nd.ni_cnd.cn_cred = td->td_ucred;
-
+		tvfslocked = VFS_LOCK_GIANT(nd.ni_startdir->v_mount);
+		if (tvfslocked)
+			nd.ni_cnd.cn_flags |= GIANTHELD;
 		error = lookup(&nd);
 		nd.ni_dvp = NULL;
+		vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
+		nd.ni_cnd.cn_flags &= ~GIANTHELD;
 
 		if (error)
 			goto out;
@@ -2152,12 +2064,11 @@
 	 * send response, cleanup, return.
 	 */
 out:
-	NFSD_UNLOCK_ASSERT();
 	vp = nd.ni_vp;
 	if (!error) {
 		bzero((caddr_t)fhp, sizeof(nfh));
 		fhp->fh_fsid = vp->v_mount->mnt_stat.f_fsid;
-		error = VFS_VPTOFH(vp, &fhp->fh_fid);
+		error = VOP_VPTOFH(vp, &fhp->fh_fid);
 		if (!error)
 			error = VOP_GETATTR(vp, vap, cred, td);
 	}
@@ -2183,10 +2094,7 @@
 		diraft_ret = VOP_GETATTR(dirp, &diraft, cred, td);
 		VOP_UNLOCK(dirp, 0, td);
 	}
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 ereply:
-	NFSD_LOCK_ASSERT();
 	nfsm_reply(NFSX_SRVFH(1) + NFSX_POSTOPATTR(1) + NFSX_WCCDATA(1));
 	if (v3) {
 		if (!error) {
@@ -2195,16 +2103,10 @@
 		}
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return (0);
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (nd.ni_dvp) {
 		if (nd.ni_dvp == nd.ni_vp)
 			vrele(nd.ni_dvp);
@@ -2219,8 +2121,7 @@
 		vrele(nd.ni_startdir);
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return (error);
 }
 
@@ -2234,7 +2135,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct nameidata nd;
 	caddr_t bpos;
 	int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
@@ -2245,11 +2146,11 @@
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	struct mount *mp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
+	vfslocked = 0;
 
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
@@ -2257,20 +2158,17 @@
 		error = ESTALE;
 		goto ereply;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	nfsm_srvnamesiz(len);
 
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = DELETE;
-	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
+	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | MPSAFE;
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3,  &dirfor, &dirfor_ret, td, FALSE);
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = NDHASGIANT(&nd);
 	if (dirp && !v3) {
 		vrele(dirp);
 		dirp = NULL;
@@ -2288,7 +2186,6 @@
 			goto out;
 		}
 out:
-		NFSD_UNLOCK_ASSERT();
 		if (!error) {
 			error = VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
 			NDFREE(&nd, NDF_ONLY_PNBUF);
@@ -2317,19 +2214,13 @@
 		vrele(dirp);
 		dirp = NULL;
 	}
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 ereply:
-	NFSD_LOCK_ASSERT();
 	nfsm_reply(NFSX_WCCDATA(v3));
 	if (v3) {
 		nfsm_srvwcc_data(dirfor_ret, &dirfor, diraft_ret, &diraft);
 		error = 0;
 	}
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	if (nd.ni_dvp) {
 		if (nd.ni_dvp == nd.ni_vp)
@@ -2340,8 +2231,7 @@
 	if (nd.ni_vp)
 		vput(nd.ni_vp);
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -2355,7 +2245,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	caddr_t bpos;
 	int error = 0, len, len2, fdirfor_ret = 1, fdiraft_ret = 1;
 	int tdirfor_ret = 1, tdiraft_ret = 1;
@@ -2369,10 +2259,10 @@
 	fhandle_t *ffhp, *tfhp;
 	uid_t saved_uid;
 	struct mount *mp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 #ifndef nolint
 	fvp = NULL;
 #endif
@@ -2391,11 +2281,9 @@
 		error = ESTALE;
 		goto out1;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	nfsm_srvnamesiz(len);
 	/*
 	 * Remember our original uid so that we can reset cr_uid before
@@ -2404,15 +2292,12 @@
 	saved_uid = cred->cr_uid;
 	fromnd.ni_cnd.cn_cred = cred;
 	fromnd.ni_cnd.cn_nameiop = DELETE;
-	fromnd.ni_cnd.cn_flags = WANTPARENT | SAVESTART;
+	fromnd.ni_cnd.cn_flags = WANTPARENT | SAVESTART | MPSAFE;
 	error = nfs_namei(&fromnd, ffhp, len, slp, nam, &md,
 		&dpos, &fdirp, v3, &fdirfor, &fdirfor_ret, td, FALSE);
+	vfslocked = nfsrv_lockedpair_nd(vfslocked, &fromnd);
 	if (fdirp && !v3) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		vrele(fdirp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		fdirp = NULL;
 	}
 	if (error) {
@@ -2430,20 +2315,16 @@
 	cred->cr_uid = saved_uid;
 	tond.ni_cnd.cn_cred = cred;
 	tond.ni_cnd.cn_nameiop = RENAME;
-	tond.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART;
+	tond.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | NOCACHE | SAVESTART | MPSAFE;
 	error = nfs_namei(&tond, tfhp, len2, slp, nam, &md,
 		&dpos, &tdirp, v3, &tdirfor, &tdirfor_ret, td, FALSE);
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = nfsrv_lockedpair_nd(vfslocked, &tond);
 	if (tdirp && !v3) {
 		vrele(tdirp);
 		tdirp = NULL;
 	}
-	if (error) {
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
+	if (error)
 		goto out1;
-	}
 
 	tdvp = tond.ni_dvp;
 	tvp = tond.ni_vp;
@@ -2500,7 +2381,6 @@
 	      fromnd.ni_cnd.cn_namelen))
 		error = -1;
 out:
-	NFSD_UNLOCK_ASSERT();
 	if (!error) {
 		/*
 		 * The VOP_RENAME function releases all vnode references &
@@ -2514,24 +2394,18 @@
 		tond.ni_dvp = NULL;
 		tond.ni_vp = NULL;
 		if (error) {
-			fromnd.ni_cnd.cn_flags &= ~HASBUF;
-			tond.ni_cnd.cn_flags &= ~HASBUF;
+			NDFREE(&fromnd, NDF_ONLY_PNBUF);
+			NDFREE(&tond, NDF_ONLY_PNBUF);
 		}
 	} else {
 		if (error == -1)
 			error = 0;
 	}
 	/* fall through */
-
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 out1:
-	NFSD_LOCK_ASSERT();
 	nfsm_reply(2 * NFSX_WCCDATA(v3));
 	if (v3) {
 		/* Release existing locks to prevent deadlock. */
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		if (tond.ni_dvp) {
 			if (tond.ni_dvp == tond.ni_vp)
 				vrele(tond.ni_dvp);
@@ -2553,8 +2427,6 @@
 			tdiraft_ret = VOP_GETATTR(tdirp, &tdiraft, cred, td);
 			VOP_UNLOCK(tdirp, 0, td);
 		}
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		nfsm_srvwcc_data(fdirfor_ret, &fdirfor, fdiraft_ret, &fdiraft);
 		nfsm_srvwcc_data(tdirfor_ret, &tdirfor, tdiraft_ret, &tdiraft);
 	}
@@ -2565,9 +2437,6 @@
 	/*
 	 * Clear out tond related fields
 	 */
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (tond.ni_dvp) {
 		if (tond.ni_dvp == tond.ni_vp)
 			vrele(tond.ni_dvp);
@@ -2595,8 +2464,7 @@
 		vrele(fromnd.ni_vp);
 
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return (error);
 }
 
@@ -2610,7 +2478,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct nameidata nd;
 	caddr_t bpos;
 	int error = 0, rdonly, len, dirfor_ret = 1, diraft_ret = 1;
@@ -2621,11 +2489,12 @@
 	nfsfh_t nfh, dnfh;
 	fhandle_t *fhp, *dfhp;
 	struct mount *mp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int tvfslocked;
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
+	vfslocked = 0;
 
 	fhp = &nfh.fh_generic;
 	dfhp = &dnfh.fh_generic;
@@ -2634,15 +2503,15 @@
 		error = ESTALE;
 		goto ereply;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	nfsm_srvmtofh(dfhp);
 	nfsm_srvnamesiz(len);
 
-	error = nfsrv_fhtovp(fhp, TRUE, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, TRUE, &vp, &tvfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
+	vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
 	if (error) {
 		nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
 		if (v3) {
@@ -2653,8 +2522,6 @@
 		error = 0;
 		goto nfsmout;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (v3)
 		getret = VOP_GETATTR(vp, &at, cred, td);
 	if (vp->v_type == VDIR) {
@@ -2664,13 +2531,10 @@
 	VOP_UNLOCK(vp, 0, td);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
-	nd.ni_cnd.cn_flags = LOCKPARENT;
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	nd.ni_cnd.cn_flags = LOCKPARENT | MPSAFE | MPSAFE;
 	error = nfs_namei(&nd, dfhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
 	if (dirp && !v3) {
 		vrele(dirp);
 		dirp = NULL;
@@ -2724,10 +2588,7 @@
 			VOP_UNLOCK(dirp, 0, td);
 		}
 	}
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 ereply:
-	NFSD_LOCK_ASSERT();
 	nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
 	if (v3) {
 		nfsm_srvpostop_attr(getret, &at);
@@ -2737,9 +2598,6 @@
 	/* fall through */
 
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	if (vp)
 		vput(vp);
@@ -2754,8 +2612,7 @@
 	if (nd.ni_vp)
 		vrele(nd.ni_vp);
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -2769,7 +2626,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct vattr va, dirfor, diraft;
 	struct nameidata nd;
 	struct vattr *vap = &va;
@@ -2784,44 +2641,41 @@
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	struct mount *mp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int tvfslocked;
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
+	vfslocked = 0;
 
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
 	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		error = ESTALE;
 		goto out;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	nfsm_srvnamesiz(len);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
-	nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART;
+	nd.ni_cnd.cn_flags = LOCKPARENT | SAVESTART | MPSAFE;
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
+	if (error == 0) {
+		VATTR_NULL(vap);
+		if (v3)
+			nfsm_srvsattr(vap);
+		nfsm_srvpathsiz(len2);
+	}
 	if (dirp && !v3) {
 		vrele(dirp);
 		dirp = NULL;
 	}
 	if (error)
 		goto out;
-
-	VATTR_NULL(vap);
-	if (v3)
-		nfsm_srvsattr(vap);
-	nfsm_srvpathsiz(len2);
 	MALLOC(pathcp, caddr_t, len2 + 1, M_TEMP, M_WAITOK);
 	iv.iov_base = pathcp;
 	iv.iov_len = len2;
@@ -2875,14 +2729,18 @@
 		nd.ni_cnd.cn_flags |= (NOFOLLOW | LOCKLEAF);
 		nd.ni_cnd.cn_thread = td;
 		nd.ni_cnd.cn_cred = cred;
-
+		tvfslocked = VFS_LOCK_GIANT(nd.ni_startdir->v_mount);
+		if (tvfslocked)
+			nd.ni_cnd.cn_flags |= GIANTHELD;
 		error = lookup(&nd);
 		nd.ni_dvp = NULL;
+		vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
+		nd.ni_cnd.cn_flags &= ~GIANTHELD;
 
 		if (error == 0) {
 			bzero((caddr_t)fhp, sizeof(nfh));
 			fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
-			error = VFS_VPTOFH(nd.ni_vp, &fhp->fh_fid);
+			error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
 			if (!error)
 				error = VOP_GETATTR(nd.ni_vp, vap, cred,
 					td);
@@ -2892,7 +2750,6 @@
 	    }
 	}
 out:
-	NFSD_UNLOCK_ASSERT();
 	/*
 	 * These releases aren't strictly required, does even doing them
 	 * make any sense? XXX can nfsm_reply() block?
@@ -2910,8 +2767,6 @@
 		vrele(nd.ni_startdir);
 		nd.ni_startdir = NULL;
 	}
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 	nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
 	if (v3) {
 		if (!error) {
@@ -2924,9 +2779,6 @@
 	/* fall through */
 
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	if (nd.ni_dvp) {
 		if (nd.ni_dvp == nd.ni_vp)
@@ -2944,8 +2796,7 @@
 		FREE(pathcp, M_TEMP);
 
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return (error);
 }
 
@@ -2959,7 +2810,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct vattr va, dirfor, diraft;
 	struct vattr *vap = &va;
 	struct nfs_fattr *fp;
@@ -2974,38 +2825,31 @@
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	struct mount *mp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
+	vfslocked = 0;
 
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
 	if ((mp = vfs_getvfs(&fhp->fh_fsid)) == NULL) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		error = ESTALE;
 		goto out;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	nfsm_srvnamesiz(len);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = CREATE;
-	nd.ni_cnd.cn_flags = LOCKPARENT;
+	nd.ni_cnd.cn_flags = LOCKPARENT | MPSAFE;
 
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
+	vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
 	if (dirp && !v3) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		vrele(dirp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		dirp = NULL;
 	}
 	if (error) {
@@ -3028,8 +2872,6 @@
 	 * nd.ni_vp, if it exists, is referenced but not locked.
 	 */
 
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	vap->va_type = VDIR;
 	if (nd.ni_vp != NULL) {
 		NDFREE(&nd, NDF_ONLY_PNBUF);
@@ -3054,12 +2896,11 @@
 	if (!error) {
 		bzero((caddr_t)fhp, sizeof(nfh));
 		fhp->fh_fsid = nd.ni_vp->v_mount->mnt_stat.f_fsid;
-		error = VFS_VPTOFH(nd.ni_vp, &fhp->fh_fid);
+		error = VOP_VPTOFH(nd.ni_vp, &fhp->fh_fid);
 		if (!error)
 			error = VOP_GETATTR(nd.ni_vp, vap, cred, td);
 	}
 out:
-	NFSD_UNLOCK_ASSERT();
 	if (dirp) {
 		if (dirp == nd.ni_dvp) {
 			diraft_ret = VOP_GETATTR(dirp, &diraft, cred, td);
@@ -3085,8 +2926,6 @@
 			VOP_UNLOCK(dirp, 0, td);
 		}
 	}
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 	nfsm_reply(NFSX_SRVFH(v3) + NFSX_POSTOPATTR(v3) + NFSX_WCCDATA(v3));
 	if (v3) {
 		if (!error) {
@@ -3104,9 +2943,6 @@
 	/* fall through */
 
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (nd.ni_dvp) {
 		NDFREE(&nd, NDF_ONLY_PNBUF);
 		if (nd.ni_dvp == nd.ni_vp && vpexcl)
@@ -3123,8 +2959,7 @@
 	if (dirp)
 		vrele(dirp);
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return (error);
 }
 
@@ -3138,7 +2973,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	caddr_t bpos;
 	int error = 0, len, dirfor_ret = 1, diraft_ret = 1;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
@@ -3149,11 +2984,11 @@
 	fhandle_t *fhp;
 	struct nameidata nd;
 	struct mount *mp = NULL;
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	ndclear(&nd);
+	vfslocked = 0;
 
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
@@ -3161,23 +2996,18 @@
 		error = ESTALE;
 		goto out;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	nfsm_srvnamesiz(len);
 	nd.ni_cnd.cn_cred = cred;
 	nd.ni_cnd.cn_nameiop = DELETE;
-	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF;
+	nd.ni_cnd.cn_flags = LOCKPARENT | LOCKLEAF | MPSAFE;
 	error = nfs_namei(&nd, fhp, len, slp, nam, &md, &dpos,
 		&dirp, v3, &dirfor, &dirfor_ret, td, FALSE);
+	vfslocked = nfsrv_lockedpair_nd(vfslocked, &nd);
 	if (dirp && !v3) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		vrele(dirp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		dirp = NULL;
 	}
 	if (error) {
@@ -3209,9 +3039,6 @@
 	 * Issue or abort op.  Since SAVESTART is not set, path name
 	 * component is freed by the VOP after either.
 	 */
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (!error)
 		error = VOP_RMDIR(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
 	NDFREE(&nd, NDF_ONLY_PNBUF);
@@ -3236,8 +3063,6 @@
 			VOP_UNLOCK(dirp, 0, td);
 		}
 	}
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 	nfsm_reply(NFSX_WCCDATA(v3));
 	error = 0;
 	if (v3)
@@ -3245,9 +3070,6 @@
 	/* fall through */
 
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	NDFREE(&nd, NDF_ONLY_PNBUF);
 	if (nd.ni_dvp) {
 		if (nd.ni_dvp == nd.ni_vp)
@@ -3261,8 +3083,7 @@
 		vrele(dirp);
 
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -3311,7 +3132,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	char *bp, *be;
 	struct mbuf *mp;
 	struct dirent *dp;
@@ -3331,10 +3152,10 @@
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
 	u_quad_t off, toff, verf;
 	u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
 	if (v3) {
@@ -3357,14 +3178,11 @@
 	if (siz > xfer)
 		siz = xfer;
 	fullsiz = siz;
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
 	if (!error && vp->v_type != VDIR) {
 		error = ENOTDIR;
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		vp = NULL;
 	}
 	if (error) {
@@ -3378,8 +3196,6 @@
 	/*
 	 * Obtain lock on vnode for this section of the code
 	 */
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (v3) {
 		error = getret = VOP_GETATTR(vp, &at, cred, td);
 #if 0
@@ -3391,11 +3207,9 @@
 #endif
 	}
 	if (!error)
-		error = nfsrv_access_withgiant(vp, VEXEC, cred, rdonly, td, 0);
+		error = nfsrv_access(vp, VEXEC, cred, rdonly, td, 0);
 	if (error) {
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		vp = NULL;
 		nfsm_reply(NFSX_POSTOPATTR(v3));
 		if (v3)
@@ -3410,7 +3224,6 @@
 	 */
 	MALLOC(rbuf, caddr_t, siz, M_TEMP, M_WAITOK);
 again:
-	NFSD_UNLOCK_ASSERT();
 	iv.iov_base = rbuf;
 	iv.iov_len = fullsiz;
 	io.uio_iov = &iv;
@@ -3438,12 +3251,10 @@
 	VOP_UNLOCK(vp, 0, td);
 	if (error) {
 		vrele(vp);
-		mtx_unlock(&Giant);	/* VFS */
 		vp = NULL;
 		free((caddr_t)rbuf, M_TEMP);
 		if (cookies)
 			free((caddr_t)cookies, M_TEMP);
-		NFSD_LOCK();
 		nfsm_reply(NFSX_POSTOPATTR(v3));
 		if (v3)
 			nfsm_srvpostop_attr(getret, &at);
@@ -3459,9 +3270,7 @@
 		 */
 		if (siz == 0) {
 			vrele(vp);
-			mtx_unlock(&Giant);	/* VFS */
 			vp = NULL;
-			NFSD_LOCK();
 			nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) +
 				2 * NFSX_UNSIGNED);
 			if (v3) {
@@ -3509,8 +3318,6 @@
 		goto again;
 	}
 
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 	len = 3 * NFSX_UNSIGNED;	/* paranoia, probably can be 0 */
 	nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_COOKIEVERF(v3) + siz);
 	if (v3) {
@@ -3587,11 +3394,7 @@
 		cookiep++;
 		ncookies--;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	vrele(vp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
 	vp = NULL;
 	nfsm_clget;
 	*tl = nfsrv_nfs_false;
@@ -3611,14 +3414,9 @@
 	FREE((caddr_t)cookies, M_TEMP);
 
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	if (vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp)
 		vrele(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -3629,7 +3427,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	char *bp, *be;
 	struct mbuf *mp;
 	struct dirent *dp;
@@ -3651,10 +3449,10 @@
 	u_quad_t off, toff, verf;
 	u_long *cookies = NULL, *cookiep; /* needs to be int64_t or off_t */
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 	if (!v3)
 		panic("nfsrv_readdirplus: v3 proc called on a v2 connection");
 	fhp = &nfh.fh_generic;
@@ -3674,15 +3472,12 @@
 	if (siz > xfer)
 		siz = xfer;
 	fullsiz = siz;
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
 	if (!error && vp->v_type != VDIR) {
 		error = ENOTDIR;
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
 		vp = NULL;
-		NFSD_LOCK();
 	}
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);
@@ -3690,8 +3485,6 @@
 		error = 0;
 		goto nfsmout;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	error = getret = VOP_GETATTR(vp, &at, cred, td);
 #if 0
 	/*
@@ -3701,11 +3494,9 @@
 		error = NFSERR_BAD_COOKIE;
 #endif
 	if (!error)
-		error = nfsrv_access_withgiant(vp, VEXEC, cred, rdonly, td, 0);
+		error = nfsrv_access(vp, VEXEC, cred, rdonly, td, 0);
 	if (error) {
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
 		vp = NULL;
 		nfsm_reply(NFSX_V3POSTOPATTR);
 		nfsm_srvpostop_attr(getret, &at);
@@ -3715,7 +3506,6 @@
 	VOP_UNLOCK(vp, 0, td);
 	MALLOC(rbuf, caddr_t, siz, M_TEMP, M_WAITOK);
 again:
-	NFSD_UNLOCK_ASSERT();
 	iv.iov_base = rbuf;
 	iv.iov_len = fullsiz;
 	io.uio_iov = &iv;
@@ -3741,12 +3531,10 @@
 		error = getret;
 	if (error) {
 		vrele(vp);
-		mtx_unlock(&Giant);	/* VFS */
 		vp = NULL;
 		if (cookies)
 			free((caddr_t)cookies, M_TEMP);
 		free((caddr_t)rbuf, M_TEMP);
-		NFSD_LOCK();
 		nfsm_reply(NFSX_V3POSTOPATTR);
 		nfsm_srvpostop_attr(getret, &at);
 		error = 0;
@@ -3761,8 +3549,6 @@
 		 */
 		if (siz == 0) {
 			vrele(vp);
-			mtx_unlock(&Giant);	/* VFS */
-			NFSD_LOCK();
 			vp = NULL;
 			nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
 				2 * NFSX_UNSIGNED);
@@ -3816,23 +3602,19 @@
 	    EOPNOTSUPP) {
 		error = NFSERR_NOTSUPP;
 		vrele(vp);
-		mtx_unlock(&Giant);	/* VFS */
 		vp = NULL;
 		free((caddr_t)cookies, M_TEMP);
 		free((caddr_t)rbuf, M_TEMP);
-		NFSD_LOCK();
 		nfsm_reply(NFSX_V3POSTOPATTR);
 		nfsm_srvpostop_attr(getret, &at);
 		error = 0;
 		goto nfsmout;
 	}
 	vput(nvp);
-	mtx_unlock(&Giant);	/* VFS */
 	nvp = NULL;
 
 	dirlen = len = NFSX_V3POSTOPATTR + NFSX_V3COOKIEVERF +
 	    2 * NFSX_UNSIGNED;
-	NFSD_LOCK();
 	nfsm_reply(cnt);
 	nfsm_srvpostop_attr(getret, &at);
 	tl = nfsm_build(u_int32_t *, 2 * NFSX_UNSIGNED);
@@ -3841,8 +3623,6 @@
 	bp = bpos;
 	be = bp + M_TRAILINGSPACE(mp);
 
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	/* Loop through the records and build reply */
 	while (cpos < cend && ncookies > 0) {
 		if (dp->d_fileno != 0 && dp->d_type != DT_WHT) {
@@ -3859,7 +3639,14 @@
 			bzero((caddr_t)nfhp, NFSX_V3FH);
 			nfhp->fh_fsid =
 				nvp->v_mount->mnt_stat.f_fsid;
-			if (VFS_VPTOFH(nvp, &nfhp->fh_fid)) {
+			/*
+			 * XXXRW: Assert the mountpoints are the same so that
+			 * we know that acquiring Giant based on the
+			 * directory is the right thing for the child.
+			 */
+			KASSERT(nvp->v_mount == vp->v_mount,
+			    ("nfsrv_readdirplus: nvp mount != vp mount"));
+			if (VOP_VPTOFH(nvp, &nfhp->fh_fid)) {
 				vput(nvp);
 				nvp = NULL;
 				goto invalid;
@@ -3898,16 +3685,16 @@
 			fl.fl_off.nfsuquad[0] = 0;
 			fl.fl_off.nfsuquad[1] = txdr_unsigned(*cookiep);
 
-			nfsm_clget_nolock;
+			nfsm_clget;
 			*tl = nfsrv_nfs_true;
 			bp += NFSX_UNSIGNED;
-			nfsm_clget_nolock;
+			nfsm_clget;
 			*tl = 0;
 			bp += NFSX_UNSIGNED;
-			nfsm_clget_nolock;
+			nfsm_clget;
 			*tl = txdr_unsigned(dp->d_fileno);
 			bp += NFSX_UNSIGNED;
-			nfsm_clget_nolock;
+			nfsm_clget;
 			*tl = txdr_unsigned(nlen);
 			bp += NFSX_UNSIGNED;
 
@@ -3915,7 +3702,7 @@
 			xfer = nlen;
 			cp = dp->d_name;
 			while (xfer > 0) {
-				nfsm_clget_nolock;
+				nfsm_clget;
 				if ((bp + xfer) > be)
 					tsiz = be - bp;
 				else
@@ -3936,7 +3723,7 @@
 			xfer = sizeof (struct flrep);
 			cp = (caddr_t)&fl;
 			while (xfer > 0) {
-				nfsm_clget_nolock;
+				nfsm_clget;
 				if ((bp + xfer) > be)
 					tsiz = be - bp;
 				else
@@ -3949,19 +3736,16 @@
 			}
 		}
 invalid:
-		NFSD_UNLOCK_ASSERT();
 		cpos += dp->d_reclen;
 		dp = (struct dirent *)cpos;
 		cookiep++;
 		ncookies--;
 	}
 	vrele(vp);
-	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
-	nfsm_clget_nolock;
+	nfsm_clget;
 	*tl = nfsrv_nfs_false;
 	bp += NFSX_UNSIGNED;
-	NFSD_LOCK();
 	nfsm_clget;
 	if (eofflag)
 		*tl = nfsrv_nfs_true;
@@ -3976,14 +3760,9 @@
 	FREE((caddr_t)cookies, M_TEMP);
 	FREE((caddr_t)rbuf, M_TEMP);
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	if (vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp)
 		vrele(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -3997,7 +3776,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct vattr bfor, aft;
 	struct vnode *vp = NULL;
 	nfsfh_t nfh;
@@ -4009,10 +3788,11 @@
 	u_quad_t off;
 	struct mount *mp = NULL;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
-
-	NFSD_LOCK_ASSERT();
+	int tvfslocked;
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 	if (!v3)
 		panic("nfsrv_commit: v3 proc called on a v2 connection");
 	fhp = &nfh.fh_generic;
@@ -4021,11 +3801,9 @@
 		error = ESTALE;
 		goto ereply;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	(void) vn_start_write(NULL, &mp, V_WAIT);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);		/* The write holds a ref. */
 	tl = nfsm_dissect_nonblock(u_int32_t *, 3 * NFSX_UNSIGNED);
 
 	/*
@@ -4035,15 +3813,15 @@
 	off = fxdr_hyper(tl);
 	tl += 2;
 	cnt = fxdr_unsigned(int, *tl);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &tvfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
+	vfslocked = nfsrv_lockedpair(vfslocked, tvfslocked);
 	if (error) {
 		nfsm_reply(2 * NFSX_UNSIGNED);
 		nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
 		error = 0;
 		goto nfsmout;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	for_ret = VOP_GETATTR(vp, &bfor, cred, td);
 
 	if (cnt > MAX_COMMIT_COUNT) {
@@ -4131,11 +3909,8 @@
 
 	aft_ret = VOP_GETATTR(vp, &aft, cred, td);
 	vput(vp);
-	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
-	NFSD_LOCK();
 ereply:
-	NFSD_LOCK_ASSERT();
 	nfsm_reply(NFSX_V3WCCDATA + NFSX_V3WRITEVERF);
 	nfsm_srvwcc_data(for_ret, &bfor, aft_ret, &aft);
 	if (!error) {
@@ -4148,14 +3923,10 @@
 		error = 0;
 	}
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	if (vp)
 		vput(vp);
 	vn_finished_write(mp);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -4169,7 +3940,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct statfs *sf;
 	struct nfs_statfs *sfp;
 	caddr_t bpos;
@@ -4182,13 +3953,14 @@
 	fhandle_t *fhp;
 	struct statfs statfs;
 	u_quad_t tval;
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
+	vfslocked = 0;
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);
 		if (v3)
@@ -4197,14 +3969,10 @@
 		goto nfsmout;
 	}
 	sf = &statfs;
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	error = VFS_STATFS(vp->v_mount, sf, td);
 	getret = VOP_GETATTR(vp, &at, cred, td);
 	vput(vp);
-	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
-	NFSD_LOCK();
 	nfsm_reply(NFSX_POSTOPATTR(v3) + NFSX_STATFS(v3));
 	if (v3)
 		nfsm_srvpostop_attr(getret, &at);
@@ -4250,14 +4018,9 @@
 			sfp->sf_bavail = txdr_unsigned(sf->f_bavail);
 	}
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	if (vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp)
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -4271,7 +4034,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct nfsv3_fsinfo *sip;
 	caddr_t bpos;
 	int error = 0, rdonly, getret = 1, pref;
@@ -4283,15 +4046,16 @@
 	u_quad_t maxfsize;
 	struct statfs sb;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	if (!v3)
 		panic("nfsrv_fsinfo: v3 proc called on a v2 connection");
 	fhp = &nfh.fh_generic;
+	vfslocked = 0;
 	nfsm_srvmtofh(fhp);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);
 		nfsm_srvpostop_attr(getret, &at);
@@ -4299,17 +4063,13 @@
 		goto nfsmout;
 	}
 
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	/* XXX Try to make a guess on the max file size. */
 	VFS_STATFS(vp->v_mount, &sb, td);
 	maxfsize = (u_quad_t)0x80000000 * sb.f_bsize - 1;
 
 	getret = VOP_GETATTR(vp, &at, cred, td);
 	vput(vp);
-	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
-	NFSD_LOCK();
 	nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3FSINFO);
 	nfsm_srvpostop_attr(getret, &at);
 	sip = nfsm_build(struct nfsv3_fsinfo *, NFSX_V3FSINFO);
@@ -4337,14 +4097,9 @@
 		NFSV3FSINFO_SYMLINK | NFSV3FSINFO_HOMOGENEOUS |
 		NFSV3FSINFO_CANSETTIME);
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	if (vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp)
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -4358,7 +4113,7 @@
 	struct mbuf *mrep = nfsd->nd_mrep, *md = nfsd->nd_md;
 	struct sockaddr *nam = nfsd->nd_nam;
 	caddr_t dpos = nfsd->nd_dpos;
-	struct ucred *cred = &nfsd->nd_cr;
+	struct ucred *cred = nfsd->nd_cr;
 	struct nfsv3_pathconf *pc;
 	caddr_t bpos;
 	int error = 0, rdonly, getret = 1;
@@ -4369,23 +4124,21 @@
 	nfsfh_t nfh;
 	fhandle_t *fhp;
 	int v3 = (nfsd->nd_flag & ND_NFSV3);
-
-	NFSD_LOCK_ASSERT();
+	int vfslocked;
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	if (!v3)
 		panic("nfsrv_pathconf: v3 proc called on a v2 connection");
 	fhp = &nfh.fh_generic;
 	nfsm_srvmtofh(fhp);
-	error = nfsrv_fhtovp(fhp, 1, &vp, cred, slp, nam, &rdonly, TRUE);
+	error = nfsrv_fhtovp(fhp, 1, &vp, &vfslocked, cred, slp,
+	    nam, &rdonly, TRUE);
 	if (error) {
 		nfsm_reply(NFSX_UNSIGNED);
 		nfsm_srvpostop_attr(getret, &at);
 		error = 0;
 		goto nfsmout;
 	}
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
 	error = VOP_PATHCONF(vp, _PC_LINK_MAX, &linkmax);
 	if (!error)
 		error = VOP_PATHCONF(vp, _PC_NAME_MAX, &namemax);
@@ -4395,9 +4148,7 @@
 		error = VOP_PATHCONF(vp, _PC_NO_TRUNC, &notrunc);
 	getret = VOP_GETATTR(vp, &at, cred, td);
 	vput(vp);
-	mtx_unlock(&Giant);	/* VFS */
 	vp = NULL;
-	NFSD_LOCK();
 	nfsm_reply(NFSX_V3POSTOPATTR + NFSX_V3PATHCONF);
 	nfsm_srvpostop_attr(getret, &at);
 	if (error) {
@@ -4419,14 +4170,9 @@
 	pc->pc_caseinsensitive = nfsrv_nfs_false;
 	pc->pc_casepreserving = nfsrv_nfs_true;
 nfsmout:
-	NFSD_LOCK_ASSERT();
-	if (vp) {
-		NFSD_UNLOCK();
-		mtx_lock(&Giant);	/* VFS */
+	if (vp)
 		vput(vp);
-		mtx_unlock(&Giant);	/* VFS */
-		NFSD_LOCK();
-	}
+	VFS_UNLOCK_GIANT(vfslocked);
 	return(error);
 }
 
@@ -4443,12 +4189,9 @@
 	int error = NFSERR_RETVOID;
 	struct mbuf *mb, *mreq;
 
-	NFSD_LOCK_ASSERT();
-
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	nfsm_reply(0);
 nfsmout:
-	NFSD_LOCK_ASSERT();
 	return (error);
 }
 
@@ -4465,8 +4208,6 @@
 	int error;
 	struct mbuf *mb, *mreq;
 
-	NFSD_LOCK_ASSERT();
-
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 	if (nfsd->nd_repstat)
 		error = nfsd->nd_repstat;
@@ -4475,7 +4216,6 @@
 	nfsm_reply(0);
 	error = 0;
 nfsmout:
-	NFSD_LOCK_ASSERT();
 	return (error);
 }
 
@@ -4493,20 +4233,15 @@
  *
  * The exception to rule 2 is EPERM. If a file is IMMUTABLE, VOP_ACCESS()
  * will return EPERM instead of EACCESS. EPERM is always an error.
- *
- * There are two versions: one to be called while holding Giant (which is
- * needed due to use of VFS), and the other called with the NFS server lock
- * (which will be dropped and reacquired).  This is necessary because
- * nfsrv_access checks are required from both classes of contexts.
  */
 static int
-nfsrv_access_withgiant(struct vnode *vp, int flags, struct ucred *cred,
+nfsrv_access(struct vnode *vp, int flags, struct ucred *cred,
     int rdonly, struct thread *td, int override)
 {
 	struct vattr vattr;
 	int error;
 
-	GIANT_REQUIRED;
+	VFS_ASSERT_GIANT(vp->v_mount);
 
 	nfsdbprintf(("%s %d\n", __FILE__, __LINE__));
 
@@ -4547,19 +4282,3 @@
 		error = 0;
 	return (error);
 }
-
-static int
-nfsrv_access(struct vnode *vp, int flags, struct ucred *cred, int rdonly,
-    struct thread *td, int override)
-{
-	int error;
-
-	NFSD_LOCK_ASSERT();
-
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
-	error = nfsrv_access_withgiant(vp, flags, cred, rdonly, td, override);
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
-	return (error);
-}
Index: nfsrvcache.h
===================================================================
RCS file: /home/cvs/src/sys/nfsserver/nfsrvcache.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/nfsserver/nfsrvcache.h -L sys/nfsserver/nfsrvcache.h -u -r1.1.1.1 -r1.2
--- sys/nfsserver/nfsrvcache.h
+++ sys/nfsserver/nfsrvcache.h
@@ -30,7 +30,7 @@
  * SUCH DAMAGE.
  *
  *	@(#)nfsrvcache.h	8.3 (Berkeley) 3/30/95
- * $FreeBSD: src/sys/nfsserver/nfsrvcache.h,v 1.17 2005/01/07 01:45:51 imp Exp $
+ * $FreeBSD: src/sys/nfsserver/nfsrvcache.h,v 1.19 2006/06/23 00:42:26 mohans Exp $
  */
 
 #ifndef _NFSSERVER_NFSRVCACHE_H_
@@ -41,8 +41,8 @@
 /*
  * Definitions for the server recent request cache
  */
-
-#define	NFSRVCACHESIZ	64
+#define NFSRVCACHE_MAX_SIZE	2048
+#define NFSRVCACHE_MIN_SIZE	  64
 
 struct nfsrvcache {
 	TAILQ_ENTRY(nfsrvcache) rc_lru;		/* LRU chain */
Index: nfs_srvsubs.c
===================================================================
RCS file: /home/cvs/src/sys/nfsserver/nfs_srvsubs.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -L sys/nfsserver/nfs_srvsubs.c -L sys/nfsserver/nfs_srvsubs.c -u -r1.2 -r1.3
--- sys/nfsserver/nfs_srvsubs.c
+++ sys/nfsserver/nfs_srvsubs.c
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvsubs.c,v 1.136.2.2 2006/04/04 15:29:51 cel Exp $");
+__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvsubs.c,v 1.149.2.1.2.1 2008/02/14 14:12:13 remko Exp $");
 
 /*
  * These functions support the macros and help fiddle mbuf chains for
@@ -53,6 +53,7 @@
 #include <sys/vnode.h>
 #include <sys/namei.h>
 #include <sys/mbuf.h>
+#include <sys/refcount.h>
 #include <sys/socket.h>
 #include <sys/stat.h>
 #include <sys/malloc.h>
@@ -97,8 +98,9 @@
 struct nfsd_head nfsd_head;
 int nfsd_head_flag;
 
-static int nfs_prev_nfssvc_sy_narg;
-static sy_call_t *nfs_prev_nfssvc_sy_call;
+static int nfssvc_offset = SYS_nfssvc;
+static struct sysent nfssvc_prev_sysent;
+MAKE_SYSENT(nfssvc);
 
 struct mtx nfsd_mtx;
 
@@ -521,9 +523,9 @@
 static int
 nfsrv_modevent(module_t mod, int type, void *data)
 {
+	static int registered;
 	int error = 0;
 
-	NET_LOCK_GIANT();
 	switch (type) {
 	case MOD_LOAD:
 		mtx_init(&nfsd_mtx, "nfsd_mtx", NULL, MTX_DEF);
@@ -546,17 +548,15 @@
 		nfsrv_initcache();	/* Init the server request cache */
 		NFSD_LOCK();
 		nfsrv_init(0);		/* Init server data structures */
-		if (debug_mpsafenet)
-			callout_init(&nfsrv_callout, CALLOUT_MPSAFE);
-		else
-			callout_init(&nfsrv_callout, 0);
+		callout_init(&nfsrv_callout, CALLOUT_MPSAFE);
 		NFSD_UNLOCK();
 		nfsrv_timer(0);
 
-		nfs_prev_nfssvc_sy_narg = sysent[SYS_nfssvc].sy_narg;
-		sysent[SYS_nfssvc].sy_narg = 2 | SYF_MPSAFE;
-		nfs_prev_nfssvc_sy_call = sysent[SYS_nfssvc].sy_call;
-		sysent[SYS_nfssvc].sy_call = (sy_call_t *)nfssvc;
+		error = syscall_register(&nfssvc_offset, &nfssvc_sysent,
+		    &nfssvc_prev_sysent);
+		if (error)
+			break;
+		registered = 1;
 		break;
 
 	case MOD_UNLOAD:
@@ -565,16 +565,16 @@
 			break;
 		}
 
-		callout_stop(&nfsrv_callout);
-		sysent[SYS_nfssvc].sy_narg = nfs_prev_nfssvc_sy_narg;
-		sysent[SYS_nfssvc].sy_call = nfs_prev_nfssvc_sy_call;
+		if (registered)
+			syscall_deregister(&nfssvc_offset, &nfssvc_prev_sysent);
+		callout_drain(&nfsrv_callout);
+		nfsrv_destroycache();	/* Free the server request cache */
 		mtx_destroy(&nfsd_mtx);
 		break;
 	default:
 		error = EOPNOTSUPP;
 		break;
 	}
-	NET_UNLOCK_GIANT();
 	return error;
 }
 static moduledata_t nfsserver_mod = {
@@ -618,11 +618,11 @@
 	int error, rdonly, linklen;
 	struct componentname *cnp = &ndp->ni_cnd;
 	int lockleaf = (cnp->cn_flags & LOCKLEAF) != 0;
+	int dvfslocked;
+	int vfslocked;
 
-	NFSD_LOCK_ASSERT();
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
-
+	vfslocked = 0;
+	dvfslocked = 0;
 	*retdirp = NULL;
 	cnp->cn_flags |= NOMACCHECK;
 	cnp->cn_pnbuf = uma_zalloc(namei_zone, M_WAITOK);
@@ -666,14 +666,11 @@
 	/*
 	 * Extract and set starting directory.
 	 */
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
-	error = nfsrv_fhtovp(fhp, FALSE, &dp, ndp->ni_cnd.cn_cred, slp,
-	    nam, &rdonly, pubflag);
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	error = nfsrv_fhtovp(fhp, FALSE, &dp, &dvfslocked,
+	    ndp->ni_cnd.cn_cred, slp, nam, &rdonly, pubflag);
 	if (error)
 		goto out;
+	vfslocked = VFS_LOCK_GIANT(dp->v_mount);
 	if (dp->v_type != VDIR) {
 		vrele(dp);
 		error = ENOTDIR;
@@ -751,8 +748,14 @@
 	if (pubflag) {
 		ndp->ni_rootdir = rootvnode;
 		ndp->ni_loopcnt = 0;
-		if (cnp->cn_pnbuf[0] == '/')
+		if (cnp->cn_pnbuf[0] == '/') {
+			int tvfslocked;
+
+			tvfslocked = VFS_LOCK_GIANT(rootvnode->v_mount);
+			VFS_UNLOCK_GIANT(vfslocked);
 			dp = rootvnode;
+			vfslocked = tvfslocked;
+		}
 	} else {
 		cnp->cn_flags |= NOCROSSMOUNT;
 	}
@@ -777,7 +780,11 @@
 		 * In either case ni_startdir will be dereferenced and NULLed
 		 * out.
 		 */
+		if (vfslocked)
+			ndp->ni_cnd.cn_flags |= GIANTHELD;
 		error = lookup(ndp);
+		vfslocked = (ndp->ni_cnd.cn_flags & GIANTHELD) != 0;
+		ndp->ni_cnd.cn_flags &= ~GIANTHELD;
 		if (error)
 			break;
 
@@ -875,6 +882,10 @@
 	}
 	if (!lockleaf)
 		cnp->cn_flags &= ~LOCKLEAF;
+	if (cnp->cn_flags & GIANTHELD) {
+		mtx_unlock(&Giant);
+		cnp->cn_flags &= ~GIANTHELD;
+	}
 
 	/*
 	 * nfs_namei() guarentees that fields will not contain garbage
@@ -888,11 +899,21 @@
 		ndp->ni_dvp = NULL;
 		ndp->ni_startdir = NULL;
 		cnp->cn_flags &= ~HASBUF;
+		VFS_UNLOCK_GIANT(vfslocked);
+		vfslocked = 0;
 	} else if ((ndp->ni_cnd.cn_flags & (WANTPARENT|LOCKPARENT)) == 0) {
 		ndp->ni_dvp = NULL;
 	}
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	/*
+	 * This differs from normal namei() in that even on failure we may
+	 * return with Giant held due to the dirp return.  Make sure we only
+	 * have not recursed however.  The calling code only expects to drop
+	 * one acquire.
+	 */
+	if (vfslocked || dvfslocked)
+		ndp->ni_cnd.cn_flags |= GIANTHELD;
+	if (vfslocked && dvfslocked)
+		VFS_UNLOCK_GIANT(vfslocked);
 	return (error);
 }
 
@@ -907,8 +928,6 @@
 	int count, i;
 	char *cp;
 
-	NFSD_LOCK_DONTCARE();
-
 	/*
 	 * Trim from tail.  Scan the mbuf chain,
 	 * calculating its length and finding the last mbuf.
@@ -1059,7 +1078,7 @@
  *	- if not lockflag unlock it with VOP_UNLOCK()
  */
 int
-nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp,
+nfsrv_fhtovp(fhandle_t *fhp, int lockflag, struct vnode **vpp, int *vfslockedp,
     struct ucred *cred, struct nfssvc_sock *slp, struct sockaddr *nam,
     int *rdonlyp, int pubflag)
 {
@@ -1071,9 +1090,9 @@
 #ifdef MNT_EXNORESPORT		/* XXX needs mountd and /etc/exports help yet */
 	struct sockaddr_int *saddr;
 #endif
+	int vfslocked;
 
-	NFSD_LOCK_ASSERT();
-
+	*vfslockedp = 0;
 	*vpp = NULL;
 
 	if (nfs_ispublicfh(fhp)) {
@@ -1085,8 +1104,7 @@
 	mp = vfs_getvfs(&fhp->fh_fsid);
 	if (!mp)
 		return (ESTALE);
-	NFSD_UNLOCK();
-	mtx_lock(&Giant);	/* VFS */
+	vfslocked = VFS_LOCK_GIANT(mp);
 	error = VFS_CHECKEXP(mp, nam, &exflags, &credanon);
 	if (error)
 		goto out;
@@ -1123,8 +1141,11 @@
 	if (!lockflag)
 		VOP_UNLOCK(*vpp, 0, td);
 out:
-	mtx_unlock(&Giant);	/* VFS */
-	NFSD_LOCK();
+	vfs_rel(mp);
+	if (error) {
+		VFS_UNLOCK_GIANT(vfslocked);
+	} else
+		*vfslockedp = vfslocked;
 	return (error);
 }
 
@@ -1200,7 +1221,6 @@
 	const short *defaulterrp, *errp;
 	int e;
 
-	NFSD_LOCK_DONTCARE();
 
 	if (nd->nd_flag & ND_NFSV3) {
 	    if (nd->nd_procnum <= NFSPROC_COMMIT) {
@@ -1234,8 +1254,6 @@
 	int i, j;
 	gid_t v;
 
-	NFSD_LOCK_DONTCARE();
-
 	/* Insertion sort. */
 	for (i = 1; i < num; i++) {
 		v = list[i];
@@ -1247,25 +1265,6 @@
 }
 
 /*
- * copy credentials making sure that the result can be compared with bcmp().
- */
-void
-nfsrv_setcred(struct ucred *incred, struct ucred *outcred)
-{
-	int i;
-
-	NFSD_LOCK_DONTCARE();
-
-	bzero((caddr_t)outcred, sizeof (struct ucred));
-	outcred->cr_ref = 1;
-	outcred->cr_uid = incred->cr_uid;
-	outcred->cr_ngroups = incred->cr_ngroups;
-	for (i = 0; i < incred->cr_ngroups; i++)
-		outcred->cr_groups[i] = incred->cr_groups[i];
-	nfsrvw_sort(outcred->cr_groups, outcred->cr_ngroups);
-}
-
-/*
  * Helper functions for macros.
  */
 
@@ -1274,8 +1273,6 @@
 {
 	u_int32_t *tl;
 
-	NFSD_LOCK_DONTCARE();
-
 	if (v3) {
 		tl = nfsm_build_xx(NFSX_UNSIGNED + NFSX_V3FH, mb, bpos);
 		*tl++ = txdr_unsigned(NFSX_V3FH);
@@ -1302,8 +1299,6 @@
 {
 	u_int32_t *tl;
 
-	NFSD_LOCK_DONTCARE();
-
 	tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
 	if (tl == NULL)
 		return EBADRPC;
@@ -1331,28 +1326,35 @@
 	return 0;
 }
 
+int
+nfsm_srvnamesiz0_xx(int *s, int m, struct mbuf **md, caddr_t *dpos)
+{
+	u_int32_t *tl;
+
+	tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
+	if (tl == NULL)
+		return EBADRPC;
+	*s = fxdr_unsigned(int32_t, *tl);
+	if (*s > m)
+		return NFSERR_NAMETOL;
+	if (*s < 0)
+		return EBADRPC;
+	return 0;
+}
+
 void
 nfsm_clget_xx(u_int32_t **tl, struct mbuf *mb, struct mbuf **mp,
-    char **bp, char **be, caddr_t bpos, int droplock)
+    char **bp, char **be, caddr_t bpos)
 {
 	struct mbuf *nmp;
 
-	NFSD_LOCK_DONTCARE();
-
-	if (droplock)
-		NFSD_LOCK_ASSERT();
-	else
-		NFSD_UNLOCK_ASSERT();
+	NFSD_UNLOCK_ASSERT();
 
 	if (*bp >= *be) {
 		if (*mp == mb)
 			(*mp)->m_len += *bp - bpos;
-		if (droplock)
-			NFSD_UNLOCK();
 		MGET(nmp, M_TRYWAIT, MT_DATA);
 		MCLGET(nmp, M_TRYWAIT);
-		if (droplock)
-			NFSD_LOCK();
 		nmp->m_len = NFSMSIZ(nmp);
 		(*mp)->m_next = nmp;
 		*mp = nmp;
@@ -1369,8 +1371,6 @@
 	u_int32_t *tl;
 	int fhlen;
 
-	NFSD_LOCK_DONTCARE();
-
 	if (nfsd->nd_flag & ND_NFSV3) {
 		tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
 		if (tl == NULL)
@@ -1398,8 +1398,6 @@
 	u_int32_t *tl;
 	int toclient = 0;
 
-	NFSD_LOCK_DONTCARE();
-
 	tl = nfsm_dissect_xx_nonblock(NFSX_UNSIGNED, md, dpos);
 	if (tl == NULL)
 		return EBADRPC;
Index: nfs_srvcache.c
===================================================================
RCS file: /home/cvs/src/sys/nfsserver/nfs_srvcache.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/nfsserver/nfs_srvcache.c -L sys/nfsserver/nfs_srvcache.c -u -r1.1.1.1 -r1.2
--- sys/nfsserver/nfs_srvcache.c
+++ sys/nfsserver/nfs_srvcache.c
@@ -33,7 +33,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvcache.c,v 1.40 2005/01/07 01:45:51 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/nfsserver/nfs_srvcache.c,v 1.44 2007/03/17 18:18:08 jeff Exp $");
 
 /*
  * Reference: Chet Juszczak, "Improving the Performance and Correctness
@@ -49,6 +49,7 @@
 #include <sys/mutex.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>	/* for sodupsockaddr */
+#include <sys/eventhandler.h>
 
 #include <netinet/in.h>
 #include <nfs/rpcv2.h>
@@ -57,13 +58,14 @@
 #include <nfsserver/nfsrvcache.h>
 
 static long numnfsrvcache;
-static long desirednfsrvcache = NFSRVCACHESIZ;
+static long desirednfsrvcache;
 
 #define	NFSRCHASH(xid) \
 	(&nfsrvhashtbl[((xid) + ((xid) >> 24)) & nfsrvhash])
 static LIST_HEAD(nfsrvhash, nfsrvcache) *nfsrvhashtbl;
 static TAILQ_HEAD(nfsrvlru, nfsrvcache) nfsrvlruhead;
 static u_long nfsrvhash;
+static eventhandler_tag nfsrv_nmbclusters_tag;
 
 #define TRUE	1
 #define	FALSE	0
@@ -122,15 +124,43 @@
 	FALSE,
 };
 
+/* 
+ * Size the NFS server's duplicate request cache at 1/2 the nmbclsters, floating 
+ * within a (64, 2048) range. This is to prevent all mbuf clusters being tied up 
+ * in the NFS dupreq cache for small values of nmbclusters. 
+ */
+static void
+nfsrvcache_size_change(void *tag)
+{
+	desirednfsrvcache = nmbclusters /2;
+	if (desirednfsrvcache > NFSRVCACHE_MAX_SIZE)
+		desirednfsrvcache = NFSRVCACHE_MAX_SIZE;
+	if (desirednfsrvcache < NFSRVCACHE_MIN_SIZE)
+		desirednfsrvcache = NFSRVCACHE_MIN_SIZE;	
+}
+
 /*
  * Initialize the server request cache list
  */
 void
 nfsrv_initcache(void)
 {
-
+	nfsrvcache_size_change(NULL);
 	nfsrvhashtbl = hashinit(desirednfsrvcache, M_NFSD, &nfsrvhash);
 	TAILQ_INIT(&nfsrvlruhead);
+	nfsrv_nmbclusters_tag = EVENTHANDLER_REGISTER(nmbclusters_change,
+	    nfsrvcache_size_change, NULL, EVENTHANDLER_PRI_FIRST);
+}
+
+/*
+ * Teardown the server request cache list
+ */
+void
+nfsrv_destroycache(void)
+{
+	KASSERT(TAILQ_EMPTY(&nfsrvlruhead), ("%s: pending requests", __func__));
+	EVENTHANDLER_DEREGISTER(nmbclusters_change, nfsrv_nmbclusters_tag);
+	hashdestroy(nfsrvhashtbl, M_NFSD, nfsrvhash);
 }
 
 /*
@@ -188,9 +218,11 @@
 				ret = RC_DROPIT;
 			} else if (rp->rc_flag & RC_REPSTATUS) {
 				nfsrvstats.srvcache_nonidemdonehits++;
+				NFSD_UNLOCK();
 				*repp = nfs_rephead(0, nd, rp->rc_status,
 				    &mb, &bpos);
 				ret = RC_REPLY;
+				NFSD_LOCK();
 			} else if (rp->rc_flag & RC_REPMBUF) {
 				nfsrvstats.srvcache_nonidemdonehits++;
 				NFSD_UNLOCK();
@@ -342,8 +374,7 @@
 
 	NFSD_LOCK_ASSERT();
 
-	for (rp = TAILQ_FIRST(&nfsrvlruhead); rp != 0; rp = nextrp) {
-		nextrp = TAILQ_NEXT(rp, rc_lru);
+	TAILQ_FOREACH_SAFE(rp, &nfsrvlruhead, rc_lru, nextrp) {
 		LIST_REMOVE(rp, rc_hash);
 		TAILQ_REMOVE(&nfsrvlruhead, rp, rc_lru);
 		if (rp->rc_flag & RC_REPMBUF)
--- sys/pccard/pccard_nbk.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/*-
- * Copyright (c) 1999, 2001 M. Warner Losh.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/pccard/pccard_nbk.h,v 1.7 2005/01/07 02:29:17 imp Exp $
- */
-
-#ifndef PCCARD_PCCARD_NBK_H
-#define PCCARD_PCCARD_NBK_H
-
-SYSCTL_DECL(_machdep_pccard);
-
-struct pccard_device;
-extern devclass_t pccard_devclass;
-
-#endif /* ! PCCARD_PCCARD_NBK_H */
--- sys/pccard/driver.h
+++ /dev/null
@@ -1,24 +0,0 @@
-/*-
- * pccard driver interface.
- * Bruce Evans, November 1995.
- * This file is in the public domain.
- *
- * $FreeBSD: src/sys/pccard/driver.h,v 1.14 2001/03/22 05:49:18 imp Exp $
- */
-
-#ifndef _PCCARD_DRIVER_H_
-#define	_PCCARD_DRIVER_H_
-
-struct pccard_device;
-
-void	pccard_add_driver(struct pccard_device *);
-
-enum beepstate { BEEP_OFF, BEEP_ON };
-
-void	pccard_insert_beep(void);
-void	pccard_remove_beep(void);
-void	pccard_success_beep(void);
-void	pccard_failure_beep(void);
-int	pccard_beep_select(int);
-
-#endif /* !_PCCARD_DRIVER_H_ */
--- sys/pccard/slot.h
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- *	Slot structures for PC-CARD interface.
- *	Each slot has a controller specific structure
- *	attached to it. A slot number allows
- *	mapping from the character device to the
- *	slot structure. This is separate to the
- *	controller slot number to allow multiple controllers
- *	to be accessed.
- *-------------------------------------------------------------------------
- */
-
-/*-
- * Copyright (c) 1995 Andrew McRae.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/pccard/slot.h,v 1.40 2005/01/07 02:29:17 imp Exp $
- */
-
-#ifndef _PCCARD_SLOT_H
-#define _PCCARD_SLOT_H
-
-/*
- * Normally we shouldn't include stuff here, but we're trying to be
- * compatible with the long, dark hand of the past.
- */
-#include <sys/param.h>
-#include <sys/bus.h>
-#include <machine/bus.h>
-#include <sys/rman.h>
-#include <machine/resource.h>
-#if __FreeBSD_version >= 500000
-#include <sys/selinfo.h>
-#else
-#include <sys/select.h>
-#endif
-
-/*
- *	Controller data - Specific to each slot controller.
- */
-struct slot;
-struct slot_ctrl {
-	void	(*mapirq)(struct slot *, int);
-				/* Map irq */
-	int	(*mapmem)(struct slot *, int);
-				/* Map memory */
-	int	(*mapio)(struct slot *, int);
-				/* Map io */
-	void	(*reset)(void *);
-				/* init */
-	void	(*disable)(struct slot *);
-				/* Disable slot */
-	int	(*power)(struct slot *);
-				/* Set power values */
-	int	(*ioctl)(struct slot *, int, caddr_t);
-				/* ioctl to lower level */
-	void	(*resume)(struct slot *);
-				/* suspend/resume support */
-	int	maxmem;		/* Number of allowed memory windows */
-	int	maxio;		/* Number of allowed I/O windows */
-};
-
-/*
- *	Device structure for cards. Each card may have one
- *	or more pccard drivers attached to it; each driver is assumed
- *	to require at most one interrupt handler, one I/O block
- *	and one memory block. This structure is used to link the different
- *	devices together.
- */
-struct pccard_devinfo {
-	uint8_t		name[128];
-	int		running;	/* Current state of driver */
-	uint8_t		misc[DEV_MISC_LEN]; /* For any random info */
-	uint8_t		manufstr[DEV_MAX_CIS_LEN];
-	uint8_t		versstr[DEV_MAX_CIS_LEN];
-	uint8_t		cis3str[DEV_MAX_CIS_LEN];
-	uint8_t		cis4str[DEV_MAX_CIS_LEN];
-	uint32_t	manufacturer;	/* Manufacturer ID */
-	uint32_t	product;	/* Product ID */
-	uint32_t	prodext;	/* Product ID (extended) */
-	struct slot	*slt;		/* Back pointer to slot */
-	struct resource_list resources;
-};
-
-/*
- *	Per-slot structure.
- */
-struct slot {
-	int slotnum;			/* Slot number */
-	int flags;			/* Slot flags (see below) */
-	int rwmem;			/* Read/write flags */
-	int irq;			/* IRQ allocated (0 = none) */
-
-	/*
-	 *	flags.
-	 */
-	unsigned int 	insert_seq;	/* Firing up under the card */
-	struct callout_handle insert_ch;/* Insert event timeout handle */
-	struct callout_handle poff_ch;	/* Power Off timeout handle */
-
-	enum cardstate 	state, laststate; /* Current/last card states */
-	struct selinfo	selp;		/* Info for select */
-	struct mem_desc	mem[NUM_MEM_WINDOWS];	/* Memory windows */
-	struct io_desc	io[NUM_IO_WINDOWS];	/* I/O windows */
-	struct power	pwr;		/* Power values */
-	struct slot_ctrl *ctrl;		/* Per-controller data */
-	void		*cdata;		/* Controller specific data */
-	int		pwr_off_pending;/* Power status of slot */
-	device_t	dev;		/* Config system device. */
-	struct cdev *d;		/* fs device */
-};
-
-#define PCCARD_DEVICE2SOFTC(d)	((struct slot *) device_get_softc(d))
-#define PCCARD_DEV2SOFTC(d)	((struct slot *) (d)->si_drv1)
-
-enum card_event { card_removed, card_inserted, card_deactivated };
-
-struct slot	*pccard_init_slot(device_t, struct slot_ctrl *);
-void		 pccard_event(struct slot *, enum card_event);
-int		 pccard_suspend(device_t);
-int		 pccard_resume(device_t);
-
-#endif /* !_PCCARD_SLOT_H */
--- sys/pccard/pcic_pci.h
+++ /dev/null
@@ -1,270 +0,0 @@
-/*-
- * Copyright (c) 2001 M. Warner Losh. All rights reserved.
- * Copyright (c) 1997 Ted Faber. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *
- * 1. Redistributions of source code must retain the above copyright
- *    notice immediately at the beginning of the file, without modification,
- *    this list of conditions, and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Absolutely no warranty of function or purpose is made by the author
- *    Ted Faber.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/pccard/pcic_pci.h,v 1.37 2005/01/07 02:29:17 imp Exp $
- */
-
-/* Share the devid database with NEWCARD */
-#include <dev/pccbb/pccbbdevid.h>
-
-/* CL-PD683x CardBus defines */
-#define	CLPD6833_CFG_MISC_1		0x98
-
-/* Configuration constants */
-#define	CLPD6832_BCR_MGMT_IRQ_ENA	0x0800
-#define CLPD6833_CM1_MGMT_EXCA_ENA	0x0001	/* Set ExCA, Clr PCI */
-
-/* End of CL-PD6832 defines */
-/* Texas Instruments PCI-1130/1131 CardBus Controller */
-#define TI113X_PCI_SYSTEM_CONTROL	0x80	/* System Control */
-#define TI12XX_PCI_MULTIMEDIA_CONTROL	0x84	/* Zoom Video */
-#define TI12XX_PCI_MFUNC		0x8c	/* multifunction pins */
-#define TI113X_PCI_RETRY_STATUS		0x90	/* Retry Status */
-#define TI113X_PCI_CARD_CONTROL		0x91	/* Card Control */
-#define TI113X_PCI_DEVICE_CONTROL	0x92	/* Device Control */
-#define TI113X_PCI_BUFFER_CONTROL	0x93	/* Buffer Control */
-#define TI12XX_PCI_DIAGNOSTIC		0x93	/* Diagnostic register */
-#define TI113X_PCI_SOCKET_DMA0		0x94	/* Socket DMA Register 0 */
-#define TI113X_PCI_SOCKET_DMA1		0x98	/* Socket DMA Register 1 */
-
-/* Card control register (TI113X_SYSTEM_CONTROL == 0x80) */
-#define TI113X_SYSCNTL_INTRTIE		0x20000000u
-#define TI12XX_SYSCNTL_PCI_CLOCK	0x08000000u
-#define TI113X_SYSCNTL_SMIENB		0x00800000u
-#define TI113X_SYSCNTL_VCC_PROTECT	0x00200000u
-#define TI113X_SYSCNTL_CLKRUN_SEL	0x00000080u
-#define	TI113X_SYSCNTL_PWRSAVINGS	0x00000040u
-#define TI113X_SYSCNTL_KEEP_CLK		0x00000002u
-#define TI113X_SYSCNTL_CLKRUN_ENA	0x00000001u
-
-/* MFUNC register (TI12XX_MFUNC == 0x8c) */
-#define TI12XX_MFUNC_PIN0		0x0000000fu
-#define   TI12XX_MFUNC_PIN0_INTA	0x2
-#define TI12XX_MFUNC_PIN1		0x000000f0u
-#define   TI12XX_MFUNC_PIN1_INTB	0x20
-#define TI12XX_MFUNC_PIN2		0x00000f00u
-#define TI12XX_MFUNC_PIN3		0x0000f000u
-#define TI12XX_MFUNC_PIN4		0x000f0000u
-#define TI12XX_MFUNC_PIN5		0x00f00000u
-#define TI12XX_MFUNC_PIN6		0x0f000000u
-
-/* Card control register (TI113X_CARD_CONTROL == 0x91) */
-#define TI113X_CARDCNTL_RING_ENA	0x80u
-#define TI113X_CARDCNTL_ZOOM_VIDEO	0x40u
-#define TI113X_CARDCNTL_PCI_IRQ_ENA	0x20u
-#define TI113X_CARDCNTL_PCI_IREQ	0x10u
-#define TI113X_CARDCNTL_PCI_CSC		0x08u
-#define	TI113X_CARDCNTL_MASK		(TI113X_CARDCNTL_PCI_IRQ_ENA | TI113X_CARDCNTL_PCI_IREQ | TI113X_CARDCNTL_PCI_CSC)
-#define	TI113X_FUNC0_VALID		TI113X_CARDCNTL_MASK
-#define	TI113X_FUNC1_VALID		(TI113X_CARDCNTL_PCI_IREQ | TI113X_CARDCNTL_PCI_CSC)
-/* Reserved bit				0x04u */
-#define TI113X_CARDCNTL_SPKR_ENA	0x02u
-#define TI113X_CARDCNTL_INT		0x01u
-
-/* Device control register (TI113X_DEVICE_CONTROL == 0x92) */
-#define	TI113X_DEVCNTL_5V_SOCKET	0x40u
-#define	TI113X_DEVCNTL_3V_SOCKET	0x20u
-#define	TI113X_DEVCNTL_INTR_MASK	0x06u
-#define	TI113X_DEVCNTL_INTR_NONE	0x00u
-#define	TI113X_DEVCNTL_INTR_ISA		0x02u
-#define	TI113X_DEVCNTL_INTR_SERIAL	0x04u
-/* TI12XX specific code */
-#define	TI12XX_DEVCNTL_INTR_ALLSERIAL	0x06u
-
-/* Diagnostic register (misnamed) TI12XX_PCI_DIAGNOSTIC == 0x93 */
-#define TI12XX_DIAG_CSC_INTR		0x20	/* see datasheet */
-
-/* Texas Instruments PCI-1130/1131 CardBus Controller */
-#define	TI113X_ExCA_IO_OFFSET0		0x36	/* Offset of I/O window */
-#define	TI113X_ExCA_IO_OFFSET1		0x38	/* Offset of I/O window */
-#define	TI113X_ExCA_MEM_WINDOW_PAGE	0x3C	/* Memory Window Page */
-
-/*
- * Ricoh R5C47[5678] parts have these registers.  Maybe the 46x also use
- * them, but I can't find out for sure without datasheets...
- */
-#define	R5C47X_MISC_CONTROL_REGISTER_2	0xa0
-#define R5C47X_MCR2_CSC_TO_INTX_DISABLE 0x0010	/* Bit 7 */
-
-/*
- * Special resister definition for Toshiba ToPIC95/97
- * These values are borrowed from pcmcia-cs/Linux.
- */
-#define TOPIC_SOCKET_CTRL  0x90
-# define TOPIC_SOCKET_CTRL_SCR_IRQSEL 0x00000001 /* PCI intr */
-
-#define TOPIC_SLOT_CTRL    0xa0
-# define TOPIC_SLOT_CTRL_SLOTON       0x00000080
-# define TOPIC_SLOT_CTRL_SLOTEN       0x00000040
-# define TOPIC_SLOT_CTRL_ID_LOCK      0x00000020
-# define TOPIC_SLOT_CTRL_ID_WP        0x00000010
-# define TOPIC_SLOT_CTRL_PORT_MASK    0x0000000c
-# define TOPIC_SLOT_CTRL_PORT_SHIFT            2
-# define TOPIC_SLOT_CTRL_OSF_MASK     0x00000003
-# define TOPIC_SLOT_CTRL_OSF_SHIFT             0
-
-# define TOPIC_SLOT_CTRL_INTB         0x00002000
-# define TOPIC_SLOT_CTRL_INTA         0x00001000
-# define TOPIC_SLOT_CTRL_INT_MASK     0x00003000
-# define TOPIC_SLOT_CTRL_CLOCK_MASK   0x00000c00
-# define TOPIC_SLOT_CTRL_CLOCK_2      0x00000800 /* PCI Clock/2 */
-# define TOPIC_SLOT_CTRL_CLOCK_1      0x00000400 /* PCI Clock */
-# define TOPIC_SLOT_CTRL_CLOCK_0      0x00000000 /* no clock */
-# define TOPIC97_SLOT_CTRL_STSIRQP    0x00000400 /* status change intr pulse */
-# define TOPIC97_SLOT_CTRL_IRQP       0x00000200 /* function intr pulse */
-# define TOPIC97_SLOT_CTRL_PCIINT     0x00000100 /* intr routing to PCI INT */
-
-# define TOPIC_SLOT_CTRL_CARDBUS      0x80000000
-# define TOPIC_SLOT_CTRL_VS1          0x04000000
-# define TOPIC_SLOT_CTRL_VS2          0x02000000
-# define TOPIC_SLOT_CTRL_SWDETECT     0x01000000
-
-#define TOPIC_REG_CTRL     0x00a4
-# define TOPIC_REG_CTRL_RESUME_RESET  0x80000000
-# define TOPIC_REG_CTRL_REMOVE_RESET  0x40000000
-# define TOPIC97_REG_CTRL_CLKRUN_ENA  0x20000000
-# define TOPIC97_REG_CTRL_TESTMODE    0x10000000
-# define TOPIC97_REG_CTRL_IOPLUP      0x08000000
-# define TOPIC_REG_CTRL_BUFOFF_PWROFF 0x02000000
-# define TOPIC_REG_CTRL_BUFOFF_SIGOFF 0x01000000
-# define TOPIC97_REG_CTRL_CB_DEV_MASK 0x0000f800
-# define TOPIC97_REG_CTRL_CB_DEV_SHIFT 11
-# define TOPIC97_REG_CTRL_RI_DISABLE  0x00000004
-# define TOPIC97_REG_CTRL_CAUDIO_OFF  0x00000002
-# define TOPIC_REG_CTRL_CAUDIO_INVERT 0x00000001
-
-/* For Bridge Control register (CB_PCI_BRIDGE_CTRL) */
-#define CB_BCR_MASTER_ABORT	0x0020
-#define CB_BCR_CB_RESET		0x0040
-#define CB_BCR_INT_EXCA		0x0080
-#define CB_BCR_WRITE_POST_EN	0x0400
-  /* additional bits for Ricoh's cardbus products */
-#define CB_BCR_RL_3E0_EN	0x0800
-#define CB_BCR_RL_3E2_EN	0x1000
-
-/* PCI Configuration Registers (common) */
-#define	CB_PCI_VENDOR_ID	0x00	/* vendor ID */
-#define	CB_PCI_DEVICE_ID	0x02	/* device ID */
-#define	CB_PCI_COMMAND		0x04	/* PCI command */
-#define	CB_PCI_STATUS		0x06	/* PCI status */
-#define	CB_PCI_REVISION_ID	0x08	/* PCI revision ID */
-#define	CB_PCI_CLASS		0x09	/* PCI class code */
-#define	CB_PCI_CACHE_LINE_SIZE	0x0c	/* Cache line size */
-#define	CB_PCI_LATENCY		0x0d	/* PCI latency timer */
-#define	CB_PCI_HEADER_TYPE	0x0e	/* PCI header type */
-#define	CB_PCI_BIST		0x0f	/* Built-in self test */
-#define	CB_PCI_SOCKET_BASE	0x10	/* Socket/ExCA base address reg. */
-#define	CB_PCI_CB_STATUS	0x16	/* CardBus Status */
-#define	CB_PCI_PCI_BUS_NUM	0x18	/* PCI bus number */
-#define	CB_PCI_CB_BUS_NUM	0x19	/* CardBus bus number */
-#define	CB_PCI_CB_SUB_BUS_NUM	0x1A	/* Subordinate CardBus bus number */
-#define	CB_PCI_CB_LATENCY	0x1A	/* CardBus latency timer */
-#define	CB_PCI_MEMBASE0		0x1C	/* Memory base register 0 */
-#define	CB_PCI_MEMLIMIT0	0x20	/* Memory limit register 0 */
-#define	CB_PCI_MEMBASE1		0x24	/* Memory base register 1 */
-#define	CB_PCI_MEMLIMIT1	0x28	/* Memory limit register 1 */
-#define	CB_PCI_IOBASE0		0x2C	/* I/O base register 0 */
-#define	CB_PCI_IOLIMIT0		0x30	/* I/O limit register 0 */
-#define	CB_PCI_IOBASE1		0x34	/* I/O base register 1 */
-#define	CB_PCI_IOLIMIT1		0x38	/* I/O limit register 1 */
-#define	CB_PCI_INT_LINE		0x3C	/* Interrupt Line */
-#define	CB_PCI_INT_PIN		0x3D	/* Interrupt Pin */
-#define	CB_PCI_BRIDGE_CTRL	0x3E	/* Bridge Control */
-#define	CB_PCI_SUBSYS_VENDOR_ID	0x40	/* Subsystem Vendor ID */
-#define	CB_PCI_SUBSYS_ID	0x42	/* Subsystem ID */
-#define	CB_PCI_LEGACY16_IOADDR	0x44	/* Legacy 16bit I/O address */
-#define	CB_PCI_LEGACY16_IOENABLE 0x01	/* Enable Legacy 16bit I/O address */
-
-/* PCI Memory register offsets for YENTA devices */
-#define CB_SOCKET_EVENT		0x00
-#define CB_SOCKET_MASK		0x04
-#define CB_SOCKET_STATE		0x08
-#define CB_SOCKET_FORCE		0x0c
-#define CB_SOCKET_POWER		0x10
-#define CB_EXCA_OFFSET		0x800	/* Offset for ExCA registers */
-
-#define CB_SE_CD		0x6	/* Socket Event Card detect */
-#define CB_SE_POWER		0x8
-
-#define CB_SM_CD		0x6	/* Socket MASK Card detect */
-#define CB_SM_POWER		0x8
-
-/* Socket State Register */
-#define CB_SS_CARDSTS		0x00000001 /* Card Status Change */
-#define CB_SS_CD1		0x00000002 /* Card Detect 1 */
-#define CB_SS_CD2		0x00000004 /* Card Detect 2 */
-#define CB_SS_CD		0x00000006 /* Card Detect all */
-#define CB_SS_PWRCYCLE		0x00000008 /* Power Cycle */
-#define CB_SS_16BIT		0x00000010 /* 16-bit Card */
-#define CB_SS_CB		0x00000020 /* Cardbus Card */
-#define CB_SS_IREQ		0x00000040 /* Ready */
-#define CB_SS_NOTCARD		0x00000080 /* Unrecognized Card */
-#define CB_SS_DATALOST		0x00000100 /* Data Lost */
-#define CB_SS_BADVCC		0x00000200 /* Bad VccRequest */
-#define CB_SS_5VCARD		0x00000400 /* 5 V Card */
-#define CB_SS_3VCARD		0x00000800 /* 3.3 V Card */
-#define CB_SS_XVCARD		0x00001000 /* X.X V Card */
-#define CB_SS_YVCARD		0x00002000 /* Y.Y V Card */
-#define CB_SS_CARD_MASK		0x00003c00 /* *VCARD signal */
-#define CB_SS_5VSOCK		0x10000000 /* 5 V Socket */
-#define CB_SS_3VSOCK		0x20000000 /* 3.3 V Socket */
-#define CB_SS_XVSOCK		0x40000000 /* X.X V Socket */
-#define CB_SS_YVSOCK		0x80000000 /* Y.Y V Socket */
-
-/* Socket power register */
-#define CB_SP_CLKSTOP		0x80	/* Cardbus clock stop protocol */
-#define CB_SP_VCC_MASK		0x70
-#define CB_SP_VCC_0V		0x00
-					/* 0x10 is reserved 12V in VPP */
-#define CB_SP_VCC_5V		0x20
-#define CB_SP_VCC_3V		0x30
-#define CB_SP_VCC_XV		0x40
-#define CB_SP_VCC_YV		0x50
-					/* 0x60 and 0x70 are reserved */
-#define CB_SP_VPP_MASK		0x07
-#define CB_SP_VPP_0V		0x00
-#define CB_SP_VPP_12V		0x01
-#define CB_SP_VPP_5V		0x02
-#define CB_SP_VPP_3V		0x03
-#define CB_SP_VPP_XV		0x04
-#define CB_SP_VPP_YV		0x05
-
-/* Socket force register */
-#define CB_SF_INTCVS		(1 << 14)	/* Interregate CVS/CCD pins */
-#define CB_SF_5VCARD		(1 << 11)
-#define CB_SF_3VCARD		(1 << 10)
-#define CB_SF_BADVCC		(1 << 9)
-#define CB_SF_DATALOST		(1 << 8)
-#define CB_SF_NOTACARD		(1 << 7)
-#define CB_SF_CBCARD		(1 << 5)
-#define CB_SF_16CARD		(1 << 4)
-#define CB_SF_POWERCYCLE	(1 << 3)
-#define CB_SF_CCD2		(1 << 2)
-#define CB_SF_CCD1		(1 << 1)
-#define CB_SF_CSTCHG		(1 << 0)
-					/* 0x6 and 0x7 are reserved */
--- sys/pccard/meciareg.h
+++ /dev/null
@@ -1,60 +0,0 @@
-/*
- * meciareg.h
- *
- * PC9801 original PCMCIA controller code for NS/A,Ne,NX/C,NR/L.
- * by Noriyuki Hosobuchi <hoso at ce.mbn.or.jp>
- *
- * $FreeBSD: src/sys/pccard/meciareg.h,v 1.2 2001/05/15 23:53:18 imp Exp $
- */
-
-/*--- I/O port definition */
-#define	MECIA_REG0		0x0a8e	/* byte */
-#define	MECIA_REG1		0x1a8e	/* byte */
-#define	MECIA_REG2		0x2a8e	/* byte */
-#define	MECIA_REG3		0x3a8e	/* byte : Interrupt */
-#define	MECIA_REG4		0x4a8e	/* word : PC98 side I/O base */
-#define	MECIA_REG5		0x5a8e	/* word : Card side I/O base */
-#define	MECIA_REG7		0x7a8e	/* byte */
-
-#define	MECIA_REG_WINSEL	0x1e8e	/* byte : win bank select register */
-#define	MECIA_REG_PAGOFS	0x0e8e	/* word */
-
-/* PC98_REG_WINSEL */
-#define	MECIA_MAPWIN		0x84	/* map Card on 0xda0000 - 0xdbffff */
-#define	MECIA_UNMAPWIN		0x00
-
-/* MECIA_REG1 */
-#define	MECIA_CARDEXIST		0x08	/* 1:exist 0:not exist */
-
-/* MECIA_REG2 */
-#define	MECIA_MAPIO		0x80	/* 1:I/O 0:Memory */
-#define	MECIA_IOTHROUGH		0x40	/* 0:I/O map 1:I/O addr-through */
-#define	MECIA_8BIT		0x20	/* bit width 1:8bit 0:16bit */
-#define	MECIA_MAP128		0x10	/* I/O map size 1:128byte 0:16byte */
-#define	MECIA_VCC3P3V		0x02	/* Vcc 1:3.3V 0:5.0V */
-
-/* MECIA_REG3 */
-#define	MECIA_INT0		(0xf8 + 0x0)	/* INT0(IRQ3) */
-#define	MECIA_INT1		(0xf8 + 0x1)	/* INT1(IRQ5) */
-#define	MECIA_INT2		(0xf8 + 0x2)	/* INT2(IRQ6) */
-#define	MECIA_INT4		(0xf8 + 0x4)	/* INT4(IRQ10) */
-#define	MECIA_INT5		(0xf8 + 0x5)	/* INT5(IRQ12) */
-#define	MECIA_INTDISABLE	(0xf8 + 0x7)	/* disable interrupt */
-
-/* MECIA_REG7 */
-#define	MECIA_ATTRMEM		0x20	/* 1:attr mem 0:common mem */
-#define	MECIA_VPP12V		0x10	/* Vpp 0:5V 1:12V */
-
-
-#ifdef KERNEL
-extern int mecia_mode;		/* in 'pccard/pcic.c' */
-#define mecia_8bit_on()	\
-	if (mecia_mode & MECIA_8BIT)	\
-		outb(MECIA_REG2, inb(MECIA_REG2) | MECIA_8BIT)
-#define mecia_8bit_off()	\
-	if (mecia_mode & MECIA_8BIT)	\
-		outb(MECIA_REG2, inb(MECIA_REG2) & ~MECIA_8BIT)
-#define mecia_map128()		(mecia_mode & MECIA_MAP128)
-#endif
-
-#define	MECIA_INT_MASK_ALLOWED	0x3E68		/* PC98 */
Index: cardinfo.h
===================================================================
RCS file: /home/cvs/src/sys/pccard/cardinfo.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/pccard/cardinfo.h -L sys/pccard/cardinfo.h -u -r1.1.1.1 -r1.2
--- sys/pccard/cardinfo.h
+++ sys/pccard/cardinfo.h
@@ -29,7 +29,7 @@
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
-/* $FreeBSD: src/sys/pccard/cardinfo.h,v 1.30 2005/01/07 02:29:17 imp Exp $ */
+/* $FreeBSD: src/sys/pccard/cardinfo.h,v 1.31 2006/01/10 05:21:01 imp Exp $ */
 
 #ifndef	_PCCARD_CARDINFO_H_
 #define	_PCCARD_CARDINFO_H_
@@ -154,25 +154,6 @@
 	uint32_t	product;	/* Product ID */
 	uint32_t	prodext;	/* Product ID (extended) */
 };
-#if __FreeBSD_version < 5000000		/* 4.x compatibility only. */
-#define PIOCSDRVOLD	_IOWR('P', 6, struct dev_desc_old) /* Set driver */
-struct dev_desc_old {
-	char		name[16];	/* Driver name */
-	int		unit;		/* Driver unit number */
-	unsigned long	mem;		/* Memory address of driver */
-	int		memsize;	/* Memory size (if used) */
-	int		iobase;		/* base of I/O ports */
-	int		iosize;		/* Length of I/O ports */
-	int		irqmask;	/* Interrupt number(s) to allocate */
-	int		flags;		/* Device flags */
-	uint8_t		misc[DEV_MISC_LEN]; /* For any random info */
-	uint8_t		manufstr[DEV_MAX_CIS_LEN];
-	uint8_t		versstr[DEV_MAX_CIS_LEN];
-	uint32_t	manufacturer;	/* Manufacturer ID */
-	uint32_t	product;	/* Product ID */
-	uint32_t	prodext;	/* Product ID (extended) */
-};
-#endif
 #define DEV_DESC_HAS_SIZE 1
 
 struct pcic_reg {
--- sys/pccard/pcicvar.h
+++ /dev/null
@@ -1,126 +0,0 @@
-/*-
- * Copyright (c) 2001 M. Warner Losh.  All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/pccard/pcicvar.h,v 1.30 2005/01/07 02:29:17 imp Exp $
- */
-
-/*
- *	Per-slot data table.
- */
-struct pcic_slot {
-	int offset;			/* Offset value for index */
-	char controller;		/* Device type */
-	char revision;			/* Device Revision */
-	struct slot *slt;		/* Back ptr to slot */
-	struct pcic_softc *sc;		/* Back pointer to softc */
-	u_int8_t (*getb)(struct pcic_slot *, int);
-	void   (*putb)(struct pcic_slot *, int, u_int8_t);
-	bus_space_tag_t bst;
-	bus_space_handle_t bsh;
-};
-
-enum pcic_intr_way { pcic_iw_isa = 1, pcic_iw_pci = 2 };
-
-struct pcic_softc 
-{
-	u_int32_t		slotmask;/* Mask of valid slots */
-	u_int32_t		flags;	/* Interesting flags */
-#define PCIC_AB_POWER	   0x00000001	/* Use old A/B step power */
-#define PCIC_DF_POWER	   0x00000002	/* Uses DF step regs  */
-#define PCIC_PD_POWER	   0x00000004	/* Uses CL-PD regs  */
-#define	PCIC_VG_POWER	   0x00000008	/* Uses VG power regs */
-#define PCIC_KING_POWER    0x00000010	/* Uses IBM KING regs  */
-#define PCIC_RICOH_POWER   0x00000020	/* Uses the ricoh power regs */
-#define PCIC_CARDBUS_POWER 0x00000040	/* Cardbus power regs */
-#define PCIC_YENTA_HIGH_MEMORY 0x0080	/* Can do high memory mapping */
-
-	enum pcic_intr_way	csc_route; /* How to route csc interrupts */
-	enum pcic_intr_way	func_route; /* How to route function ints */
-	int			iorid;	/* Rid of I/O region */
-	struct resource 	*iores;	/* resource for I/O region */
-	int			memrid;	/* Memory rid */
-	struct resource		*memres;/* Resource for memory mapped regs */
-	int			irqrid;	/* Irq rid */
-	struct resource		*irqres;/* Irq resource */
-	void			*ih;	/* Our interrupt handler. */
-	int			irq;
-	device_t		dev;	/* Our device */
-	void (*slot_poll)(void *);
-	struct callout_handle	timeout_ch;
-	struct pcic_slot	slots[PCIC_MAX_SLOTS];
-	int			cd_pending; /* debounce timeout active */
-	int			cd_present; /* debounced card-present state */
-	struct callout_handle	cd_ch;	/* handle for pcic_cd_insert */
-	struct pcic_chip	*chip;
-	driver_intr_t		*func_intr;
-	void			*func_arg;
-};
-
-typedef int (pcic_intr_way_t)(struct pcic_slot *, enum pcic_intr_way);
-typedef int (pcic_intr_mapirq_t)(struct pcic_slot *, int irq);
-typedef void (pcic_init_t)(device_t);
-
-struct pcic_chip
-{
-	pcic_intr_way_t *func_intr_way;
-	pcic_intr_way_t *csc_intr_way;
-	pcic_intr_mapirq_t *map_irq;
-	pcic_init_t	*init;
-};
-
-extern devclass_t	pcic_devclass;
-extern int		pcic_override_irq;
-
-int pcic_activate_resource(device_t dev, device_t child, int type, int rid,
-    struct resource *r);
-struct resource *pcic_alloc_resource(device_t dev, device_t child, int type,
-    int *rid, u_long start, u_long end, u_long count, u_int flags);
-int pcic_attach(device_t dev);
-void pcic_clrb(struct pcic_slot *sp, int reg, unsigned char mask);
-int pcic_deactivate_resource(device_t dev, device_t child, int type, int rid,
-    struct resource *r);
-void pcic_dealloc(device_t dev);
-void pcic_do_stat_delta(struct pcic_slot *sp);
-int pcic_get_memory_offset(device_t bus, device_t child, int rid,
-    u_int32_t *offset);
-int pcic_get_res_flags(device_t bus, device_t child, int restype, int rid,
-    u_long *value);
-unsigned char pcic_getb_io(struct pcic_slot *sp, int reg);
-driver_intr_t	pcic_isa_intr;
-int		pcic_isa_intr1(void *);
-pcic_intr_mapirq_t pcic_isa_mapirq;
-void pcic_putb_io(struct pcic_slot *sp, int reg, unsigned char val);
-int pcic_set_memory_offset(device_t bus, device_t child, int rid,
-    u_int32_t offset
-#if __FreeBSD_version >= 500000
-    , u_int32_t *deltap
-#endif
-    );
-int pcic_set_res_flags(device_t bus, device_t child, int restype, int rid,
-    u_long value);
-void pcic_setb(struct pcic_slot *sp, int reg, unsigned char mask);
-int pcic_setup_intr(device_t dev, device_t child, struct resource *irq,
-    int flags, driver_intr_t *intr, void *arg, void **cookiep);
-int pcic_teardown_intr(device_t dev, device_t child, struct resource *irq,
-    void *cookie);
-timeout_t 	pcic_timeout;
--- sys/pccard/i82365.h
+++ /dev/null
@@ -1,345 +0,0 @@
-/*
- *	i82365.h - Definitions for Intel 82365 PCIC
- *	PCMCIA Card Interface Controller
- *
- * originally by Barry Jaspan; hacked over by Keith Moore
- * hacked to unrecognisability by Andrew McRae (andrew at mega.com.au)
- *
- * Updated 3/3/95 to include Cirrus Logic stuff.
- *-------------------------------------------------------------------------
- */
-/*-
- * Copyright (c) 2001 M. Warner Losh.  All rights reserved.
- * Copyright (c) 1995 Andrew McRae.  All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. The name of the author may not be used to endorse or promote products
- *    derived from this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
- * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
- * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
- * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
- * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * $FreeBSD: src/sys/pccard/i82365.h,v 1.29 2005/01/07 02:29:17 imp Exp $
- */
-
-#define	PCIC_I82365	0		/* Intel i82365SL-A/B or clone */
-#define	PCIC_IBM	1		/* IBM clone */
-#define	PCIC_VLSI	2		/* VLSI chip */
-#define	PCIC_PD6722	3		/* Cirrus logic PD6722 */
-#define	PCIC_PD6710	4		/* Cirrus logic PD6710 */
-#define	PCIC_VG365	5		/* Vadem 365 */
-#define	PCIC_VG465      6		/* Vadem 465 */
-#define	PCIC_VG468	7		/* Vadem 468 */
-#define	PCIC_VG469	8		/* Vadem 469 */
-#define	PCIC_RF5C296	9		/* Ricoh RF5C296 */
-#define	PCIC_RF5C396	10		/* Ricoh RF5C396 */
-#define	PCIC_IBM_KING	11		/* IBM KING PCMCIA Controller */
-#define PCIC_I82365SL_DF 12		/* Intel i82365sl-DF step */
-#define PCIC_PD6729	13		/* Cirrus Logic PD6729 */
-#define PCIC_PD673X	14		/* Cirrus Logic PD673x */
-
-/*
- *	Address of the controllers. Each controller can manage
- *	two PCMCIA slots. Up to 8 slots are supported in total.
- *	The PCIC controller is accessed via an index port and a
- *	data port. The index port has the 8 bit address of the
- *	register accessed via the data port. How I long for
- *	real memory mapped I/O!
- *	The top two bits of the index address are used to
- *	identify the port number, and the lower 6 bits
- *	select one of the 64 possible data registers.
- */
-#define PCIC_INDEX	0			/* Index register */
-#define PCIC_DATA	1			/* Data register */
-#define PCIC_NPORT	2			/* Number of ports */
-#define PCIC_PORT_0	0x3e0			/* index reg, chips 0 and 1 */
-
-/*
- *	Register index addresses.
- */
-#define PCIC_ID_REV	0x00	/* Identification and Revision */
-#define PCIC_STATUS	0x01	/* Interface Status */
-#define PCIC_POWER	0x02	/* Power and RESETDRV control */
-#define PCIC_INT_GEN	0x03	/* Interrupt and General Control */
-#define PCIC_STAT_CHG	0x04	/* Card Status Change */
-#define PCIC_STAT_INT	0x05	/* Card Status Change Interrupt Config */
-#define PCIC_ADDRWINE	0x06	/* Address Window Enable */
-#define PCIC_IOCTL	0x07	/* I/O Control */
-#define PCIC_IO0	0x08	/* I/O Address 0 */
-#define PCIC_IO1	0x0c	/* I/O Address 1 */
-#define	PCIC_MEMBASE	0x10	/* Base of memory window registers */
-#define PCIC_CDGC	0x16	/* Card Detect and General Control */
-#define PCIC_MISC1	0x16	/* PD67xx: Misc control register 1 per slot */
-#define PCIC_GLO_CTRL	0x1e	/* Global Control Register */
-#define PCIC_MISC2	0x1e	/* PD67xx: Misc control register 2 per chip */
-#define PCIC_CLCHIP	0x1f	/* PD67xx: Chip I/D */
-#define PCIC_EXT_IND	0x2e	/* PD67xx: Extended Index */
-#define PCIC_EXTENDED	0x2f	/* PD67xx: Extended register */
-#define PCIC_CVSR	0x2f	/* Vadem: Voltage select register */
-#define PCIC_RICOH_MCR2 0x2f	/* Ricoh: Mode Control Register 2 */
-
-#define PCIC_VMISC	0x3a	/* Vadem: Misc control register */
-#define PCIC_RICOH_ID	0x3a	/* Ricoh: ID register */
-
-#define PCIC_TOPIC_FCR	0x3e	/* Toshiba ToPIC: Function Control Register */
-
-#define	PCIC_TIME_SETUP0	0x3a
-#define	PCIC_TIME_CMD0		0x3b
-#define	PCIC_TIME_RECOV0	0x3c
-#define	PCIC_TIME_SETUP1	0x3d
-#define	PCIC_TIME_CMD1		0x3e
-#define	PCIC_TIME_RECOV1	0x3f
-
-/* Yenta only registers */
-#define PCIC_MEMORY_HIGH0	0x40	/* A31..A25 of mapping addres for */
-#define PCIC_MEMORY_HIGH1	0x41	/* the memory windows. */
-#define PCIC_MEMORY_HIGH2	0x42
-#define PCIC_MEMORY_HIGH3	0x43
-
-
-#define	PCIC_SLOT_SIZE	0x40	/* Size of register set for one slot */
-
-/* Now register bits, ordered by reg # */
-
-/* For Identification and Revision (PCIC_ID_REV) */
-#define PCIC_INTEL0	0x82	/* Intel 82365SL Rev. 0; Both Memory and I/O */
-#define PCIC_INTEL1	0x83	/* Intel 82365SL Rev. 1; Both Memory and I/O */
-#define PCIC_INTEL2	0x84	/* Intel 82365SL step D */
-#define PCIC_VLSI82C146	0x84	/* VLSI 82C146 */
-#define PCIC_IBM1	0x88	/* IBM PCIC clone; Both Memory and I/O */
-#define PCIC_IBM2	0x89	/* IBM PCIC clone; Both Memory and I/O */
-#define PCIC_IBM3	0x8a	/* IBM KING PCIC clone; Both Memory and I/O */
-
-/* For Interface Status register (PCIC_STATUS) */
-#define PCIC_VPPV	0x80	/* Vpp_valid or reserved*/
-#define PCIC_RICOH_5VCARD 0x80	/* 5V card detected */
-#define PCIC_POW	0x40	/* PC Card power active */
-#define PCIC_READY	0x20	/* Ready/~Busy */
-#define PCIC_MWP	0x10	/* Memory Write Protect */
-#define PCIC_CD		0x0C	/* Both card detect bits */
-#define PCIC_BVD	0x03	/* Both Battery Voltage Detect bits */
-
-/* For the Power and RESETDRV register (PCIC_POWER) */
-#define PCIC_OUTENA	0x80	/* Output Enable */
-#define PCIC_DISRST	0x40	/* Disable RESETDRV */
-#define PCIC_APSENA	0x20	/* Auto Pwer Switch Enable */
-#define PCIC_PCPWRE	0x10	/* PC Card Power Enable */
-#define	PCIC_VCC	0x18	/* Vcc control bits */
-#define	PCIC_VCC_5V	0x10	/* 5 volts */
-#define	PCIC_VCC_ON	0x10	/* Turn on VCC on some chips. */
-#define	PCIC_VCC_3V	0x18	/* 3 volts */
-#define	PCIC_VCC_5V_KING	0x14	/* 5 volts for KING PCIC */
-#define	PCIC_VPP	0x03	/* Vpp control bits */
-#define	PCIC_VPP_5V	0x01	/* 5 volts */
-#define	PCIC_VPP_12V	0x02	/* 12 volts */
-
-/* For the Interrupt and General Control register (PCIC_INT_GEN) */
-#define PCIC_CARDRESET	0x40	/* Card reset 0 = Reset, 1 = Normal */
-#define PCIC_CARDTYPE	0x20	/* Card Type 0 = memory, 1 = I/O */
-#define		PCIC_IOCARD	0x20
-#define		PCIC_MEMCARD	0x00
-#define	PCIC_INTR_ENA	0x10	/* PCI CSC Interrupt enable */
-
-/* For the Card Status Change register (PCIC_STAT_CHG) */
-#define PCIC_CDTCH	0x08	/* Card Detect Change */
-#define PCIC_RDYCH	0x04	/* Ready Change */
-#define PCIC_BATWRN	0x02	/* Battery Warning */
-#define PCIC_BATDED	0x01	/* Battery Dead */
-
-/* For the Card status change interrupt PCIC_STAT_INT */
-#define PCIC_CSCSELECT		0xf0	/* CSCSELECT */
-#define PCIC_SI_IRQ_SHIFT	4
-#define PCIC_CDEN		0x8
-#define PCIC_READYEN		0x4
-#define PCIC_BATWARNEN		0x2
-#define PCIC_BATDEADEN		0x1
-
-/*
- * For the Address Window Enable Register (PCIC_ADDRWINE)
- * The lower 5 bits contain enable bits for the memory
- * windows (LSB = memory window 0).
- */
-#define PCIC_MEMCS16	0x20	/* ~MEMCS16 Decode A23-A12 */
-#define PCIC_IO0_EN	0x40	/* I/O Window 0 Enable */
-#define PCIC_IO1_EN	0x80	/* I/O Window 1 Enable */
-
-/*
- * For the I/O Control Register (PCIC_IOCTL)
- * The lower nybble is the flags for I/O window 0
- * The upper nybble is the flags for I/O window 1
- */
-#define PCIC_IO_16BIT	0x01	/* I/O to this segment is 16 bit */
-#define PCIC_IO_CS16	0x02	/* I/O cs16 source is the card */
-#define PCIC_IO_0WS	0x04	/* zero wait states added on 8 bit cycles */
-#define PCIC_IO_WS	0x08	/* Wait states added for 16 bit cycles */
-
-/*
- *	The memory window registers contain the start and end
- *	physical host address that the PCIC maps to the card,
- *	and an offset calculated from the card memory address.
- *	All values are shifted down 12 bits, so allocation is
- *	done in 4Kb blocks. Only 12 bits of each value is
- *	stored, limiting the range to the ISA address size of
- *	24 bits. The upper 4 bits of the most significant byte
- *	within the values are used for various flags.
- *
- *	The layout is:
- *
- *	base+0 : lower 8 bits of system memory start address
- *	base+1 : upper 4 bits of system memory start address + flags
- *	base+2 : lower 8 bits of system memory end address
- *	base+3 : upper 4 bits of system memory end address + flags
- *	base+4 : lower 8 bits of offset to card address
- *	base+5 : upper 4 bits of offset to card address + flags
- *
- *	The following two bytes are reserved for other use.
- */
-#define	PCIC_MEMSIZE	8
-/*
- *	Flags for system memory start address upper byte
- */
-#define PCIC_ZEROWS	0x40	/* Zero wait states */
-#define PCIC_DATA16	0x80	/* Data width is 16 bits */
-
-/*
- *	Flags for system memory end address upper byte
- */
-#define PCIC_MW0	0x40	/* Wait state bit 0 */
-#define PCIC_MW1	0x80	/* Wait state bit 1 */
-
-/*
- *	Flags for card offset upper byte
- */
-#define PCIC_REG	0x40	/* Attribute/Common select (why called Reg?) */
-#define PCIC_WP		0x80	/* Write-protect this window */
-
-/* For Card Detect and General Control register (PCIC_CDGC) */
-#define PCIC_16_DL_INH	0x01	/* 16-bit memory delay inhibit */
-#define PCIC_CNFG_RST_EN 0x02	/* configuration reset enable */
-#define PCIC_GPI_EN	0x04	/* GPI Enable */
-#define PCIC_GPI_TRANS	0x08	/* GPI Transition Control */
-#define PCIC_CDRES_EN	0x10	/* card detect resume enable */
-#define PCIC_SW_CD_INT	0x20	/* s/w card detect interrupt */
-#define PCIC_VS1STAT	0x40	/* 0 VS1# low, 1 VS1# high */
-#define PCIC_VS2STAT	0x80	/* 0 VS2# low, 1 VS2# high */
-
-/* CL-PD67[12]x: For 3.3V cards, etc. (PCIC_MISC1) */
-#define PCIC_MISC1_5V_DETECT 0x01	/* PD6710 only */
-#define PCIC_MISC1_VCC_33    0x02	/* Set Vcc is 3.3V, else 5.0V */
-#define PCIC_MISC1_PMINT     0x04	/* Pulse management intr */
-#define PCIC_MISC1_PCINT     0x08	/* Pulse card interrupt */
-#define PCIC_MISC1_SPEAKER   0x10	/* Enable speaker */
-#define PCIC_MISC1_INPACK    0x80	/* INPACK throttles data */
-
-/* i82365B and newer (!PD67xx) Global Control register (PCIC_GLO_CTRL) */
-#define PCIC_PWR_DOWN	0x01	/* power down */
-#define PCIC_LVL_MODE	0x02	/* level mode interrupt enable */
-#define PCIC_WB_CSCINT	0x04	/* explicit write-back csc intr */
-/* Rev B only */
-#define PCIC_IRQ0_LEVEL 0x08	/* irq 14 pulse mode enable */
-#define PCIC_IRQ1_LEVEL 0x10
-
-/* CL-PD67[12]x: For Misc. Control Register 2 (PCIC_MISC2) */
-#define PCIC_LPDM_EN	0x02	/* Cirrus PD672x: low power dynamic mode */
-
-/* CL-PD67[12]x: Chip info (PCIC_CLCHIP) */
-#define PCIC_CLC_TOGGLE 0xc0		/* These bits toggle 1 -> 0 */
-#define PCIC_CLC_DUAL	0x20		/* Single/dual socket version */
-
-/* Cirrus Logic: Extended Registers (PCIC_EXT_IND) */
-#define PCIC_EXT_DATA	0x0a		/* External Data */
-
-/* EXT_DATA */
-#define PCIC_VS1A	0x01
-#define PCIC_VS2A	0x02
-#define PCIC_VS1B	0x04
-#define PCIC_VS2B	0x08
-
-/* Cirrus Logic: Extended register Extension Control 1 */
-#define PCIC_EXTCTRL1	0x03
-#define PCIC_EC1_VCC_LOCK 0x1		/* Vcc Power locked to s/w change */
-#define PCIC_EC1_AUTO_POWER_CLEAR 0x2	/* Vcc power cleared on eject? */
-#define PCIC_EC1_LED_ENABLE 0x4		/* LED activity enable */
-#define PCIC_EC1_CARD_IRQ_INV 0x8	/* Card IRQ level inverted for pci? */
-#define PCIC_EC1_CSC_IRQ_INV 0x10	/* CSC IRQ level inverted for pci? */
-#define PCIC_EC1_PULLUP 0x20		/* Dis pullup when 1. */
-
-/* Vadem: Card Voltage Select register (PCIC_CVSR) */
-#define PCIC_CVSR_VS	0x03		/* Voltage select */
-#define PCIC_CVSR_VS_5	0x00		/* 5.0 V */
-#define PCIC_CVSR_VS_33a 0x01		/* alt 3.3V */
-#define PCIC_CVSR_VS_XX	0x02		/* X.XV when available */
-#define PCIC_CVSR_VS_33 0x03		/* 3.3V */
-
-/* Ricoh: Misc Control Register 2 (PCIC_RICOH_MCR2) */
-#define PCIC_MCR2_VCC_33 0x01		/* 3.3V */
-
-/* Vadem: misc register (PCIC_VMISC) */
-#define PCIC_VADEMREV	0x40
-
-/* Ricoh: ID register values (PCIC_RICOH_ID) */
-#define PCIC_RID_296	0x32
-#define PCIC_RID_396	0xb2
-
-/* Toshiba ToPIC: Function Control Register */
-#define PCIC_FCR_3V_EN		0x01	/* Enable 3V cards */
-#define PCIC_FCR_VS_EN		0x02	/* Voltage Sense enable */
-
-/*
- *	Mask of allowable interrupts.
- *
- *	For IBM-AT machines, irqs 3, 4, 5, 7, 9, 10, 11, 12, 14, 15 are
- *	allowed.  Nearly all IBM-AT machines with pcic cards or bridges
- *	wire these interrupts (or a subset thereof) to the corresponding
- *	pins on the ISA bus.  Some older laptops are reported to not route
- *	all the interrupt pins to the bus because the designers knew that
- *	some would conflict with builtin devices.
- *
- *	For NEC PC98 machines, irq 3, 5, 6, 9, 10, 11, 12, 13 are allowed.
- *	These correspond to the C-BUS signals INT 0, 1, 2, 3, 41, 42, 5, 6
- *	respectively.  This is with the desktop C-BUS addin card.
- *
- *	Hiroshi TSUKADA-san writes in FreeBSD98-testers that cbus IRQ
- *	6 is routed to the IRQ 7 pin of the pcic in pc98 cbus based
- *	cards.  I do not know how pc98 laptop models are wired.
- */
-#ifdef PC98
-#define	PCIC_INT_MASK_ALLOWED	0x3E68		/* PC98 */
-#else
-#define	PCIC_INT_MASK_ALLOWED	0xDEB8		/* AT */
-#endif
-
-#define	PCIC_IO_WIN	2
-#define	PCIC_MEM_WIN	5
-
-#define	PCIC_CARD_SLOTS	4
-#define PCIC_MAX_CARDS	2
-#define PCIC_MAX_SLOTS (PCIC_MAX_CARDS * PCIC_CARD_SLOTS)
-
-/* Plug and play */
-#define PCIC_PNP_ACTIONTEC	0x1802A904	/* AEI0218 */
-#define PCIC_PNP_IBM3765	0x65374d24	/* IBM3765 */
-#define PCIC_PNP_82365		0x000ED041	/* PNP0E00 */
-#define PCIC_PNP_CL_PD6720	0x010ED041	/* PNP0E01 */
-#define PCIC_PNP_VLSI_82C146	0x020ED041	/* PNP0E02 */
-#define PCIC_PNP_82365_CARDBUS	0x030ED041	/* PNP0E03 */
-#define PCIC_PNP_SCM_SWAPBOX	0x69046d4c	/* SMC0469 */
-
-/* C-Bus PnP Definitions */
-#define PCIC_NEC_PC9801_102	0x9180a3b8	/* NEC8091 PC-9801-102 */
-#define	PCIC_NEC_PC9821RA_E01	0x2181a3b8	/* NEC8121 PC-9821RA-E01 */
Index: Makefile
===================================================================
RCS file: /home/cvs/src/sys/Makefile,v
retrieving revision 1.6
retrieving revision 1.7
diff -L sys/Makefile -L sys/Makefile -u -r1.6 -r1.7
--- sys/Makefile
+++ sys/Makefile
@@ -9,10 +9,11 @@
 .endif
 
 # Directories to include in cscope name file and TAGS.
-CSCOPEDIRS=	compat conf contrib crypto ddb dev fs gnu i4b isa \
-		isofs kern libkern modules net netatalk netatm netgraph \
-		netinet netinet6 netipx netkey netnatm netncp netsmb nfs \
-		pccard pci posix4 sys ufs vm ${ARCHDIR}
+CSCOPEDIRS=	bsm cam compat conf contrib crypto ddb dev fs geom gnu \
+		isa kern libkern modules net net80211 netatalk netatm \
+		netgraph netinet netinet6 netipsec netipx netnatm netncp \
+		netsmb nfs nfsclient nfs4client rpc pccard pci security sys \
+		ufs vm ${ARCHDIR}
 
 ARCHDIR	?=	${MACHINE}
 
@@ -24,12 +25,14 @@
 
 HTAGSFLAGS+= -at `awk -F= '/^RELEASE *=/{release=$2}; END {print "MidnightBSD", release, "kernel"}' < conf/newvers.sh`
 
+# You need the devel/cscope port for this.
 cscope:	${.CURDIR}/cscopenamefile
 	cd ${.CURDIR}; cscope -k -p4 -i cscopenamefile
 
 ${.CURDIR}/cscopenamefile: 
 	cd ${.CURDIR}; find ${CSCOPEDIRS} -name "*.[csh]" > ${.TARGET}
 
+# You need the devel/global and one of editor/emacs* ports for that.
 TAGS ${.CURDIR}/TAGS:	${.CURDIR}/cscopenamefile
 	rm -f ${.CURDIR}/TAGS
 	cd ${.CURDIR}; xargs etags -a < ${.CURDIR}/cscopenamefile
Index: smb_smb.c
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_smb.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netsmb/smb_smb.c -L sys/netsmb/smb_smb.c -u -r1.1.1.1 -r1.2
--- sys/netsmb/smb_smb.c
+++ sys/netsmb/smb_smb.c
@@ -35,7 +35,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netsmb/smb_smb.c,v 1.13 2005/01/07 01:45:49 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netsmb/smb_smb.c,v 1.15 2007/06/15 23:49:54 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -197,10 +197,8 @@
 				vcp->vc_chlen = sblen;
 				vcp->obj.co_flags |= SMBV_ENCRYPT;
 			}
-#ifdef NETSMBCRYPTO
 			if (sp->sv_sm & SMB_SM_SIGS_REQUIRE)
 				vcp->vc_hflags2 |= SMB_FLAGS2_SECURITY_SIGNATURE;
-#endif
 			vcp->vc_hflags2 |= SMB_FLAGS2_KNOWS_LONG_NAMES;
 			if (dp->d_id == SMB_DIALECT_NTLM0_12 &&
 			    sp->sv_maxtx < 4096 &&
@@ -807,6 +805,7 @@
 
 	tsize = uio->uio_resid;
 	while (tsize > 0) {
+		resid = 0;
 		len = tsize;
 		error = smb_smb_read(ssp, fid, &len, &resid, uio, scred);
 		if (error)
@@ -882,6 +881,7 @@
 	tsize = uio->uio_resid;
 	olduio = *uio;
 	while (tsize > 0) {
+		resid = 0;
 		len = tsize;
 		error = smb_smb_write(ssp, fid, &len, &resid, uio, scred);
 		if (error)
Index: smb_iod.c
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_iod.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netsmb/smb_iod.c -L sys/netsmb/smb_iod.c -u -r1.1.1.1 -r1.2
--- sys/netsmb/smb_iod.c
+++ sys/netsmb/smb_iod.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netsmb/smb_iod.c,v 1.16 2005/01/07 01:45:49 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netsmb/smb_iod.c,v 1.17 2006/08/22 03:05:51 marcel Exp $");
  
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -244,8 +244,8 @@
 		if (vcp->vc_maxmux != 0 && iod->iod_muxcnt >= vcp->vc_maxmux)
 			return 0;
 #endif
-		*rqp->sr_rqtid = htole16(ssp ? ssp->ss_tid : SMB_TID_UNKNOWN);
-		*rqp->sr_rquid = htole16(vcp ? vcp->vc_smbuid : 0);
+		le16enc(rqp->sr_rqtid, ssp ? ssp->ss_tid : SMB_TID_UNKNOWN);
+		le16enc(rqp->sr_rquid, vcp ? vcp->vc_smbuid : 0);
 		mb_fixhdr(&rqp->sr_rq);
 		if (vcp->vc_hflags2 & SMB_FLAGS2_SECURITY_SIGNATURE)
 			smb_rq_sign(rqp);
Index: smb_crypt.c
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_crypt.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netsmb/smb_crypt.c -L sys/netsmb/smb_crypt.c -u -r1.1.1.1 -r1.2
--- sys/netsmb/smb_crypt.c
+++ sys/netsmb/smb_crypt.c
@@ -34,7 +34,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netsmb/smb_crypt.c,v 1.8 2005/01/07 01:45:49 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netsmb/smb_crypt.c,v 1.10 2006/08/22 03:05:51 marcel Exp $");
 
 #include <sys/param.h>
 #include <sys/malloc.h>
@@ -59,12 +59,10 @@
 #include <netsmb/smb_rq.h>
 #include <netsmb/smb_dev.h>
 
-#include "opt_netsmb.h"
-
-#ifdef NETSMBCRYPTO
-
 #include <crypto/des/des.h>
 
+#include "opt_netsmb.h"
+
 static u_char N8[] = {0x4b, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25};
 
 
@@ -87,13 +85,11 @@
 	des_ecb_encrypt((des_cblock *)data, (des_cblock *)dest, *ksp, 1);
 	free(ksp, M_SMBTEMP);
 }
-#endif
 
 
 int
 smb_encrypt(const u_char *apwd, u_char *C8, u_char *RN)
 {
-#ifdef NETSMBCRYPTO
 	u_char *p, *P14, *S21;
 
 	p = malloc(14 + 21, M_SMBTEMP, M_WAITOK);
@@ -112,17 +108,11 @@
 	smb_E(S21 + 14, C8, RN + 16);
 	free(p, M_SMBTEMP);
 	return 0;
-#else
-	SMBERROR("password encryption is not available\n");
-	bzero(RN, 24);
-	return EAUTH;
-#endif
 }
 
 int
 smb_ntencrypt(const u_char *apwd, u_char *C8, u_char *RN)
 {
-#ifdef NETSMBCRYPTO
 	u_char S21[21];
 	u_int16_t *unipwd;
 	MD4_CTX *ctxp;
@@ -146,11 +136,6 @@
 	smb_E(S21 + 7, C8, RN + 8);
 	smb_E(S21 + 14, C8, RN + 16);
 	return 0;
-#else
-	SMBERROR("password encryption is not available\n");
-	bzero(RN, 24);
-	return EAUTH;
-#endif
 }
 
 /*
@@ -159,7 +144,6 @@
 int
 smb_calcmackey(struct smb_vc *vcp)
 {
-#ifdef NETSMBCRYPTO
 	const char *pwd;
 	u_int16_t *unipwd;
 	int len;
@@ -210,10 +194,6 @@
 	smb_E(S21 + 14, vcp->vc_ch, vcp->vc_mackey + 32);
 
 	return (0);
-#else
-	panic("smb_calcmackey: encryption not available");
-	return (0);
-#endif	/* NETSMBCRYPTO */
 }
 
 /*
@@ -222,7 +202,6 @@
 int
 smb_rq_sign(struct smb_rq *rqp)
 {
-#ifdef NETSMBCRYPTO
 	struct smb_vc *vcp = rqp->sr_vc;
 	struct mbchain *mbp;
 	struct mbuf *mb;
@@ -262,8 +241,8 @@
 	}
 
 	/* Initialize sec. signature field to sequence number + zeros. */
-	*(u_int32_t *)rqp->sr_rqsig = htole32(rqp->sr_seqno);
-	*(u_int32_t *)(rqp->sr_rqsig + 4) = 0;
+	le32enc(rqp->sr_rqsig, rqp->sr_seqno);
+	le32enc(rqp->sr_rqsig + 4, 0);
 
 	/*
 	 * Compute HMAC-MD5 of packet data, keyed by MAC key.
@@ -278,10 +257,6 @@
 	bcopy(digest, rqp->sr_rqsig, 8);
 
 	return (0);
-#else
-	panic("smb_rq_sign: encryption not available");
-	return (0);
-#endif	/* NETSMBCRYPTO */
 }
 
 /*
@@ -290,7 +265,6 @@
 int
 smb_rq_verify(struct smb_rq *rqp)
 {
-#ifdef NETSMBCRYPTO
 	struct smb_vc *vcp = rqp->sr_vc;
 	struct mdchain *mdp;
 	u_char sigbuf[8];
@@ -332,8 +306,4 @@
 		return (EAUTH);
 
 	return (0);
-#else
-	panic("smb_rq_verify: encryption not available");
-	return (0);
-#endif	/* NETSMBCRYPTO */
 }
Index: smb_subr.h
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_subr.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netsmb/smb_subr.h -L sys/netsmb/smb_subr.h -u -r1.1.1.1 -r1.2
--- sys/netsmb/smb_subr.h
+++ sys/netsmb/smb_subr.h
@@ -29,7 +29,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/netsmb/smb_subr.h,v 1.12 2005/01/07 01:45:49 imp Exp $
+ * $FreeBSD: src/sys/netsmb/smb_subr.h,v 1.13 2006/11/06 13:42:06 rwatson Exp $
  */
 #ifndef _NETSMB_SMB_SUBR_H_
 #define _NETSMB_SMB_SUBR_H_
@@ -68,7 +68,7 @@
 	 SIGISMEMBER(set, SIGHUP) || SIGISMEMBER(set, SIGKILL) ||	\
 	 SIGISMEMBER(set, SIGQUIT))
 
-#define	smb_suser(cred)	suser_cred(cred, 0)
+#define	smb_suser(cred)	priv_check_cred(cred, PRIV_NETSMB, 0)
 
 /*
  * Compatibility wrappers for simple locks
Index: smb_dev.c
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_dev.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/netsmb/smb_dev.c -L sys/netsmb/smb_dev.c -u -r1.1.1.2 -r1.2
--- sys/netsmb/smb_dev.c
+++ sys/netsmb/smb_dev.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netsmb/smb_dev.c,v 1.27.2.2 2006/01/13 10:23:39 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netsmb/smb_dev.c,v 1.33 2007/07/10 09:23:10 avatar Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -175,7 +175,7 @@
 */
 	dev->si_drv1 = NULL;
 	free(sdp, M_NSMBDEV);
-	destroy_dev(dev);
+	destroy_dev_sched(dev);
 	splx(s);
 	return 0;
 }
@@ -349,6 +349,8 @@
 		if (error)
 			break;
 		EVENTHANDLER_DEREGISTER(dev_clone, nsmb_dev_tag);
+		drain_dev_clone_events();
+		destroy_dev_drain(&nsmb_cdevsw);
 		printf("netsmb_dev: unloaded\n");
 		break;
 	    default:
@@ -368,15 +370,15 @@
 {
 	struct file* fp;
 
-	FILEDESC_LOCK(fdp);
+	FILEDESC_SLOCK(fdp);
 	if (((u_int)fd) >= fdp->fd_nfiles ||
 	    (fp = fdp->fd_ofiles[fd]) == NULL ||
 	    (fp->f_flag & flag) == 0) {
-		FILEDESC_UNLOCK(fdp);
+		FILEDESC_SUNLOCK(fdp);
 		return (NULL);
 	}
 	fhold(fp);
-	FILEDESC_UNLOCK(fdp);
+	FILEDESC_SUNLOCK(fdp);
 	return (fp);
 }
 
Index: smb_rq.h
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_rq.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netsmb/smb_rq.h -L sys/netsmb/smb_rq.h -u -r1.1.1.1 -r1.2
--- sys/netsmb/smb_rq.h
+++ sys/netsmb/smb_rq.h
@@ -29,7 +29,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/netsmb/smb_rq.h,v 1.4 2005/01/07 01:45:49 imp Exp $
+ * $FreeBSD: src/sys/netsmb/smb_rq.h,v 1.5 2006/08/22 03:05:51 marcel Exp $
  */
 #ifndef _NETSMB_SMB_RQ_H_
 #define	_NETSMB_SMB_RQ_H_
@@ -82,7 +82,7 @@
 	u_int8_t		sr_rqflags;
 	u_int16_t		sr_rqflags2;
 	u_char *		sr_wcount;
-	u_short *		sr_bcount;
+	void *			sr_bcount;	/* Points to 2-byte buffer. */
 	struct mdchain		sr_rp;
 	int			sr_rpgen;
 	int			sr_rplast;
@@ -95,8 +95,8 @@
 	struct timespec 	sr_timesent;
 	int			sr_lerror;
 	u_int8_t *		sr_rqsig;
-	u_int16_t *		sr_rqtid;
-	u_int16_t *		sr_rquid;
+	void *			sr_rqtid;	/* Points to 2-byte buffer. */
+	void *			sr_rquid;	/* Points to 2-byte buffer. */
 	u_int8_t		sr_errclass;
 	u_int16_t		sr_serror;
 	u_int32_t		sr_error;
Index: smb_subr.c
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_subr.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/netsmb/smb_subr.c -L sys/netsmb/smb_subr.c -u -r1.1.1.2 -r1.2
--- sys/netsmb/smb_subr.c
+++ sys/netsmb/smb_subr.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netsmb/smb_subr.c,v 1.18.2.1 2006/01/24 04:08:48 csjp Exp $");
+__FBSDID("$FreeBSD: src/sys/netsmb/smb_subr.c,v 1.21 2006/11/05 06:31:08 bp Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -269,6 +269,8 @@
 			return ENOENT;
 		    case 145:		/* samba */
 			return ENOTEMPTY;
+		    case ERRnotlocked:
+			return 0;	/* file become unlocked */
 		    case 183:
 			return EEXIST;
 		    case ERRquota:
@@ -323,11 +325,20 @@
 }
 
 static int
-smb_copy_iconv(struct mbchain *mbp, c_caddr_t src, caddr_t dst, size_t len)
+smb_copy_iconv(struct mbchain *mbp, c_caddr_t src, caddr_t dst,
+    size_t *srclen, size_t *dstlen)
 {
-	size_t outlen = len;
+	int error;
+	size_t inlen = *srclen, outlen = *dstlen;
 
-	return iconv_conv((struct iconv_drv*)mbp->mb_udata, &src, &len, &dst, &outlen);
+	error = iconv_conv((struct iconv_drv*)mbp->mb_udata, &src, &inlen,
+	    &dst, &outlen);
+	if (inlen != *srclen || outlen != *dstlen) {
+		*srclen -= inlen;
+		*dstlen -= outlen;
+		return 0;
+	} else
+		return error;
 }
 
 int
Index: netbios.h
===================================================================
RCS file: /home/cvs/src/sys/netsmb/netbios.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netsmb/netbios.h -L sys/netsmb/netbios.h -u -r1.1.1.1 -r1.2
--- sys/netsmb/netbios.h
+++ sys/netsmb/netbios.h
@@ -29,7 +29,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $FreeBSD: src/sys/netsmb/netbios.h,v 1.5.2.1 2005/11/22 02:01:01 bp Exp $
+ * $FreeBSD: src/sys/netsmb/netbios.h,v 1.6 2005/10/02 08:32:49 bp Exp $
  */
 #ifndef _NETSMB_NETBIOS_H_
 #define	_NETSMB_NETBIOS_H_
Index: smb_rq.c
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_rq.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netsmb/smb_rq.c -L sys/netsmb/smb_rq.c -u -r1.1.1.1 -r1.2
--- sys/netsmb/smb_rq.c
+++ sys/netsmb/smb_rq.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netsmb/smb_rq.c,v 1.16 2005/01/07 01:45:49 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netsmb/smb_rq.c,v 1.17 2006/08/22 03:05:51 marcel Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -141,9 +141,9 @@
 		rqp->sr_rqsig = (u_int8_t *)mb_reserve(mbp, 8);
 		mb_put_uint16le(mbp, 0);
 	}
-	rqp->sr_rqtid = (u_int16_t*)mb_reserve(mbp, sizeof(u_int16_t));
+	rqp->sr_rqtid = mb_reserve(mbp, sizeof(u_int16_t));
 	mb_put_uint16le(mbp, 1 /*scred->sc_p->p_pid & 0xffff*/);
-	rqp->sr_rquid = (u_int16_t*)mb_reserve(mbp, sizeof(u_int16_t));
+	rqp->sr_rquid = mb_reserve(mbp, sizeof(u_int16_t));
 	mb_put_uint16le(mbp, rqp->sr_mid);
 	return 0;
 }
@@ -239,7 +239,7 @@
 void
 smb_rq_bstart(struct smb_rq *rqp)
 {
-	rqp->sr_bcount = (u_short*)mb_reserve(&rqp->sr_rq, sizeof(u_short));
+	rqp->sr_bcount = mb_reserve(&rqp->sr_rq, sizeof(u_short));
 	rqp->sr_rq.mb_count = 0;
 }
 
@@ -255,7 +255,7 @@
 	bcnt = rqp->sr_rq.mb_count;
 	if (bcnt > 0xffff)
 		SMBERROR("byte count too large (%d)\n", bcnt);
-	*rqp->sr_bcount = htole16(bcnt);
+	le16enc(rqp->sr_bcount, bcnt);
 }
 
 int
Index: smb_trantcp.c
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_trantcp.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netsmb/smb_trantcp.c -L sys/netsmb/smb_trantcp.c -u -r1.1.1.1 -r1.2
--- sys/netsmb/smb_trantcp.c
+++ sys/netsmb/smb_trantcp.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netsmb/smb_trantcp.c,v 1.22 2005/01/07 01:45:49 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netsmb/smb_trantcp.c,v 1.26 2007/06/15 23:49:54 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/condvar.h>
@@ -75,8 +75,7 @@
 SYSCTL_INT(_net_smb, OID_AUTO, tcpsndbuf, CTLFLAG_RW, &smb_tcpsndbuf, 0, "");
 SYSCTL_INT(_net_smb, OID_AUTO, tcprcvbuf, CTLFLAG_RW, &smb_tcprcvbuf, 0, "");
 
-#define nb_sosend(so,m,flags,td) (so)->so_proto->pr_usrreqs->pru_sosend( \
-				    so, NULL, 0, m, 0, flags, td)
+#define nb_sosend(so,m,flags,td) sosend(so, NULL, 0, m, 0, flags, td)
 
 static int  nbssn_recv(struct nbpcb *nbp, struct mbuf **mpp, int *lenp,
 	u_int8_t *rpcodep, struct thread *td);
@@ -95,19 +94,12 @@
 	return sosetopt(so, &sopt);
 }
 
-static __inline int
-nb_poll(struct nbpcb *nbp, int events, struct thread *td)
-{
-	return nbp->nbp_tso->so_proto->pr_usrreqs->pru_sopoll(nbp->nbp_tso,
-	    events, NULL, td);
-}
-
 static int
 nbssn_rselect(struct nbpcb *nbp, struct timeval *tv, int events,
 	struct thread *td)
 {
 	struct timeval atv, rtv, ttv;
-	int ncoll, timo, error;
+	int ncoll, timo, error, revents;
 
 	if (tv) {
 		atv = *tv;
@@ -123,23 +115,25 @@
 retry:
 
 	ncoll = nselcoll;
-	mtx_lock_spin(&sched_lock);
+	thread_lock(td);
 	td->td_flags |= TDF_SELECT;
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(td);
 	mtx_unlock(&sellock);
 
 	/* XXX: Should be done when the thread is initialized. */
 	TAILQ_INIT(&td->td_selq);
-	error = nb_poll(nbp, events, td);
+	revents = sopoll(nbp->nbp_tso, events, NULL, td);
 	mtx_lock(&sellock);
-	if (error) {
+	if (revents) {
 		error = 0;
 		goto done;
 	}
 	if (tv) {
 		getmicrouptime(&rtv);
-		if (timevalcmp(&rtv, &atv, >=))
+		if (timevalcmp(&rtv, &atv, >=)) {
+			error = EWOULDBLOCK;
 			goto done;
+		}
 		ttv = atv;
 		timevalsub(&ttv, &rtv);
 		timo = tvtohz(&ttv);
@@ -150,12 +144,12 @@
 	 * the process, test P_SELECT and rescan file descriptors if
 	 * necessary.
 	 */
-	mtx_lock_spin(&sched_lock);
+	thread_lock(td);
 	if ((td->td_flags & TDF_SELECT) == 0 || nselcoll != ncoll) {
-		mtx_unlock_spin(&sched_lock);
+		thread_unlock(td);
 		goto retry;
 	}
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(td);
 
 	if (timo > 0)
 		error = cv_timedwait(&selwait, &sellock, timo);
@@ -167,9 +161,9 @@
 done:
 	clear_selinfo_list(td);
 	
-	mtx_lock_spin(&sched_lock);
+	thread_lock(td);
 	td->td_flags &= ~TDF_SELECT;
-	mtx_unlock_spin(&sched_lock);
+	thread_unlock(td);
 	mtx_unlock(&sellock);
 
 done_noproclock:
@@ -377,8 +371,7 @@
 	auio.uio_offset = 0;
 	auio.uio_resid = sizeof(len);
 	auio.uio_td = td;
-	error = so->so_proto->pr_usrreqs->pru_soreceive
-	    (so, (struct sockaddr **)NULL, &auio,
+	error = soreceive(so, (struct sockaddr **)NULL, &auio,
 	    (struct mbuf **)NULL, (struct mbuf **)NULL, &flags);
 	if (error)
 		return error;
@@ -419,6 +412,8 @@
 		 * Poll for a response header.
 		 * If we don't have one waiting, return.
 		 */
+		len = 0;
+		rpcode = 0;
 		error = nbssn_recvhdr(nbp, &len, &rpcode, MSG_DONTWAIT, td);
 		if ((so->so_state & (SS_ISDISCONNECTING | SS_ISDISCONNECTED)) ||
 		    (so->so_rcv.sb_state & SBS_CANTRCVMORE)) {
@@ -461,8 +456,7 @@
 			 */
 			do {
 				rcvflg = MSG_WAITALL;
-				error = so->so_proto->pr_usrreqs->pru_soreceive
-				    (so, (struct sockaddr **)NULL,
+				error = soreceive(so, (struct sockaddr **)NULL,
 				    &auio, &tm, (struct mbuf **)NULL, &rcvflg);
 			} while (error == EWOULDBLOCK || error == EINTR ||
 				 error == ERESTART);
Index: smb_conn.c
===================================================================
RCS file: /home/cvs/src/sys/netsmb/smb_conn.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netsmb/smb_conn.c -L sys/netsmb/smb_conn.c -u -r1.1.1.1 -r1.2
--- sys/netsmb/smb_conn.c
+++ sys/netsmb/smb_conn.c
@@ -35,12 +35,13 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netsmb/smb_conn.c,v 1.15 2005/05/13 11:27:48 peadar Exp $");
+__FBSDID("$FreeBSD: src/sys/netsmb/smb_conn.c,v 1.18 2006/11/06 13:42:06 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/kernel.h>
 #include <sys/malloc.h>
+#include <sys/priv.h>
 #include <sys/proc.h>
 #include <sys/lock.h>
 #include <sys/sysctl.h>
@@ -59,7 +60,7 @@
 
 SYSCTL_NODE(_net, OID_AUTO, smb, CTLFLAG_RW, NULL, "SMB protocol");
 
-MALLOC_DEFINE(M_SMBCONN, "SMB conn", "SMB connection");
+MALLOC_DEFINE(M_SMBCONN, "smb_conn", "SMB connection");
 
 static void smb_co_init(struct smb_connobj *cp, int level, char *objname,
 	struct thread *td);
@@ -233,7 +234,8 @@
 	lockinit(&cp->co_lock, PZERO, objname, 0, 0);
 	cp->co_level = level;
 	cp->co_usecount = 1;
-	KASSERT(smb_co_lock(cp, LK_EXCLUSIVE, td) == 0, ("smb_co_init: lock failed"));
+	if (smb_co_lock(cp, LK_EXCLUSIVE, td) != 0)
+	    panic("smb_co_init: lock failed");
 }
 
 static void
Index: aarp.c
===================================================================
RCS file: /home/cvs/src/sys/netatalk/aarp.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/aarp.c -L sys/netatalk/aarp.c -u -r1.1.1.1 -r1.2
--- sys/netatalk/aarp.c
+++ sys/netatalk/aarp.c
@@ -22,8 +22,7 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- */
-/*-
+ *
  * Copyright (c) 1990,1991,1994 Regents of The University of Michigan.
  * All Rights Reserved.
  *
@@ -48,7 +47,7 @@
  *	+1-313-764-2278
  *	netatalk at umich.edu
  *
- * $FreeBSD: src/sys/netatalk/aarp.c,v 1.37 2005/06/10 16:49:20 brooks Exp $
+ * $FreeBSD: src/sys/netatalk/aarp.c,v 1.42 2007/01/12 12:25:12 rwatson Exp $
  */
 
 #include "opt_atalk.h"
@@ -56,13 +55,13 @@
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/mac.h>
 #include <sys/mbuf.h>
 #include <sys/kernel.h>
 #include <sys/socket.h>
 #include <sys/syslog.h>
 
 #include <net/if.h>
+#include <net/if_dl.h>
 
 #include <netinet/in.h>
 #undef s_net
@@ -74,95 +73,91 @@
 #include <netatalk/phase2.h>
 #include <netatalk/at_extern.h>
 
-static void aarptfree(struct aarptab *aat);
-static void at_aarpinput(struct ifnet *ifp, struct mbuf *m);
+#include <security/mac/mac_framework.h>
+
+static void	aarptfree(struct aarptab *aat);
+static void	at_aarpinput(struct ifnet *ifp, struct mbuf *m);
 
-#define AARPTAB_BSIZ	9
-#define AARPTAB_NB	19
-#define AARPTAB_SIZE	(AARPTAB_BSIZ * AARPTAB_NB)
+#define	AARPTAB_BSIZ	9
+#define	AARPTAB_NB	19
+#define	AARPTAB_SIZE	(AARPTAB_BSIZ * AARPTAB_NB)
 static struct aarptab	aarptab[AARPTAB_SIZE];
 
-struct mtx aarptab_mtx;
+struct mtx	aarptab_mtx;
 MTX_SYSINIT(aarptab_mtx, &aarptab_mtx, "aarptab_mtx", MTX_DEF);
 
-#define AARPTAB_HASH(a) \
-    ((((a).s_net << 8) + (a).s_node) % AARPTAB_NB)
+#define	AARPTAB_HASH(a)	((((a).s_net << 8) + (a).s_node) % AARPTAB_NB)
 
-#define AARPTAB_LOOK(aat, addr) { \
-    int		n; \
-    AARPTAB_LOCK_ASSERT(); \
-    aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ]; \
-    for (n = 0; n < AARPTAB_BSIZ; n++, aat++) \
-	if (aat->aat_ataddr.s_net == (addr).s_net && \
-	     aat->aat_ataddr.s_node == (addr).s_node) \
-	    break; \
-	if (n >= AARPTAB_BSIZ) \
-	    aat = NULL; \
-}
-
-#define AARPT_AGE	(60 * 1)
-#define AARPT_KILLC	20
-#define AARPT_KILLI	3
-
-# if !defined(__FreeBSD__)
-extern u_char			etherbroadcastaddr[6];
-# endif /* __FreeBSD__ */
+#define	AARPTAB_LOOK(aat, addr)	do {					\
+	int n;								\
+									\
+	AARPTAB_LOCK_ASSERT();						\
+	aat = &aarptab[ AARPTAB_HASH(addr) * AARPTAB_BSIZ ];		\
+	for (n = 0; n < AARPTAB_BSIZ; n++, aat++) {			\
+		if (aat->aat_ataddr.s_net == (addr).s_net &&		\
+		    aat->aat_ataddr.s_node == (addr).s_node)		\
+			break;						\
+	}								\
+	if (n >= AARPTAB_BSIZ)						\
+		aat = NULL;						\
+} while (0)
+
+#define	AARPT_AGE	(60 * 1)
+#define	AARPT_KILLC	20
+#define	AARPT_KILLI	3
 
-static const u_char atmulticastaddr[ 6 ] = {
-    0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
+static const u_char	atmulticastaddr[6] = {
+	0x09, 0x00, 0x07, 0xff, 0xff, 0xff,
 };
 
-u_char	at_org_code[ 3 ] = {
-    0x08, 0x00, 0x07,
+u_char	at_org_code[3] = {
+	0x08, 0x00, 0x07,
 };
-const u_char	aarp_org_code[ 3 ] = {
-    0x00, 0x00, 0x00,
+const u_char	aarp_org_code[3] = {
+	0x00, 0x00, 0x00,
 };
 
-static struct callout_handle aarptimer_ch =
+static struct callout_handle	aarptimer_ch =
     CALLOUT_HANDLE_INITIALIZER(&aarptimer_ch);
 
 static void
 aarptimer(void *ignored)
 {
-    struct aarptab	*aat;
-    int			i;
+	struct aarptab *aat;
+	int i;
 
-    aarptimer_ch = timeout(aarptimer, (caddr_t)0, AARPT_AGE * hz);
-    aat = aarptab;
-    AARPTAB_LOCK();
-    for (i = 0; i < AARPTAB_SIZE; i++, aat++) {
-	if (aat->aat_flags == 0 || (aat->aat_flags & ATF_PERM))
-	    continue;
-	if (++aat->aat_timer < ((aat->aat_flags & ATF_COM) ?
-		AARPT_KILLC : AARPT_KILLI))
-	    continue;
-	aarptfree(aat);
-    }
-    AARPTAB_UNLOCK();
+	aarptimer_ch = timeout(aarptimer, NULL, AARPT_AGE * hz);
+	aat = aarptab;
+	AARPTAB_LOCK();
+	for (i = 0; i < AARPTAB_SIZE; i++, aat++) {
+		if (aat->aat_flags == 0 || (aat->aat_flags & ATF_PERM))
+			continue;
+		if (++aat->aat_timer < ((aat->aat_flags & ATF_COM) ?
+		    AARPT_KILLC : AARPT_KILLI))
+			continue;
+		aarptfree(aat);
+	}
+	AARPTAB_UNLOCK();
 }
 
 /* 
- * search through the network addresses to find one that includes
- * the given network.. remember to take netranges into
- * consideration.
+ * Search through the network addresses to find one that includes the given
+ * network.  Remember to take netranges into consideration.
  */
 struct at_ifaddr *
 at_ifawithnet(struct sockaddr_at  *sat)
 {
-    struct at_ifaddr	*aa;
-    struct sockaddr_at	*sat2;
+	struct at_ifaddr *aa;
+	struct sockaddr_at *sat2;
 
 	for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
 		sat2 = &(aa->aa_addr);
-		if (sat2->sat_addr.s_net == sat->sat_addr.s_net) {
-	    		break;
-		}
-		if((aa->aa_flags & AFA_PHASE2)
-	 	&& (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net))
-	 	&& (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net))) {
+		if (sat2->sat_addr.s_net == sat->sat_addr.s_net)
+			break;
+		if ((aa->aa_flags & AFA_PHASE2) &&
+		    (ntohs(aa->aa_firstnet) <= ntohs(sat->sat_addr.s_net)) &&
+		    (ntohs(aa->aa_lastnet) >= ntohs(sat->sat_addr.s_net)))
 			break;
-		}
 	}
 	return (aa);
 }
@@ -170,522 +165,514 @@
 static void
 aarpwhohas(struct ifnet *ifp, struct sockaddr_at *sat)
 {
-    struct mbuf		*m;
-    struct ether_header	*eh;
-    struct ether_aarp	*ea;
-    struct at_ifaddr	*aa;
-    struct llc		*llc;
-    struct sockaddr	sa;
-
-    AARPTAB_UNLOCK_ASSERT();
-    if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) {
-	return;
-    }
+	struct mbuf *m;
+	struct ether_header *eh;
+	struct ether_aarp *ea;
+	struct at_ifaddr *aa;
+	struct llc *llc;
+	struct sockaddr	sa;
+
+	AARPTAB_UNLOCK_ASSERT();
+	m = m_gethdr(M_DONTWAIT, MT_DATA);
+	if (m == NULL)
+		return;
 #ifdef MAC
-    mac_create_mbuf_linklayer(ifp, m);
+	mac_create_mbuf_linklayer(ifp, m);
 #endif
-    m->m_len = sizeof(*ea);
-    m->m_pkthdr.len = sizeof(*ea);
-    MH_ALIGN(m, sizeof(*ea));
-
-    ea = mtod(m, struct ether_aarp *);
-    bzero((caddr_t)ea, sizeof(*ea));
-
-    ea->aarp_hrd = htons(AARPHRD_ETHER);
-    ea->aarp_pro = htons(ETHERTYPE_AT);
-    ea->aarp_hln = sizeof(ea->aarp_sha);
-    ea->aarp_pln = sizeof(ea->aarp_spu);
-    ea->aarp_op = htons(AARPOP_REQUEST);
-    bcopy(IFP2ENADDR(ifp), (caddr_t)ea->aarp_sha,
-	    sizeof(ea->aarp_sha));
+	m->m_len = sizeof(*ea);
+	m->m_pkthdr.len = sizeof(*ea);
+	MH_ALIGN(m, sizeof(*ea));
+
+	ea = mtod(m, struct ether_aarp *);
+	bzero((caddr_t)ea, sizeof(*ea));
+
+	ea->aarp_hrd = htons(AARPHRD_ETHER);
+	ea->aarp_pro = htons(ETHERTYPE_AT);
+	ea->aarp_hln = sizeof(ea->aarp_sha);
+	ea->aarp_pln = sizeof(ea->aarp_spu);
+	ea->aarp_op = htons(AARPOP_REQUEST);
+	bcopy(IF_LLADDR(ifp), (caddr_t)ea->aarp_sha, sizeof(ea->aarp_sha));
 
-    /*
-     * We need to check whether the output ethernet type should
-     * be phase 1 or 2. We have the interface that we'll be sending
-     * the aarp out. We need to find an AppleTalk network on that
-     * interface with the same address as we're looking for. If the
-     * net is phase 2, generate an 802.2 and SNAP header.
-     */
-    if ((aa = at_ifawithnet(sat)) == NULL) {
-	m_freem(m);
-	return;
-    }
+	/*
+	 * We need to check whether the output ethernet type should be phase
+	 * 1 or 2.  We have the interface that we'll be sending the aarp out.
+	 * We need to find an AppleTalk network on that interface with the
+	 * same address as we're looking for.  If the net is phase 2,
+	 * generate an 802.2 and SNAP header.
+	 */
+	if ((aa = at_ifawithnet(sat)) == NULL) {
+		m_freem(m);
+		return;
+	}
 
-    eh = (struct ether_header *)sa.sa_data;
+	eh = (struct ether_header *)sa.sa_data;
 
-    if (aa->aa_flags & AFA_PHASE2) {
-	bcopy(atmulticastaddr, eh->ether_dhost, sizeof(eh->ether_dhost));
-	eh->ether_type = htons(sizeof(struct llc) + sizeof(struct ether_aarp));
-	M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
-	if (m == NULL) {
-	    return;
-	}
-	llc = mtod(m, struct llc *);
-	llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
-	llc->llc_control = LLC_UI;
-	bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code));
-	llc->llc_ether_type = htons(ETHERTYPE_AARP);
-
-	bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet,
-	       sizeof(ea->aarp_spnet));
-	bcopy(&sat->sat_addr.s_net, ea->aarp_tpnet,
-	       sizeof(ea->aarp_tpnet));
-	ea->aarp_spnode = AA_SAT(aa)->sat_addr.s_node;
-	ea->aarp_tpnode = sat->sat_addr.s_node;
-    } else {
-	bcopy(ifp->if_broadcastaddr, (caddr_t)eh->ether_dhost,
-		sizeof(eh->ether_dhost));
-	eh->ether_type = htons(ETHERTYPE_AARP);
-
-	ea->aarp_spa = AA_SAT(aa)->sat_addr.s_node;
-	ea->aarp_tpa = sat->sat_addr.s_node;
-    }
+	if (aa->aa_flags & AFA_PHASE2) {
+		bcopy(atmulticastaddr, eh->ether_dhost,
+		    sizeof(eh->ether_dhost));
+		eh->ether_type = htons(sizeof(struct llc) +
+		    sizeof(struct ether_aarp));
+		M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
+		if (m == NULL)
+			return;
+		llc = mtod(m, struct llc *);
+		llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
+		llc->llc_control = LLC_UI;
+		bcopy(aarp_org_code, llc->llc_org_code,
+		    sizeof(aarp_org_code));
+		llc->llc_ether_type = htons(ETHERTYPE_AARP);
+		bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet,
+		    sizeof(ea->aarp_spnet));
+		bcopy(&sat->sat_addr.s_net, ea->aarp_tpnet,
+		    sizeof(ea->aarp_tpnet));
+		ea->aarp_spnode = AA_SAT(aa)->sat_addr.s_node;
+		ea->aarp_tpnode = sat->sat_addr.s_node;
+	} else {
+		bcopy(ifp->if_broadcastaddr, (caddr_t)eh->ether_dhost,
+		    sizeof(eh->ether_dhost));
+		eh->ether_type = htons(ETHERTYPE_AARP);
+		ea->aarp_spa = AA_SAT(aa)->sat_addr.s_node;
+		ea->aarp_tpa = sat->sat_addr.s_node;
+	}
 
 #ifdef NETATALKDEBUG
-    printf("aarp: sending request for %u.%u\n",
-	   ntohs(AA_SAT(aa)->sat_addr.s_net),
-	   AA_SAT(aa)->sat_addr.s_node);
+	printf("aarp: sending request for %u.%u\n",
+	    ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node);
 #endif /* NETATALKDEBUG */
 
-    sa.sa_len = sizeof(struct sockaddr);
-    sa.sa_family = AF_UNSPEC;
-    ifp->if_output(ifp, m, &sa, NULL /* route */);
+	sa.sa_len = sizeof(struct sockaddr);
+	sa.sa_family = AF_UNSPEC;
+	ifp->if_output(ifp, m, &sa, NULL);
 }
 
 int
-aarpresolve(ifp, m, destsat, desten)
-    struct ifnet	*ifp;
-    struct mbuf		*m;
-    struct sockaddr_at	*destsat;
-    u_char		*desten;
+aarpresolve(struct ifnet *ifp, struct mbuf *m, struct sockaddr_at *destsat,
+    u_char *desten)
 {
-    struct at_ifaddr	*aa;
-    struct aarptab	*aat;
+	struct at_ifaddr *aa;
+	struct aarptab *aat;
 
-    if (at_broadcast(destsat)) {
-	m->m_flags |= M_BCAST;
-	if ((aa = at_ifawithnet(destsat)) == NULL)  {
-	    m_freem(m);
-	    return (0);
-	}
-	if (aa->aa_flags & AFA_PHASE2) {
-	    bcopy(atmulticastaddr, (caddr_t)desten, sizeof(atmulticastaddr));
-	} else {
-	    bcopy(ifp->if_broadcastaddr, (caddr_t)desten,
-		    sizeof(ifp->if_addrlen));
-	}
-	return (1);
-    }
-
-    AARPTAB_LOCK();
-    AARPTAB_LOOK(aat, destsat->sat_addr);
-    if (aat == NULL) {			/* No entry */
-	aat = aarptnew(&destsat->sat_addr);
-	if (aat == NULL) { /* we should fail more gracefully! */
-	    panic("aarpresolve: no free entry");
-	}
-	goto done;
-    }
-    /* found an entry */
-    aat->aat_timer = 0;
-    if (aat->aat_flags & ATF_COM) {	/* entry is COMplete */
-	bcopy((caddr_t)aat->aat_enaddr, (caddr_t)desten,
-		sizeof(aat->aat_enaddr));
-	AARPTAB_UNLOCK();
-	return (1);
-    }
-    /* entry has not completed */
-    if (aat->aat_hold) {
-	m_freem(aat->aat_hold);
-    }
+	if (at_broadcast(destsat)) {
+		m->m_flags |= M_BCAST;
+		if ((aa = at_ifawithnet(destsat)) == NULL)  {
+			m_freem(m);
+			return (0);
+		}
+		if (aa->aa_flags & AFA_PHASE2)
+			bcopy(atmulticastaddr, (caddr_t)desten,
+			    sizeof(atmulticastaddr));
+		else
+			bcopy(ifp->if_broadcastaddr, (caddr_t)desten,
+			    sizeof(ifp->if_addrlen));
+		return (1);
+	}
+
+	AARPTAB_LOCK();
+	AARPTAB_LOOK(aat, destsat->sat_addr);
+	if (aat == NULL) {
+		/* No entry. */
+		aat = aarptnew(&destsat->sat_addr);
+
+		/* We should fail more gracefully. */
+		if (aat == NULL)
+			panic("aarpresolve: no free entry");
+		goto done;
+	}
+
+	/* Found an entry. */
+	aat->aat_timer = 0;
+	if (aat->aat_flags & ATF_COM) {
+		/* Entry is COMplete. */
+		bcopy((caddr_t)aat->aat_enaddr, (caddr_t)desten,
+		    sizeof(aat->aat_enaddr));
+		AARPTAB_UNLOCK();
+		return (1);
+	}
+
+	/* Entry has not completed. */
+	if (aat->aat_hold)
+		m_freem(aat->aat_hold);
 done:
-    aat->aat_hold = m;
-    AARPTAB_UNLOCK();
-    aarpwhohas(ifp, destsat);
-    return (0);
+	aat->aat_hold = m;
+	AARPTAB_UNLOCK();
+	aarpwhohas(ifp, destsat);
+	return (0);
 }
 
 void
-aarpintr(m)
-    struct mbuf		*m;
+aarpintr(struct mbuf *m)
 {
-    struct arphdr	*ar;
-    struct ifnet	*ifp;
+	struct arphdr *ar;
+	struct ifnet *ifp;
 
-    ifp = m->m_pkthdr.rcvif;
-    if (ifp->if_flags & IFF_NOARP)
-	goto out;
-
-    if (m->m_len < sizeof(struct arphdr)) {
-	goto out;
-    }
-
-    ar = mtod(m, struct arphdr *);
-    if (ntohs(ar->ar_hrd) != AARPHRD_ETHER) {
-	goto out;
-    }
-    
-    if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln +
-	    2 * ar->ar_pln) {
-	goto out;
-    }
-    
-    switch(ntohs(ar->ar_pro)) {
-    case ETHERTYPE_AT :
-	at_aarpinput(ifp, m);
-	return;
-
-    default:
-	break;
-    }
+	ifp = m->m_pkthdr.rcvif;
+	if (ifp->if_flags & IFF_NOARP)
+		goto out;
+
+	if (m->m_len < sizeof(struct arphdr))
+		goto out;
+
+	ar = mtod(m, struct arphdr *);
+	if (ntohs(ar->ar_hrd) != AARPHRD_ETHER)
+		goto out;
+	
+	if (m->m_len < sizeof(struct arphdr) + 2 * ar->ar_hln +
+	    2 * ar->ar_pln)
+		goto out;
+	
+	switch(ntohs(ar->ar_pro)) {
+	case ETHERTYPE_AT:
+		at_aarpinput(ifp, m);
+		return;
+	default:
+		break;
+	}
 
 out:
-    m_freem(m);
+	m_freem(m);
 }
 
 static void
 at_aarpinput(struct ifnet *ifp, struct mbuf *m)
 {
-    struct ether_aarp	*ea;
-    struct at_ifaddr	*aa;
-    struct aarptab	*aat;
-    struct ether_header	*eh;
-    struct llc		*llc;
-    struct sockaddr_at	sat;
-    struct sockaddr	sa;
-    struct at_addr	spa, tpa, ma;
-    int			op;
-    u_short		net;
-
-    ea = mtod(m, struct ether_aarp *);
-
-    /* Check to see if from my hardware address */
-    if (!bcmp((caddr_t)ea->aarp_sha, IFP2ENADDR(ifp),
-	    sizeof(IFP2ENADDR(ifp)))) {
-	m_freem(m);
-	return;
-    }
+	struct ether_aarp *ea;
+	struct at_ifaddr *aa;
+	struct aarptab *aat;
+	struct ether_header *eh;
+	struct llc *llc;
+	struct sockaddr_at sat;
+	struct sockaddr sa;
+	struct at_addr spa, tpa, ma;
+	int op;
+	u_short net;
+
+	ea = mtod(m, struct ether_aarp *);
+
+	/* Check to see if from my hardware address. */
+	if (!bcmp((caddr_t)ea->aarp_sha, IF_LLADDR(ifp), ETHER_ADDR_LEN)) {
+		m_freem(m);
+		return;
+	}
+
+	op = ntohs(ea->aarp_op);
+	bcopy(ea->aarp_tpnet, &net, sizeof(net));
+
+	if (net != 0) {
+		/* Should be ATADDR_ANYNET? */
+		sat.sat_len = sizeof(struct sockaddr_at);
+		sat.sat_family = AF_APPLETALK;
+		sat.sat_addr.s_net = net;
+		if ((aa = at_ifawithnet(&sat)) == NULL) {
+			m_freem(m);
+			return;
+		}
+		bcopy(ea->aarp_spnet, &spa.s_net, sizeof(spa.s_net));
+		bcopy(ea->aarp_tpnet, &tpa.s_net, sizeof(tpa.s_net));
+	} else {
+		/*
+		 * Since we don't know the net, we just look for the first
+		 * phase 1 address on the interface.
+		 */
+		for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ifp->if_addrhead);
+		    aa;
+		    aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) {
+			if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
+			    (aa->aa_flags & AFA_PHASE2) == 0) {
+				break;
+			}
+		}
+		if (aa == NULL) {
+			m_freem(m);
+			return;
+		}
+		tpa.s_net = spa.s_net = AA_SAT(aa)->sat_addr.s_net;
+	}
 
-    op = ntohs(ea->aarp_op);
-    bcopy(ea->aarp_tpnet, &net, sizeof(net));
+	spa.s_node = ea->aarp_spnode;
+	tpa.s_node = ea->aarp_tpnode;
+	ma.s_net = AA_SAT(aa)->sat_addr.s_net;
+	ma.s_node = AA_SAT(aa)->sat_addr.s_node;
 
-    if (net != 0) { /* should be ATADDR_ANYNET? */
-	sat.sat_len = sizeof(struct sockaddr_at);
-	sat.sat_family = AF_APPLETALK;
-	sat.sat_addr.s_net = net;
-	if ((aa = at_ifawithnet(&sat)) == NULL) {
-	    m_freem(m);
-	    return;
-	}
-	bcopy(ea->aarp_spnet, &spa.s_net, sizeof(spa.s_net));
-	bcopy(ea->aarp_tpnet, &tpa.s_net, sizeof(tpa.s_net));
-    } else {
 	/*
-	 * Since we don't know the net, we just look for the first
-	 * phase 1 address on the interface.
+	 * This looks like it's from us.
 	 */
-	for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ifp->if_addrhead); aa;
-		aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) {
-	    if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
-		    (aa->aa_flags & AFA_PHASE2) == 0) {
-		break;
-	    }
-	}
-	if (aa == NULL) {
-	    m_freem(m);
-	    return;
+	if (spa.s_net == ma.s_net && spa.s_node == ma.s_node) {
+		if (aa->aa_flags & AFA_PROBING) {
+			/*
+			 * We're probing, someone either responded to our
+			 * probe, or probed for the same address we'd like to
+			 * use. Change the address we're probing for.
+	    		 */
+			callout_stop(&aa->aa_callout);
+			wakeup(aa);
+			m_freem(m);
+			return;
+		} else if (op != AARPOP_PROBE) {
+			/*
+			 * This is not a probe, and we're not probing.  This
+			 * means that someone's saying they have the same
+			 * source address as the one we're using.  Get upset.
+			 */
+			log(LOG_ERR,
+			    "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n",
+			    ea->aarp_sha[0], ea->aarp_sha[1],
+			    ea->aarp_sha[2], ea->aarp_sha[3],
+			    ea->aarp_sha[4], ea->aarp_sha[5]);
+			m_freem(m);
+			return;
+		}
 	}
-	tpa.s_net = spa.s_net = AA_SAT(aa)->sat_addr.s_net;
-    }
 
-    spa.s_node = ea->aarp_spnode;
-    tpa.s_node = ea->aarp_tpnode;
-    ma.s_net = AA_SAT(aa)->sat_addr.s_net;
-    ma.s_node = AA_SAT(aa)->sat_addr.s_node;
-
-    /*
-     * This looks like it's from us.
-     */
-    if (spa.s_net == ma.s_net && spa.s_node == ma.s_node) {
-	if (aa->aa_flags & AFA_PROBING) {
-	    /*
-	     * We're probing, someone either responded to our probe, or
-	     * probed for the same address we'd like to use. Change the
-	     * address we're probing for.
-	     */
-	    callout_stop(&aa->aa_callout);
-	    wakeup(aa);
-	    m_freem(m);
-	    return;
-	} else if (op != AARPOP_PROBE) {
-	    /*
-	     * This is not a probe, and we're not probing. This means
-	     * that someone's saying they have the same source address
-	     * as the one we're using. Get upset...
-	     */
-	    log(LOG_ERR,
-		    "aarp: duplicate AT address!! %x:%x:%x:%x:%x:%x\n",
-		    ea->aarp_sha[ 0 ], ea->aarp_sha[ 1 ], ea->aarp_sha[ 2 ],
-		    ea->aarp_sha[ 3 ], ea->aarp_sha[ 4 ], ea->aarp_sha[ 5 ]);
-	    m_freem(m);
-	    return;
-	}
-    }
-
-    AARPTAB_LOCK();
-    AARPTAB_LOOK(aat, spa);
-    if (aat != NULL) {
-	if (op == AARPOP_PROBE) {
-	    /*
-	     * Someone's probing for spa, dealocate the one we've got,
-	     * so that if the prober keeps the address, we'll be able
-	     * to arp for him.
-	     */
-	    aarptfree(aat);
-	    AARPTAB_UNLOCK();
-	    m_freem(m);
-	    return;
-	}
-
-	bcopy((caddr_t)ea->aarp_sha, (caddr_t)aat->aat_enaddr,
-		sizeof(ea->aarp_sha));
-	aat->aat_flags |= ATF_COM;
-	if (aat->aat_hold) {
-	    struct mbuf *mhold = aat->aat_hold;
-	    aat->aat_hold = NULL;
-	    AARPTAB_UNLOCK();
-	    sat.sat_len = sizeof(struct sockaddr_at);
-	    sat.sat_family = AF_APPLETALK;
-	    sat.sat_addr = spa;
-	    (*ifp->if_output)(ifp, mhold,
-		    (struct sockaddr *)&sat, NULL); /* XXX */
-	} else
-	    AARPTAB_UNLOCK();
-    } else if ((tpa.s_net == ma.s_net)
-	   && (tpa.s_node == ma.s_node)
-	   && (op != AARPOP_PROBE)
-	   && ((aat = aarptnew(&spa)) != NULL)) {
+	AARPTAB_LOCK();
+	AARPTAB_LOOK(aat, spa);
+	if (aat != NULL) {
+		if (op == AARPOP_PROBE) {
+			/*
+			 * Someone's probing for spa, dealocate the one we've
+			 * got, so that if the prober keeps the address,
+			 * we'll be able to arp for him.
+			 */
+			aarptfree(aat);
+			AARPTAB_UNLOCK();
+			m_freem(m);
+			return;
+		}
+
+		bcopy((caddr_t)ea->aarp_sha, (caddr_t)aat->aat_enaddr,
+		    sizeof(ea->aarp_sha));
+		aat->aat_flags |= ATF_COM;
+		if (aat->aat_hold) {
+			struct mbuf *mhold = aat->aat_hold;
+			aat->aat_hold = NULL;
+			AARPTAB_UNLOCK();
+			sat.sat_len = sizeof(struct sockaddr_at);
+			sat.sat_family = AF_APPLETALK;
+			sat.sat_addr = spa;
+			(*ifp->if_output)(ifp, mhold,
+			    (struct sockaddr *)&sat, NULL); /* XXX */
+		} else
+			AARPTAB_UNLOCK();
+	} else if ((tpa.s_net == ma.s_net) && (tpa.s_node == ma.s_node)
+	    && (op != AARPOP_PROBE) && ((aat = aarptnew(&spa)) != NULL)) {
 		bcopy((caddr_t)ea->aarp_sha, (caddr_t)aat->aat_enaddr,
 		    sizeof(ea->aarp_sha));
 		aat->aat_flags |= ATF_COM;
 	        AARPTAB_UNLOCK();
-    } else
-	AARPTAB_UNLOCK();
+	} else
+		AARPTAB_UNLOCK();
 
-    /*
-     * Don't respond to responses, and never respond if we're
-     * still probing.
-     */
-    if (tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
+	/*
+	 * Don't respond to responses, and never respond if we're still
+	 * probing.
+	 */
+	if (tpa.s_net != ma.s_net || tpa.s_node != ma.s_node ||
 	    op == AARPOP_RESPONSE || (aa->aa_flags & AFA_PROBING)) {
-	m_freem(m);
-	return;
-    }
+		m_freem(m);
+		return;
+	}
 
-    bcopy((caddr_t)ea->aarp_sha, (caddr_t)ea->aarp_tha,
-	    sizeof(ea->aarp_sha));
-    bcopy(IFP2ENADDR(ifp), (caddr_t)ea->aarp_sha,
+	bcopy((caddr_t)ea->aarp_sha, (caddr_t)ea->aarp_tha,
 	    sizeof(ea->aarp_sha));
+	bcopy(IF_LLADDR(ifp), (caddr_t)ea->aarp_sha, sizeof(ea->aarp_sha));
 
-    /* XXX */
-    eh = (struct ether_header *)sa.sa_data;
-    bcopy((caddr_t)ea->aarp_tha, (caddr_t)eh->ether_dhost,
+	/* XXX */
+	eh = (struct ether_header *)sa.sa_data;
+	bcopy((caddr_t)ea->aarp_tha, (caddr_t)eh->ether_dhost,
 	    sizeof(eh->ether_dhost));
 
-    if (aa->aa_flags & AFA_PHASE2) {
-	eh->ether_type = htons(sizeof(struct llc) +
-		sizeof(struct ether_aarp));
-	M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
-	if (m == NULL) {
-	    return;
-	}
-	llc = mtod(m, struct llc *);
-	llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
-	llc->llc_control = LLC_UI;
-	bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code));
-	llc->llc_ether_type = htons(ETHERTYPE_AARP);
-
-	bcopy(ea->aarp_spnet, ea->aarp_tpnet, sizeof(ea->aarp_tpnet));
-	bcopy(&ma.s_net, ea->aarp_spnet, sizeof(ea->aarp_spnet));
-    } else {
-	eh->ether_type = htons(ETHERTYPE_AARP);
-    }
-
-    ea->aarp_tpnode = ea->aarp_spnode;
-    ea->aarp_spnode = ma.s_node;
-    ea->aarp_op = htons(AARPOP_RESPONSE);
-
-    sa.sa_len = sizeof(struct sockaddr);
-    sa.sa_family = AF_UNSPEC;
-    (*ifp->if_output)(ifp, m, &sa, NULL); /* XXX */
-    return;
+	if (aa->aa_flags & AFA_PHASE2) {
+		eh->ether_type = htons(sizeof(struct llc) +
+		    sizeof(struct ether_aarp));
+		M_PREPEND(m, sizeof(struct llc), M_DONTWAIT);
+		if (m == NULL)
+			return;
+		llc = mtod(m, struct llc *);
+		llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
+		llc->llc_control = LLC_UI;
+		bcopy(aarp_org_code, llc->llc_org_code,
+		    sizeof(aarp_org_code));
+		llc->llc_ether_type = htons(ETHERTYPE_AARP);
+
+		bcopy(ea->aarp_spnet, ea->aarp_tpnet,
+		    sizeof(ea->aarp_tpnet));
+		bcopy(&ma.s_net, ea->aarp_spnet, sizeof(ea->aarp_spnet));
+	} else
+		eh->ether_type = htons(ETHERTYPE_AARP);
+
+	ea->aarp_tpnode = ea->aarp_spnode;
+	ea->aarp_spnode = ma.s_node;
+	ea->aarp_op = htons(AARPOP_RESPONSE);
+
+	sa.sa_len = sizeof(struct sockaddr);
+	sa.sa_family = AF_UNSPEC;
+	(*ifp->if_output)(ifp, m, &sa, NULL); /* XXX */
+	return;
 }
 
 static void
 aarptfree(struct aarptab *aat)
 {
 
-    AARPTAB_LOCK_ASSERT();
-    if (aat->aat_hold)
-	m_freem(aat->aat_hold);
-    aat->aat_hold = NULL;
-    aat->aat_timer = aat->aat_flags = 0;
-    aat->aat_ataddr.s_net = 0;
-    aat->aat_ataddr.s_node = 0;
+	AARPTAB_LOCK_ASSERT();
+	if (aat->aat_hold)
+		m_freem(aat->aat_hold);
+	aat->aat_hold = NULL;
+	aat->aat_timer = aat->aat_flags = 0;
+	aat->aat_ataddr.s_net = 0;
+	aat->aat_ataddr.s_node = 0;
 }
 
 struct aarptab *
-aarptnew(addr)
-    struct at_addr	*addr;
+aarptnew(struct at_addr *addr)
 {
-    int			n;
-    int			oldest = -1;
-    struct aarptab	*aat, *aato = NULL;
-    static int		first = 1;
-
-    AARPTAB_LOCK_ASSERT();
-    if (first) {
-	first = 0;
-	aarptimer_ch = timeout(aarptimer, (caddr_t)0, hz);
-    }
-    aat = &aarptab[ AARPTAB_HASH(*addr) * AARPTAB_BSIZ ];
-    for (n = 0; n < AARPTAB_BSIZ; n++, aat++) {
-	if (aat->aat_flags == 0)
-	    goto out;
-	if (aat->aat_flags & ATF_PERM)
-	    continue;
-	if ((int) aat->aat_timer > oldest) {
-	    oldest = aat->aat_timer;
-	    aato = aat;
-	}
-    }
-    if (aato == NULL)
-	return (NULL);
-    aat = aato;
-    aarptfree(aat);
+	int n;
+	int oldest = -1;
+	struct aarptab *aat, *aato = NULL;
+	static int first = 1;
+
+	AARPTAB_LOCK_ASSERT();
+	if (first) {
+		first = 0;
+		aarptimer_ch = timeout(aarptimer, (caddr_t)0, hz);
+	}
+	aat = &aarptab[AARPTAB_HASH(*addr) * AARPTAB_BSIZ];
+	for (n = 0; n < AARPTAB_BSIZ; n++, aat++) {
+		if (aat->aat_flags == 0)
+			goto out;
+		if (aat->aat_flags & ATF_PERM)
+			continue;
+		if ((int) aat->aat_timer > oldest) {
+			oldest = aat->aat_timer;
+			aato = aat;
+		}
+	}
+	if (aato == NULL)
+		return (NULL);
+	aat = aato;
+	aarptfree(aat);
 out:
-    aat->aat_ataddr = *addr;
-    aat->aat_flags = ATF_INUSE;
-    return (aat);
+	aat->aat_ataddr = *addr;
+	aat->aat_flags = ATF_INUSE;
+	return (aat);
 }
 
 
 void
 aarpprobe(void *arg)
 {
-    struct ifnet	*ifp = arg;
-    struct mbuf		*m;
-    struct ether_header	*eh;
-    struct ether_aarp	*ea;
-    struct at_ifaddr	*aa;
-    struct llc		*llc;
-    struct sockaddr	sa;
-
-    /*
-     * We need to check whether the output ethernet type should
-     * be phase 1 or 2. We have the interface that we'll be sending
-     * the aarp out. We need to find an AppleTalk network on that
-     * interface with the same address as we're looking for. If the
-     * net is phase 2, generate an 802.2 and SNAP header.
-     */
-    AARPTAB_LOCK();
-    for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ifp->if_addrhead); aa;
+	struct ifnet *ifp = arg;
+	struct mbuf *m;
+	struct ether_header *eh;
+	struct ether_aarp *ea;
+	struct at_ifaddr *aa;
+	struct llc *llc;
+	struct sockaddr sa;
+
+	/*
+	 * We need to check whether the output ethernet type should be phase
+	 * 1 or 2.  We have the interface that we'll be sending the aarp out.
+	 * We need to find an AppleTalk network on that interface with the
+	 * same address as we're looking for.  If the net is phase 2,
+	 * generate an 802.2 and SNAP header.
+	 */
+	AARPTAB_LOCK();
+	for (aa = (struct at_ifaddr *)TAILQ_FIRST(&ifp->if_addrhead); aa;
 	    aa = (struct at_ifaddr *)aa->aa_ifa.ifa_link.tqe_next) {
-	if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
-		(aa->aa_flags & AFA_PROBING)) {
-	    break;
+		if (AA_SAT(aa)->sat_family == AF_APPLETALK &&
+		    (aa->aa_flags & AFA_PROBING))
+			break;
+	}
+	if (aa == NULL) {
+		/* Serious error XXX. */
+		AARPTAB_UNLOCK();
+		printf("aarpprobe why did this happen?!\n");
+		return;
 	}
-    }
-    if (aa == NULL) {		/* serious error XXX */
-	AARPTAB_UNLOCK();
-	printf("aarpprobe why did this happen?!\n");
-	return;
-    }
 
-    if (aa->aa_probcnt <= 0) {
-	aa->aa_flags &= ~AFA_PROBING;
-	wakeup(aa);
+	if (aa->aa_probcnt <= 0) {
+		aa->aa_flags &= ~AFA_PROBING;
+		wakeup(aa);
+		AARPTAB_UNLOCK();
+		return;
+	} else
+		callout_reset(&aa->aa_callout, hz / 5, aarpprobe, ifp);
 	AARPTAB_UNLOCK();
-	return;
-    } else {
-	callout_reset(&aa->aa_callout, hz / 5, aarpprobe, ifp);
-    }
-    AARPTAB_UNLOCK();
 
-    if ((m = m_gethdr(M_DONTWAIT, MT_DATA)) == NULL) {
-	return;
-    }
+	m = m_gethdr(M_DONTWAIT, MT_DATA);
+	if (m == NULL)
+		return;
 #ifdef MAC
-    mac_create_mbuf_linklayer(ifp, m);
+	mac_create_mbuf_linklayer(ifp, m);
 #endif
-    m->m_len = sizeof(*ea);
-    m->m_pkthdr.len = sizeof(*ea);
-    MH_ALIGN(m, sizeof(*ea));
-
-    ea = mtod(m, struct ether_aarp *);
-    bzero((caddr_t)ea, sizeof(*ea));
-
-    ea->aarp_hrd = htons(AARPHRD_ETHER);
-    ea->aarp_pro = htons(ETHERTYPE_AT);
-    ea->aarp_hln = sizeof(ea->aarp_sha);
-    ea->aarp_pln = sizeof(ea->aarp_spu);
-    ea->aarp_op = htons(AARPOP_PROBE);
-    bcopy(IFP2ENADDR(ifp), (caddr_t)ea->aarp_sha,
+	m->m_len = sizeof(*ea);
+	m->m_pkthdr.len = sizeof(*ea);
+	MH_ALIGN(m, sizeof(*ea));
+
+	ea = mtod(m, struct ether_aarp *);
+	bzero((caddr_t)ea, sizeof(*ea));
+
+	ea->aarp_hrd = htons(AARPHRD_ETHER);
+	ea->aarp_pro = htons(ETHERTYPE_AT);
+	ea->aarp_hln = sizeof(ea->aarp_sha);
+	ea->aarp_pln = sizeof(ea->aarp_spu);
+	ea->aarp_op = htons(AARPOP_PROBE);
+	bcopy(IF_LLADDR(ifp), (caddr_t)ea->aarp_sha,
 	    sizeof(ea->aarp_sha));
 
-    eh = (struct ether_header *)sa.sa_data;
+	eh = (struct ether_header *)sa.sa_data;
 
-    if (aa->aa_flags & AFA_PHASE2) {
-	bcopy(atmulticastaddr, eh->ether_dhost, sizeof(eh->ether_dhost));
-	eh->ether_type = htons(sizeof(struct llc) +
-		sizeof(struct ether_aarp));
-	M_PREPEND(m, sizeof(struct llc), M_TRYWAIT);
-	if (m == NULL) {
-	    return;
-	}
-	llc = mtod(m, struct llc *);
-	llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
-	llc->llc_control = LLC_UI;
-	bcopy(aarp_org_code, llc->llc_org_code, sizeof(aarp_org_code));
-	llc->llc_ether_type = htons(ETHERTYPE_AARP);
-
-	bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet,
-		sizeof(ea->aarp_spnet));
-	bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_tpnet,
-		sizeof(ea->aarp_tpnet));
-	ea->aarp_spnode = ea->aarp_tpnode = AA_SAT(aa)->sat_addr.s_node;
-    } else {
-	bcopy(ifp->if_broadcastaddr, (caddr_t)eh->ether_dhost,
-		sizeof(eh->ether_dhost));
-	eh->ether_type = htons(ETHERTYPE_AARP);
-	ea->aarp_spa = ea->aarp_tpa = AA_SAT(aa)->sat_addr.s_node;
-    }
+	if (aa->aa_flags & AFA_PHASE2) {
+		bcopy(atmulticastaddr, eh->ether_dhost,
+		    sizeof(eh->ether_dhost));
+		eh->ether_type = htons(sizeof(struct llc) +
+		    sizeof(struct ether_aarp));
+		M_PREPEND(m, sizeof(struct llc), M_TRYWAIT);
+		if (m == NULL)
+			return;
+		llc = mtod(m, struct llc *);
+		llc->llc_dsap = llc->llc_ssap = LLC_SNAP_LSAP;
+		llc->llc_control = LLC_UI;
+		bcopy(aarp_org_code, llc->llc_org_code,
+		    sizeof(aarp_org_code));
+		llc->llc_ether_type = htons(ETHERTYPE_AARP);
+
+		bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_spnet,
+		    sizeof(ea->aarp_spnet));
+		bcopy(&AA_SAT(aa)->sat_addr.s_net, ea->aarp_tpnet,
+		    sizeof(ea->aarp_tpnet));
+		ea->aarp_spnode = ea->aarp_tpnode =
+		    AA_SAT(aa)->sat_addr.s_node;
+	} else {
+		bcopy(ifp->if_broadcastaddr, (caddr_t)eh->ether_dhost,
+		    sizeof(eh->ether_dhost));
+		eh->ether_type = htons(ETHERTYPE_AARP);
+		ea->aarp_spa = ea->aarp_tpa = AA_SAT(aa)->sat_addr.s_node;
+	}
 
 #ifdef NETATALKDEBUG
-    printf("aarp: sending probe for %u.%u\n",
-	   ntohs(AA_SAT(aa)->sat_addr.s_net),
-	   AA_SAT(aa)->sat_addr.s_node);
+	printf("aarp: sending probe for %u.%u\n",
+	    ntohs(AA_SAT(aa)->sat_addr.s_net), AA_SAT(aa)->sat_addr.s_node);
 #endif /* NETATALKDEBUG */
 
-    sa.sa_len = sizeof(struct sockaddr);
-    sa.sa_family = AF_UNSPEC;
-    (*ifp->if_output)(ifp, m, &sa, NULL); /* XXX */
-    aa->aa_probcnt--;
+	sa.sa_len = sizeof(struct sockaddr);
+	sa.sa_family = AF_UNSPEC;
+	(*ifp->if_output)(ifp, m, &sa, NULL); /* XXX */
+	aa->aa_probcnt--;
 }
 
 void
 aarp_clean(void)
 {
-    struct aarptab	*aat;
-    int			i;
+	struct aarptab *aat;
+	int i;
 
-    untimeout(aarptimer, 0, aarptimer_ch);
-    AARPTAB_LOCK();
-    for (i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++) {
-	if (aat->aat_hold) {
-	    m_freem(aat->aat_hold);
-	    aat->aat_hold = NULL;
+	untimeout(aarptimer, 0, aarptimer_ch);
+	AARPTAB_LOCK();
+	for (i = 0, aat = aarptab; i < AARPTAB_SIZE; i++, aat++) {
+		if (aat->aat_hold) {
+			m_freem(aat->aat_hold);
+			aat->aat_hold = NULL;
+		}
 	}
-    }
-    AARPTAB_UNLOCK();
+	AARPTAB_UNLOCK();
 }
Index: at_proto.c
===================================================================
RCS file: /home/cvs/src/sys/netatalk/at_proto.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/at_proto.c -L sys/netatalk/at_proto.c -u -r1.1.1.1 -r1.2
--- sys/netatalk/at_proto.c
+++ sys/netatalk/at_proto.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * Copyright (c) 1990, 1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software and
@@ -20,7 +20,7 @@
  *	+1-313-763-0525
  *	netatalk at itd.umich.edu
  *
- * $FreeBSD: src/sys/netatalk/at_proto.c,v 1.10.2.1 2005/11/16 10:31:22 ru Exp $
+ * $FreeBSD: src/sys/netatalk/at_proto.c,v 1.13 2007/01/12 13:18:08 rwatson Exp $
  */
 
 #include <sys/param.h>
@@ -36,19 +36,19 @@
 #include <netatalk/ddp_var.h>
 #include <netatalk/at_extern.h>
 
-extern struct domain	atalkdomain;
+static struct domain	atalkdomain;
 
 static struct protosw	atalksw[] = {
-    {
-	/* Identifiers */
-	.pr_type =		SOCK_DGRAM,
-	.pr_domain =		&atalkdomain,
-	.pr_protocol =		ATPROTO_DDP,
-	.pr_flags =		PR_ATOMIC|PR_ADDR,
-	.pr_output =		ddp_output,
-	.pr_init =		ddp_init,
-	.pr_usrreqs =		&ddp_usrreqs
-    },
+	{
+		/* Identifiers */
+		.pr_type =		SOCK_DGRAM,
+		.pr_domain =		&atalkdomain,
+		.pr_protocol =		ATPROTO_DDP,
+		.pr_flags =		PR_ATOMIC|PR_ADDR,
+		.pr_output =		ddp_output,
+		.pr_init =		ddp_init,
+		.pr_usrreqs =		&ddp_usrreqs,
+	},
 };
 
 static struct domain	atalkdomain = {
@@ -58,8 +58,7 @@
 	.dom_protoswNPROTOSW =	&atalksw[sizeof(atalksw)/sizeof(atalksw[0])],
 	.dom_rtattach =		rn_inithead,
 	.dom_rtoffset =		offsetof(struct sockaddr_at, sat_addr) << 3,
-	.dom_maxrtkey =		sizeof(struct sockaddr_at)
+	.dom_maxrtkey =		sizeof(struct sockaddr_at),
 };
 
 DOMAIN_SET(atalk);
-
Index: ddp_pcb.c
===================================================================
RCS file: /home/cvs/src/sys/netatalk/ddp_pcb.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/ddp_pcb.c -L sys/netatalk/ddp_pcb.c -u -r1.1.1.1 -r1.2
--- sys/netatalk/ddp_pcb.c
+++ sys/netatalk/ddp_pcb.c
@@ -1,6 +1,29 @@
 /*-
  * Copyright (c) 2004-2005 Robert N. M. Watson
- * Copyright (c) 1990,1994 Regents of The University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (c) 1990, 1994 Regents of The University of Michigan.
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software and
@@ -23,13 +46,14 @@
  *	Ann Arbor, Michigan
  *	+1-313-764-2278
  *	netatalk at umich.edu
- * $FreeBSD: src/sys/netatalk/ddp_pcb.c,v 1.47 2005/01/07 02:35:34 imp Exp $
+ * $FreeBSD: src/sys/netatalk/ddp_pcb.c,v 1.52 2007/01/12 15:07:51 rwatson Exp $
  */
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/malloc.h>
 #include <sys/mbuf.h>
+#include <sys/priv.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 #include <sys/protosw.h>
@@ -44,232 +68,225 @@
 #include <netatalk/at_extern.h>
 
 struct mtx		 ddp_list_mtx;
-static struct ddpcb	*ddp_ports[ ATPORT_LAST ];
+static struct ddpcb	*ddp_ports[ATPORT_LAST];
 struct ddpcb		*ddpcb_list = NULL;
 
 void
 at_sockaddr(struct ddpcb *ddp, struct sockaddr **addr)
 {
 
-    /*
-     * Prevent modification of ddp during copy of addr.
-     */
-    DDP_LOCK_ASSERT(ddp);
-    *addr = sodupsockaddr((struct sockaddr *)&ddp->ddp_lsat, M_NOWAIT);
+	/*
+	 * Prevent modification of ddp during copy of addr.
+	 */
+	DDP_LOCK_ASSERT(ddp);
+	*addr = sodupsockaddr((struct sockaddr *)&ddp->ddp_lsat, M_NOWAIT);
 }
 
 int 
 at_pcbsetaddr(struct ddpcb *ddp, struct sockaddr *addr, struct thread *td)
 {
-    struct sockaddr_at	lsat, *sat;
-    struct at_ifaddr	*aa;
-    struct ddpcb	*ddpp;
-
-    /*
-     * We read and write both the ddp passed in, and also ddp_ports.
-     */
-    DDP_LIST_XLOCK_ASSERT();
-    DDP_LOCK_ASSERT(ddp);
-
-    if (ddp->ddp_lsat.sat_port != ATADDR_ANYPORT) { /* shouldn't be bound */
-	return (EINVAL);
-    }
-
-    if (addr != NULL) {			/* validate passed address */
-	sat = (struct sockaddr_at *)addr;
-	if (sat->sat_family != AF_APPLETALK) {
-	    return (EAFNOSUPPORT);
-	}
+	struct sockaddr_at lsat, *sat;
+	struct at_ifaddr *aa;
+	struct ddpcb *ddpp;
+
+	/*
+	 * We read and write both the ddp passed in, and also ddp_ports.
+	 */
+	DDP_LIST_XLOCK_ASSERT();
+	DDP_LOCK_ASSERT(ddp);
 
-	if (sat->sat_addr.s_node != ATADDR_ANYNODE ||
-		sat->sat_addr.s_net != ATADDR_ANYNET) {
-	    for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
-		if ((sat->sat_addr.s_net == AA_SAT(aa)->sat_addr.s_net) &&
-		 (sat->sat_addr.s_node == AA_SAT(aa)->sat_addr.s_node)) {
-		    break;
+	/*
+	 * Shouldn't be bound.
+	 */
+	if (ddp->ddp_lsat.sat_port != ATADDR_ANYPORT)
+		return (EINVAL);
+
+	/*
+	 * Validate passed address.
+	 */
+	if (addr != NULL) {
+		sat = (struct sockaddr_at *)addr;
+		if (sat->sat_family != AF_APPLETALK)
+			return (EAFNOSUPPORT);
+
+		if (sat->sat_addr.s_node != ATADDR_ANYNODE ||
+		    sat->sat_addr.s_net != ATADDR_ANYNET) {
+			for (aa = at_ifaddr_list; aa != NULL;
+			    aa = aa->aa_next) {
+				if ((sat->sat_addr.s_net ==
+				    AA_SAT(aa)->sat_addr.s_net) &&
+				    (sat->sat_addr.s_node ==
+				    AA_SAT(aa)->sat_addr.s_node))
+					break;
+			}
+			if (aa == NULL)
+				return (EADDRNOTAVAIL);
 		}
-	    }
-	    if (!aa) {
-		return (EADDRNOTAVAIL);
-	    }
-	}
 
-	if (sat->sat_port != ATADDR_ANYPORT) {
-	    if (sat->sat_port < ATPORT_FIRST ||
-		    sat->sat_port >= ATPORT_LAST) {
-		return (EINVAL);
-	    }
-	    if (sat->sat_port < ATPORT_RESERVED &&
-		 suser(td)) {
-		return (EACCES);
-	    }
+		if (sat->sat_port != ATADDR_ANYPORT) {
+			if (sat->sat_port < ATPORT_FIRST ||
+			    sat->sat_port >= ATPORT_LAST)
+				return (EINVAL);
+			if (sat->sat_port < ATPORT_RESERVED &&
+			    priv_check(td, PRIV_NETATALK_RESERVEDPORT))
+				return (EACCES);
+		}
+	} else {
+		bzero((caddr_t)&lsat, sizeof(struct sockaddr_at));
+		lsat.sat_len = sizeof(struct sockaddr_at);
+		lsat.sat_addr.s_node = ATADDR_ANYNODE;
+		lsat.sat_addr.s_net = ATADDR_ANYNET;
+		lsat.sat_family = AF_APPLETALK;
+		sat = &lsat;
 	}
-    } else {
-	bzero((caddr_t)&lsat, sizeof(struct sockaddr_at));
-	lsat.sat_len = sizeof(struct sockaddr_at);
-	lsat.sat_addr.s_node = ATADDR_ANYNODE;
-	lsat.sat_addr.s_net = ATADDR_ANYNET;
-	lsat.sat_family = AF_APPLETALK;
-	sat = &lsat;
-    }
 
-    if (sat->sat_addr.s_node == ATADDR_ANYNODE &&
+	if (sat->sat_addr.s_node == ATADDR_ANYNODE &&
 	    sat->sat_addr.s_net == ATADDR_ANYNET) {
-	if (at_ifaddr_list == NULL) {
-	    return (EADDRNOTAVAIL);
-	}
-	sat->sat_addr = AA_SAT(at_ifaddr_list)->sat_addr;
-    }
-    ddp->ddp_lsat = *sat;
-
-    /*
-     * Choose port.
-     */
-    if (sat->sat_port == ATADDR_ANYPORT) {
-	for (sat->sat_port = ATPORT_RESERVED;
-		sat->sat_port < ATPORT_LAST; sat->sat_port++) {
-	    if (ddp_ports[ sat->sat_port - 1 ] == NULL) {
-		break;
-	    }
-	}
-	if (sat->sat_port == ATPORT_LAST) {
-	    return (EADDRNOTAVAIL);
-	}
-	ddp->ddp_lsat.sat_port = sat->sat_port;
-	ddp_ports[ sat->sat_port - 1 ] = ddp;
-    } else {
-	for (ddpp = ddp_ports[ sat->sat_port - 1 ]; ddpp;
-		ddpp = ddpp->ddp_pnext) {
-	    if (ddpp->ddp_lsat.sat_addr.s_net == sat->sat_addr.s_net &&
-		    ddpp->ddp_lsat.sat_addr.s_node == sat->sat_addr.s_node) {
-		break;
-	    }
-	}
-	if (ddpp != NULL) {
-	    return (EADDRINUSE);
-	}
-	ddp->ddp_pnext = ddp_ports[ sat->sat_port - 1 ];
-	ddp_ports[ sat->sat_port - 1 ] = ddp;
-	if (ddp->ddp_pnext) {
-	    ddp->ddp_pnext->ddp_pprev = ddp;
+		if (at_ifaddr_list == NULL)
+			return (EADDRNOTAVAIL);
+		sat->sat_addr = AA_SAT(at_ifaddr_list)->sat_addr;
+	}
+	ddp->ddp_lsat = *sat;
+
+	/*
+	 * Choose port.
+	 */
+	if (sat->sat_port == ATADDR_ANYPORT) {
+		for (sat->sat_port = ATPORT_RESERVED;
+		    sat->sat_port < ATPORT_LAST; sat->sat_port++) {
+			if (ddp_ports[sat->sat_port - 1] == NULL)
+				break;
+		}
+		if (sat->sat_port == ATPORT_LAST)
+			return (EADDRNOTAVAIL);
+		ddp->ddp_lsat.sat_port = sat->sat_port;
+		ddp_ports[sat->sat_port - 1] = ddp;
+	} else {
+		for (ddpp = ddp_ports[sat->sat_port - 1]; ddpp;
+		    ddpp = ddpp->ddp_pnext) {
+			if (ddpp->ddp_lsat.sat_addr.s_net ==
+			    sat->sat_addr.s_net &&
+			    ddpp->ddp_lsat.sat_addr.s_node ==
+			    sat->sat_addr.s_node)
+				break;
+		}
+		if (ddpp != NULL)
+			return (EADDRINUSE);
+		ddp->ddp_pnext = ddp_ports[sat->sat_port - 1];
+		ddp_ports[sat->sat_port - 1] = ddp;
+		if (ddp->ddp_pnext != NULL)
+			ddp->ddp_pnext->ddp_pprev = ddp;
 	}
-    }
 
-    return (0);
+	return (0);
 }
 
 int
 at_pcbconnect(struct ddpcb *ddp, struct sockaddr *addr, struct thread *td)
 {
-    struct sockaddr_at	*sat = (struct sockaddr_at *)addr;
-    struct route	*ro;
-    struct at_ifaddr	*aa = NULL;
-    struct ifnet	*ifp;
-    u_short		hintnet = 0, net;
-
-    DDP_LIST_XLOCK_ASSERT();
-    DDP_LOCK_ASSERT(ddp);
-
-    if (sat->sat_family != AF_APPLETALK) {
-	return (EAFNOSUPPORT);
-    }
-
-    /*
-     * Under phase 2, network 0 means "the network".  We take "the
-     * network" to mean the network the control block is bound to.
-     * If the control block is not bound, there is an error.
-     */
-    if (sat->sat_addr.s_net == ATADDR_ANYNET
-		&& sat->sat_addr.s_node != ATADDR_ANYNODE) {
-	if (ddp->ddp_lsat.sat_port == ATADDR_ANYPORT) {
-	    return (EADDRNOTAVAIL);
-	}
-	hintnet = ddp->ddp_lsat.sat_addr.s_net;
-    }
+	struct sockaddr_at	*sat = (struct sockaddr_at *)addr;
+	struct route	*ro;
+	struct at_ifaddr	*aa = NULL;
+	struct ifnet	*ifp;
+	u_short		hintnet = 0, net;
 
-    ro = &ddp->ddp_route;
-    /*
-     * If we've got an old route for this pcb, check that it is valid.
-     * If we've changed our address, we may have an old "good looking"
-     * route here.  Attempt to detect it.
-     */
-    if (ro->ro_rt) {
-	if (hintnet) {
-	    net = hintnet;
-	} else {
-	    net = sat->sat_addr.s_net;
+	DDP_LIST_XLOCK_ASSERT();
+	DDP_LOCK_ASSERT(ddp);
+
+	if (sat->sat_family != AF_APPLETALK)
+		return (EAFNOSUPPORT);
+
+	/*
+	 * Under phase 2, network 0 means "the network".  We take "the
+	 * network" to mean the network the control block is bound to.  If
+	 * the control block is not bound, there is an error.
+	 */
+	if (sat->sat_addr.s_net == ATADDR_ANYNET &&
+	    sat->sat_addr.s_node != ATADDR_ANYNODE) {
+		if (ddp->ddp_lsat.sat_port == ATADDR_ANYPORT)
+			return (EADDRNOTAVAIL);
+		hintnet = ddp->ddp_lsat.sat_addr.s_net;
+	}
+
+	ro = &ddp->ddp_route;
+	/*
+	 * If we've got an old route for this pcb, check that it is valid.
+	 * If we've changed our address, we may have an old "good looking"
+	 * route here.  Attempt to detect it.
+	 */
+	if (ro->ro_rt) {
+		if (hintnet)
+			net = hintnet;
+		else
+			net = sat->sat_addr.s_net;
+		aa = NULL;
+		if ((ifp = ro->ro_rt->rt_ifp) != NULL) {
+			for (aa = at_ifaddr_list; aa != NULL;
+			    aa = aa->aa_next) {
+				if (aa->aa_ifp == ifp &&
+				    ntohs(net) >= ntohs(aa->aa_firstnet) &&
+				    ntohs(net) <= ntohs(aa->aa_lastnet))
+					break;
+			}
+		}
+		if (aa == NULL || (satosat(&ro->ro_dst)->sat_addr.s_net !=
+		    (hintnet ? hintnet : sat->sat_addr.s_net) ||
+		    satosat(&ro->ro_dst)->sat_addr.s_node !=
+		    sat->sat_addr.s_node)) {
+			RTFREE(ro->ro_rt);
+			ro->ro_rt = NULL;
+		}
 	}
+
+	/*
+	 * If we've got no route for this interface, try to find one.
+	 */
+	if (ro->ro_rt == NULL || ro->ro_rt->rt_ifp == NULL) {
+		ro->ro_dst.sa_len = sizeof(struct sockaddr_at);
+		ro->ro_dst.sa_family = AF_APPLETALK;
+		if (hintnet)
+			satosat(&ro->ro_dst)->sat_addr.s_net = hintnet;
+		else
+			satosat(&ro->ro_dst)->sat_addr.s_net =
+			    sat->sat_addr.s_net;
+		satosat(&ro->ro_dst)->sat_addr.s_node = sat->sat_addr.s_node;
+		rtalloc(ro);
+	}
+
+	/*
+	 * Make sure any route that we have has a valid interface.
+	 */
 	aa = NULL;
-	if ((ifp = ro->ro_rt->rt_ifp) != NULL) {
-	    for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
-		if (aa->aa_ifp == ifp &&
-			ntohs(net) >= ntohs(aa->aa_firstnet) &&
-			ntohs(net) <= ntohs(aa->aa_lastnet)) {
-		    break;
+	if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp)) {
+		for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
+			if (aa->aa_ifp == ifp)
+				break;
 		}
-	    }
-	}
-	if (aa == NULL || (satosat(&ro->ro_dst)->sat_addr.s_net !=
-		(hintnet ? hintnet : sat->sat_addr.s_net) ||
-		satosat(&ro->ro_dst)->sat_addr.s_node !=
-		sat->sat_addr.s_node)) {
-	    RTFREE(ro->ro_rt);
-	    ro->ro_rt = NULL;
 	}
-    }
+	if (aa == NULL)
+		return (ENETUNREACH);
 
-    /*
-     * If we've got no route for this interface, try to find one.
-     */
-    if (ro->ro_rt == NULL || ro->ro_rt->rt_ifp == NULL) {
-	ro->ro_dst.sa_len = sizeof(struct sockaddr_at);
-	ro->ro_dst.sa_family = AF_APPLETALK;
-	if (hintnet) {
-	    satosat(&ro->ro_dst)->sat_addr.s_net = hintnet;
-	} else {
-	    satosat(&ro->ro_dst)->sat_addr.s_net = sat->sat_addr.s_net;
-	}
-	satosat(&ro->ro_dst)->sat_addr.s_node = sat->sat_addr.s_node;
-	rtalloc(ro);
-    }
-
-    /*
-     * Make sure any route that we have has a valid interface.
-     */
-    aa = NULL;
-    if (ro->ro_rt && (ifp = ro->ro_rt->rt_ifp)) {
-	for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
-	    if (aa->aa_ifp == ifp) {
-		break;
-	    }
-	}
-    }
-    if (aa == NULL) {
-	return (ENETUNREACH);
-    }
-
-    ddp->ddp_fsat = *sat;
-    if (ddp->ddp_lsat.sat_port == ATADDR_ANYPORT) {
-	return (at_pcbsetaddr(ddp, NULL, td));
-    }
-    return (0);
+	ddp->ddp_fsat = *sat;
+	if (ddp->ddp_lsat.sat_port == ATADDR_ANYPORT)
+		return (at_pcbsetaddr(ddp, NULL, td));
+	return (0);
 }
 
 void 
 at_pcbdisconnect(struct ddpcb	*ddp)
 {
 
-    DDP_LOCK_ASSERT(ddp);
+	DDP_LOCK_ASSERT(ddp);
 
-    ddp->ddp_fsat.sat_addr.s_net = ATADDR_ANYNET;
-    ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE;
-    ddp->ddp_fsat.sat_port = ATADDR_ANYPORT;
+	ddp->ddp_fsat.sat_addr.s_net = ATADDR_ANYNET;
+	ddp->ddp_fsat.sat_addr.s_node = ATADDR_ANYNODE;
+	ddp->ddp_fsat.sat_port = ATADDR_ANYPORT;
 }
 
 int
 at_pcballoc(struct socket *so)
 {
-	struct ddpcb	*ddp;
+	struct ddpcb *ddp;
 
 	DDP_LIST_XLOCK_ASSERT();
 
@@ -286,9 +303,8 @@
 	ddp->ddp_prev = NULL;
 	ddp->ddp_pprev = NULL;
 	ddp->ddp_pnext = NULL;
-	if (ddpcb_list != NULL) {
+	if (ddpcb_list != NULL)
 		ddpcb_list->ddp_prev = ddp;
-	}
 	ddpcb_list = ddp;
 	return(0);
 }
@@ -297,103 +313,95 @@
 at_pcbdetach(struct socket *so, struct ddpcb *ddp)
 {
 
-    /*
-     * We modify ddp, ddp_ports, and the global list.
-     */
-    DDP_LIST_XLOCK_ASSERT();
-    DDP_LOCK_ASSERT(ddp);
-
-    soisdisconnected(so);
-    ACCEPT_LOCK();
-    SOCK_LOCK(so);
-    so->so_pcb = NULL;
-    sotryfree(so);
-
-    /* remove ddp from ddp_ports list */
-    if (ddp->ddp_lsat.sat_port != ATADDR_ANYPORT &&
-	    ddp_ports[ ddp->ddp_lsat.sat_port - 1 ] != NULL) {
-	if (ddp->ddp_pprev != NULL) {
-	    ddp->ddp_pprev->ddp_pnext = ddp->ddp_pnext;
-	} else {
-	    ddp_ports[ ddp->ddp_lsat.sat_port - 1 ] = ddp->ddp_pnext;
-	}
-	if (ddp->ddp_pnext != NULL) {
-	    ddp->ddp_pnext->ddp_pprev = ddp->ddp_pprev;
-	}
-    }
+	/*
+	 * We modify ddp, ddp_ports, and the global list.
+	 */
+	DDP_LIST_XLOCK_ASSERT();
+	DDP_LOCK_ASSERT(ddp);
+	KASSERT(so->so_pcb != NULL, ("at_pcbdetach: so_pcb == NULL"));
 
-    if (ddp->ddp_route.ro_rt) {
-	RTFREE(ddp->ddp_route.ro_rt);
-    }
-
-    if (ddp->ddp_prev) {
-	ddp->ddp_prev->ddp_next = ddp->ddp_next;
-    } else {
-	ddpcb_list = ddp->ddp_next;
-    }
-    if (ddp->ddp_next) {
-	ddp->ddp_next->ddp_prev = ddp->ddp_prev;
-    }
-    DDP_UNLOCK(ddp);
-    DDP_LOCK_DESTROY(ddp);
-    FREE(ddp, M_PCB);
+	so->so_pcb = NULL;
+
+	/* Remove ddp from ddp_ports list. */
+	if (ddp->ddp_lsat.sat_port != ATADDR_ANYPORT &&
+	    ddp_ports[ddp->ddp_lsat.sat_port - 1] != NULL) {
+		if (ddp->ddp_pprev != NULL)
+			ddp->ddp_pprev->ddp_pnext = ddp->ddp_pnext;
+		else
+			ddp_ports[ddp->ddp_lsat.sat_port - 1] = ddp->ddp_pnext;
+		if (ddp->ddp_pnext != NULL)
+			ddp->ddp_pnext->ddp_pprev = ddp->ddp_pprev;
+	}
+
+	if (ddp->ddp_route.ro_rt)
+		RTFREE(ddp->ddp_route.ro_rt);
+
+	if (ddp->ddp_prev)
+		ddp->ddp_prev->ddp_next = ddp->ddp_next;
+	else
+		ddpcb_list = ddp->ddp_next;
+	if (ddp->ddp_next)
+		ddp->ddp_next->ddp_prev = ddp->ddp_prev;
+	DDP_UNLOCK(ddp);
+	DDP_LOCK_DESTROY(ddp);
+	FREE(ddp, M_PCB);
 }
 
 /*
- * For the moment, this just find the pcb with the correct local address.
- * In the future, this will actually do some real searching, so we can use
- * the sender's address to do de-multiplexing on a single port to many
- * sockets (pcbs).
+ * For the moment, this just find the pcb with the correct local address.  In
+ * the future, this will actually do some real searching, so we can use the
+ * sender's address to do de-multiplexing on a single port to many sockets
+ * (pcbs).
  */
 struct ddpcb *
 ddp_search(struct sockaddr_at *from, struct sockaddr_at *to,
-			struct at_ifaddr *aa)
+    struct at_ifaddr *aa)
 {
-    struct ddpcb	*ddp;
+	struct ddpcb *ddp;
 
-    DDP_LIST_SLOCK_ASSERT();
+	DDP_LIST_SLOCK_ASSERT();
 
-    /*
-     * Check for bad ports.
-     */
-    if (to->sat_port < ATPORT_FIRST || to->sat_port >= ATPORT_LAST) {
-	return (NULL);
-    }
-
-    /*
-     * Make sure the local address matches the sent address.  What about
-     * the interface?
-     */
-    for (ddp = ddp_ports[ to->sat_port - 1 ]; ddp; ddp = ddp->ddp_pnext) {
-	DDP_LOCK(ddp);
-	/* XXX should we handle 0.YY? */
-
-	/* XXXX.YY to socket on destination interface */
-	if (to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net &&
-		to->sat_addr.s_node == ddp->ddp_lsat.sat_addr.s_node) {
-	    DDP_UNLOCK(ddp);
-	    break;
-	}
+	/*
+	 * Check for bad ports.
+	 */
+	if (to->sat_port < ATPORT_FIRST || to->sat_port >= ATPORT_LAST)
+		return (NULL);
+
+	/*
+	 * Make sure the local address matches the sent address.  What about
+	 * the interface?
+	 */
+	for (ddp = ddp_ports[to->sat_port - 1]; ddp; ddp = ddp->ddp_pnext) {
+		DDP_LOCK(ddp);
+		/* XXX should we handle 0.YY? */
+		/* XXXX.YY to socket on destination interface */
+		if (to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net &&
+		    to->sat_addr.s_node == ddp->ddp_lsat.sat_addr.s_node) {
+			DDP_UNLOCK(ddp);
+			break;
+		}
 
-	/* 0.255 to socket on receiving interface */
-	if (to->sat_addr.s_node == ATADDR_BCAST && (to->sat_addr.s_net == 0 ||
-		to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net) &&
-		ddp->ddp_lsat.sat_addr.s_net == AA_SAT(aa)->sat_addr.s_net) {
-	    DDP_UNLOCK(ddp);
-	    break;
-	}
+		/* 0.255 to socket on receiving interface */
+		if (to->sat_addr.s_node == ATADDR_BCAST &&
+		    (to->sat_addr.s_net == 0 ||
+		    to->sat_addr.s_net == ddp->ddp_lsat.sat_addr.s_net) &&
+		    ddp->ddp_lsat.sat_addr.s_net ==
+		    AA_SAT(aa)->sat_addr.s_net) {
+			DDP_UNLOCK(ddp);
+			break;
+		}
 
-	/* XXXX.0 to socket on destination interface */
-	if (to->sat_addr.s_net == aa->aa_firstnet &&
-		to->sat_addr.s_node == 0 &&
-		ntohs(ddp->ddp_lsat.sat_addr.s_net) >=
-		ntohs(aa->aa_firstnet) &&
-		ntohs(ddp->ddp_lsat.sat_addr.s_net) <=
-		ntohs(aa->aa_lastnet)) {
-	    DDP_UNLOCK(ddp);
-	    break;
+		/* XXXX.0 to socket on destination interface */
+		if (to->sat_addr.s_net == aa->aa_firstnet &&
+		    to->sat_addr.s_node == 0 &&
+		    ntohs(ddp->ddp_lsat.sat_addr.s_net) >=
+		    ntohs(aa->aa_firstnet) &&
+		    ntohs(ddp->ddp_lsat.sat_addr.s_net) <=
+		    ntohs(aa->aa_lastnet)) {
+			DDP_UNLOCK(ddp);
+			break;
+		}
+		DDP_UNLOCK(ddp);
 	}
-	DDP_UNLOCK(ddp);
-    }
-    return (ddp);
+	return (ddp);
 }
Index: at_extern.h
===================================================================
RCS file: /home/cvs/src/sys/netatalk/at_extern.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/at_extern.h -L sys/netatalk/at_extern.h -u -r1.1.1.1 -r1.2
--- sys/netatalk/at_extern.h
+++ sys/netatalk/at_extern.h
@@ -23,58 +23,42 @@
  *	+1-313-764-2278
  *	netatalk at umich.edu
  *
- * $FreeBSD: src/sys/netatalk/at_extern.h,v 1.16 2005/02/22 14:20:29 rwatson Exp $
+ * $FreeBSD: src/sys/netatalk/at_extern.h,v 1.18 2007/01/12 13:18:08 rwatson Exp $
  */
-struct mbuf;
-struct sockaddr_at;
 
-#ifdef _NET_IF_ARP_H_
-extern timeout_t	aarpprobe;
-extern int	aarpresolve	(struct ifnet *,
-					struct mbuf *,
-					struct sockaddr_at *,
-					u_char *);
-extern int	at_broadcast	(struct sockaddr_at  *);
+#ifndef _NETATALK_AT_EXTERN_H_
+#define	_NETATALK_AT_EXTERN_H_
 
-extern struct mtx aarptab_mtx;
+extern struct mtx	aarptab_mtx;
 
 #define	AARPTAB_LOCK()		mtx_lock(&aarptab_mtx)
 #define	AARPTAB_UNLOCK()	mtx_unlock(&aarptab_mtx)
 #define	AARPTAB_LOCK_ASSERT()	mtx_assert(&aarptab_mtx, MA_OWNED)
 #define	AARPTAB_UNLOCK_ASSERT()	mtx_assert(&aarptab_mtx, MA_NOTOWNED)
-#endif
-
-#ifdef _NETATALK_AARP_H_
-extern void	aarptfree	(struct aarptab *);
-#endif
 
+struct at_ifaddr;
 struct ifnet;
+struct mbuf;
+struct route;
 struct thread;
+struct sockaddr_at;
 struct socket;
+void		 aarpintr(struct mbuf *);
+void		 aarpprobe(void *arg);
+int		 aarpresolve(struct ifnet *, struct mbuf *,
+		    struct sockaddr_at *, u_char *);
+void		 aarp_clean(void);
+void		 at1intr(struct mbuf *);
+void		 at2intr(struct mbuf *);
+int		 at_broadcast(struct sockaddr_at  *);
+u_short		 at_cksum(struct mbuf *m, int skip);
+int		 at_control(struct socket *so, u_long cmd, caddr_t data,
+		    struct ifnet *ifp, struct thread *td);
+struct at_ifaddr	*at_ifawithnet(struct sockaddr_at *);
+void		 ddp_init(void);
+int		 ddp_output(struct mbuf *m, struct socket *so); 
+int		 ddp_route(struct mbuf *m, struct route *ro);
+struct ddpcb	*ddp_search(struct sockaddr_at *, struct sockaddr_at *,
+		    struct at_ifaddr *);
 
-extern void	aarpintr	(struct mbuf *);
-extern void	at1intr		(struct mbuf *);
-extern void	at2intr		(struct mbuf *);
-extern void	aarp_clean	(void);
-extern int	at_control	(struct socket *so,
-					u_long cmd,
-					caddr_t data,
-					struct ifnet *ifp,
-					struct thread *td);
-extern u_short	at_cksum	(struct mbuf *m, int skip);
-extern void	ddp_init	(void);
-extern struct at_ifaddr *at_ifawithnet	(struct sockaddr_at *);
-#ifdef	_NETATALK_DDP_VAR_H_
-extern int	ddp_output	(struct mbuf *m, struct socket *so); 
-
-#endif
-#if	defined (_NETATALK_DDP_VAR_H_) && defined(_NETATALK_AT_VAR_H_)
-extern struct ddpcb  *ddp_search(struct sockaddr_at *,
-                                		struct sockaddr_at *,
-						struct at_ifaddr *);
-#endif
-#ifdef _NET_ROUTE_H_
-int     ddp_route(struct mbuf *m, struct route *ro);
-#endif
-
-
+#endif /* !_NETATALK_AT_EXTERN_H_ */
Index: ddp_var.h
===================================================================
RCS file: /home/cvs/src/sys/netatalk/ddp_var.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/ddp_var.h -L sys/netatalk/ddp_var.h -u -r1.1.1.1 -r1.2
--- sys/netatalk/ddp_var.h
+++ sys/netatalk/ddp_var.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1990,1994 Regents of The University of Michigan.
+ * Copyright (c) 1990, 1994 Regents of The University of Michigan.
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software and
@@ -23,39 +23,41 @@
  *	+1-313-764-2278
  *	netatalk at umich.edu
  *
- * $FreeBSD: src/sys/netatalk/ddp_var.h,v 1.8 2005/01/07 02:35:34 imp Exp $
+ * $FreeBSD: src/sys/netatalk/ddp_var.h,v 1.9 2007/01/12 15:07:51 rwatson Exp $
  */
 
 #ifndef _NETATALK_DDP_VAR_H_
-#define _NETATALK_DDP_VAR_H_ 1
+#define	_NETATALK_DDP_VAR_H_
+
 struct ddpcb {
-    struct sockaddr_at	ddp_fsat, ddp_lsat;
-    struct route	ddp_route;
-    struct socket	*ddp_socket;
-    struct ddpcb	*ddp_prev, *ddp_next;
-    struct ddpcb	*ddp_pprev, *ddp_pnext;
-    struct mtx		 ddp_mtx;
+	struct sockaddr_at	 ddp_fsat, ddp_lsat;
+	struct route		 ddp_route;
+	struct socket		*ddp_socket;
+	struct ddpcb		*ddp_prev, *ddp_next;
+	struct ddpcb		*ddp_pprev, *ddp_pnext;
+	struct mtx		 ddp_mtx;
 };
 
-#define sotoddpcb(so)	((struct ddpcb *)(so)->so_pcb)
+#define	sotoddpcb(so)	((struct ddpcb *)(so)->so_pcb)
 
 struct ddpstat {
-    long	ddps_short;		/* short header packets received */
-    long	ddps_long;		/* long header packets received */
-    long	ddps_nosum;		/* no checksum */
-    long	ddps_badsum;		/* bad checksum */
-    long	ddps_tooshort;		/* packet too short */
-    long	ddps_toosmall;		/* not enough data */
-    long	ddps_forward;		/* packets forwarded */
-    long	ddps_encap;		/* packets encapsulated */
-    long	ddps_cantforward;	/* packets rcvd for unreachable dest */
-    long	ddps_nosockspace;	/* no space in sockbuf for packet */
+	long	ddps_short;		/* short header packets received */
+	long	ddps_long;		/* long header packets received */
+	long	ddps_nosum;		/* no checksum */
+	long	ddps_badsum;		/* bad checksum */
+	long	ddps_tooshort;		/* packet too short */
+	long	ddps_toosmall;		/* not enough data */
+	long	ddps_forward;		/* packets forwarded */
+	long	ddps_encap;		/* packets encapsulated */
+	long	ddps_cantforward;	/* packets rcvd for unreachable dest */
+	long	ddps_nosockspace;	/* no space in sockbuf for packet */
 };
 
 #ifdef _KERNEL
-extern int	ddp_cksum;
+extern int			 ddp_cksum;
 extern struct ddpcb		*ddpcb_list;
-extern struct pr_usrreqs	ddp_usrreqs;
+extern struct pr_usrreqs	 ddp_usrreqs;
 extern struct mtx		 ddp_list_mtx;
 #endif
+
 #endif /* _NETATALK_DDP_VAR_H_ */
Index: at.h
===================================================================
RCS file: /home/cvs/src/sys/netatalk/at.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/at.h -L sys/netatalk/at.h -u -r1.1.1.1 -r1.2
--- sys/netatalk/at.h
+++ sys/netatalk/at.h
@@ -20,67 +20,67 @@
  *	+1-313-763-0525
  *	netatalk at itd.umich.edu
  *
- * $FreeBSD: src/sys/netatalk/at.h,v 1.7 2005/01/07 02:35:34 imp Exp $
+ * $FreeBSD: src/sys/netatalk/at.h,v 1.8 2007/01/12 13:18:08 rwatson Exp $
  */
 
-#ifndef __AT_HEADER__
-#define __AT_HEADER__
+#ifndef _NETATALK_AT_H_
+#define	_NETATALK_AT_H_
+
 /*
  * Supported protocols
  */
-#define ATPROTO_DDP	0
-#define ATPROTO_AARP	254
+#define	ATPROTO_DDP	0
+#define	ATPROTO_AARP	254
 
-#define DDP_MAXSZ	587
+#define	DDP_MAXSZ	587
 
 /*
- * If ATPORT_FIRST <= Port < ATPORT_RESERVED,
- * Port was created by a privileged process.
- * If ATPORT_RESERVED <= Port < ATPORT_LAST,
- * Port was not necessarily created by a
+ * If ATPORT_FIRST <= Port < ATPORT_RESERVED, the port was created by a
  * privileged process.
+ *
+ * If ATPORT_RESERVED <= Port < ATPORT_LAST, the port was not necessarily
+ * created by a privileged process.
  */
-#define ATPORT_FIRST	1
-#define ATPORT_RESERVED	128
-#define ATPORT_LAST	255
+#define	ATPORT_FIRST	1
+#define	ATPORT_RESERVED	128
+#define	ATPORT_LAST	255
 
 /*
  * AppleTalk address.
  */
 struct at_addr {
-    u_short	s_net;
-    u_char	s_node;
+	u_short	s_net;
+	u_char	s_node;
 };
 
-#define ATADDR_ANYNET	(u_short)0x0000
-#define ATADDR_ANYNODE	(u_char)0x00
-#define ATADDR_ANYPORT	(u_char)0x00
-#define ATADDR_BCAST	(u_char)0xff		/* There is no BCAST for NET */
+#define	ATADDR_ANYNET	(u_short)0x0000
+#define	ATADDR_ANYNODE	(u_char)0x00
+#define	ATADDR_ANYPORT	(u_char)0x00
+#define	ATADDR_BCAST	(u_char)0xff	/* There is no BCAST for NET. */
 
 struct netrange {
-    u_char		nr_phase;
-    u_short		nr_firstnet;
-    u_short		nr_lastnet;
+	u_char	nr_phase;
+	u_short	nr_firstnet;
+	u_short	nr_lastnet;
 };
 
 /*
- * Socket address, AppleTalk style.  We keep magic information in the 
- * zero bytes.  There are three types, NONE, CONFIG which has the phase
- * and a net range, and IFACE which has the network address of an
- * interface.  IFACE may be filled in by the client, and is filled in
- * by the kernel.
+ * Socket address, AppleTalk style.  We keep magic information in the zero
+ * bytes.  There are three types, NONE, CONFIG which has the phase and a net
+ * range, and IFACE which has the network address of an interface.  IFACE may
+ * be filled in by the client, and is filled in by the kernel.
  */
 struct sockaddr_at {
-    u_char		sat_len;
-    u_char		sat_family;
-    u_char		sat_port;
-    struct at_addr	sat_addr;
-    union {
-	struct netrange r_netrange;
-    	char		r_zero[ 8 ];	/* Hide a struct netrange in here */
-    } sat_range;
+	u_char		sat_len;
+	u_char		sat_family;
+	u_char		sat_port;
+	struct at_addr	sat_addr;
+	union {
+		struct netrange	r_netrange;
+		char		r_zero[8];	/* Hide struct netrange here. */
+	} sat_range;
 };
 
-#define sat_zero sat_range.r_zero
+#define	sat_zero	sat_range.r_zero
 
-#endif /* !__AT_HEADER__ */
+#endif /* !_NETATALK_AT_H_ */
Index: at_control.c
===================================================================
RCS file: /home/cvs/src/sys/netatalk/at_control.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/at_control.c -L sys/netatalk/at_control.c -u -r1.1.1.1 -r1.2
--- sys/netatalk/at_control.c
+++ sys/netatalk/at_control.c
@@ -23,7 +23,7 @@
  *	+1-313-764-2278
  *	netatalk at umich.edu
  *
- * $FreeBSD: src/sys/netatalk/at_control.c,v 1.44 2005/02/22 14:20:29 rwatson Exp $
+ * $FreeBSD: src/sys/netatalk/at_control.c,v 1.46 2007/02/19 22:40:02 rwatson Exp $
  */
 
 #include <sys/param.h>
@@ -31,6 +31,7 @@
 #include <sys/sockio.h>
 #include <sys/malloc.h>
 #include <sys/kernel.h>
+#include <sys/priv.h>
 #include <sys/socket.h>
 #include <net/if.h>
 #include <net/route.h>
@@ -118,8 +119,10 @@
 	case SIOCSIFADDR:
 		/* 
 		 * If we are not superuser, then we don't get to do these ops.
+		 *
+		 * XXXRW: Layering?
 		 */
-		if (suser(td))
+		if (priv_check(td, PRIV_NET_ADDIFADDR))
 			return (EPERM);
 
 		sat = satosat(&ifr->ifr_addr);
Index: ddp_output.c
===================================================================
RCS file: /home/cvs/src/sys/netatalk/ddp_output.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/ddp_output.c -L sys/netatalk/ddp_output.c -u -r1.1.1.1 -r1.2
--- sys/netatalk/ddp_output.c
+++ sys/netatalk/ddp_output.c
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * Copyright (c) 1990, 1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software and
@@ -21,13 +21,12 @@
  *	netatalk at itd.umich.edu
  */
 
-/* $FreeBSD: src/sys/netatalk/ddp_output.c,v 1.27.2.1 2005/10/09 04:22:03 delphij Exp $ */
+/* $FreeBSD: src/sys/netatalk/ddp_output.c,v 1.30 2007/01/12 15:07:51 rwatson Exp $ */
 
 #include "opt_mac.h"
 
 #include <sys/param.h>
 #include <sys/systm.h>
-#include <sys/mac.h>
 #include <sys/mbuf.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
@@ -43,202 +42,194 @@
 #include <netatalk/ddp_var.h>
 #include <netatalk/at_extern.h>
 
+#include <security/mac/mac_framework.h>
+
 int	ddp_cksum = 1;
 
 int
 ddp_output(struct mbuf *m, struct socket *so)
 {
-    struct ddpehdr	*deh;
-    struct ddpcb *ddp = sotoddpcb(so);
+	struct ddpehdr	*deh;
+	struct ddpcb *ddp = sotoddpcb(so);
 
 #ifdef MAC
-    SOCK_LOCK(so);
-    mac_create_mbuf_from_socket(so, m);
-    SOCK_UNLOCK(so);
+	SOCK_LOCK(so);
+	mac_create_mbuf_from_socket(so, m);
+	SOCK_UNLOCK(so);
 #endif
 
-    M_PREPEND(m, sizeof(struct ddpehdr), M_DONTWAIT);
-    if (m == NULL)
+	M_PREPEND(m, sizeof(struct ddpehdr), M_DONTWAIT);
+	if (m == NULL)
 	return (ENOBUFS);
 
-    deh = mtod(m, struct ddpehdr *);
-    deh->deh_pad = 0;
-    deh->deh_hops = 0;
-
-    deh->deh_len = m->m_pkthdr.len;
-
-    deh->deh_dnet = ddp->ddp_fsat.sat_addr.s_net;
-    deh->deh_dnode = ddp->ddp_fsat.sat_addr.s_node;
-    deh->deh_dport = ddp->ddp_fsat.sat_port;
-    deh->deh_snet = ddp->ddp_lsat.sat_addr.s_net;
-    deh->deh_snode = ddp->ddp_lsat.sat_addr.s_node;
-    deh->deh_sport = ddp->ddp_lsat.sat_port;
-
-    /*
-     * The checksum calculation is done after all of the other bytes have
-     * been filled in.
-     */
-    if (ddp_cksum) {
-	deh->deh_sum = at_cksum(m, sizeof(int));
-    } else {
-	deh->deh_sum = 0;
-    }
-    deh->deh_bytes = htonl(deh->deh_bytes);
+	deh = mtod(m, struct ddpehdr *);
+	deh->deh_pad = 0;
+	deh->deh_hops = 0;
+
+	deh->deh_len = m->m_pkthdr.len;
+
+	deh->deh_dnet = ddp->ddp_fsat.sat_addr.s_net;
+	deh->deh_dnode = ddp->ddp_fsat.sat_addr.s_node;
+	deh->deh_dport = ddp->ddp_fsat.sat_port;
+	deh->deh_snet = ddp->ddp_lsat.sat_addr.s_net;
+	deh->deh_snode = ddp->ddp_lsat.sat_addr.s_node;
+	deh->deh_sport = ddp->ddp_lsat.sat_port;
+
+	/*
+	 * The checksum calculation is done after all of the other bytes have
+	 * been filled in.
+	 */
+	if (ddp_cksum)
+		deh->deh_sum = at_cksum(m, sizeof(int));
+	else
+		deh->deh_sum = 0;
+	deh->deh_bytes = htonl(deh->deh_bytes);
 
 #ifdef NETATALK_DEBUG
-    printf ("ddp_output: from %d.%d:%d to %d.%d:%d\n",
+	printf ("ddp_output: from %d.%d:%d to %d.%d:%d\n",
 	ntohs(deh->deh_snet), deh->deh_snode, deh->deh_sport,
 	ntohs(deh->deh_dnet), deh->deh_dnode, deh->deh_dport);
 #endif
-    return (ddp_route(m, &ddp->ddp_route));
+	return (ddp_route(m, &ddp->ddp_route));
 }
 
 u_short
 at_cksum(struct mbuf *m, int skip)
 {
-    u_char	*data, *end;
-    u_long	cksum = 0;
+	u_char	*data, *end;
+	u_long	cksum = 0;
 
-    for (; m; m = m->m_next) {
-	for (data = mtod(m, u_char *), end = data + m->m_len; data < end;
-		data++) {
-	    if (skip) {
-		skip--;
-		continue;
-	    }
-	    cksum = (cksum + *data) << 1;
-	    if (cksum & 0x00010000) {
-		cksum++;
-	    }
-	    cksum &= 0x0000ffff;
+	for (; m; m = m->m_next) {
+		for (data = mtod(m, u_char *), end = data + m->m_len;
+		    data < end; data++) {
+			if (skip) {
+				skip--;
+				continue;
+			}
+			cksum = (cksum + *data) << 1;
+			if (cksum & 0x00010000)
+				cksum++;
+			cksum &= 0x0000ffff;
+		}
 	}
-    }
 
-    if (cksum == 0) {
-	cksum = 0x0000ffff;
-    }
-    return ((u_short)cksum);
+	if (cksum == 0)
+		cksum = 0x0000ffff;
+	return ((u_short)cksum);
 }
 
 int
 ddp_route(struct mbuf *m, struct route *ro)
 {
-    struct sockaddr_at	gate;
-    struct elaphdr	*elh;
-    struct mbuf		*m0;
-    struct at_ifaddr	*aa = NULL;
-    struct ifnet	*ifp = NULL;
-    u_short		net;
+	struct sockaddr_at	gate;
+	struct elaphdr	*elh;
+	struct mbuf		*m0;
+	struct at_ifaddr	*aa = NULL;
+	struct ifnet	*ifp = NULL;
+	u_short		net;
 
 #if 0
-    /* Check for net zero, node zero ("myself") */
-    if (satosat(&ro->ro_dst)->sat_addr.s_net == ATADDR_ANYNET
-        && satosat(&ro->ro_dst)->sat_addr.s_node == ATADDR_ANYNODE) {
-	    /* Find the loopback interface */
-    }
-#endif
-
-    /*
-     * if we have a route, find the ifa that refers to this route.
-     * I.e The ifa used to get to the gateway.
-     */
-    if ((ro->ro_rt == NULL)
-    || (ro->ro_rt->rt_ifa == NULL)
-    || ((ifp = ro->ro_rt->rt_ifa->ifa_ifp) == NULL)) {
-	rtalloc(ro);
-    }
-    if ((ro->ro_rt != NULL)
-    && (ro->ro_rt->rt_ifa)
-    && (ifp = ro->ro_rt->rt_ifa->ifa_ifp)) {
-	net = ntohs(satosat(ro->ro_rt->rt_gateway)->sat_addr.s_net);
-	for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
-	    if (((net == 0) || (aa->aa_ifp == ifp)) &&
-		    net >= ntohs(aa->aa_firstnet) &&
-		    net <= ntohs(aa->aa_lastnet)) {
-		break;
-	    }
+	/* Check for net zero, node zero ("myself") */
+	if (satosat(&ro->ro_dst)->sat_addr.s_net == ATADDR_ANYNET
+	    && satosat(&ro->ro_dst)->sat_addr.s_node == ATADDR_ANYNODE) {
+		/* Find the loopback interface */
 	}
-    } else {
-	m_freem(m);
+#endif
+
+	/*
+	 * If we have a route, find the ifa that refers to this route.  I.e
+	 * the ifa used to get to the gateway.
+	 */
+	if ((ro->ro_rt == NULL) || (ro->ro_rt->rt_ifa == NULL) ||
+	    ((ifp = ro->ro_rt->rt_ifa->ifa_ifp) == NULL))
+		rtalloc(ro);
+	if ((ro->ro_rt != NULL) && (ro->ro_rt->rt_ifa) &&
+	    (ifp = ro->ro_rt->rt_ifa->ifa_ifp)) {
+		net = ntohs(satosat(ro->ro_rt->rt_gateway)->sat_addr.s_net);
+		for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
+			if (((net == 0) || (aa->aa_ifp == ifp)) &&
+			    net >= ntohs(aa->aa_firstnet) &&
+			    net <= ntohs(aa->aa_lastnet))
+				break;
+		}
+	} else {
+		m_freem(m);
 #ifdef NETATALK_DEBUG
-	if (ro->ro_rt == NULL)
-	    printf ("ddp_route: no ro_rt.\n");
-	else if (ro->ro_rt->rt_ifa == NULL)
-	    printf ("ddp_route: no ro_rt->rt_ifa\n");
-	else
-	    printf ("ddp_route: no ro_rt->rt_ifa->ifa_ifp\n");
+		if (ro->ro_rt == NULL)
+			printf ("ddp_route: no ro_rt.\n");
+		else if (ro->ro_rt->rt_ifa == NULL)
+			printf ("ddp_route: no ro_rt->rt_ifa\n");
+		else
+			printf ("ddp_route: no ro_rt->rt_ifa->ifa_ifp\n");
 #endif
-	return (ENETUNREACH);
-    }
+		return (ENETUNREACH);
+	}
 
-    if (aa == NULL) {
+	if (aa == NULL) {
 #ifdef NETATALK_DEBUG
-	printf("ddp_route: no atalk address found for %s\n", 
-	    ifp->if_xname);
+		printf("ddp_route: no atalk address found for %s\n",
+		    ifp->if_xname);
 #endif
-	m_freem(m);
-	return (ENETUNREACH);
-    }
-
-    /*
-     * if the destination address is on a directly attached node use that,
-     * else use the official gateway.
-     */
-    if (ntohs(satosat(&ro->ro_dst)->sat_addr.s_net) >=
+		m_freem(m);
+		return (ENETUNREACH);
+	}
+
+	/*
+	 * If the destination address is on a directly attached node use
+	 * that, else use the official gateway.
+	 */
+	if (ntohs(satosat(&ro->ro_dst)->sat_addr.s_net) >=
 	    ntohs(aa->aa_firstnet) &&
 	    ntohs(satosat(&ro->ro_dst)->sat_addr.s_net) <=
-	    ntohs(aa->aa_lastnet)) {
-	gate = *satosat(&ro->ro_dst);
-    } else {
-	gate = *satosat(ro->ro_rt->rt_gateway);
-    }
-
-    /*
-     * There are several places in the kernel where data is added to
-     * an mbuf without ensuring that the mbuf pointer is aligned.
-     * This is bad for transition routing, since phase 1 and phase 2
-     * packets end up poorly aligned due to the three byte elap header.
-     */
-    if (!(aa->aa_flags & AFA_PHASE2)) {
-	MGET(m0, M_DONTWAIT, MT_DATA);
-	if (m0 == NULL) {
-	    m_freem(m);
-	    printf("ddp_route: no buffers\n");
-	    return (ENOBUFS);
-	}
+	    ntohs(aa->aa_lastnet))
+		gate = *satosat(&ro->ro_dst);
+	else
+		gate = *satosat(ro->ro_rt->rt_gateway);
+
+	/*
+	 * There are several places in the kernel where data is added to an
+	 * mbuf without ensuring that the mbuf pointer is aligned.  This is
+	 * bad for transition routing, since phase 1 and phase 2 packets end
+	 * up poorly aligned due to the three byte elap header.
+	 */
+	if (!(aa->aa_flags & AFA_PHASE2)) {
+		MGET(m0, M_DONTWAIT, MT_DATA);
+		if (m0 == NULL) {
+			m_freem(m);
+			printf("ddp_route: no buffers\n");
+			return (ENOBUFS);
+		}
 #ifdef MAC
-	mac_copy_mbuf(m, m0);
+		mac_copy_mbuf(m, m0);
 #endif
-	m0->m_next = m;
-	/* XXX perhaps we ought to align the header? */
-	m0->m_len = SZ_ELAPHDR;
-	m = m0;
-
-	elh = mtod(m, struct elaphdr *);
-	elh->el_snode = satosat(&aa->aa_addr)->sat_addr.s_node;
-	elh->el_type = ELAP_DDPEXTEND;
-	elh->el_dnode = gate.sat_addr.s_node;
-    }
-    ro->ro_rt->rt_use++;
+		m0->m_next = m;
+		/* XXX perhaps we ought to align the header? */
+		m0->m_len = SZ_ELAPHDR;
+		m = m0;
+
+		elh = mtod(m, struct elaphdr *);
+		elh->el_snode = satosat(&aa->aa_addr)->sat_addr.s_node;
+		elh->el_type = ELAP_DDPEXTEND;
+		elh->el_dnode = gate.sat_addr.s_node;
+	}
+	ro->ro_rt->rt_use++;
 
 #ifdef NETATALK_DEBUG
-    printf ("ddp_route: from %d.%d to %d.%d, via %d.%d (%s)\n",
-	ntohs(satosat(&aa->aa_addr)->sat_addr.s_net),
-	satosat(&aa->aa_addr)->sat_addr.s_node,
-	ntohs(satosat(&ro->ro_dst)->sat_addr.s_net),
-	satosat(&ro->ro_dst)->sat_addr.s_node,
-	ntohs(gate.sat_addr.s_net),
-	gate.sat_addr.s_node,
-	ifp->if_xname);
-#endif
-
-    /* short-circuit the output if we're sending this to ourself */
-    if ((satosat(&aa->aa_addr)->sat_addr.s_net  == satosat(&ro->ro_dst)->sat_addr.s_net) &&
-	(satosat(&aa->aa_addr)->sat_addr.s_node == satosat(&ro->ro_dst)->sat_addr.s_node))
-    {
-	return (if_simloop(ifp, m, gate.sat_family, 0));
-    }
+	printf ("ddp_route: from %d.%d to %d.%d, via %d.%d (%s)\n",
+	    ntohs(satosat(&aa->aa_addr)->sat_addr.s_net),
+	    satosat(&aa->aa_addr)->sat_addr.s_node,
+	    ntohs(satosat(&ro->ro_dst)->sat_addr.s_net),
+	    satosat(&ro->ro_dst)->sat_addr.s_node,
+	    ntohs(gate.sat_addr.s_net), gate.sat_addr.s_node, ifp->if_xname);
+#endif
+
+	/* Short-circuit the output if we're sending this to ourself. */
+	if ((satosat(&aa->aa_addr)->sat_addr.s_net ==
+	    satosat(&ro->ro_dst)->sat_addr.s_net) &&
+	    (satosat(&aa->aa_addr)->sat_addr.s_node ==
+	    satosat(&ro->ro_dst)->sat_addr.s_node))
+		return (if_simloop(ifp, m, gate.sat_family, 0));
 
-    return ((*ifp->if_output)(ifp,
-	m, (struct sockaddr *)&gate, NULL)); /* XXX */
+	/* XXX */
+	return ((*ifp->if_output)(ifp, m, (struct sockaddr *)&gate, NULL));
 }
Index: at_var.h
===================================================================
RCS file: /home/cvs/src/sys/netatalk/at_var.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/at_var.h -L sys/netatalk/at_var.h -u -r1.1.1.1 -r1.2
--- sys/netatalk/at_var.h
+++ sys/netatalk/at_var.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * Copyright (c) 1990, 1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software and
@@ -20,44 +20,45 @@
  *	+1-313-763-0525
  *	netatalk at itd.umich.edu
  *
- * $FreeBSD: src/sys/netatalk/at_var.h,v 1.14 2005/02/22 14:20:29 rwatson Exp $
+ * $FreeBSD: src/sys/netatalk/at_var.h,v 1.15 2007/01/12 13:18:08 rwatson Exp $
  */
 
 #ifndef _NETATALK_AT_VAR_H_
-#define _NETATALK_AT_VAR_H_ 1
+#define	_NETATALK_AT_VAR_H_
+
 /*
- * For phase2, we need to keep not only our address on an interface,
- * but also the legal networks on the interface.
+ * For phase2, we need to keep not only our address on an interface, but also
+ * the legal networks on the interface.
  */
 struct at_ifaddr {
-    struct ifaddr	  aa_ifa;
-# define aa_ifp			aa_ifa.ifa_ifp
-    struct sockaddr_at	  aa_addr;
-    struct sockaddr_at	  aa_broadaddr;
-# define aa_dstaddr		aa_broadaddr;
-    struct sockaddr_at	  aa_netmask;
-    int			  aa_flags;
-    u_short		  aa_firstnet, aa_lastnet;
-    int			  aa_probcnt;
-    struct callout	  aa_callout;
-    struct at_ifaddr	  *aa_next;
+	struct ifaddr		 aa_ifa;
+	struct sockaddr_at	 aa_addr;
+	struct sockaddr_at	 aa_broadaddr;
+	struct sockaddr_at	 aa_netmask;
+	int			 aa_flags;
+	u_short			 aa_firstnet;
+	u_short			 aa_lastnet;
+	int			 aa_probcnt;
+	struct callout		 aa_callout;
+	struct at_ifaddr	*aa_next;
 };
+#define	aa_ifp		aa_ifa.ifa_ifp
+#define	aa_dstaddr	aa_broadaddr;
 
 struct at_aliasreq {
-	char	ifra_name[IFNAMSIZ];		/* if name, e.g. "en0" */
-	struct	sockaddr_at ifra_addr;
-	struct	sockaddr_at ifra_broadaddr;
-#define ifra_dstaddr ifra_broadaddr
-	struct	sockaddr_at ifra_mask;
+	char			ifra_name[IFNAMSIZ];
+	struct sockaddr_at	ifra_addr;
+	struct sockaddr_at	ifra_broadaddr;
+	struct sockaddr_at	ifra_mask;
 };
+#define	ifra_dstaddr	ifra_broadaddr
+
+#define	AA_SAT(aa)	(&(aa->aa_addr))
+#define	satosat(sa)	((struct sockaddr_at *)(sa))
 
-#define AA_SAT(aa) \
-    (&(aa->aa_addr))
-#define satosat(sa)	((struct sockaddr_at *)(sa))
-
-#define AFA_ROUTE	0x0001
-#define AFA_PROBING	0x0002
-#define AFA_PHASE2	0x0004
+#define	AFA_ROUTE	0x0001
+#define	AFA_PROBING	0x0002
+#define	AFA_PHASE2	0x0004
 
 #ifdef _KERNEL
 extern struct at_ifaddr	*at_ifaddr_list;
Index: ddp_pcb.h
===================================================================
RCS file: /home/cvs/src/sys/netatalk/ddp_pcb.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/ddp_pcb.h -L sys/netatalk/ddp_pcb.h -u -r1.1.1.1 -r1.2
--- sys/netatalk/ddp_pcb.h
+++ sys/netatalk/ddp_pcb.h
@@ -1,6 +1,29 @@
 /*-
  * Copyright (c) 2004 Robert N. M. Watson
- * Copyright (c) 1990,1994 Regents of The University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (c) 1990, 1994 Regents of The University of Michigan.
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software and
@@ -24,7 +47,7 @@
  *	+1-313-764-2278
  *	netatalk at umich.edu
  *
- * $FreeBSD: src/sys/netatalk/ddp_pcb.h,v 1.3 2005/01/07 02:35:34 imp Exp $
+ * $FreeBSD: src/sys/netatalk/ddp_pcb.h,v 1.5 2007/01/12 15:07:51 rwatson Exp $
  */
 
 #ifndef _NETATALK_DDP_PCB_H_
@@ -58,4 +81,4 @@
 #define	DDP_LIST_SUNLOCK()	mtx_unlock(&ddp_list_mtx)
 #define	DDP_LIST_SLOCK_ASSERT()	mtx_assert(&ddp_list_mtx, MA_OWNED)
 
-#endif
+#endif /* !_NETATALK_DDP_PCB_H_ */
Index: ddp_input.c
===================================================================
RCS file: /home/cvs/src/sys/netatalk/ddp_input.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/ddp_input.c -L sys/netatalk/ddp_input.c -u -r1.1.1.1 -r1.2
--- sys/netatalk/ddp_input.c
+++ sys/netatalk/ddp_input.c
@@ -22,9 +22,8 @@
  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
- */
-/*-
- * Copyright (c) 1990,1994 Regents of The University of Michigan.
+ *
+ * Copyright (c) 1990, 1994 Regents of The University of Michigan.
  *
  * Permission to use, copy, modify, and distribute this software and
  * its documentation for any purpose and without fee is hereby granted,
@@ -47,7 +46,7 @@
  *	+1-313-764-2278
  *	netatalk at umich.edu
  *
- * $FreeBSD: src/sys/netatalk/ddp_input.c,v 1.29 2005/01/07 02:35:34 imp Exp $
+ * $FreeBSD: src/sys/netatalk/ddp_input.c,v 1.32 2007/01/12 15:07:51 rwatson Exp $
  */
 
 #include "opt_mac.h"
@@ -55,7 +54,6 @@
 #include <sys/param.h>
 #include <sys/kernel.h>
 #include <sys/lock.h>
-#include <sys/mac.h>
 #include <sys/mbuf.h>
 #include <sys/signalvar.h>
 #include <sys/socket.h>
@@ -72,6 +70,8 @@
 #include <netatalk/ddp_pcb.h>
 #include <netatalk/at_extern.h>
 
+#include <security/mac/mac_framework.h>
+
 static volatile int	ddp_forward = 1;
 static volatile int	ddp_firewall = 0;
 static struct ddpstat	ddpstat;
@@ -88,10 +88,9 @@
 {
 
 	/*
-	 * Phase 2 packet handling 
+	 * Phase 2 packet handling .
 	 */
 	ddp_input(m, m->m_pkthdr.rcvif, NULL, 2);
-	return;
 }
 
 void
@@ -102,7 +101,8 @@
 	/*
 	 * Phase 1 packet handling 
 	 */
-	if (m->m_len < SZ_ELAPHDR && ((m = m_pullup(m, SZ_ELAPHDR)) == NULL)) {
+	if (m->m_len < SZ_ELAPHDR && ((m = m_pullup(m, SZ_ELAPHDR)) ==
+	    NULL)) {
 		ddpstat.ddps_tooshort++;
 		return;
 	}
@@ -113,392 +113,332 @@
 	elhp = mtod(m, struct elaphdr *);
 	m_adj(m, SZ_ELAPHDR);
 
-	if (elhp->el_type == ELAP_DDPEXTEND) {
-		ddp_input(m, m->m_pkthdr.rcvif, NULL, 1);
-	} else {
+	if (elhp->el_type != ELAP_DDPEXTEND) {
 		bcopy((caddr_t)elhp, (caddr_t)&elh, SZ_ELAPHDR);
 		ddp_input(m, m->m_pkthdr.rcvif, &elh, 1);
-	}
-	return;
+	} else
+		ddp_input(m, m->m_pkthdr.rcvif, NULL, 1);
 }
 
 static void
-ddp_input(m, ifp, elh, phase)
-    struct mbuf		*m;
-    struct ifnet	*ifp;
-    struct elaphdr	*elh;
-    int			phase;
+ddp_input(struct mbuf *m, struct ifnet *ifp, struct elaphdr *elh, int phase)
 {
-    struct sockaddr_at	from, to;
-    struct ddpshdr	*dsh, ddps;
-    struct at_ifaddr	*aa;
-    struct ddpehdr	*deh = NULL, ddpe;
-    struct ddpcb	*ddp;
-    int			dlen, mlen;
-    u_short		cksum = 0;
-
-    bzero((caddr_t)&from, sizeof(struct sockaddr_at));
-    bzero((caddr_t)&to, sizeof(struct sockaddr_at));
-    if (elh != NULL) {
-	/*
-	 * Extract the information in the short header.
-	 * netowrk information is defaulted to ATADDR_ANYNET
-	 * and node information comes from the elh info.
-	 * We must be phase 1.
-	 */
-	ddpstat.ddps_short++;
+	struct sockaddr_at from, to;
+	struct ddpshdr *dsh, ddps;
+	struct at_ifaddr *aa;
+	struct ddpehdr *deh = NULL, ddpe;
+	struct ddpcb *ddp;
+	int dlen, mlen;
+	u_short cksum = 0;
+
+	bzero((caddr_t)&from, sizeof(struct sockaddr_at));
+	bzero((caddr_t)&to, sizeof(struct sockaddr_at));
+	if (elh != NULL) {
+		/*
+		 * Extract the information in the short header.  Network
+		 * information is defaulted to ATADDR_ANYNET and node
+		 * information comes from the elh info.  We must be phase 1.
+		 */
+		ddpstat.ddps_short++;
 
-	if (m->m_len < sizeof(struct ddpshdr) &&
-		((m = m_pullup(m, sizeof(struct ddpshdr))) == NULL)) {
-	    ddpstat.ddps_tooshort++;
-	    return;
-	}
+		if (m->m_len < sizeof(struct ddpshdr) &&
+		    ((m = m_pullup(m, sizeof(struct ddpshdr))) == NULL)) {
+			ddpstat.ddps_tooshort++;
+			return;
+		}
 
-	dsh = mtod(m, struct ddpshdr *);
-	bcopy((caddr_t)dsh, (caddr_t)&ddps, sizeof(struct ddpshdr));
-	ddps.dsh_bytes = ntohl(ddps.dsh_bytes);
-	dlen = ddps.dsh_len;
-
-	to.sat_addr.s_net = ATADDR_ANYNET;
-	to.sat_addr.s_node = elh->el_dnode;
-	to.sat_port = ddps.dsh_dport;
-	from.sat_addr.s_net = ATADDR_ANYNET;
-	from.sat_addr.s_node = elh->el_snode;
-	from.sat_port = ddps.dsh_sport;
+		dsh = mtod(m, struct ddpshdr *);
+		bcopy((caddr_t)dsh, (caddr_t)&ddps, sizeof(struct ddpshdr));
+		ddps.dsh_bytes = ntohl(ddps.dsh_bytes);
+		dlen = ddps.dsh_len;
+
+		to.sat_addr.s_net = ATADDR_ANYNET;
+		to.sat_addr.s_node = elh->el_dnode;
+		to.sat_port = ddps.dsh_dport;
+		from.sat_addr.s_net = ATADDR_ANYNET;
+		from.sat_addr.s_node = elh->el_snode;
+		from.sat_port = ddps.dsh_sport;
+
+		/* 
+		 * Make sure that we point to the phase1 ifaddr info and that
+		 * it's valid for this packet.
+		 */
+		for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
+			if ((aa->aa_ifp == ifp)
+			    && ((aa->aa_flags & AFA_PHASE2) == 0)
+			    && ((to.sat_addr.s_node ==
+			    AA_SAT(aa)->sat_addr.s_node) ||
+			    (to.sat_addr.s_node == ATADDR_BCAST)))
+				break;
+		}
+		/* 
+		 * maybe we got a broadcast not meant for us.. ditch it.
+		 */
+		if (aa == NULL) {
+			m_freem(m);
+			return;
+		}
+	} else {
+		/*
+		 * There was no 'elh' passed on. This could still be either
+		 * phase1 or phase2.  We have a long header, but we may be
+		 * running on a phase 1 net.  Extract out all the info
+		 * regarding this packet's src & dst.
+		 */
+		ddpstat.ddps_long++;
 
-	/* 
-	 * Make sure that we point to the phase1 ifaddr info 
-	 * and that it's valid for this packet.
-	 */
-	for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
-	    if ((aa->aa_ifp == ifp)
-	    && ((aa->aa_flags & AFA_PHASE2) == 0)
-	    && ((to.sat_addr.s_node == AA_SAT(aa)->sat_addr.s_node)
-	      || (to.sat_addr.s_node == ATADDR_BCAST))) {
-		break;
-	    }
-	}
-	/* 
-	 * maybe we got a broadcast not meant for us.. ditch it.
-	 */
-	if (aa == NULL) {
-	    m_freem(m);
-	    return;
-	}
-    } else {
-	/*
-	 * There was no 'elh' passed on. This could still be
-	 * either phase1 or phase2.
-	 * We have a long header, but we may be running on a phase 1 net.
-	 * Extract out all the info regarding this packet's src & dst.
-	 */
-	ddpstat.ddps_long++;
+		if (m->m_len < sizeof(struct ddpehdr) &&
+		    ((m = m_pullup(m, sizeof(struct ddpehdr))) == NULL)) {
+			ddpstat.ddps_tooshort++;
+			return;
+		}
 
-	if (m->m_len < sizeof(struct ddpehdr) &&
-		((m = m_pullup(m, sizeof(struct ddpehdr))) == NULL)) {
-	    ddpstat.ddps_tooshort++;
-	    return;
+		deh = mtod(m, struct ddpehdr *);
+		bcopy((caddr_t)deh, (caddr_t)&ddpe, sizeof(struct ddpehdr));
+		ddpe.deh_bytes = ntohl(ddpe.deh_bytes);
+		dlen = ddpe.deh_len;
+
+		if ((cksum = ddpe.deh_sum) == 0)
+			ddpstat.ddps_nosum++;
+
+		from.sat_addr.s_net = ddpe.deh_snet;
+		from.sat_addr.s_node = ddpe.deh_snode;
+		from.sat_port = ddpe.deh_sport;
+		to.sat_addr.s_net = ddpe.deh_dnet;
+		to.sat_addr.s_node = ddpe.deh_dnode;
+		to.sat_port = ddpe.deh_dport;
+
+		if (to.sat_addr.s_net == ATADDR_ANYNET) {
+			/*
+			 * The TO address doesn't specify a net, so by
+			 * definition it's for this net.  Try find ifaddr
+			 * info with the right phase, the right interface,
+			 * and either to our node, a broadcast, or looped
+			 * back (though that SHOULD be covered in the other
+			 * cases).
+			 *
+			 * XXX If we have multiple interfaces, then the first
+			 * with this node number will match (which may NOT be
+			 * what we want, but it's probably safe in 99.999% of
+			 * cases.
+			 */
+			for (aa = at_ifaddr_list; aa != NULL;
+			    aa = aa->aa_next) {
+				if (phase == 1 && (aa->aa_flags &
+				    AFA_PHASE2))
+					continue;
+				if (phase == 2 && (aa->aa_flags &
+				    AFA_PHASE2) == 0)
+					continue;
+				if ((aa->aa_ifp == ifp) &&
+				    ((to.sat_addr.s_node ==
+				    AA_SAT(aa)->sat_addr.s_node) ||
+				    (to.sat_addr.s_node == ATADDR_BCAST) ||
+				    (ifp->if_flags & IFF_LOOPBACK)))
+					break;
+			}
+		} else {
+			/* 
+			 * A destination network was given.  We just try to
+			 * find which ifaddr info matches it.
+	    		 */
+			for (aa = at_ifaddr_list; aa != NULL;
+			    aa = aa->aa_next) {
+				/*
+				 * This is a kludge. Accept packets that are
+				 * for any router on a local netrange.
+				 */
+				if (to.sat_addr.s_net == aa->aa_firstnet &&
+				    to.sat_addr.s_node == 0)
+					break;
+				/*
+				 * Don't use ifaddr info for which we are
+				 * totally outside the netrange, and it's not
+				 * a startup packet.  Startup packets are
+				 * always implicitly allowed on to the next
+				 * test.
+				 */
+				if (((ntohs(to.sat_addr.s_net) <
+				    ntohs(aa->aa_firstnet)) ||
+				    (ntohs(to.sat_addr.s_net) >
+				    ntohs(aa->aa_lastnet))) &&
+				    ((ntohs(to.sat_addr.s_net) < 0xff00) ||
+				    (ntohs(to.sat_addr.s_net) > 0xfffe)))
+					continue;
+
+				/*
+				 * Don't record a match either if we just
+				 * don't have a match in the node address.
+				 * This can have if the interface is in
+				 * promiscuous mode for example.
+				 */
+				if ((to.sat_addr.s_node !=
+				    AA_SAT(aa)->sat_addr.s_node) &&
+				    (to.sat_addr.s_node != ATADDR_BCAST))
+					continue;
+				break;
+			}
+		}
 	}
 
-	deh = mtod(m, struct ddpehdr *);
-	bcopy((caddr_t)deh, (caddr_t)&ddpe, sizeof(struct ddpehdr));
-	ddpe.deh_bytes = ntohl(ddpe.deh_bytes);
-	dlen = ddpe.deh_len;
-
-	if ((cksum = ddpe.deh_sum) == 0) {
-	    ddpstat.ddps_nosum++;
+	/*
+	 * Adjust the length, removing any padding that may have been added
+	 * at a link layer.  We do this before we attempt to forward a
+	 * packet, possibly on a different media.
+	 */
+	mlen = m->m_pkthdr.len;
+	if (mlen < dlen) {
+		ddpstat.ddps_toosmall++;
+		m_freem(m);
+		return;
 	}
+	if (mlen > dlen)
+		m_adj(m, dlen - mlen);
 
-	from.sat_addr.s_net = ddpe.deh_snet;
-	from.sat_addr.s_node = ddpe.deh_snode;
-	from.sat_port = ddpe.deh_sport;
-	to.sat_addr.s_net = ddpe.deh_dnet;
-	to.sat_addr.s_node = ddpe.deh_dnode;
-	to.sat_port = ddpe.deh_dport;
-
-	if (to.sat_addr.s_net == ATADDR_ANYNET) {
-	    /*
-	     * The TO address doesn't specify a net,
-	     * So by definition it's for this net.
-	     * Try find ifaddr info with the right phase, 
-	     * the right interface, and either to our node, a broadcast,
-	     * or looped back (though that SHOULD be covered in the other
-	     * cases).
-	     *
-	     * XXX If we have multiple interfaces, then the first with
-	     * this node number will match (which may NOT be what we want,
-	     * but it's probably safe in 99.999% of cases.
-	     */
-	    for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
-		if (phase == 1 && (aa->aa_flags & AFA_PHASE2)) {
-		    continue;
-		}
-		if (phase == 2 && (aa->aa_flags & AFA_PHASE2) == 0) {
-		    continue;
-		}
-		if ((aa->aa_ifp == ifp)
-		&& ((to.sat_addr.s_node == AA_SAT(aa)->sat_addr.s_node)
-		  || (to.sat_addr.s_node == ATADDR_BCAST)
-		  || (ifp->if_flags & IFF_LOOPBACK))) {
-		    break;
+	/*
+	 * If it isn't for a net on any of our interfaces, or it IS for a net
+	 * on a different interface than it came in on, (and it is not looped
+	 * back) then consider if we should forward it.  As we are not really
+	 * a router this is a bit cheeky, but it may be useful some day.
+	 */
+	if ((aa == NULL) || ((to.sat_addr.s_node == ATADDR_BCAST) &&
+	    (aa->aa_ifp != ifp) && ((ifp->if_flags & IFF_LOOPBACK) == 0))) {
+		/* 
+		 * If we've explicitly disabled it, don't route anything.
+		 */
+		if (ddp_forward == 0) {
+			m_freem(m);
+			return;
 		}
-	    }
-	} else {
-	    /* 
-	     * A destination network was given. We just try to find 
-	     * which ifaddr info matches it.
-	     */
-	    for (aa = at_ifaddr_list; aa != NULL; aa = aa->aa_next) {
-		/*
-		 * This is a kludge. Accept packets that are
-		 * for any router on a local netrange.
+
+		/* 
+		 * If the cached forwarding route is still valid, use it.
+		 *
+		 * XXXRW: Access to the cached route may not be properly
+		 * synchronized for parallel input handling.
 		 */
-		if (to.sat_addr.s_net == aa->aa_firstnet &&
-			to.sat_addr.s_node == 0) {
-		    break;
+		if (forwro.ro_rt &&
+		    (satosat(&forwro.ro_dst)->sat_addr.s_net !=
+		    to.sat_addr.s_net ||
+		    satosat(&forwro.ro_dst)->sat_addr.s_node !=
+		    to.sat_addr.s_node)) {
+			RTFREE(forwro.ro_rt);
+			forwro.ro_rt = NULL;
 		}
+
 		/*
-		 * Don't use ifaddr info for which we are totally outside the
-		 * netrange, and it's not a startup packet.
-		 * Startup packets are always implicitly allowed on to
-		 * the next test.
-		 */
-		if (((ntohs(to.sat_addr.s_net) < ntohs(aa->aa_firstnet))
-		    || (ntohs(to.sat_addr.s_net) > ntohs(aa->aa_lastnet)))
-		 && ((ntohs(to.sat_addr.s_net) < 0xff00)
-		    || (ntohs(to.sat_addr.s_net) > 0xfffe))) {
-		    continue;
+		 * If we don't have a cached one (any more) or it's useless,
+		 * then get a new route.
+		 *
+		 * XXX this could cause a 'route leak'.  Check this!
+		 */
+		if (forwro.ro_rt == NULL || forwro.ro_rt->rt_ifp == NULL) {
+			forwro.ro_dst.sa_len = sizeof(struct sockaddr_at);
+			forwro.ro_dst.sa_family = AF_APPLETALK;
+			satosat(&forwro.ro_dst)->sat_addr.s_net =
+			    to.sat_addr.s_net;
+			satosat(&forwro.ro_dst)->sat_addr.s_node =
+			    to.sat_addr.s_node;
+			rtalloc(&forwro);
+		}
+
+		/* 
+		 * If it's not going to get there on this hop, and it's
+		 * already done too many hops, then throw it away.
+		 */
+		if ((to.sat_addr.s_net !=
+		    satosat(&forwro.ro_dst)->sat_addr.s_net) &&
+		    (ddpe.deh_hops == DDP_MAXHOPS)) {
+			m_freem(m);
+			return;
 		}
 
 		/*
-		 * Don't record a match either if we just don't have a match
-		 * in the node address. This can have if the interface
-		 * is in promiscuous mode for example.
-		 */
-		if ((to.sat_addr.s_node != AA_SAT(aa)->sat_addr.s_node)
-		&& (to.sat_addr.s_node != ATADDR_BCAST)) {
-		    continue;
+		 * A ddp router might use the same interface to forward the
+		 * packet, which this would not effect.  Don't allow packets
+		 * to cross from one interface to another however.
+		 */
+		if (ddp_firewall && ((forwro.ro_rt == NULL) ||
+		    (forwro.ro_rt->rt_ifp != ifp))) {
+			m_freem(m);
+			return;
 		}
-		break;
-	    }
-	}
-    }
 
-    /*
-     * Adjust the length, removing any padding that may have been added
-     * at a link layer.  We do this before we attempt to forward a packet,
-     * possibly on a different media.
-     */
-    mlen = m->m_pkthdr.len;
-    if (mlen < dlen) {
-	ddpstat.ddps_toosmall++;
-	m_freem(m);
-	return;
-    }
-    if (mlen > dlen) {
-	m_adj(m, dlen - mlen);
-    }
-
-    /*
-     * If it aint for a net on any of our interfaces,
-     * or it IS for a net on a different interface than it came in on,
-     * (and it is not looped back) then consider if we should forward it.
-     * As we are not really a router this is a bit cheeky, but it may be
-     * useful some day.
-     */
-    if ((aa == NULL)
-    || ((to.sat_addr.s_node == ATADDR_BCAST)
-      && (aa->aa_ifp != ifp)
-      && ((ifp->if_flags & IFF_LOOPBACK) == 0))) {
-	/* 
-	 * If we've explicitly disabled it, don't route anything
-	 */
-	if (ddp_forward == 0) {
-	    m_freem(m);
-	    return;
-	}
-	/* 
-	 * If the cached forwarding route is still valid, use it.
-	 */
-	if (forwro.ro_rt
-	&& (satosat(&forwro.ro_dst)->sat_addr.s_net != to.sat_addr.s_net
-	  || satosat(&forwro.ro_dst)->sat_addr.s_node != to.sat_addr.s_node)) {
-	    RTFREE(forwro.ro_rt);
-	    forwro.ro_rt = NULL;
+		/*
+		 * Adjust the header.  If it was a short header then it would
+		 * have not gotten here, so we can assume there is room to
+		 * drop the header in.
+		 *
+		 * XXX what about promiscuous mode, etc...
+		 */
+		ddpe.deh_hops++;
+		ddpe.deh_bytes = htonl(ddpe.deh_bytes);
+		/* XXX deh? */
+		bcopy((caddr_t)&ddpe, (caddr_t)deh, sizeof(u_short));
+		if (ddp_route(m, &forwro))
+			ddpstat.ddps_cantforward++;
+		else
+			ddpstat.ddps_forward++;
+		return;
 	}
 
 	/*
-	 * If we don't have a cached one (any more) or it's useless,
-	 * Then get a new route.
-	 * XXX this could cause a 'route leak'. check this!
+	 * It was for us, and we have an ifaddr to use with it.
 	 */
-	if (forwro.ro_rt == NULL || forwro.ro_rt->rt_ifp == NULL) {
-	    forwro.ro_dst.sa_len = sizeof(struct sockaddr_at);
-	    forwro.ro_dst.sa_family = AF_APPLETALK;
-	    satosat(&forwro.ro_dst)->sat_addr.s_net = to.sat_addr.s_net;
-	    satosat(&forwro.ro_dst)->sat_addr.s_node = to.sat_addr.s_node;
-	    rtalloc(&forwro);
-	}
+	from.sat_len = sizeof(struct sockaddr_at);
+	from.sat_family = AF_APPLETALK;
 
 	/* 
-	 * If it's not going to get there on this hop, and it's
-	 * already done too many hops, then throw it away.
-	 */
-	if ((to.sat_addr.s_net != satosat(&forwro.ro_dst)->sat_addr.s_net)
-	&& (ddpe.deh_hops == DDP_MAXHOPS)) {
-	    m_freem(m);
-	    return;
-	}
-
-	/*
-	 * A ddp router might use the same interface
-	 * to forward the packet, which this would not effect.
-	 * Don't allow packets to cross from one interface to another however.
+	 * We are no longer interested in the link layer so cut it off.
 	 */
-	if (ddp_firewall
-	&& ((forwro.ro_rt == NULL)
-	  || (forwro.ro_rt->rt_ifp != ifp))) {
-	    m_freem(m);
-	    return;
-	}
+	if (elh == NULL) {
+		if (ddp_cksum && cksum && cksum !=
+		    at_cksum(m, sizeof(int))) {
+			ddpstat.ddps_badsum++;
+			m_freem(m);
+			return;
+		}
+		m_adj(m, sizeof(struct ddpehdr));
+	} else
+		m_adj(m, sizeof(struct ddpshdr));
 
-	/*
-	 * Adjust the header.
-	 * If it was a short header then it would have not gotten here,
-	 * so we can assume there is room to drop the header in.
-	 * XXX what about promiscuous mode, etc...
+	/* 
+	 * Search for ddp protocol control blocks that match these addresses. 
 	 */
-	ddpe.deh_hops++;
-	ddpe.deh_bytes = htonl(ddpe.deh_bytes);
-	bcopy((caddr_t)&ddpe, (caddr_t)deh, sizeof(u_short)); /* XXX deh? */
-	if (ddp_route(m, &forwro)) {
-	    ddpstat.ddps_cantforward++;
-	} else {
-	    ddpstat.ddps_forward++;
-	}
-	return;
-    }
-
-    /*
-     * It was for us, and we have an ifaddr to use with it.
-     */
-    from.sat_len = sizeof(struct sockaddr_at);
-    from.sat_family = AF_APPLETALK;
-
-    /* 
-     * We are no longer interested in the link layer.
-     * so cut it off.
-     */
-    if (elh != NULL) {
-	m_adj(m, sizeof(struct ddpshdr));
-    } else {
-	if (ddp_cksum && cksum && cksum != at_cksum(m, sizeof(int))) {
-	    ddpstat.ddps_badsum++;
-	    m_freem(m);
-	    return;
-	}
-	m_adj(m, sizeof(struct ddpehdr));
-    }
-
-    /* 
-     * Search for ddp protocol control blocks that match these
-     * addresses. 
-     */
-    DDP_LIST_SLOCK();
-    if ((ddp = ddp_search(&from, &to, aa)) == NULL) {
-	goto out;
-    }
+	DDP_LIST_SLOCK();
+	if ((ddp = ddp_search(&from, &to, aa)) == NULL)
+		goto out;
 
 #ifdef MAC
-    SOCK_LOCK(ddp->ddp_socket);
-    if (mac_check_socket_deliver(ddp->ddp_socket, m) != 0) {
+	SOCK_LOCK(ddp->ddp_socket);
+	if (mac_check_socket_deliver(ddp->ddp_socket, m) != 0) {
+		SOCK_UNLOCK(ddp->ddp_socket);
+		goto out;
+	}
 	SOCK_UNLOCK(ddp->ddp_socket);
-	goto out;
-    }
-    SOCK_UNLOCK(ddp->ddp_socket);
 #endif
 
-    /* 
-     * If we found one, deliver the packet to the socket
-     */
-    SOCKBUF_LOCK(&ddp->ddp_socket->so_rcv);
-    if (sbappendaddr_locked(&ddp->ddp_socket->so_rcv, (struct sockaddr *)&from,
-	    m, NULL) == 0) {
-    	SOCKBUF_UNLOCK(&ddp->ddp_socket->so_rcv);
 	/* 
-	 * If the socket is full (or similar error) dump the packet.
+	 * If we found one, deliver the packet to the socket
 	 */
-	ddpstat.ddps_nosockspace++;
-	goto out;
-    }
-    /*
-     * And wake up whatever might be waiting for it
-     */
-    sorwakeup_locked(ddp->ddp_socket);
-    m = NULL;
-out:
-    DDP_LIST_SUNLOCK();
-    if (m != NULL)
-	m_freem(m);
-}
-
-#if 0
-/* As if we haven't got enough of this sort of think floating
-around the kernel :) */
-
-#define BPXLEN	48
-#define BPALEN	16
-#include <ctype.h>
-char	hexdig[] = "0123456789ABCDEF";
-
-static void
-bprint(char *data, int len)
-{
-    char	xout[ BPXLEN ], aout[ BPALEN ];
-    int		i = 0;
-
-    bzero(xout, BPXLEN);
-    bzero(aout, BPALEN);
-
-    for (;;) {
-	if (len < 1) {
-	    if (i != 0) {
-		printf("%s\t%s\n", xout, aout);
-	    }
-	    printf("%s\n", "(end)");
-	    break;
-	}
-
-	xout[ (i*3) ] = hexdig[ (*data & 0xf0) >> 4 ];
-	xout[ (i*3) + 1 ] = hexdig[ *data & 0x0f ];
-
-	if ((u_char)*data < 0x7f && (u_char)*data > 0x20) {
-	    aout[ i ] = *data;
-	} else {
-	    aout[ i ] = '.';
-	}
-
-	xout[ (i*3) + 2 ] = ' ';
-
-	i++;
-	len--;
-	data++;
-
-	if (i > BPALEN - 2) {
-	    printf("%s\t%s\n", xout, aout);
-	    bzero(xout, BPXLEN);
-	    bzero(aout, BPALEN);
-	    i = 0;
-	    continue;
+	SOCKBUF_LOCK(&ddp->ddp_socket->so_rcv);
+	if (sbappendaddr_locked(&ddp->ddp_socket->so_rcv,
+	    (struct sockaddr *)&from, m, NULL) == 0) {
+    		SOCKBUF_UNLOCK(&ddp->ddp_socket->so_rcv);
+		/* 
+		 * If the socket is full (or similar error) dump the packet.
+		 */
+		ddpstat.ddps_nosockspace++;
+		goto out;
 	}
-    }
-}
 
-static void
-m_printm(struct mbuf *m)
-{
-    for (; m; m = m->m_next) {
-	bprint(mtod(m, char *), m->m_len);
-    }
+	/*
+	 * And wake up whatever might be waiting for it
+	 */
+	sorwakeup_locked(ddp->ddp_socket);
+	m = NULL;
+out:
+	DDP_LIST_SUNLOCK();
+	if (m != NULL)
+		m_freem(m);
 }
-#endif
Index: COPYRIGHT
===================================================================
RCS file: /home/cvs/src/sys/netatalk/COPYRIGHT,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/COPYRIGHT -L sys/netatalk/COPYRIGHT -u -r1.1.1.1 -r1.2
--- sys/netatalk/COPYRIGHT
+++ sys/netatalk/COPYRIGHT
@@ -1,4 +1,28 @@
 /*-
+ * Copyright (c) 2004-2005 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
  * Copyright (c) 1990,1994 Regents of The University of Michigan.
  * All Rights Reserved.
  *
@@ -22,5 +46,5 @@
  *	Ann Arbor, Michigan
  *	+1-313-764-2278
  *	netatalk at umich.edu
- * $FreeBSD: src/sys/netatalk/COPYRIGHT,v 1.2 2005/01/07 02:35:34 imp Exp $
+ * $FreeBSD: src/sys/netatalk/COPYRIGHT,v 1.4 2007/01/08 17:58:27 rwatson Exp $
  */
Index: at_rmx.c
===================================================================
RCS file: /home/cvs/src/sys/netatalk/at_rmx.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/at_rmx.c -L sys/netatalk/at_rmx.c -u -r1.1.1.1 -r1.2
--- sys/netatalk/at_rmx.c
+++ sys/netatalk/at_rmx.c
@@ -27,10 +27,10 @@
  * SUCH DAMAGE.
  *
  * at_rmx.c,v 1.13 1995/05/30 08:09:31 rgrimes Exp
- * $FreeBSD: src/sys/netatalk/at_rmx.c,v 1.9 2005/01/07 02:35:34 imp Exp $
+ * $FreeBSD: src/sys/netatalk/at_rmx.c,v 1.10 2007/01/12 13:18:08 rwatson Exp $
  */
 
-/* This code generates debugging traces to the radix code */
+/* This code generates debugging traces to the radix code. */
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -38,7 +38,7 @@
 
 #include <net/route.h>
 
-int at_inithead(void **head, int off);
+int	at_inithead(void **head, int off);
 
 #define	HEXBUF_LEN	256
 
@@ -55,13 +55,13 @@
 		/* return: "(len) hexdump" */
 
 		bp += sprintf(bp, "(%d)", len);
-		for (cp++; cp < cplim && bp < hexbuf + (HEXBUF_LEN - 4); cp++) {
+		for (cp++; cp < cplim && bp < hexbuf + (HEXBUF_LEN - 4);
+		    cp++) {
 			*bp++ = "0123456789abcdef"[*cp / 16];
 			*bp++ = "0123456789abcdef"[*cp % 16];
 		}
-	} else {
+	} else
 		bp+= sprintf(bp, "null");
-	}
 	*bp = '\0';
 	return (hexbuf);
 }
@@ -75,14 +75,14 @@
 
 	printf("at_addroute: v=%s\n", prsockaddr(v_arg, hexbuf));
 	printf("at_addroute: n=%s\n", prsockaddr(n_arg, hexbuf));
-	printf("at_addroute: head=%p treenodes=%p\n",
-	    (void *)head, (void *)treenodes);
+	printf("at_addroute: head=%p treenodes=%p\n", (void *)head,
+	    (void *)treenodes);
 
 	rn = rn_addroute(v_arg, n_arg, head, treenodes);
 
 	printf("at_addroute: returns rn=%p\n", (void *)rn);
 
-	return rn;
+	return (rn);
 }
 
 static struct radix_node *
@@ -98,7 +98,7 @@
 
 	printf("at_matroute: returnr rn=%p\n", (void *)rn);
 
-	return rn;
+	return (rn);
 }
 
 static struct radix_node *
@@ -115,10 +115,10 @@
 
 	printf("at_lookup: returns rn=%p\n", (void *)rn);
 
-	return rn;
+	return (rn);
 }
 
-static struct radix_node *  
+static struct radix_node *
 at_delroute(void *v_arg, void *netmask_arg, struct radix_node_head *head)
 {
 	struct radix_node *rn;
@@ -132,7 +132,7 @@
 
 	printf("at_delroute: returns rn=%p\n", (void *)rn);
 
-	return rn;
+	return (rn);
 }
 
 /*
@@ -143,13 +143,13 @@
 {
 	struct radix_node_head *rnh;
 
-	if(!rn_inithead(head, off))
-		return 0;
+	if (!rn_inithead(head, off))
+		return (0);
 
 	rnh = *head;
 	rnh->rnh_addaddr = at_addroute;
 	rnh->rnh_deladdr = at_delroute;
 	rnh->rnh_matchaddr = at_matroute;
 	rnh->rnh_lookup = at_lookup;
-	return 1;
+	return (1);
 }
Index: ddp_usrreq.c
===================================================================
RCS file: /home/cvs/src/sys/netatalk/ddp_usrreq.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/ddp_usrreq.c -L sys/netatalk/ddp_usrreq.c -u -r1.1.1.1 -r1.2
--- sys/netatalk/ddp_usrreq.c
+++ sys/netatalk/ddp_usrreq.c
@@ -1,6 +1,29 @@
 /*-
  * Copyright (c) 2004-2005 Robert N. M. Watson
- * Copyright (c) 1990,1994 Regents of The University of Michigan.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ * Copyright (c) 1990, 1994 Regents of The University of Michigan.
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software and
@@ -24,7 +47,7 @@
  *	+1-313-764-2278
  *	netatalk at umich.edu
  *
- * $FreeBSD: src/sys/netatalk/ddp_usrreq.c,v 1.45 2005/02/18 10:53:00 rwatson Exp $
+ * $FreeBSD: src/sys/netatalk/ddp_usrreq.c,v 1.55 2007/05/11 10:20:49 rwatson Exp $
  */
 
 #include <sys/param.h>
@@ -52,12 +75,11 @@
 static int
 ddp_attach(struct socket *so, int proto, struct thread *td)
 {
-	struct ddpcb	*ddp;
-	int		error = 0;
+	struct ddpcb *ddp;
+	int error = 0;
 	
 	ddp = sotoddpcb(so);
-	if (ddp != NULL)
-		return (EINVAL);
+	KASSERT(ddp == NULL, ("ddp_attach: ddp != NULL"));
 
 	/*
 	 * Allocate socket buffer space first so that it's present
@@ -73,32 +95,29 @@
 	return (error);
 }
 
-static int
+static void
 ddp_detach(struct socket *so)
 {
-	struct ddpcb	*ddp;
+	struct ddpcb *ddp;
 	
 	ddp = sotoddpcb(so);
-	if (ddp == NULL)
-	    return (EINVAL);
+	KASSERT(ddp != NULL, ("ddp_detach: ddp == NULL"));
 
 	DDP_LIST_XLOCK();
 	DDP_LOCK(ddp);
 	at_pcbdetach(so, ddp);
 	DDP_LIST_XUNLOCK();
-	return (0);
 }
 
 static int      
 ddp_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
-	struct ddpcb	*ddp;
-	int		error = 0;
+	struct ddpcb *ddp;
+	int error = 0;
 	
 	ddp = sotoddpcb(so);
-	if (ddp == NULL) {
-	    return (EINVAL);
-	}
+	KASSERT(ddp != NULL, ("ddp_bind: ddp == NULL"));
+
 	DDP_LIST_XLOCK();
 	DDP_LOCK(ddp);
 	error = at_pcbsetaddr(ddp, nam, td);
@@ -110,44 +129,40 @@
 static int
 ddp_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
 {
-	struct ddpcb	*ddp;
-	int		error = 0;
+	struct ddpcb *ddp;
+	int error = 0;
 	
 	ddp = sotoddpcb(so);
-	if (ddp == NULL) {
-	    return (EINVAL);
-	}
+	KASSERT(ddp != NULL, ("ddp_connect: ddp == NULL"));
 
 	DDP_LIST_XLOCK();
 	DDP_LOCK(ddp);
 	if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
-	    DDP_UNLOCK(ddp);
-	    DDP_LIST_XUNLOCK();
-	    return (EISCONN);
+		DDP_UNLOCK(ddp);
+		DDP_LIST_XUNLOCK();
+		return (EISCONN);
 	}
 
 	error = at_pcbconnect( ddp, nam, td );
 	DDP_UNLOCK(ddp);
 	DDP_LIST_XUNLOCK();
 	if (error == 0)
-	    soisconnected(so);
+		soisconnected(so);
 	return (error);
 }
 
 static int
 ddp_disconnect(struct socket *so)
 {
-
-	struct ddpcb	*ddp;
+	struct ddpcb *ddp;
 	
 	ddp = sotoddpcb(so);
-	if (ddp == NULL) {
-	    return (EINVAL);
-	}
+	KASSERT(ddp != NULL, ("ddp_disconnect: ddp == NULL"));
+
 	DDP_LOCK(ddp);
 	if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE) {
-	    DDP_UNLOCK(ddp);
-	    return (ENOTCONN);
+		DDP_UNLOCK(ddp);
+		return (ENOTCONN);
 	}
 
 	at_pcbdisconnect(ddp);
@@ -163,28 +178,24 @@
 	struct ddpcb	*ddp;
 
 	ddp = sotoddpcb(so);
-	if (ddp == NULL) {
-		return (EINVAL);
-	}
+	KASSERT(ddp != NULL, ("ddp_shutdown: ddp == NULL"));
+
 	socantsendmore(so);
 	return (0);
 }
 
 static int
 ddp_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
-            struct mbuf *control, struct thread *td)
+    struct mbuf *control, struct thread *td)
 {
-	struct ddpcb	*ddp;
-	int		error = 0;
+	struct ddpcb *ddp;
+	int error = 0;
 	
 	ddp = sotoddpcb(so);
-	if (ddp == NULL) {
-		return (EINVAL);
-	}
+	KASSERT(ddp != NULL, ("ddp_send: ddp == NULL"));
 
-    	if (control && control->m_len) {
+    	if (control && control->m_len)
 		return (EINVAL);
-    	}
 
 	if (addr != NULL) {
 		DDP_LIST_XLOCK();
@@ -213,25 +224,42 @@
 	return (error);
 }
 
-static int
+/*
+ * XXXRW: This is never called because we only invoke abort on stream
+ * protocols.
+ */
+static void
 ddp_abort(struct socket *so)
 {
 	struct ddpcb	*ddp;
 	
 	ddp = sotoddpcb(so);
-	if (ddp == NULL) {
-		return (EINVAL);
-	}
-	DDP_LIST_XLOCK();
+	KASSERT(ddp != NULL, ("ddp_abort: ddp == NULL"));
+
 	DDP_LOCK(ddp);
-	at_pcbdetach(so, ddp);
-	DDP_LIST_XUNLOCK();
-	return (0);
+	at_pcbdisconnect(ddp);
+	DDP_UNLOCK(ddp);
+	soisdisconnected(so);
+}
+
+static void
+ddp_close(struct socket *so)
+{
+	struct ddpcb	*ddp;
+	
+	ddp = sotoddpcb(so);
+	KASSERT(ddp != NULL, ("ddp_close: ddp == NULL"));
+
+	DDP_LOCK(ddp);
+	at_pcbdisconnect(ddp);
+	DDP_UNLOCK(ddp);
+	soisdisconnected(so);
 }
 
 void 
 ddp_init(void)
 {
+
 	atintrq1.ifq_maxlen = IFQ_MAXLEN;
 	atintrq2.ifq_maxlen = IFQ_MAXLEN;
 	aarpintrq.ifq_maxlen = IFQ_MAXLEN;
@@ -248,30 +276,29 @@
 static void 
 ddp_clean(void)
 {
-    struct ddpcb	*ddp;
+	struct ddpcp	*ddp;
 
-    for (ddp = ddpcb_list; ddp != NULL; ddp = ddp->ddp_next) {
-	at_pcbdetach(ddp->ddp_socket, ddp);
-    }
-    DDP_LIST_LOCK_DESTROY();
+	for (ddp = ddpcb_list; ddp != NULL; ddp = ddp->ddp_next)
+		at_pcbdetach(ddp->ddp_socket, ddp);
+	DDP_LIST_LOCK_DESTROY();
 }
 #endif
 
 static int
-at_setpeeraddr(struct socket *so, struct sockaddr **nam)
+at_getpeeraddr(struct socket *so, struct sockaddr **nam)
 {
+
 	return (EOPNOTSUPP);
 }
 
 static int
-at_setsockaddr(struct socket *so, struct sockaddr **nam)
+at_getsockaddr(struct socket *so, struct sockaddr **nam)
 {
 	struct ddpcb	*ddp;
 
 	ddp = sotoddpcb(so);
-	if (ddp == NULL) {
-	    return (EINVAL);
-	}
+	KASSERT(ddp != NULL, ("at_getsockaddr: ddp == NULL"));
+
 	DDP_LOCK(ddp);
 	at_sockaddr(ddp, nam);
 	DDP_UNLOCK(ddp);
@@ -286,8 +313,9 @@
 	.pru_control =		at_control,
 	.pru_detach =		ddp_detach,
 	.pru_disconnect =	ddp_disconnect,
-	.pru_peeraddr =		at_setpeeraddr,
+	.pru_peeraddr =		at_getpeeraddr,
 	.pru_send =		ddp_send,
 	.pru_shutdown =		ddp_shutdown,
-	.pru_sockaddr =		at_setsockaddr,
+	.pru_sockaddr =		at_getsockaddr,
+	.pru_close =		ddp_close,
 };
Index: ddp.h
===================================================================
RCS file: /home/cvs/src/sys/netatalk/ddp.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/ddp.h -L sys/netatalk/ddp.h -u -r1.1.1.1 -r1.2
--- sys/netatalk/ddp.h
+++ sys/netatalk/ddp.h
@@ -1,5 +1,5 @@
 /*-
- * Copyright (c) 1990,1991 Regents of The University of Michigan.
+ * Copyright (c) 1990, 1991 Regents of The University of Michigan.
  * All Rights Reserved.
  *
  * Permission to use, copy, modify, and distribute this software and
@@ -20,12 +20,13 @@
  *	+1-313-763-0525
  *	netatalk at itd.umich.edu
  *
- * $FreeBSD: src/sys/netatalk/ddp.h,v 1.2 2005/01/07 02:35:34 imp Exp $
+ * $FreeBSD: src/sys/netatalk/ddp.h,v 1.4 2007/06/28 12:54:58 rwatson Exp $
  */
+
 #ifndef _NETATALK_DDP_H_
-#define _NETATALK_DDP_H_ 1
+#define	_NETATALK_DDP_H_
 
-/*
+/*-
  * <-1byte(8bits) ->
  * +---------------+
  * | 0 | hopc  |len|
@@ -53,83 +54,84 @@
  * | Src PORT      |
  * +---------------+
  *
- * On Apples, there is also a ddp_type field, after src_port. However,
- * under this unix implementation, user level processes need to be able
- * to set the ddp_type. In later revisions, the ddp_type may only be
- * available in a raw_appletalk interface.
+ * On Apples, there is also a ddp_type field, after src_port.  However, under
+ * this unix implementation, user level processes need to be able to set the
+ * ddp_type.  In later revisions, the ddp_type may only be available in a
+ * raw_appletalk interface.
  */
 
 struct elaphdr {
-    u_char	el_dnode;
-    u_char	el_snode;
-    u_char	el_type;
-};
+	u_char	el_dnode;
+	u_char	el_snode;
+	u_char	el_type;
+} __packed;
 
 #define	SZ_ELAPHDR	3
 
-#define ELAP_DDPSHORT	0x01
-#define ELAP_DDPEXTEND	0x02
+#define	ELAP_DDPSHORT	0x01
+#define	ELAP_DDPEXTEND	0x02
 
 /*
  * Extended DDP header. Includes sickness for dealing with arbitrary
  * bitfields on a little-endian arch.
  */
 struct ddpehdr {
-    union {
-	struct {
+	union {
+		struct {
 #if BYTE_ORDER == BIG_ENDIAN
-    unsigned		dub_pad:2;
-    unsigned		dub_hops:4;
-    unsigned		dub_len:10;
-    unsigned		dub_sum:16;
+			unsigned	dub_pad:2;
+			unsigned	dub_hops:4;
+			unsigned	dub_len:10;
+			unsigned	dub_sum:16;
 #endif
 #if BYTE_ORDER == LITTLE_ENDIAN
-    unsigned		dub_sum:16;
-    unsigned		dub_len:10;
-    unsigned		dub_hops:4;
-    unsigned		dub_pad:2;
+			unsigned	dub_sum:16;
+			unsigned	dub_len:10;
+			unsigned	dub_hops:4;
+			unsigned	dub_pad:2;
 #endif
-	} du_bits;
-	unsigned	du_bytes;
-    } deh_u;
-#define deh_pad		deh_u.du_bits.dub_pad
-#define deh_hops	deh_u.du_bits.dub_hops
-#define deh_len		deh_u.du_bits.dub_len
-#define deh_sum		deh_u.du_bits.dub_sum
-#define deh_bytes	deh_u.du_bytes
-    u_short		deh_dnet;
-    u_short		deh_snet;
-    u_char		deh_dnode;
-    u_char		deh_snode;
-    u_char		deh_dport;
-    u_char		deh_sport;
-};
+		} __packed du_bits;
+		unsigned	du_bytes;
+	} deh_u;
+	u_short	deh_dnet;
+	u_short	deh_snet;
+	u_char	deh_dnode;
+	u_char	deh_snode;
+	u_char	deh_dport;
+	u_char	deh_sport;
+} __packed;
+#define	deh_pad		deh_u.du_bits.dub_pad
+#define	deh_hops	deh_u.du_bits.dub_hops
+#define	deh_len		deh_u.du_bits.dub_len
+#define	deh_sum		deh_u.du_bits.dub_sum
+#define	deh_bytes	deh_u.du_bytes
 
-#define DDP_MAXHOPS	15
+#define	DDP_MAXHOPS	15
 
 struct ddpshdr {
-    union {
-	struct {
+	union {
+		struct {
 #if BYTE_ORDER == BIG_ENDIAN
-    unsigned		dub_pad:6;
-    unsigned		dub_len:10;
-    unsigned		dub_dport:8;
-    unsigned		dub_sport:8;
+			unsigned	dub_pad:6;
+			unsigned	dub_len:10;
+			unsigned	dub_dport:8;
+			unsigned	dub_sport:8;
 #endif
 #if BYTE_ORDER == LITTLE_ENDIAN
-    unsigned		dub_sport:8;
-    unsigned		dub_dport:8;
-    unsigned		dub_len:10;
-    unsigned		dub_pad:6;
+			unsigned	dub_sport:8;
+			unsigned	dub_dport:8;
+			unsigned	dub_len:10;
+			unsigned	dub_pad:6;
 #endif
-	} du_bits;
-	unsigned	du_bytes;
-    } dsh_u;
-#define dsh_pad		dsh_u.du_bits.dub_pad
-#define dsh_len		dsh_u.du_bits.dub_len
-#define dsh_dport	dsh_u.du_bits.dub_dport
-#define dsh_sport	dsh_u.du_bits.dub_sport
-#define dsh_bytes	dsh_u.du_bytes
-};
+		} __packed du_bits;
+		unsigned	du_bytes;
+	} dsh_u;
+} __packed;
+
+#define	dsh_pad		dsh_u.du_bits.dub_pad
+#define	dsh_len		dsh_u.du_bits.dub_len
+#define	dsh_dport	dsh_u.du_bits.dub_dport
+#define	dsh_sport	dsh_u.du_bits.dub_sport
+#define	dsh_bytes	dsh_u.du_bytes
 
 #endif /* _NETATALK_DDP_H_ */
Index: aarp.h
===================================================================
RCS file: /home/cvs/src/sys/netatalk/aarp.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatalk/aarp.h -L sys/netatalk/aarp.h -u -r1.1.1.1 -r1.2
--- sys/netatalk/aarp.h
+++ sys/netatalk/aarp.h
@@ -23,10 +23,12 @@
  *	+1-313-764-2278
  *	netatalk at umich.edu
  *
- * $FreeBSD: src/sys/netatalk/aarp.h,v 1.4 2005/01/07 02:35:34 imp Exp $
+ * $FreeBSD: src/sys/netatalk/aarp.h,v 1.6 2007/06/28 12:54:58 rwatson Exp $
  */
 
 #ifndef _NETATALK_AARP_H_
+#define	_NETATALK_AARP_H_
+
 /*
  * This structure is used for both phase 1 and 2. Under phase 1
  * the net is not filled in. It is in phase 2. In both cases, the
@@ -35,46 +37,47 @@
  * would be 1 and 3 respectively for phase 1 and 2.
  */
 union aapa {
-    u_char		ap_pa[4];
-    struct ap_node {
-	u_char		an_zero;
-	u_char		an_net[2];
-	u_char		an_node;
-    } ap_node;
+	u_char ap_pa[4];
+	struct ap_node {
+		u_char an_zero;
+		u_char an_net[2];
+		u_char an_node;
+	} __packed ap_node;
 };
 
 struct ether_aarp {
-    struct arphdr	eaa_hdr;
-    u_char		aarp_sha[6];
-    union aapa		aarp_spu;
-    u_char		aarp_tha[6];
-    union aapa		aarp_tpu;
-};
-#define aarp_hrd	eaa_hdr.ar_hrd
-#define aarp_pro	eaa_hdr.ar_pro
-#define aarp_hln	eaa_hdr.ar_hln
-#define aarp_pln	eaa_hdr.ar_pln
-#define aarp_op		eaa_hdr.ar_op
-#define aarp_spa	aarp_spu.ap_node.an_node
-#define aarp_tpa	aarp_tpu.ap_node.an_node
-#define aarp_spnet	aarp_spu.ap_node.an_net
-#define aarp_tpnet	aarp_tpu.ap_node.an_net
-#define aarp_spnode	aarp_spu.ap_node.an_node
-#define aarp_tpnode	aarp_tpu.ap_node.an_node
+	struct arphdr eaa_hdr;
+	u_char aarp_sha[6];
+	union aapa aarp_spu;
+	u_char aarp_tha[6];
+	union aapa aarp_tpu;
+} __packed;
+
+#define	aarp_hrd	eaa_hdr.ar_hrd
+#define	aarp_pro	eaa_hdr.ar_pro
+#define	aarp_hln	eaa_hdr.ar_hln
+#define	aarp_pln	eaa_hdr.ar_pln
+#define	aarp_op		eaa_hdr.ar_op
+#define	aarp_spa	aarp_spu.ap_node.an_node
+#define	aarp_tpa	aarp_tpu.ap_node.an_node
+#define	aarp_spnet	aarp_spu.ap_node.an_net
+#define	aarp_tpnet	aarp_tpu.ap_node.an_net
+#define	aarp_spnode	aarp_spu.ap_node.an_node
+#define	aarp_tpnode	aarp_tpu.ap_node.an_node
 
 struct aarptab {
-    struct at_addr	aat_ataddr;
-    u_char		aat_enaddr[ 6 ];
-    u_char		aat_timer;
-    u_char		aat_flags;
-    struct mbuf		*aat_hold;
+	struct at_addr aat_ataddr;
+	u_char aat_enaddr[6];
+	u_char aat_timer;
+	u_char aat_flags;
+	struct mbuf *aat_hold;
 };
 
-#define AARPHRD_ETHER	0x0001
+#define	AARPHRD_ETHER	0x0001
 
-#define AARPOP_REQUEST	0x01
-#define AARPOP_RESPONSE	0x02
-#define AARPOP_PROBE	0x03
+#define	AARPOP_REQUEST	0x01
+#define	AARPOP_RESPONSE	0x02
+#define	AARPOP_PROBE	0x03
 
 #ifdef _KERNEL
 struct aarptab		*aarptnew(struct at_addr      *);
Index: atm_usrreq.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/atm_usrreq.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/atm_usrreq.c -L sys/netatm/atm_usrreq.c -u -r1.1.1.1 -r1.2
--- sys/netatm/atm_usrreq.c
+++ sys/netatm/atm_usrreq.c
@@ -31,11 +31,12 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/atm_usrreq.c,v 1.24 2005/06/10 16:49:20 brooks Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/atm_usrreq.c,v 1.28 2006/11/06 13:42:03 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
 #include <sys/sockio.h>
+#include <sys/priv.h>
 #include <sys/protosw.h>
 #include <sys/socket.h>
 #include <net/if.h>
@@ -66,11 +67,11 @@
  * New-style socket request routines
  */
 struct pr_usrreqs	atm_dgram_usrreqs = {
-	.pru_abort =		atm_proto_notsupp1,
+	.pru_abort =		atm_proto_notsupp5,
 	.pru_attach =		atm_dgram_attach,
 	.pru_bind =		atm_proto_notsupp2,
 	.pru_control =		atm_dgram_control,
-	.pru_detach =		atm_proto_notsupp1,
+	.pru_detach =		atm_proto_notsupp5,
 	.pru_disconnect =	atm_proto_notsupp1,
 	.pru_peeraddr =		atm_proto_notsupp3,
 	.pru_send =		atm_proto_notsupp4,
@@ -79,6 +80,7 @@
 	.pru_sosend =		NULL,
 	.pru_soreceive =	NULL,
 	.pru_sopoll =		NULL,
+	.pru_close =		atm_proto_notsupp5,
 };
 
 
@@ -180,8 +182,11 @@
 		struct atmcfgreq	*acp = (struct atmcfgreq *)data;
 		struct atm_pif		*pip;
 
-		if (td && (suser(td) != 0))
-			ATM_RETERR(EPERM);
+		if (td != NULL) {
+			err = priv_check(td, PRIV_NETATM_CFG);
+			if (err)
+				ATM_RETERR(err);
+		}
 
 		switch (acp->acr_opcode) {
 
@@ -213,8 +218,11 @@
 		struct atmaddreq	*aap = (struct atmaddreq *)data;
 		Atm_endpoint		*epp;
 
-		if (td && (suser(td) != 0))
-			ATM_RETERR(EPERM);
+		if (td != NULL) {
+			err = priv_check(td, PRIV_NETATM_ADD);
+			if (err)
+				ATM_RETERR(err);
+		}
 
 		switch (aap->aar_opcode) {
 
@@ -263,8 +271,11 @@
 		struct sigmgr		*smp;
 		Atm_endpoint		*epp;
 
-		if (td && (suser(td) != 0))
-			ATM_RETERR(EPERM);
+		if (td != NULL) {
+			err = priv_check(td, PRIV_NETATM_DEL);
+			if (err)
+				ATM_RETERR(err);
+		}
 
 		switch (adp->adr_opcode) {
 
@@ -316,8 +327,11 @@
 		struct sigmgr		*smp;
 		struct ifnet		*ifp2;
 
-		if (td && (suser(td) != 0))
-			ATM_RETERR(EPERM);
+		if (td != NULL) {
+			err = priv_check(td, PRIV_NETATM_SET);
+			if (err)
+				ATM_RETERR(err);
+		}
 
 		switch (asp->asr_opcode) {
 
Index: atm_sys.h
===================================================================
RCS file: /home/cvs/src/sys/netatm/atm_sys.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/atm_sys.h -L sys/netatm/atm_sys.h -u -r1.1.1.1 -r1.2
--- sys/netatm/atm_sys.h
+++ sys/netatm/atm_sys.h
@@ -23,7 +23,7 @@
  * Copies of this Software may be made, however, the above copyright
  * notice must be reproduced on all copies.
  *
- *	@(#) $FreeBSD: src/sys/netatm/atm_sys.h,v 1.8 2005/01/07 01:45:36 imp Exp $
+ *	@(#) $FreeBSD: src/sys/netatm/atm_sys.h,v 1.9 2005/12/27 12:33:18 stefanf Exp $
  *
  */
 
@@ -186,7 +186,7 @@
 		delta.tv_sec--;						\
 		delta.tv_usec += 1000000;				\
 	}								\
-	printf("%3ld.%6ld: ", delta.tv_sec, delta.tv_usec);
+	printf("%3ld.%6ld: ", (long)delta.tv_sec, delta.tv_usec);
 
 #define	ATM_DEBUG0(f)		if (atm_debug) {ATM_TIME; printf(f);}
 #define	ATM_DEBUGN0(f)		if (atm_debug) {printf(f);}
Index: atm_socket.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/atm_socket.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/atm_socket.c -L sys/netatm/atm_socket.c -u -r1.1.1.1 -r1.2
--- sys/netatm/atm_socket.c
+++ sys/netatm/atm_socket.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/atm_socket.c,v 1.24 2005/06/10 16:49:20 brooks Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/atm_socket.c,v 1.26 2006/04/01 15:41:59 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -146,12 +146,8 @@
  * Arguments:
  *	so	pointer to socket
  *
- * Returns:
- *	0	detach successful
- *	errno	detach failed - reason indicated
- *
  */
-int
+void
 atm_sock_detach(so)
 	struct socket	*so;
 {
@@ -160,8 +156,7 @@
 	/*
 	 * Make sure we're still attached
 	 */
-	if (atp == NULL)
-		return (ENOTCONN);
+	KASSERT(atp != NULL, ("atm_sock_detach: atp == NULL"));
 
 	/*
 	 * Terminate any (possibly pending) connection
@@ -170,17 +165,9 @@
 		(void) atm_sock_disconnect(so);
 	}
 
-	/*
-	 * Break links and free control blocks
-	 */
-	ACCEPT_LOCK();
-	SOCK_LOCK(so);
 	so->so_pcb = NULL;
-	sotryfree(so);
 
 	uma_zfree(atm_pcb_zone, atp);
-
-	return (0);
 }
 
 
@@ -335,9 +322,10 @@
  *
  */
 int
-atm_sock_listen(so, epp)
+atm_sock_listen(so, epp, backlog)
 	struct socket	*so;
 	Atm_endpoint	*epp;
+	int		 backlog;
 {
 	Atm_pcb		*atp = sotoatmpcb(so);
 
@@ -350,7 +338,8 @@
 	/*
 	 * Start listening for incoming calls
 	 */
-	return (atm_cm_listen(so, epp, atp, &atp->atp_attr, &atp->atp_conn));
+	return (atm_cm_listen(so, epp, atp, &atp->atp_attr, &atp->atp_conn,
+	    backlog));
 }
 
 
Index: atm_if.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/atm_if.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/atm_if.c -L sys/netatm/atm_if.c -u -r1.1.1.1 -r1.2
--- sys/netatm/atm_if.c
+++ sys/netatm/atm_if.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/atm_if.c,v 1.30.2.1 2005/08/25 05:01:21 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/atm_if.c,v 1.33 2007/04/03 12:45:10 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -169,7 +169,7 @@
 	Cmn_unit	*cup;
 {
 	struct atm_pif	*pip = (struct atm_pif *)&cup->cu_pif;
-	Cmn_vcc		*cvp;
+	Cmn_vcc		*cvp, *cvp_next;
 	int	err;
 	int	s = splnet();
 
@@ -215,8 +215,9 @@
 	 */
 	cvp = cup->cu_vcc;
 	while (cvp) {
+		cvp_next = cvp->cv_next;
 		uma_zfree(cup->cu_vcc_zone, cvp);
-		cvp = cvp->cv_next;
+		cvp = cvp_next;
 	}
 	cup->cu_vcc = (Cmn_vcc *)NULL;
 
@@ -561,7 +562,7 @@
 			 * Set macaddr in <Link> address
 			 */
 			ifp->if_addrlen = 6;
-			ifa = ifaddr_byindex(ifp->if_index);
+			ifa = ifp->if_addr;
 			if ( ifa ) {
 				sdl = (struct sockaddr_dl *)
 					ifa->ifa_addr;
Index: atm_proto.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/atm_proto.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/atm_proto.c -L sys/netatm/atm_proto.c -u -r1.1.1.1 -r1.2
--- sys/netatm/atm_proto.c
+++ sys/netatm/atm_proto.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/atm_proto.c,v 1.13.2.1 2005/11/16 10:31:22 ru Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/atm_proto.c,v 1.16 2007/07/14 21:49:23 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -51,7 +51,7 @@
 #include <netatm/atm_pcb.h>
 #include <netatm/atm_var.h>
 
-NET_NEEDS_GIANT("netatm");
+#error "NET_NEEDS_GIANT"
 
 struct protosw atmsw[] = {
 {
@@ -184,3 +184,17 @@
 {
 	return (EOPNOTSUPP);
 }
+
+/*
+ * Protocol request not supported
+ *
+ * Arguments:
+ *	so	pointer to socket
+ *
+ */
+void
+atm_proto_notsupp5(so)
+	struct socket	*so;
+{
+
+}
Index: atm_var.h
===================================================================
RCS file: /home/cvs/src/sys/netatm/atm_var.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/atm_var.h -L sys/netatm/atm_var.h -u -r1.1.1.1 -r1.2
--- sys/netatm/atm_var.h
+++ sys/netatm/atm_var.h
@@ -23,7 +23,7 @@
  * Copies of this Software may be made, however, the above copyright
  * notice must be reproduced on all copies.
  *
- *	@(#) $FreeBSD: src/sys/netatm/atm_var.h,v 1.26 2005/02/21 21:58:16 rwatson Exp $
+ *	@(#) $FreeBSD: src/sys/netatm/atm_var.h,v 1.29 2006/04/01 15:41:59 rwatson Exp $
  *
  */
 
@@ -82,7 +82,7 @@
 int		atm_cm_connect(Atm_endpoint *, void *, Atm_attributes *,
 			Atm_connection **);
 int		atm_cm_listen(struct socket *, Atm_endpoint *, void *,
-			Atm_attributes *, Atm_connection **);
+			Atm_attributes *, Atm_connection **, int);
 int		atm_cm_addllc(Atm_endpoint *, void *, struct attr_llc *,
 			Atm_connection *, Atm_connection **);
 int		atm_cm_addparty(Atm_connection *, int, struct t_atm_sap *);
@@ -136,6 +136,7 @@
 int		atm_proto_notsupp3(struct socket *, struct sockaddr **);
 int		atm_proto_notsupp4(struct socket *, int, KBuffer *, 
 			struct sockaddr *, KBuffer *, struct thread *);
+void		atm_proto_notsupp5(struct socket *);
 
 	/* atm_signal.c */
 int		atm_sigmgr_register(struct sigmgr *);
@@ -150,9 +151,9 @@
 	/* atm_socket.c */
 void		atm_sock_init(void);
 int		atm_sock_attach(struct socket *, u_long, u_long);
-int		atm_sock_detach(struct socket *);
+void		atm_sock_detach(struct socket *);
 int		atm_sock_bind(struct socket *, struct sockaddr *);
-int		atm_sock_listen(struct socket *, Atm_endpoint *);
+int		atm_sock_listen(struct socket *, Atm_endpoint *, int);
 int		atm_sock_connect(struct socket *, struct sockaddr *,
 			Atm_endpoint *);
 int		atm_sock_disconnect(struct socket *);
Index: atm_signal.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/atm_signal.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/netatm/atm_signal.c -L sys/netatm/atm_signal.c -u -r1.1.1.2 -r1.2
--- sys/netatm/atm_signal.c
+++ sys/netatm/atm_signal.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/atm_signal.c,v 1.13.2.1 2006/02/13 23:54:48 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/atm_signal.c,v 1.14 2006/01/22 01:04:05 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
Index: atm_aal5.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/atm_aal5.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/atm_aal5.c -L sys/netatm/atm_aal5.c -u -r1.1.1.1 -r1.2
--- sys/netatm/atm_aal5.c
+++ sys/netatm/atm_aal5.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/atm_aal5.c,v 1.21 2005/01/07 01:45:36 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/atm_aal5.c,v 1.25 2006/07/21 17:11:13 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/lock.h>
@@ -66,10 +66,11 @@
  * Local functions
  */
 static int	atm_aal5_attach(struct socket *, int, struct thread *td);
-static int	atm_aal5_detach(struct socket *);
+static void	atm_aal5_detach(struct socket *);
 static int	atm_aal5_bind(struct socket *, struct sockaddr *, 
 			struct thread *td);
-static int	atm_aal5_listen(struct socket *, struct thread *td);
+static int	atm_aal5_listen(struct socket *, int backlog,
+			struct thread *td);
 static int	atm_aal5_connect(struct socket *, struct sockaddr *,
 			struct thread *td);
 static int	atm_aal5_accept(struct socket *, struct sockaddr **);
@@ -77,7 +78,7 @@
 static int	atm_aal5_shutdown(struct socket *);
 static int	atm_aal5_send(struct socket *, int, KBuffer *,
 			struct sockaddr *, KBuffer *, struct thread *td);
-static int	atm_aal5_abort(struct socket *);
+static void	atm_aal5_abort(struct socket *);
 static int	atm_aal5_control(struct socket *, u_long, caddr_t, 
 			struct ifnet *, struct thread *td);
 static int	atm_aal5_sense(struct socket *, struct stat *);
@@ -87,6 +88,7 @@
 			Atm_attributes *, void **);
 static void	atm_aal5_cpcs_data(void *, KBuffer *);
 static caddr_t	atm_aal5_getname(void *);
+static void	atm_aal5_close(struct socket *);
 
 
 /*
@@ -107,6 +109,7 @@
 	.pru_sense =		atm_aal5_sense,
 	.pru_shutdown =		atm_aal5_shutdown,
 	.pru_sockaddr =		atm_aal5_sockaddr,
+	.pru_close =		atm_aal5_close,
 };
 
 /*
@@ -203,6 +206,11 @@
 	;
 #endif /* DIAGNOSTIC */
 
+#define	ATM_INTRO_NOERR(f)					\
+	int		s;					\
+	s = splnet();						\
+	;
+
 #define	ATM_OUTRO()						\
 	/*							\
 	 * Drain any deferred calls				\
@@ -212,6 +220,14 @@
 	return (err);						\
 	;
 
+#define	ATM_OUTRO_NOERR()					\
+	/*							\
+	 * Drain any deferred calls				\
+	 */							\
+	STACK_DRAIN();						\
+	(void) splx(s);						\
+	;
+
 #define	ATM_RETERR(errno) {					\
 	err = errno;						\
 	goto out;						\
@@ -276,15 +292,15 @@
  *	errno	error processing request - reason indicated
  *
  */
-static int
+static void
 atm_aal5_detach(so)
 	struct socket	*so;
 {
-	ATM_INTRO("detach");
+	ATM_INTRO_NOERR("detach");
 
-	err = atm_sock_detach(so);
+	atm_sock_detach(so);
 
-	ATM_OUTRO();
+	ATM_OUTRO_NOERR();
 }
 
 
@@ -328,13 +344,14 @@
  *
  */
 static int
-atm_aal5_listen(so, td)
+atm_aal5_listen(so, backlog, td)
 	struct socket	*so;
+	int		 backlog;
 	struct thread	*td;
 {
 	ATM_INTRO("listen");
 
-	err = atm_sock_listen(so, &atm_aal5_endpt);
+	err = atm_sock_listen(so, &atm_aal5_endpt, backlog);
 
 	ATM_OUTRO();
 }
@@ -544,16 +561,27 @@
  *	errno	error processing request - reason indicated
  *
  */
-static int
+static void
 atm_aal5_abort(so)
 	struct socket	*so;
 {
-	ATM_INTRO("abort");
+	ATM_INTRO_NOERR("abort");
 
+	(void)atm_sock_disconnect(so);
 	so->so_error = ECONNABORTED;
-	err = atm_sock_detach(so);
 
-	ATM_OUTRO();
+	ATM_OUTRO_NOERR();
+}
+
+static void
+atm_aal5_close(so)
+	struct socket	*so;
+{
+	ATM_INTRO_NOERR("close");
+
+	(void)atm_sock_disconnect(so);
+
+	ATM_OUTRO_NOERR();
 }
 
 
Index: atm_cm.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/atm_cm.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/atm_cm.c -L sys/netatm/atm_cm.c -u -r1.1.1.1 -r1.2
--- sys/netatm/atm_cm.c
+++ sys/netatm/atm_cm.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/atm_cm.c,v 1.33 2005/02/21 21:58:16 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/atm_cm.c,v 1.35 2007/06/23 00:02:19 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -536,12 +536,13 @@
  *
  */
 int
-atm_cm_listen(so, epp, token, ap, copp)
+atm_cm_listen(so, epp, token, ap, copp, backlog)
 	struct socket	*so;
 	Atm_endpoint	*epp;
 	void		*token;
 	Atm_attributes	*ap;
 	Atm_connection	**copp;
+	int		 backlog;
 {
 	Atm_connection	*cop;
 	int		s, err = 0;
@@ -737,7 +738,7 @@
 	cop->co_state = COS_LISTEN;
 	LINK2TAIL(cop, Atm_connection, atm_listen_queue, co_next);
 	if (so != NULL)
-		solisten_proto(so);
+		solisten_proto(so, backlog);
 
 donex:
 	(void) splx(s);
@@ -2611,7 +2612,7 @@
 	 * Back-off to cvc control block
 	 */
 	cvp = (Atm_connvc *)
-			((caddr_t)tip - (int)(&((Atm_connvc *)0)->cvc_time));
+		((caddr_t)tip - offsetof(Atm_connvc, cvc_time));
 
 	/*
 	 * Process timeout based on protocol state
Index: unisig_proto.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/uni/unisig_proto.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/uni/unisig_proto.c -L sys/netatm/uni/unisig_proto.c -u -r1.1.1.1 -r1.2
--- sys/netatm/uni/unisig_proto.c
+++ sys/netatm/uni/unisig_proto.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/uni/unisig_proto.c,v 1.12 2005/01/07 01:45:37 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/uni/unisig_proto.c,v 1.13 2007/06/23 00:02:20 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -88,7 +88,7 @@
 	 * Back-off to UNISIG control block
 	 */
 	usp = (struct unisig *)
-		((caddr_t)tip - (int)(&((struct unisig *)0)->us_time));
+		((caddr_t)tip - offsetof(struct unisig, us_time));
 
 	ATM_DEBUG2("unisig_timer: usp=%p,state=%d\n",
 			usp, usp->us_state);
@@ -127,8 +127,8 @@
 	/*
 	 * Get VCCB and UNISIG control block addresses
 	 */
-	uvp = (struct unisig_vccb *) ((caddr_t)tip -
-			(int)(&((struct vccb *)0)->vc_time));
+	uvp = (struct unisig_vccb *)
+		((caddr_t)tip - offsetof(struct vccb, vc_time));
 	usp = (struct unisig *)uvp->uv_pif->pif_siginst;
 
 	ATM_DEBUG3("unisig_vctimer: uvp=%p, sstate=%d, ustate=%d\n",
Index: sscf_uni_lower.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/uni/sscf_uni_lower.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/uni/sscf_uni_lower.c -L sys/netatm/uni/sscf_uni_lower.c -u -r1.1.1.1 -r1.2
--- sys/netatm/uni/sscf_uni_lower.c
+++ sys/netatm/uni/sscf_uni_lower.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/uni/sscf_uni_lower.c,v 1.13 2005/01/07 01:45:37 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/uni/sscf_uni_lower.c,v 1.14 2007/06/23 00:02:20 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -142,7 +142,7 @@
 		uvp->uv_lstate = UVL_IDLE;
 
 		STACK_CALL(SSCOP_INIT, uvp->uv_lower, uvp->uv_tokl, cvp, 
-			(int)vers, (int)&sscf_uni_sscop_parms, err);
+			(int)vers, (size_t)&sscf_uni_sscop_parms, err);
 		if (err) {
 			/*
 			 * Should never happen
Index: unisig_decode.h
===================================================================
RCS file: /home/cvs/src/sys/netatm/uni/unisig_decode.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/uni/unisig_decode.h -L sys/netatm/uni/unisig_decode.h -u -r1.1.1.1 -r1.2
--- sys/netatm/uni/unisig_decode.h
+++ sys/netatm/uni/unisig_decode.h
@@ -23,7 +23,7 @@
  * Copies of this Software may be made, however, the above copyright
  * notice must be reproduced on all copies.
  *
- *	@(#) $FreeBSD: src/sys/netatm/uni/unisig_decode.h,v 1.4 2005/01/07 01:45:37 imp Exp $
+ *	@(#) $FreeBSD: src/sys/netatm/uni/unisig_decode.h,v 1.5 2007/06/23 00:02:20 mjacob Exp $
  *
  */
 
@@ -58,19 +58,8 @@
 				(struct usfmt *, struct ie_generic *);
 };
 
-/*
- * Macro to give the offset of a field in a generic IE structure
- */
-#define	IE_OFFSET(f) \
-	((int)&((struct ie_generic *) 0)->f)
-
-/*
- * Macro to give the size of a field in a generic IE structure
- */
-#define IE_FSIZE(f) \
-	(sizeof(((struct ie_generic *) 0)->f))
-
-#define IE_OFF_SIZE(f)   IE_OFFSET(f),IE_FSIZE(f)
+#define IE_OFF_SIZE(f)   \
+	offsetof(struct ie_generic, f), (sizeof(((struct ie_generic *) 0)->f))
 
 
 /*
Index: uniarp_timer.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/uni/uniarp_timer.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/uni/uniarp_timer.c -L sys/netatm/uni/uniarp_timer.c -u -r1.1.1.1 -r1.2
--- sys/netatm/uni/uniarp_timer.c
+++ sys/netatm/uni/uniarp_timer.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/uni/uniarp_timer.c,v 1.11 2005/01/07 01:45:37 imp Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/uni/uniarp_timer.c,v 1.12 2007/06/23 00:02:20 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -90,7 +90,7 @@
 	 * Back-off to uniarp control block
 	 */
 	uap = (struct uniarp *)
-			((caddr_t)tip - (int)(&((struct uniarp *)0)->ua_time));
+		((caddr_t)tip - offsetof(struct uniarp, ua_time));
 	uip = uap->ua_intf;
 
 
Index: uniarp.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/uni/uniarp.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netatm/uni/uniarp.c -L sys/netatm/uni/uniarp.c -u -r1.1.1.1 -r1.2
--- sys/netatm/uni/uniarp.c
+++ sys/netatm/uni/uniarp.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/uni/uniarp.c,v 1.23 2005/06/10 16:49:20 brooks Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/uni/uniarp.c,v 1.24 2007/06/23 00:02:20 mjacob Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -776,7 +776,7 @@
 	 * Back-off to uniip control block
 	 */
 	uip = (struct uniip *)
-		((caddr_t)tip - (int)(&((struct uniip *)0)->uip_arptime));
+		((caddr_t)tip - offsetof(struct uniip, uip_arptime));
 
 	ATM_DEBUG2("uniarp_iftimeout: uip=%p, state=%d\n", uip, 
 		uip->uip_arpstate);
Index: unisig_encode.c
===================================================================
RCS file: /home/cvs/src/sys/netatm/uni/unisig_encode.c,v
retrieving revision 1.1.1.2
retrieving revision 1.2
diff -L sys/netatm/uni/unisig_encode.c -L sys/netatm/uni/unisig_encode.c -u -r1.1.1.2 -r1.2
--- sys/netatm/uni/unisig_encode.c
+++ sys/netatm/uni/unisig_encode.c
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netatm/uni/unisig_encode.c,v 1.14.2.1 2006/01/29 06:55:03 sam Exp $");
+__FBSDID("$FreeBSD: src/sys/netatm/uni/unisig_encode.c,v 1.15 2005/12/21 00:19:08 sam Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
--- sys/netkey/keydb.c
+++ /dev/null
@@ -1,261 +0,0 @@
-/*	$KAME: keydb.c,v 1.82 2003/09/07 07:47:33 itojun Exp $	*/
-
-/*-
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netkey/keydb.c,v 1.6 2005/01/07 01:45:48 imp Exp $");
-
-#include "opt_inet.h"
-#include "opt_inet6.h"
-
-#include <sys/types.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/malloc.h>
-#include <sys/errno.h>
-#include <sys/queue.h>
-
-#include <net/if.h>
-#include <net/route.h>
-
-#include <netinet/in.h>
-
-#include <net/pfkeyv2.h>
-#include <netkey/keydb.h>
-#include <netkey/key.h>
-#include <netinet6/ipsec.h>
-
-#include <net/net_osdep.h>
-
-MALLOC_DEFINE(M_SECA, "key mgmt", "security associations, key management");
-
-/*
- * secpolicy management
- */
-struct secpolicy *
-keydb_newsecpolicy()
-{
-	struct secpolicy *p;
-
-	p = (struct secpolicy *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
-	if (!p)
-		return p;
-	bzero(p, sizeof(*p));
-	TAILQ_INSERT_TAIL(&sptailq, p, tailq);
-
-	return p;
-}
-
-u_int32_t
-keydb_newspid(void)
-{
-	u_int32_t newid = 0;
-	static u_int32_t lastalloc = IPSEC_MANUAL_POLICYID_MAX;
-	struct secpolicy *sp;
-
-	newid = lastalloc + 1;
-	/* XXX possible infinite loop */
-again:
-	TAILQ_FOREACH(sp, &sptailq, tailq) {
-		if (sp->id == newid)
-			break;
-	}
-	if (sp != NULL) {
-		if (newid + 1 < newid)	/* wraparound */
-			newid = IPSEC_MANUAL_POLICYID_MAX + 1;
-		else
-			newid++;
-		goto again;
-	}
-	lastalloc = newid;
-
-	return newid;
-}
-
-void
-keydb_delsecpolicy(p)
-	struct secpolicy *p;
-{
-
-	TAILQ_REMOVE(&sptailq, p, tailq);
-	if (p->spidx)
-		free(p->spidx, M_SECA);
-	free(p, M_SECA);
-}
-
-int
-keydb_setsecpolicyindex(p, idx)
-	struct secpolicy *p;
-	struct secpolicyindex *idx;
-{
-
-	if (!p->spidx)
-		p->spidx = (struct secpolicyindex *)malloc(sizeof(*p->spidx),
-		    M_SECA, M_NOWAIT);
-	if (!p->spidx)
-		return ENOMEM;
-	memcpy(p->spidx, idx, sizeof(*p->spidx));
-	return 0;
-}
-
-/*
- * secashead management
- */
-struct secashead *
-keydb_newsecashead()
-{
-	struct secashead *p;
-	int i;
-
-	p = (struct secashead *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
-	if (!p)
-		return p;
-	bzero(p, sizeof(*p));
-	for (i = 0; i < sizeof(p->savtree)/sizeof(p->savtree[0]); i++)
-		LIST_INIT(&p->savtree[i]);
-	return p;
-}
-
-void
-keydb_delsecashead(p)
-	struct secashead *p;
-{
-
-	free(p, M_SECA);
-}
-
-/*
- * secasvar management (reference counted)
- */
-struct secasvar *
-keydb_newsecasvar()
-{
-	struct secasvar *p, *q;
-	static u_int32_t said = 0;
-
-	p = (struct secasvar *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
-	if (!p)
-		return p;
-
-again:
-	said++;
-	if (said == 0)
-		said++;
-	TAILQ_FOREACH(q, &satailq, tailq) {
-		if (q->id == said)
-			goto again;
-		if (TAILQ_NEXT(q, tailq)) {
-			if (q->id < said && said < TAILQ_NEXT(q, tailq)->id)
-				break;
-			if (q->id + 1 < TAILQ_NEXT(q, tailq)->id) {
-				said = q->id + 1;
-				break;
-			}
-		}
-	}
-
-	bzero(p, sizeof(*p));
-	p->id = said;
-	if (q)
-		TAILQ_INSERT_AFTER(&satailq, q, p, tailq);
-	else
-		TAILQ_INSERT_TAIL(&satailq, p, tailq);
-	return p;
-}
-
-void
-keydb_delsecasvar(p)
-	struct secasvar *p;
-{
-
-	TAILQ_REMOVE(&satailq, p, tailq);
-
-	free(p, M_SECA);
-}
-
-/*
- * secreplay management
- */
-struct secreplay *
-keydb_newsecreplay(wsize)
-	size_t wsize;
-{
-	struct secreplay *p;
-
-	p = (struct secreplay *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
-	if (!p)
-		return p;
-
-	bzero(p, sizeof(*p));
-	if (wsize != 0) {
-		p->bitmap = malloc(wsize, M_SECA, M_NOWAIT);
-		if (!p->bitmap) {
-			free(p, M_SECA);
-			return NULL;
-		}
-		bzero(p->bitmap, wsize);
-	}
-	p->wsize = wsize;
-	return p;
-}
-
-void
-keydb_delsecreplay(p)
-	struct secreplay *p;
-{
-
-	if (p->bitmap)
-		free(p->bitmap, M_SECA);
-	free(p, M_SECA);
-}
-
-/*
- * secreg management
- */
-struct secreg *
-keydb_newsecreg()
-{
-	struct secreg *p;
-
-	p = (struct secreg *)malloc(sizeof(*p), M_SECA, M_NOWAIT);
-	if (p)
-		bzero(p, sizeof(*p));
-	return p;
-}
-
-void
-keydb_delsecreg(p)
-	struct secreg *p;
-{
-
-	free(p, M_SECA);
-}
--- sys/netkey/key_debug.h
+++ /dev/null
@@ -1,88 +0,0 @@
-/*	$FreeBSD: src/sys/netkey/key_debug.h,v 1.12 2005/01/07 01:45:48 imp Exp $	*/
-/*	$KAME: key_debug.h,v 1.11 2002/11/05 03:48:34 itojun Exp $	*/
-
-/*-
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _NETKEY_KEY_DEBUG_H_
-#define _NETKEY_KEY_DEBUG_H_
-
-#ifdef _KERNEL
-/* debug flags */
-#define KEYDEBUG_STAMP		0x00000001 /* path */
-#define KEYDEBUG_DATA		0x00000002 /* data */
-#define KEYDEBUG_DUMP		0x00000004 /* dump */
-
-#define KEYDEBUG_KEY		0x00000010 /* key processing */
-#define KEYDEBUG_ALG		0x00000020 /* ciph & auth algorithm */
-#define KEYDEBUG_IPSEC		0x00000040 /* ipsec processing */
-
-#define KEYDEBUG_KEY_STAMP	(KEYDEBUG_KEY | KEYDEBUG_STAMP)
-#define KEYDEBUG_KEY_DATA	(KEYDEBUG_KEY | KEYDEBUG_DATA)
-#define KEYDEBUG_KEY_DUMP	(KEYDEBUG_KEY | KEYDEBUG_DUMP)
-#define KEYDEBUG_ALG_STAMP	(KEYDEBUG_ALG | KEYDEBUG_STAMP)
-#define KEYDEBUG_ALG_DATA	(KEYDEBUG_ALG | KEYDEBUG_DATA)
-#define KEYDEBUG_ALG_DUMP	(KEYDEBUG_ALG | KEYDEBUG_DUMP)
-#define KEYDEBUG_IPSEC_STAMP	(KEYDEBUG_IPSEC | KEYDEBUG_STAMP)
-#define KEYDEBUG_IPSEC_DATA	(KEYDEBUG_IPSEC | KEYDEBUG_DATA)
-#define KEYDEBUG_IPSEC_DUMP	(KEYDEBUG_IPSEC | KEYDEBUG_DUMP)
-
-#define KEYDEBUG(lev,arg) \
-	do { if ((key_debug_level & (lev)) == (lev)) { arg; } } while (/*CONSTCOND*/ 0)
-
-extern u_int32_t key_debug_level;
-#endif /*_KERNEL*/
-
-struct sadb_msg;
-struct sadb_ext;
-extern void kdebug_sadb(struct sadb_msg *);
-extern void kdebug_sadb_x_policy(struct sadb_ext *);
-
-#ifdef _KERNEL
-struct secpolicy;
-struct secpolicyindex;
-struct secasindex;
-struct secasvar;
-struct secreplay;
-struct mbuf;
-extern void kdebug_secpolicy(struct secpolicy *);
-extern void kdebug_secpolicyindex(struct secpolicyindex *);
-extern void kdebug_secasindex(struct secasindex *);
-extern void kdebug_secasv(struct secasvar *);
-extern void kdebug_mbufhdr(struct mbuf *);
-extern void kdebug_mbuf(struct mbuf *);
-#endif /*_KERNEL*/
-
-struct sockaddr;
-extern void kdebug_sockaddr(struct sockaddr *);
-
-extern void ipsec_hexdump(caddr_t, int);
-extern void ipsec_bindump(caddr_t, int);
-
-#endif /* _NETKEY_KEY_DEBUG_H_ */
--- sys/netkey/key.c
+++ /dev/null
@@ -1,7649 +0,0 @@
-/*	$KAME: key.c,v 1.308 2003/09/07 20:35:59 itojun Exp $	*/
-
-/*-
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netkey/key.c,v 1.71.2.2 2005/11/04 20:26:16 ume Exp $");
-
-/*
- * This code is referd to RFC 2367
- */
-
-#include "opt_inet.h"
-#include "opt_inet6.h"
-#include "opt_ipsec.h"
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/kernel.h>
-#include <sys/mbuf.h>
-#include <sys/domain.h>
-#include <sys/protosw.h>
-#include <sys/malloc.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/sysctl.h>
-#include <sys/errno.h>
-#include <sys/proc.h>
-#include <sys/queue.h>
-#include <sys/syslog.h>
-
-#include <net/if.h>
-#include <net/route.h>
-#include <net/raw_cb.h>
-
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <netinet/in_var.h>
-
-#ifdef INET6
-#include <netinet/ip6.h>
-#include <netinet6/in6_var.h>
-#include <netinet6/ip6_var.h>
-#include <netinet6/scope6_var.h>
-#endif /* INET6 */
-
-#ifdef INET
-#include <netinet/in_pcb.h>
-#endif
-#ifdef INET6
-#include <netinet6/in6_pcb.h>
-#endif /* INET6 */
-
-#include <net/pfkeyv2.h>
-#include <netkey/keydb.h>
-#include <netkey/key.h>
-#include <netkey/keysock.h>
-#include <netkey/key_debug.h>
-
-#include <netinet6/ipsec.h>
-#ifdef INET6
-#include <netinet6/ipsec6.h>
-#endif
-#include <netinet6/ah.h>
-#ifdef INET6
-#include <netinet6/ah6.h>
-#endif
-#ifdef IPSEC_ESP
-#include <netinet6/esp.h>
-#ifdef INET6
-#include <netinet6/esp6.h>
-#endif
-#endif
-#include <netinet6/ipcomp.h>
-#ifdef INET6
-#include <netinet6/ipcomp6.h>
-#endif
-
-#include <machine/stdarg.h>
-
-/* randomness */
-#include <sys/random.h>
-
-#include <net/net_osdep.h>
-
-#ifndef satosin
-#define satosin(s) ((struct sockaddr_in *)s)
-#endif
-
-#define FULLMASK	0xff
-
-/*
- * Note on SA reference counting:
- * - SAs that are not in DEAD state will have (total external reference + 1)
- *   following value in reference count field.  they cannot be freed and are
- *   referenced from SA header.
- * - SAs that are in DEAD state will have (total external reference)
- *   in reference count field.  they are ready to be freed.  reference from
- *   SA header will be removed in keydb_delsecasvar(), when the reference count
- *   field hits 0 (= no external reference other than from SA header.
- */
-
-u_int32_t key_debug_level = 0;
-static u_int key_spi_trycnt = 1000;
-static u_int32_t key_spi_minval = 0x100;
-static u_int32_t key_spi_maxval = 0x0fffffff;	/* XXX */
-static u_int key_larval_lifetime = 30;	/* interval to expire acquiring, 30(s)*/
-static int key_blockacq_count = 10;	/* counter for blocking SADB_ACQUIRE.*/
-static int key_blockacq_lifetime = 20;	/* lifetime for blocking SADB_ACQUIRE.*/
-static int key_preferred_oldsa = 1;	/* preferred old sa rather than new sa.*/
-
-static u_int32_t acq_seq = 0;
-
-struct _satailq satailq;		/* list of all SAD entry */
-struct _sptailq sptailq;		/* SPD table + pcb */
-static LIST_HEAD(_sptree, secpolicy) sptree[IPSEC_DIR_MAX];	/* SPD table */
-static LIST_HEAD(_sahtree, secashead) sahtree;			/* SAD */
-static LIST_HEAD(_regtree, secreg) regtree[SADB_SATYPE_MAX + 1];
-							/* registed list */
-
-#define SPIHASHSIZE	128
-#define	SPIHASH(x)	(((x) ^ ((x) >> 16)) % SPIHASHSIZE)
-static LIST_HEAD(_spihash, secasvar) spihash[SPIHASHSIZE];
-
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-static LIST_HEAD(_acqtree, secacq) acqtree;		/* acquiring list */
-#endif
-static LIST_HEAD(_spacqtree, secspacq) spacqtree;	/* SP acquiring list */
-
-struct key_cb key_cb;
-
-/* search order for SAs */
-static const u_int saorder_state_valid_prefer_old[] = {
-	SADB_SASTATE_DYING, SADB_SASTATE_MATURE,
-};
-static const u_int saorder_state_valid_prefer_new[] = {
-	SADB_SASTATE_MATURE, SADB_SASTATE_DYING,
-};
-static const u_int saorder_state_alive[] = {
-	/* except DEAD */
-	SADB_SASTATE_MATURE, SADB_SASTATE_DYING, SADB_SASTATE_LARVAL
-};
-static const u_int saorder_state_any[] = {
-	SADB_SASTATE_MATURE, SADB_SASTATE_DYING,
-	SADB_SASTATE_LARVAL, SADB_SASTATE_DEAD
-};
-
-static const int minsize[] = {
-	sizeof(struct sadb_msg),	/* SADB_EXT_RESERVED */
-	sizeof(struct sadb_sa),		/* SADB_EXT_SA */
-	sizeof(struct sadb_lifetime),	/* SADB_EXT_LIFETIME_CURRENT */
-	sizeof(struct sadb_lifetime),	/* SADB_EXT_LIFETIME_HARD */
-	sizeof(struct sadb_lifetime),	/* SADB_EXT_LIFETIME_SOFT */
-	sizeof(struct sadb_address),	/* SADB_EXT_ADDRESS_SRC */
-	sizeof(struct sadb_address),	/* SADB_EXT_ADDRESS_DST */
-	sizeof(struct sadb_address),	/* SADB_EXT_ADDRESS_PROXY */
-	sizeof(struct sadb_key),	/* SADB_EXT_KEY_AUTH */
-	sizeof(struct sadb_key),	/* SADB_EXT_KEY_ENCRYPT */
-	sizeof(struct sadb_ident),	/* SADB_EXT_IDENTITY_SRC */
-	sizeof(struct sadb_ident),	/* SADB_EXT_IDENTITY_DST */
-	sizeof(struct sadb_sens),	/* SADB_EXT_SENSITIVITY */
-	sizeof(struct sadb_prop),	/* SADB_EXT_PROPOSAL */
-	sizeof(struct sadb_supported),	/* SADB_EXT_SUPPORTED_AUTH */
-	sizeof(struct sadb_supported),	/* SADB_EXT_SUPPORTED_ENCRYPT */
-	sizeof(struct sadb_spirange),	/* SADB_EXT_SPIRANGE */
-	0,				/* SADB_X_EXT_KMPRIVATE */
-	sizeof(struct sadb_x_policy),	/* SADB_X_EXT_POLICY */
-	sizeof(struct sadb_x_sa2),	/* SADB_X_SA2 */
-};
-static const int maxsize[] = {
-	sizeof(struct sadb_msg),	/* SADB_EXT_RESERVED */
-	sizeof(struct sadb_sa),		/* SADB_EXT_SA */
-	sizeof(struct sadb_lifetime),	/* SADB_EXT_LIFETIME_CURRENT */
-	sizeof(struct sadb_lifetime),	/* SADB_EXT_LIFETIME_HARD */
-	sizeof(struct sadb_lifetime),	/* SADB_EXT_LIFETIME_SOFT */
-	0,				/* SADB_EXT_ADDRESS_SRC */
-	0,				/* SADB_EXT_ADDRESS_DST */
-	0,				/* SADB_EXT_ADDRESS_PROXY */
-	0,				/* SADB_EXT_KEY_AUTH */
-	0,				/* SADB_EXT_KEY_ENCRYPT */
-	0,				/* SADB_EXT_IDENTITY_SRC */
-	0,				/* SADB_EXT_IDENTITY_DST */
-	0,				/* SADB_EXT_SENSITIVITY */
-	0,				/* SADB_EXT_PROPOSAL */
-	0,				/* SADB_EXT_SUPPORTED_AUTH */
-	0,				/* SADB_EXT_SUPPORTED_ENCRYPT */
-	sizeof(struct sadb_spirange),	/* SADB_EXT_SPIRANGE */
-	0,				/* SADB_X_EXT_KMPRIVATE */
-	0,				/* SADB_X_EXT_POLICY */
-	sizeof(struct sadb_x_sa2),	/* SADB_X_SA2 */
-};
-
-static int ipsec_esp_keymin = 256;
-#ifdef IPSEC_ESP
-static int ipsec_esp_auth = 0;
-#endif
-static int ipsec_ah_keymin = 128;
-
-SYSCTL_DECL(_net_key);
-
-SYSCTL_INT(_net_key, KEYCTL_DEBUG_LEVEL,	debug,	CTLFLAG_RW, \
-	&key_debug_level,	0,	"");
-
-/* max count of trial for the decision of spi value */
-SYSCTL_INT(_net_key, KEYCTL_SPI_TRY,		spi_trycnt,	CTLFLAG_RW, \
-	&key_spi_trycnt,	0,	"");
-
-/* minimum spi value to allocate automatically. */
-SYSCTL_INT(_net_key, KEYCTL_SPI_MIN_VALUE,	spi_minval,	CTLFLAG_RW, \
-	&key_spi_minval,	0,	"");
-
-/* maximun spi value to allocate automatically. */
-SYSCTL_INT(_net_key, KEYCTL_SPI_MAX_VALUE,	spi_maxval,	CTLFLAG_RW, \
-	&key_spi_maxval,	0,	"");
-
-/* lifetime for larval SA */
-SYSCTL_INT(_net_key, KEYCTL_LARVAL_LIFETIME,	larval_lifetime, CTLFLAG_RW, \
-	&key_larval_lifetime,	0,	"");
-
-/* counter for blocking to send SADB_ACQUIRE to IKEd */
-SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_COUNT,	blockacq_count,	CTLFLAG_RW, \
-	&key_blockacq_count,	0,	"");
-
-/* lifetime for blocking to send SADB_ACQUIRE to IKEd */
-SYSCTL_INT(_net_key, KEYCTL_BLOCKACQ_LIFETIME,	blockacq_lifetime, CTLFLAG_RW, \
-	&key_blockacq_lifetime,	0,	"");
-
-#ifdef IPSEC_ESP
-/* ESP auth */
-SYSCTL_INT(_net_key, KEYCTL_ESP_AUTH,	esp_auth, CTLFLAG_RW, \
-	&ipsec_esp_auth,	0,	"ESP auth");
-#endif
-
-/* minimum ESP key length */
-SYSCTL_INT(_net_key, KEYCTL_ESP_KEYMIN,	esp_keymin, CTLFLAG_RW, \
-	&ipsec_esp_keymin,	0,	"");
-
-/* minimum AH key length */
-SYSCTL_INT(_net_key, KEYCTL_AH_KEYMIN,	ah_keymin, CTLFLAG_RW, \
-	&ipsec_ah_keymin,	0,	"");
-
-/* perfered old SA rather than new SA */
-SYSCTL_INT(_net_key, KEYCTL_PREFERED_OLDSA,	preferred_oldsa, CTLFLAG_RW,\
-	&key_preferred_oldsa,	0,	"");
-
-#define __LIST_CHAINED(elm) \
-	(!((elm)->chain.le_next == NULL && (elm)->chain.le_prev == NULL))
-#define LIST_INSERT_TAIL(head, elm, type, field) \
-do {\
-	struct type *curelm = LIST_FIRST(head); \
-	if (curelm == NULL) {\
-		LIST_INSERT_HEAD(head, elm, field); \
-	} else { \
-		while (LIST_NEXT(curelm, field)) \
-			curelm = LIST_NEXT(curelm, field);\
-		LIST_INSERT_AFTER(curelm, elm, field);\
-	}\
-} while (/*CONSTCOND*/ 0)
-
-#define KEY_CHKSASTATE(head, sav, name) \
-do { \
-	if ((head) != (sav)) {						\
-		ipseclog((LOG_DEBUG, "%s: state mismatched (TREE=%u SA=%u)\n", \
-			(name), (head), (sav)));			\
-		continue;						\
-	}								\
-} while (/*CONSTCOND*/ 0)
-
-#define KEY_CHKSPDIR(head, sp, name) \
-do { \
-	if ((head) != (sp)) {						\
-		ipseclog((LOG_DEBUG, "%s: direction mismatched (TREE=%u SP=%u), " \
-			"anyway continue.\n",				\
-			(name), (head), (sp)));				\
-	}								\
-} while (/*CONSTCOND*/ 0)
-
-#if 1
-#define KMALLOC(p, t, n)                                                     \
-	((p) = (t) malloc((unsigned long)(n), M_SECA, M_NOWAIT))
-#define KFREE(p)                                                             \
-	free((caddr_t)(p), M_SECA)
-#else
-#define KMALLOC(p, t, n) \
-do { \
-	((p) = (t)malloc((unsigned long)(n), M_SECA, M_NOWAIT));             \
-	printf("%s %d: %p <- KMALLOC(%s, %d)\n",                             \
-		__FILE__, __LINE__, (p), #t, n);                             \
-} while (/*CONSTCOND*/ 0)
-
-#define KFREE(p)                                                             \
-	do {                                                                 \
-		printf("%s %d: %p -> KFREE()\n", __FILE__, __LINE__, (p));   \
-		free((caddr_t)(p), M_SECA);                                  \
-	} while (/*CONSTCOND*/ 0)
-#endif
-
-/*
- * set parameters into secpolicyindex buffer.
- * Must allocate secpolicyindex buffer passed to this function.
- */
-#define KEY_SETSECSPIDX(s, d, ps, pd, ulp, idx) \
-do { \
-	bzero((idx), sizeof(struct secpolicyindex));                             \
-	(idx)->prefs = (ps);                                                 \
-	(idx)->prefd = (pd);                                                 \
-	(idx)->ul_proto = (ulp);                                             \
-	bcopy((s), &(idx)->src, ((struct sockaddr *)(s))->sa_len);           \
-	bcopy((d), &(idx)->dst, ((struct sockaddr *)(d))->sa_len);           \
-} while (/*CONSTCOND*/ 0)
-
-/*
- * set parameters into secasindex buffer.
- * Must allocate secasindex buffer before calling this function.
- */
-#define KEY_SETSECASIDX(p, m, r, s, d, idx) \
-do { \
-	bzero((idx), sizeof(struct secasindex));                             \
-	(idx)->proto = (p);                                                  \
-	(idx)->mode = (m);                                                   \
-	(idx)->reqid = (r);                                                  \
-	bcopy((s), &(idx)->src, ((struct sockaddr *)(s))->sa_len);           \
-	bcopy((d), &(idx)->dst, ((struct sockaddr *)(d))->sa_len);           \
-} while (/*CONSTCOND*/ 0)
-
-/* key statistics */
-struct _keystat {
-	u_long getspi_count; /* the avarage of count to try to get new SPI */
-} keystat;
-
-struct sadb_msghdr {
-	struct sadb_msg *msg;
-	struct sadb_ext *ext[SADB_EXT_MAX + 1];
-	int extoff[SADB_EXT_MAX + 1];
-	int extlen[SADB_EXT_MAX + 1];
-};
-
-static struct secasvar *key_allocsa_policy(struct secasindex *);
-static struct secasvar *key_do_allocsa_policy(struct secashead *, u_int);
-static void key_delsav(struct secasvar *);
-static void key_delsp(struct secpolicy *);
-static struct secpolicy *key_getsp(struct secpolicyindex *, int);
-static struct secpolicy *key_getspbyid(u_int32_t);
-static u_int32_t key_newreqid(void);
-static struct mbuf *key_gather_mbuf(struct mbuf *,
-	const struct sadb_msghdr *, int, int, ...);
-static int key_spdadd(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_spddelete(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_spddelete2(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_spdget(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_spdflush(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_spddump(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static struct mbuf *key_setdumpsp(struct secpolicy *,
-	u_int8_t, u_int32_t, u_int32_t);
-static u_int key_getspreqmsglen(struct secpolicy *);
-static int key_spdexpire(struct secpolicy *);
-static struct secashead *key_newsah(struct secasindex *);
-static void key_delsah(struct secashead *);
-static struct secasvar *key_newsav(struct mbuf *,
-	const struct sadb_msghdr *, struct secashead *, int *);
-static struct secashead *key_getsah(struct secasindex *);
-static struct secasvar *key_checkspidup(struct secasindex *, u_int32_t);
-static void key_setspi(struct secasvar *, u_int32_t);
-static struct secasvar *key_getsavbyspi(struct secashead *, u_int32_t);
-static int key_setsaval(struct secasvar *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_mature(struct secasvar *);
-static struct mbuf *key_setdumpsa(struct secasvar *, u_int8_t,
-	u_int8_t, u_int32_t, u_int32_t);
-static struct mbuf *key_setsadbmsg(u_int8_t, u_int16_t, u_int8_t,
-	u_int32_t, pid_t, u_int16_t);
-static struct mbuf *key_setsadbsa(struct secasvar *);
-static struct mbuf *key_setsadbaddr(u_int16_t,
-	struct sockaddr *, u_int8_t, u_int16_t);
-#if 0
-static struct mbuf *key_setsadbident(u_int16_t, u_int16_t, caddr_t,
-	int, u_int64_t);
-#endif
-static struct mbuf *key_setsadbxsa2(u_int8_t, u_int32_t, u_int32_t);
-static struct mbuf *key_setsadblifetime(u_int16_t, u_int32_t,
-	u_int64_t, u_int64_t, u_int64_t);
-static struct mbuf *key_setsadbxpolicy(u_int16_t, u_int8_t,
-	u_int32_t);
-static void *key_newbuf(const void *, u_int);
-static int key_ismyaddr(struct sockaddr *);
-#ifdef INET6
-static int key_ismyaddr6(struct sockaddr_in6 *);
-#endif
-
-/* flags for key_cmpsaidx() */
-#define CMP_HEAD	1	/* protocol, addresses. */
-#define CMP_MODE_REQID	2	/* additionally HEAD, reqid, mode. */
-#define CMP_REQID	3	/* additionally HEAD, reqid. not used */
-#define CMP_EXACTLY	4	/* all elements. */
-static int key_cmpsaidx(struct secasindex *, struct secasindex *, int);
-
-static int key_sockaddrcmp(struct sockaddr *, struct sockaddr *, int);
-static int key_bbcmp(caddr_t, caddr_t, u_int);
-static u_long key_random(void);
-static u_int16_t key_satype2proto(u_int8_t);
-static u_int8_t key_proto2satype(u_int16_t);
-
-static int key_getspi(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static u_int32_t key_do_getnewspi(struct sadb_spirange *,
-					struct secasindex *);
-static int key_update(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-#ifdef IPSEC_DOSEQCHECK
-static struct secasvar *key_getsavbyseq(struct secashead *, u_int32_t);
-#endif
-static int key_add(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_setident(struct secashead *, struct mbuf *,
-	const struct sadb_msghdr *);
-static struct mbuf *key_getmsgbuf_x1(struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_delete(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_get(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-
-static void key_getcomb_setlifetime(struct sadb_comb *);
-#ifdef IPSEC_ESP
-static struct mbuf *key_getcomb_esp(void);
-#endif
-static struct mbuf *key_getcomb_ah(void);
-static struct mbuf *key_getcomb_ipcomp(void);
-static struct mbuf *key_getprop(const struct secasindex *);
-
-static int key_acquire(struct secasindex *, struct secpolicy *);
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-static struct secacq *key_newacq(struct secasindex *);
-static struct secacq *key_getacq(struct secasindex *);
-static struct secacq *key_getacqbyseq(u_int32_t);
-#endif
-static struct secspacq *key_newspacq(struct secpolicyindex *);
-static struct secspacq *key_getspacq(struct secpolicyindex *);
-static int key_acquire2(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_register(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_expire(struct secasvar *);
-static int key_flush(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_dump(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_promisc(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *);
-static int key_senderror(struct socket *, struct mbuf *, int);
-static int key_validate_ext(struct sadb_ext *, int);
-static int key_align(struct mbuf *, struct sadb_msghdr *);
-#if 0
-static const char *key_getfqdn(void);
-static const char *key_getuserfqdn(void);
-#endif
-static void key_sa_chgstate(struct secasvar *, u_int8_t);
-static void key_sp_dead(struct secpolicy *);
-static void key_sp_unlink(struct secpolicy *);
-static struct mbuf *key_alloc_mbuf(int);
-static struct callout key_timehandler_ch;
-
-/* %%% IPsec policy management */
-/*
- * allocating a SP for OUTBOUND or INBOUND packet.
- * Must call key_freesp() later.
- * OUT:	NULL:	not found
- *	others:	found and return the pointer.
- */
-struct secpolicy *
-key_allocsp(tag, spidx, dir)
-	u_int16_t tag;
-	struct secpolicyindex *spidx;
-	u_int dir;
-{
-	struct secpolicy *sp;
-	int s;
-
-	/* check direction */
-	switch (dir) {
-	case IPSEC_DIR_INBOUND:
-	case IPSEC_DIR_OUTBOUND:
-		break;
-	default:
-		panic("key_allocsp: Invalid direction is passed.");
-	}
-
-	/* get a SP entry */
-	s = splnet();	/*called from softclock()*/
-	if (spidx) {
-		KEYDEBUG(KEYDEBUG_IPSEC_DATA,
-			printf("*** objects\n");
-			kdebug_secpolicyindex(spidx));
-	}
-
-	LIST_FOREACH(sp, &sptree[dir], chain) {
-		if (sp->state == IPSEC_SPSTATE_DEAD)
-			continue;
-		if (sp->spidx) {
-			if (!spidx)
-				continue;
-
-			KEYDEBUG(KEYDEBUG_IPSEC_DATA,
-				printf("*** in SPD\n");
-				kdebug_secpolicyindex(sp->spidx));
-
-			if (key_cmpspidx_withmask(sp->spidx, spidx))
-				goto found;
-		}
-	}
-
-	splx(s);
-	return NULL;
-
-found:
-	/* sanity check */
-	KEY_CHKSPDIR(sp->dir, dir, "key_allocsp");
-
-	/* found a SPD entry */
-	sp->lastused = time_second;
-	sp->refcnt++;
-	splx(s);
-	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-		printf("DP key_allocsp cause refcnt++:%d SP:%p\n",
-			sp->refcnt, sp));
-
-	return sp;
-}
-
-/*
- * return a policy that matches this particular inbound packet.
- * XXX slow
- */
-struct secpolicy *
-key_gettunnel(osrc, odst, isrc, idst)
-	struct sockaddr *osrc, *odst, *isrc, *idst;
-{
-	struct secpolicy *sp;
-	const int dir = IPSEC_DIR_INBOUND;
-	int s;
-	struct ipsecrequest *r1, *r2, *p;
-	struct sockaddr *os, *od, *is, *id;
-	struct secpolicyindex spidx;
-
-	if (isrc->sa_family != idst->sa_family) {
-		ipseclog((LOG_ERR, "protocol family mismatched %u != %u\n",
-			isrc->sa_family, idst->sa_family));
-		return NULL;
-	}
-
-	s = splnet();	/*called from softclock()*/
-	LIST_FOREACH(sp, &sptree[dir], chain) {
-		if (sp->state == IPSEC_SPSTATE_DEAD)
-			continue;
-
-		r1 = r2 = NULL;
-		for (p = sp->req; p; p = p->next) {
-			if (p->saidx.mode != IPSEC_MODE_TUNNEL)
-				continue;
-
-			r1 = r2;
-			r2 = p;
-
-			if (!r1) {
-				if (sp->spidx) {
-					/*
-					 * here we look at address matches
-					 * only
-					 */
-					spidx = *sp->spidx;
-					if (isrc->sa_len > sizeof(spidx.src) ||
-					    idst->sa_len > sizeof(spidx.dst))
-						continue;
-					bcopy(isrc, &spidx.src, isrc->sa_len);
-					bcopy(idst, &spidx.dst, idst->sa_len);
-					if (!key_cmpspidx_withmask(sp->spidx,
-					    &spidx))
-						continue;
-				} else
-					; /* can't check for tagged policy */
-			} else {
-				is = (struct sockaddr *)&r1->saidx.src;
-				id = (struct sockaddr *)&r1->saidx.dst;
-				if (key_sockaddrcmp(is, isrc, 0) ||
-				    key_sockaddrcmp(id, idst, 0))
-					continue;
-			}
-
-			os = (struct sockaddr *)&r2->saidx.src;
-			od = (struct sockaddr *)&r2->saidx.dst;
-			if (key_sockaddrcmp(os, osrc, 0) ||
-			    key_sockaddrcmp(od, odst, 0))
-				continue;
-
-			goto found;
-		}
-	}
-	splx(s);
-	return NULL;
-
-found:
-	sp->lastused = time_second;
-	sp->refcnt++;
-	splx(s);
-	return sp;
-}
-
-/*
- * allocating an SA entry for an *OUTBOUND* packet.
- * checking each request entries in SP, and acquire an SA if need.
- * OUT:	0: there are valid requests.
- *	ENOENT: policy may be valid, but SA with REQUIRE is on acquiring.
- */
-int
-key_checkrequest(isr, saidx)
-	struct ipsecrequest *isr;
-	struct secasindex *saidx;
-{
-	u_int level;
-	int error;
-
-	/* sanity check */
-	if (isr == NULL || saidx == NULL)
-		panic("key_checkrequest: NULL pointer is passed.");
-
-	/* check mode */
-	switch (saidx->mode) {
-	case IPSEC_MODE_TRANSPORT:
-	case IPSEC_MODE_TUNNEL:
-		break;
-	case IPSEC_MODE_ANY:
-	default:
-		panic("key_checkrequest: Invalid policy defined.");
-	}
-
-	/* get current level */
-	level = ipsec_get_reqlevel(isr, saidx->src.ss_family);
-
-#if 0
-	/*
-	 * We do allocate new SA only if the state of SA in the holder is
-	 * SADB_SASTATE_DEAD.  The SA for outbound must be the oldest.
-	 */
-	if (isr->sav != NULL) {
-		if (isr->sav->sah == NULL)
-			panic("key_checkrequest: sah is null.");
-		if (isr->sav ==
-		    LIST_FIRST(&isr->sav->sah->savtree[SADB_SASTATE_DEAD])) {
-			KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-				printf("DP checkrequest calls free SA:%p\n",
-					isr->sav));
-			key_freesav(isr->sav);
-			isr->sav = NULL;
-		}
-	}
-#else
-	/*
-	 * we free any SA stashed in the IPsec request because a different
-	 * SA may be involved each time this request is checked, either
-	 * because new SAs are being configured, or this request is
-	 * associated with an unconnected datagram socket, or this request
-	 * is associated with a system default policy.
-	 *
-	 * The operation may have negative impact to performance.  We may
-	 * want to check cached SA carefully, rather than picking new SA
-	 * every time.
-	 */
-	if (isr->sav != NULL) {
-		key_freesav(isr->sav);
-		isr->sav = NULL;
-	}
-#endif
-
-	/*
-	 * new SA allocation if no SA found.
-	 * key_allocsa_policy should allocate the oldest SA available.
-	 * See key_do_allocsa_policy(), and draft-jenkins-ipsec-rekeying-03.txt.
-	 */
-	if (isr->sav == NULL)
-		isr->sav = key_allocsa_policy(saidx);
-
-	/* When there is SA. */
-	if (isr->sav != NULL)
-		return 0;
-
-	/* there is no SA */
-	if ((error = key_acquire(saidx, isr->sp)) != 0) {
-		/* XXX What should I do ? */
-		ipseclog((LOG_DEBUG, "key_checkrequest: error %d returned "
-			"from key_acquire.\n", error));
-		return error;
-	}
-
-	return level == IPSEC_LEVEL_REQUIRE ? ENOENT : 0;
-}
-
-/*
- * allocating a SA for policy entry from SAD.
- * NOTE: searching SAD of aliving state.
- * OUT:	NULL:	not found.
- *	others:	found and return the pointer.
- */
-static struct secasvar *
-key_allocsa_policy(saidx)
-	struct secasindex *saidx;
-{
-	struct secashead *sah;
-	struct secasvar *sav;
-	u_int stateidx, state;
-	const u_int *saorder_state_valid;
-	int arraysize;
-
-	LIST_FOREACH(sah, &sahtree, chain) {
-		if (sah->state == SADB_SASTATE_DEAD)
-			continue;
-		if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID))
-			goto found;
-	}
-
-	return NULL;
-
-    found:
-
-	/*
-	 * search a valid state list for outbound packet.
-	 * This search order is important.
-	 */
-	if (key_preferred_oldsa) {
-		saorder_state_valid = saorder_state_valid_prefer_old;
-		arraysize = _ARRAYLEN(saorder_state_valid_prefer_old);
-	} else {
-		saorder_state_valid = saorder_state_valid_prefer_new;
-		arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
-	}
-
-	for (stateidx = 0; stateidx < arraysize; stateidx++) {
-
-		state = saorder_state_valid[stateidx];
-
-		sav = key_do_allocsa_policy(sah, state);
-		if (sav != NULL)
-			return sav;
-	}
-
-	return NULL;
-}
-
-/*
- * searching SAD with direction, protocol, mode and state.
- * called by key_allocsa_policy().
- * OUT:
- *	NULL	: not found
- *	others	: found, pointer to a SA.
- */
-static struct secasvar *
-key_do_allocsa_policy(sah, state)
-	struct secashead *sah;
-	u_int state;
-{
-	struct secasvar *sav, *nextsav, *candidate, *d;
-
-	/* initilize */
-	candidate = NULL;
-
-	for (sav = LIST_FIRST(&sah->savtree[state]);
-	     sav != NULL;
-	     sav = nextsav) {
-
-		nextsav = LIST_NEXT(sav, chain);
-
-		/* sanity check */
-		KEY_CHKSASTATE(sav->state, state, "key_do_allocsa_policy");
-
-		/* initialize */
-		if (candidate == NULL) {
-			candidate = sav;
-			continue;
-		}
-
-		/* Which SA is the better ? */
-
-		/* sanity check 2 */
-		if (candidate->lft_c == NULL || sav->lft_c == NULL)
-			panic("key_do_allocsa_policy: "
-				"lifetime_current is NULL.");
-
-		/* What the best method is to compare ? */
-		if (key_preferred_oldsa) {
-			if (candidate->lft_c->sadb_lifetime_addtime >
-					sav->lft_c->sadb_lifetime_addtime) {
-				candidate = sav;
-			}
-			continue;
-			/*NOTREACHED*/
-		}
-
-		/* preferred new sa rather than old sa */
-		if (candidate->lft_c->sadb_lifetime_addtime <
-				sav->lft_c->sadb_lifetime_addtime) {
-			d = candidate;
-			candidate = sav;
-		} else
-			d = sav;
-
-		/*
-		 * prepared to delete the SA when there is more
-		 * suitable candidate and the lifetime of the SA is not
-		 * permanent.
-		 */
-		if (d->lft_c->sadb_lifetime_addtime != 0) {
-			struct mbuf *m, *result = NULL;
-
-			key_sa_chgstate(d, SADB_SASTATE_DEAD);
-
-			m = key_setsadbmsg(SADB_DELETE, 0,
-			    key_proto2satype(d->sah->saidx.proto),
-			    0, 0, d->refcnt - 1);
-			if (!m)
-				goto msgfail;
-			result = m;
-
-			/* set sadb_address for saidx's. */
-			m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
-				(struct sockaddr *)&d->sah->saidx.src,
-				FULLMASK, IPSEC_ULPROTO_ANY);
-			if (!m)
-				goto msgfail;
-			m_cat(result, m);
-
-			/* set sadb_address for saidx's. */
-			m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
-				(struct sockaddr *)&d->sah->saidx.dst,
-				FULLMASK, IPSEC_ULPROTO_ANY);
-			if (!m)
-				goto msgfail;
-			m_cat(result, m);
-
-			/* create SA extension */
-			m = key_setsadbsa(d);
-			if (!m)
-				goto msgfail;
-			m_cat(result, m);
-
-			if (result->m_len < sizeof(struct sadb_msg)) {
-				result = m_pullup(result,
-						sizeof(struct sadb_msg));
-				if (result == NULL)
-					goto msgfail;
-			}
-
-			result->m_pkthdr.len = 0;
-			for (m = result; m; m = m->m_next)
-				result->m_pkthdr.len += m->m_len;
-			mtod(result, struct sadb_msg *)->sadb_msg_len =
-				PFKEY_UNIT64(result->m_pkthdr.len);
-
-			if (key_sendup_mbuf(NULL, result,
-					KEY_SENDUP_REGISTERED))
-				goto msgfail;
-
-			result = NULL;
-
-		 msgfail:
-			if (result != NULL)
-				m_freem(result);
-			key_freesav(d);
-		}
-	}
-
-	if (candidate) {
-		candidate->refcnt++;
-		KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-			printf("DP allocsa_policy cause "
-				"refcnt++:%d SA:%p\n",
-				candidate->refcnt, candidate));
-	}
-	return candidate;
-}
-
-/*
- * allocating a SA entry for a *INBOUND* packet.
- * Must call key_freesav() later.
- * OUT: positive:	pointer to a sav.
- *	NULL:		not found, or error occured.
- *
- * In the comparison, source address will be ignored for RFC2401 conformance.
- * To quote, from section 4.1:
- *	A security association is uniquely identified by a triple consisting
- *	of a Security Parameter Index (SPI), an IP Destination Address, and a
- *	security protocol (AH or ESP) identifier.
- * Note that, however, we do need to keep source address in IPsec SA.
- * IKE specification and PF_KEY specification do assume that we
- * keep source address in IPsec SA.  We see a tricky situation here.
- */
-struct secasvar *
-key_allocsa(family, src, dst, proto, spi)
-	u_int family, proto;
-	caddr_t src, dst;
-	u_int32_t spi;
-{
-	struct secasvar *sav, *match;
-	u_int stateidx, state, tmpidx, matchidx;
-	struct sockaddr_in sin;
-#ifdef INET6
-	struct sockaddr_in6 sin6;
-#endif
-	int s;
-	const u_int *saorder_state_valid;
-	int arraysize;
-
-	/* sanity check */
-	if (src == NULL || dst == NULL)
-		panic("key_allocsa: NULL pointer is passed.");
-
-	/*
-	 * when both systems employ similar strategy to use a SA.
-	 * the search order is important even in the inbound case.
-	 */
-	if (key_preferred_oldsa) {
-		saorder_state_valid = saorder_state_valid_prefer_old;
-		arraysize = _ARRAYLEN(saorder_state_valid_prefer_old);
-	} else {
-		saorder_state_valid = saorder_state_valid_prefer_new;
-		arraysize = _ARRAYLEN(saorder_state_valid_prefer_new);
-	}
-
-	bzero(&sin, sizeof(sin));
-	sin.sin_family = AF_INET;
-	sin.sin_len = sizeof(sin);
-#ifdef INET6
-	bzero(&sin6, sizeof(sin6));
-	sin6.sin6_family = AF_INET6;
-	sin6.sin6_len = sizeof(sin6);
-#endif
-
-	/*
-	 * searching SAD.
-	 * XXX: to be checked internal IP header somewhere.  Also when
-	 * IPsec tunnel packet is received.  But ESP tunnel mode is
-	 * encrypted so we can't check internal IP header.
-	 */
-	s = splnet();	/*called from softclock()*/
-	/*
-	 * search a valid state list for inbound packet.
-	 * the search order is not important.
-	 */
-	match = NULL;
-	matchidx = arraysize;
-	LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) {
-		if (sav->spi != spi)
-			continue;
-		if (proto != sav->sah->saidx.proto)
-			continue;
-		if (family != sav->sah->saidx.src.ss_family ||
-		    family != sav->sah->saidx.dst.ss_family)
-			continue;
-		tmpidx = arraysize;
-		for (stateidx = 0; stateidx < matchidx; stateidx++) {
-			state = saorder_state_valid[stateidx];
-			if (sav->state == state) {
-				tmpidx = stateidx;
-				break;
-			}
-		}
-		if (tmpidx >= matchidx)
-			continue;
-
-#if 0	/* don't check src */
-		/* check src address */
-		switch (family) {
-		case AF_INET:
-			bcopy(src, &sin.sin_addr, sizeof(sin.sin_addr));
-			if (key_sockaddrcmp((struct sockaddr*)&sin,
-			    (struct sockaddr *)&sav->sah->saidx.src, 0) != 0)
-				continue;
-
-			break;
-#ifdef INET6
-		case AF_INET6:
-			bcopy(src, &sin6.sin6_addr, sizeof(sin6.sin6_addr));
-			sin6.sin6_scope_id = 0;
-			if (sa6_recoverscope(&sin6))
-				continue;
-			if (key_sockaddrcmp((struct sockaddr *)&sin6,
-			    (struct sockaddr *)&sav->sah->saidx.src, 0) != 0)
-				continue;
-			break;
-#endif
-		default:
-			ipseclog((LOG_DEBUG, "key_allocsa: "
-			    "unknown address family=%d.\n",
-			    family));
-			continue;
-		}
-
-#endif
-		/* check dst address */
-		switch (family) {
-		case AF_INET:
-			bcopy(dst, &sin.sin_addr, sizeof(sin.sin_addr));
-			if (key_sockaddrcmp((struct sockaddr*)&sin,
-			    (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0)
-				continue;
-
-			break;
-#ifdef INET6
-		case AF_INET6:
-			bcopy(dst, &sin6.sin6_addr, sizeof(sin6.sin6_addr));
-			sin6.sin6_scope_id = 0;
-			if (sa6_recoverscope(&sin6))
-				continue;
-			if (key_sockaddrcmp((struct sockaddr *)&sin6,
-			    (struct sockaddr *)&sav->sah->saidx.dst, 0) != 0)
-				continue;
-			break;
-#endif
-		default:
-			ipseclog((LOG_DEBUG, "key_allocsa: "
-			    "unknown address family=%d.\n", family));
-			continue;
-		}
-
-		match = sav;
-		matchidx = tmpidx;
-	}
-
-	if (match)
-		goto found;
-
-	/* not found */
-	splx(s);
-	return NULL;
-
-found:
-	match->refcnt++;
-	splx(s);
-	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-		printf("DP allocsa cause refcnt++:%d SA:%p\n",
-			match->refcnt, match));
-	return match;
-}
-
-/*
- * Must be called after calling key_allocsp().
- * For both the packet without socket and key_freeso().
- */
-void
-key_freesp(sp)
-	struct secpolicy *sp;
-{
-	/* sanity check */
-	if (sp == NULL)
-		panic("key_freesp: NULL pointer is passed.");
-
-	sp->refcnt--;
-	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-		printf("DP freesp cause refcnt--:%d SP:%p\n",
-			sp->refcnt, sp));
-
-	if (sp->refcnt == 0)
-		key_delsp(sp);
-
-	return;
-}
-
-/*
- * Must be called after calling key_allocsa().
- * This function is called by key_freesp() to free some SA allocated
- * for a policy.
- */
-void
-key_freesav(sav)
-	struct secasvar *sav;
-{
-	/* sanity check */
-	if (sav == NULL)
-		panic("key_freesav: NULL pointer is passed.");
-
-	sav->refcnt--;
-	KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-		printf("DP freesav cause refcnt--:%d SA:%p SPI %u\n",
-			sav->refcnt, sav, (u_int32_t)ntohl(sav->spi)));
-
-	if (sav->refcnt > 0)
-		return;
-
-	key_delsav(sav);
-}
-
-static void
-key_delsav(sav)
-	struct secasvar *sav;
-{
-	int s;
-
-	/* sanity check */
-	if (sav == NULL)
-		panic("key_delsav: NULL pointer is passed.");
-
-	if (sav->refcnt > 0)
-		panic("key_delsav: called with positive refcnt");
-
-	s = splnet();
-
-	if (__LIST_CHAINED(sav))
-		LIST_REMOVE(sav, chain);
-
-	if (sav->spihash.le_prev || sav->spihash.le_next)
-		LIST_REMOVE(sav, spihash);
-
-	if (sav->key_auth != NULL) {
-		bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
-		KFREE(sav->key_auth);
-		sav->key_auth = NULL;
-	}
-	if (sav->key_enc != NULL) {
-		bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc));
-		KFREE(sav->key_enc);
-		sav->key_enc = NULL;
-	}
-	if (sav->sched) {
-		bzero(sav->sched, sav->schedlen);
-		KFREE(sav->sched);
-		sav->sched = NULL;
-	}
-	if (sav->replay != NULL) {
-		keydb_delsecreplay(sav->replay);
-		sav->replay = NULL;
-	}
-	if (sav->lft_c != NULL) {
-		KFREE(sav->lft_c);
-		sav->lft_c = NULL;
-	}
-	if (sav->lft_h != NULL) {
-		KFREE(sav->lft_h);
-		sav->lft_h = NULL;
-	}
-	if (sav->lft_s != NULL) {
-		KFREE(sav->lft_s);
-		sav->lft_s = NULL;
-	}
-	if (sav->iv != NULL) {
-		KFREE(sav->iv);
-		sav->iv = NULL;
-	}
-
-	keydb_delsecasvar(sav);
-
-	splx(s);
-}
-
-/* %%% SPD management */
-/*
- * free security policy entry.
- */
-static void
-key_delsp(sp)
-	struct secpolicy *sp;
-{
-	int s;
-
-	/* sanity check */
-	if (sp == NULL)
-		panic("key_delsp: NULL pointer is passed.");
-
-	if (sp->refcnt > 0)
-		panic("key_delsp: called with positive refcnt");
-
-	s = splnet();	/*called from softclock()*/
-
-    {
-	struct ipsecrequest *isr = sp->req, *nextisr;
-
-	while (isr != NULL) {
-		if (isr->sav != NULL) {
-			KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-				printf("DP delsp calls free SA:%p\n",
-					isr->sav));
-			key_freesav(isr->sav);
-			isr->sav = NULL;
-		}
-
-		nextisr = isr->next;
-		KFREE(isr);
-		isr = nextisr;
-	}
-    }
-
-	keydb_delsecpolicy(sp);
-
-	splx(s);
-
-	return;
-}
-
-/*
- * search SPD
- * OUT:	NULL	: not found
- *	others	: found, pointer to a SP.
- */
-static struct secpolicy *
-key_getsp(spidx, dir)
-	struct secpolicyindex *spidx;
-	int dir;
-{
-	struct secpolicy *sp;
-
-	/* sanity check */
-	if (spidx == NULL)
-		panic("key_getsp: NULL pointer is passed.");
-
-	LIST_FOREACH(sp, &sptree[dir], chain) {
-		if (sp->state == IPSEC_SPSTATE_DEAD)
-			continue;
-		if (!sp->spidx)
-			continue;
-		if (key_cmpspidx_exactly(spidx, sp->spidx)) {
-			sp->refcnt++;
-			return sp;
-		}
-	}
-
-	return NULL;
-}
-
-/*
- * get SP by index.
- * OUT:	NULL	: not found
- *	others	: found, pointer to a SP.
- */
-static struct secpolicy *
-key_getspbyid(id)
-	u_int32_t id;
-{
-	struct secpolicy *sp;
-
-	TAILQ_FOREACH(sp, &sptailq, tailq) {
-		if (sp->id == id) {
-			sp->refcnt++;
-			return sp;
-		}
-	}
-
-	return NULL;
-}
-
-struct secpolicy *
-key_newsp(id)
-	u_int32_t id;
-{
-	struct secpolicy *newsp = NULL, *sp;
-	u_int32_t newid;
-
-	if (id > IPSEC_MANUAL_POLICYID_MAX) {
-		ipseclog((LOG_DEBUG,
-		    "key_newsp: policy_id=%u range "
-		    "violation, updated by kernel.\n", id));
-		id = 0;
-	}
-
-	if (id == 0) {
-		if ((newid = keydb_newspid()) == 0) {
-			ipseclog((LOG_DEBUG, 
-			    "key_newsp: new policy_id allocation failed."));
-			return NULL;
-		}
-	} else {
-		sp = key_getspbyid(id);
-		if (sp != NULL) {
-			ipseclog((LOG_DEBUG,
-			    "key_newsp: policy_id(%u) has been used.\n", id));
-			key_freesp(sp);
-			return NULL;
-		}
-		newid = id;
-	}
-
-	newsp = keydb_newsecpolicy();
-	if (!newsp)
-		return newsp;
-
-	newsp->id = newid;
-	newsp->refcnt = 1;
-	newsp->req = NULL;
-
-	return newsp;
-}
-
-/*
- * create secpolicy structure from sadb_x_policy structure.
- * NOTE: `state', `secpolicyindex' in secpolicy structure are not set,
- * so must be set properly later.
- */
-struct secpolicy *
-key_msg2sp(xpl0, len, error)
-	struct sadb_x_policy *xpl0;
-	size_t len;
-	int *error;
-{
-	struct secpolicy *newsp;
-
-	/* sanity check */
-	if (xpl0 == NULL)
-		panic("key_msg2sp: NULL pointer was passed.");
-	if (len < sizeof(*xpl0))
-		panic("key_msg2sp: invalid length.");
-	if (len != PFKEY_EXTLEN(xpl0)) {
-		ipseclog((LOG_DEBUG, "key_msg2sp: Invalid msg length.\n"));
-		*error = EINVAL;
-		return NULL;
-	}
-
-	if ((newsp = key_newsp(xpl0->sadb_x_policy_id)) == NULL) {
-		*error = ENOBUFS;
-		return NULL;
-	}
-
-	newsp->dir = xpl0->sadb_x_policy_dir;
-	newsp->policy = xpl0->sadb_x_policy_type;
-
-	/* check policy */
-	switch (xpl0->sadb_x_policy_type) {
-	case IPSEC_POLICY_DISCARD:
-	case IPSEC_POLICY_NONE:
-	case IPSEC_POLICY_ENTRUST:
-	case IPSEC_POLICY_BYPASS:
-		newsp->req = NULL;
-		break;
-
-	case IPSEC_POLICY_IPSEC:
-	    {
-		int tlen;
-		struct sadb_x_ipsecrequest *xisr;
-		struct ipsecrequest **p_isr = &newsp->req;
-
-		/* validity check */
-		if (PFKEY_EXTLEN(xpl0) < sizeof(*xpl0)) {
-			ipseclog((LOG_DEBUG,
-			    "key_msg2sp: Invalid msg length.\n"));
-			key_freesp(newsp);
-			*error = EINVAL;
-			return NULL;
-		}
-
-		tlen = PFKEY_EXTLEN(xpl0) - sizeof(*xpl0);
-		xisr = (struct sadb_x_ipsecrequest *)(xpl0 + 1);
-
-		while (tlen > 0) {
-
-			/* length check */
-			if (xisr->sadb_x_ipsecrequest_len < sizeof(*xisr)) {
-				ipseclog((LOG_DEBUG, "key_msg2sp: "
-					"invalid ipsecrequest length.\n"));
-				key_freesp(newsp);
-				*error = EINVAL;
-				return NULL;
-			}
-
-			/* allocate request buffer */
-			KMALLOC(*p_isr, struct ipsecrequest *, sizeof(**p_isr));
-			if ((*p_isr) == NULL) {
-				ipseclog((LOG_DEBUG,
-				    "key_msg2sp: No more memory.\n"));
-				key_freesp(newsp);
-				*error = ENOBUFS;
-				return NULL;
-			}
-			bzero(*p_isr, sizeof(**p_isr));
-
-			/* set values */
-			(*p_isr)->next = NULL;
-
-			switch (xisr->sadb_x_ipsecrequest_proto) {
-			case IPPROTO_ESP:
-			case IPPROTO_AH:
-			case IPPROTO_IPCOMP:
-				break;
-			default:
-				ipseclog((LOG_DEBUG,
-				    "key_msg2sp: invalid proto type=%u\n",
-				    xisr->sadb_x_ipsecrequest_proto));
-				key_freesp(newsp);
-				*error = EPROTONOSUPPORT;
-				return NULL;
-			}
-			(*p_isr)->saidx.proto = xisr->sadb_x_ipsecrequest_proto;
-
-			switch (xisr->sadb_x_ipsecrequest_mode) {
-			case IPSEC_MODE_TRANSPORT:
-			case IPSEC_MODE_TUNNEL:
-				break;
-			case IPSEC_MODE_ANY:
-			default:
-				ipseclog((LOG_DEBUG,
-				    "key_msg2sp: invalid mode=%u\n",
-				    xisr->sadb_x_ipsecrequest_mode));
-				key_freesp(newsp);
-				*error = EINVAL;
-				return NULL;
-			}
-			(*p_isr)->saidx.mode = xisr->sadb_x_ipsecrequest_mode;
-
-			switch (xisr->sadb_x_ipsecrequest_level) {
-			case IPSEC_LEVEL_DEFAULT:
-			case IPSEC_LEVEL_USE:
-			case IPSEC_LEVEL_REQUIRE:
-				break;
-			case IPSEC_LEVEL_UNIQUE:
-				/* validity check */
-				/*
-				 * If range violation of reqid, kernel will
-				 * update it, don't refuse it.
-				 */
-				if (xisr->sadb_x_ipsecrequest_reqid
-						> IPSEC_MANUAL_REQID_MAX) {
-					ipseclog((LOG_DEBUG,
-					    "key_msg2sp: reqid=%u range "
-					    "violation, updated by kernel.\n",
-					    xisr->sadb_x_ipsecrequest_reqid));
-					xisr->sadb_x_ipsecrequest_reqid = 0;
-				}
-
-				/* allocate new reqid id if reqid is zero. */
-				if (xisr->sadb_x_ipsecrequest_reqid == 0) {
-					u_int32_t reqid;
-					if ((reqid = key_newreqid()) == 0) {
-						key_freesp(newsp);
-						*error = ENOBUFS;
-						return NULL;
-					}
-					(*p_isr)->saidx.reqid = reqid;
-					xisr->sadb_x_ipsecrequest_reqid = reqid;
-				} else {
-				/* set it for manual keying. */
-					(*p_isr)->saidx.reqid =
-						xisr->sadb_x_ipsecrequest_reqid;
-				}
-				break;
-
-			default:
-				ipseclog((LOG_DEBUG, "key_msg2sp: invalid level=%u\n",
-					xisr->sadb_x_ipsecrequest_level));
-				key_freesp(newsp);
-				*error = EINVAL;
-				return NULL;
-			}
-			(*p_isr)->level = xisr->sadb_x_ipsecrequest_level;
-
-			/* set IP addresses if there */
-			if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
-				struct sockaddr *paddr;
-
-				paddr = (struct sockaddr *)(xisr + 1);
-
-				/* validity check */
-				if (paddr->sa_len
-				    > sizeof((*p_isr)->saidx.src)) {
-					ipseclog((LOG_DEBUG, "key_msg2sp: invalid request "
-						"address length.\n"));
-					key_freesp(newsp);
-					*error = EINVAL;
-					return NULL;
-				}
-				bcopy(paddr, &(*p_isr)->saidx.src,
-					paddr->sa_len);
-
-				paddr = (struct sockaddr *)((caddr_t)paddr
-							+ paddr->sa_len);
-
-				/* validity check */
-				if (paddr->sa_len
-				    > sizeof((*p_isr)->saidx.dst)) {
-					ipseclog((LOG_DEBUG, "key_msg2sp: invalid request "
-						"address length.\n"));
-					key_freesp(newsp);
-					*error = EINVAL;
-					return NULL;
-				}
-				bcopy(paddr, &(*p_isr)->saidx.dst,
-					paddr->sa_len);
-			}
-
-			(*p_isr)->sav = NULL;
-			(*p_isr)->sp = newsp;
-
-			/* initialization for the next. */
-			p_isr = &(*p_isr)->next;
-			tlen -= xisr->sadb_x_ipsecrequest_len;
-
-			/* validity check */
-			if (tlen < 0) {
-				ipseclog((LOG_DEBUG, "key_msg2sp: becoming tlen < 0.\n"));
-				key_freesp(newsp);
-				*error = EINVAL;
-				return NULL;
-			}
-
-			xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
-			                 + xisr->sadb_x_ipsecrequest_len);
-		}
-	    }
-		break;
-	default:
-		ipseclog((LOG_DEBUG, "key_msg2sp: invalid policy type.\n"));
-		key_freesp(newsp);
-		*error = EINVAL;
-		return NULL;
-	}
-
-	*error = 0;
-	return newsp;
-}
-
-static u_int32_t
-key_newreqid()
-{
-	static u_int32_t auto_reqid = IPSEC_MANUAL_REQID_MAX + 1;
-
-	auto_reqid = (auto_reqid == ~0
-			? IPSEC_MANUAL_REQID_MAX + 1 : auto_reqid + 1);
-
-	/* XXX should be unique check */
-
-	return auto_reqid;
-}
-
-/*
- * copy secpolicy struct to sadb_x_policy structure indicated.
- */
-struct mbuf *
-key_sp2msg(sp)
-	struct secpolicy *sp;
-{
-	struct sadb_x_policy *xpl;
-	int tlen;
-	caddr_t p;
-	struct mbuf *m;
-
-	/* sanity check. */
-	if (sp == NULL)
-		panic("key_sp2msg: NULL pointer was passed.");
-
-	tlen = key_getspreqmsglen(sp);
-
-	m = key_alloc_mbuf(tlen);
-	if (!m || m->m_next) {	/*XXX*/
-		if (m)
-			m_freem(m);
-		return NULL;
-	}
-
-	m->m_len = tlen;
-	m->m_next = NULL;
-	xpl = mtod(m, struct sadb_x_policy *);
-	bzero(xpl, tlen);
-
-	xpl->sadb_x_policy_len = PFKEY_UNIT64(tlen);
-	xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
-	xpl->sadb_x_policy_type = sp->policy;
-	xpl->sadb_x_policy_dir = sp->dir;
-	xpl->sadb_x_policy_id = sp->id;
-	p = (caddr_t)xpl + sizeof(*xpl);
-
-	/* if is the policy for ipsec ? */
-	if (sp->policy == IPSEC_POLICY_IPSEC) {
-		struct sadb_x_ipsecrequest *xisr;
-		struct ipsecrequest *isr;
-
-		for (isr = sp->req; isr != NULL; isr = isr->next) {
-
-			xisr = (struct sadb_x_ipsecrequest *)p;
-
-			xisr->sadb_x_ipsecrequest_proto = isr->saidx.proto;
-			xisr->sadb_x_ipsecrequest_mode = isr->saidx.mode;
-			xisr->sadb_x_ipsecrequest_level = isr->level;
-			xisr->sadb_x_ipsecrequest_reqid = isr->saidx.reqid;
-
-			p += sizeof(*xisr);
-			bcopy(&isr->saidx.src, p, isr->saidx.src.ss_len);
-			p += isr->saidx.src.ss_len;
-			bcopy(&isr->saidx.dst, p, isr->saidx.dst.ss_len);
-			p += isr->saidx.src.ss_len;
-
-			xisr->sadb_x_ipsecrequest_len =
-			    PFKEY_ALIGN8(sizeof(*xisr) +
-			    isr->saidx.src.ss_len + isr->saidx.dst.ss_len);
-		}
-	}
-
-	return m;
-}
-
-/* m will not be freed nor modified */
-static struct mbuf *
-#ifdef __STDC__
-key_gather_mbuf(struct mbuf *m, const struct sadb_msghdr *mhp,
-	int ndeep, int nitem, ...)
-#else
-key_gather_mbuf(m, mhp, ndeep, nitem, va_alist)
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-	int ndeep;
-	int nitem;
-	va_dcl
-#endif
-{
-	va_list ap;
-	int idx;
-	int i;
-	struct mbuf *result = NULL, *n;
-	int len;
-
-	if (m == NULL || mhp == NULL)
-		panic("null pointer passed to key_gather");
-
-	va_start(ap, nitem);
-	for (i = 0; i < nitem; i++) {
-		idx = va_arg(ap, int);
-		if (idx < 0 || idx > SADB_EXT_MAX)
-			goto fail;
-		/* don't attempt to pull empty extension */
-		if (idx == SADB_EXT_RESERVED && mhp->msg == NULL)
-			continue;
-		if (idx != SADB_EXT_RESERVED  &&
-		    (mhp->ext[idx] == NULL || mhp->extlen[idx] == 0))
-			continue;
-
-		if (idx == SADB_EXT_RESERVED) {
-			len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
-#ifdef DIAGNOSTIC
-			if (len > MHLEN)
-				panic("assumption failed");
-#endif
-			MGETHDR(n, M_DONTWAIT, MT_DATA);
-			if (!n)
-				goto fail;
-			n->m_len = len;
-			n->m_next = NULL;
-			m_copydata(m, 0, sizeof(struct sadb_msg),
-			    mtod(n, caddr_t));
-		} else if (i < ndeep) {
-			len = mhp->extlen[idx];
-			n = key_alloc_mbuf(len);
-			if (!n || n->m_next) {	/*XXX*/
-				if (n)
-					m_freem(n);
-				goto fail;
-			}
-			m_copydata(m, mhp->extoff[idx], mhp->extlen[idx],
-			    mtod(n, caddr_t));
-		} else {
-			n = m_copym(m, mhp->extoff[idx], mhp->extlen[idx],
-			    M_DONTWAIT);
-		}
-		if (n == NULL)
-			goto fail;
-
-		if (result)
-			m_cat(result, n);
-		else
-			result = n;
-	}
-	va_end(ap);
-
-	if ((result->m_flags & M_PKTHDR) != 0) {
-		result->m_pkthdr.len = 0;
-		for (n = result; n; n = n->m_next)
-			result->m_pkthdr.len += n->m_len;
-	}
-
-	return result;
-
-fail:
-	va_end(ap);
-	m_freem(result);
-	return NULL;
-}
-
-/*
- * SADB_X_SPDADD, SADB_X_SPDSETIDX or SADB_X_SPDUPDATE processing
- * add an entry to SP database, when received
- *   <base, address(SD), (lifetime(H),) policy>
- * from the user(?).
- * Adding to SP database,
- * and send
- *   <base, address(SD), (lifetime(H),) policy>
- * to the socket which was send.
- *
- * SPDADD set a unique policy entry.
- * SPDSETIDX like SPDADD without a part of policy requests.
- * SPDUPDATE replace a unique policy entry.
- *
- * m will always be freed.
- */
-static int
-key_spdadd(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_address *src0 = NULL, *dst0 = NULL;
-	struct sadb_x_policy *xpl0, *xpl;
-	struct sadb_lifetime *lft = NULL;
-	struct secpolicyindex spidx;
-	struct secpolicy *newsp;
-	struct ipsecrequest *isr;
-	int error;
-	int spidxmode;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_spdadd: NULL pointer is passed.");
-
-	if (mhp->ext[SADB_EXT_ADDRESS_SRC] != NULL &&
-	    mhp->ext[SADB_EXT_ADDRESS_DST] != NULL) {
-		;
-	} else {
-		ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->ext[SADB_X_EXT_POLICY] == NULL) {
-		ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if ((mhp->extlen[SADB_EXT_ADDRESS_SRC] &&
-	     mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address)) ||
-	    (mhp->extlen[SADB_EXT_ADDRESS_DST] &&
-	     mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) ||
-	    mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
-		ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL) {
-		if (mhp->extlen[SADB_EXT_LIFETIME_HARD]
-			< sizeof(struct sadb_lifetime)) {
-			ipseclog((LOG_DEBUG, "key_spdadd: invalid message is passed.\n"));
-			return key_senderror(so, m, EINVAL);
-		}
-		lft = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_HARD];
-	}
-
-	/* spidx mode, or tag mode */
-	spidxmode = (mhp->ext[SADB_EXT_ADDRESS_SRC] != NULL);
-
-	if (spidxmode) {
-		src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
-		dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
-		/* make secindex */
-		/* XXX boundary check against sa_len */
-		KEY_SETSECSPIDX(src0 + 1, dst0 + 1,
-		    src0->sadb_address_prefixlen, dst0->sadb_address_prefixlen,
-		    src0->sadb_address_proto, &spidx);
-	}
-	xpl0 = (struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY];
-
-	/* checking the direciton. */
-	switch (xpl0->sadb_x_policy_dir) {
-	case IPSEC_DIR_INBOUND:
-	case IPSEC_DIR_OUTBOUND:
-		break;
-	default:
-		ipseclog((LOG_DEBUG, "key_spdadd: Invalid SP direction.\n"));
-		mhp->msg->sadb_msg_errno = EINVAL;
-		return 0;
-	}
-
-	/* check policy */
-	/* key_spdadd() accepts DISCARD, NONE and IPSEC. */
-	if (xpl0->sadb_x_policy_type == IPSEC_POLICY_ENTRUST ||
-	    xpl0->sadb_x_policy_type == IPSEC_POLICY_BYPASS) {
-		ipseclog((LOG_DEBUG, "key_spdadd: Invalid policy type.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	/* policy requests are mandatory when action is ipsec. */
-	if (mhp->msg->sadb_msg_type != SADB_X_SPDSETIDX &&
-	    xpl0->sadb_x_policy_type == IPSEC_POLICY_IPSEC &&
-	    mhp->extlen[SADB_X_EXT_POLICY] <= sizeof(*xpl0)) {
-		ipseclog((LOG_DEBUG, "key_spdadd: some policy requests part required.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	/*
-	 * checking there is SP already or not.
-	 * SPDUPDATE doesn't depend on whether there is a SP or not.
-	 * If the type is either SPDADD or SPDSETIDX AND a SP is found,
-	 * then error.
-	 */
-	if (xpl0->sadb_x_policy_id != 0)
-		newsp = key_getspbyid(xpl0->sadb_x_policy_id);
-	else if (spidxmode)
-		newsp = key_getsp(&spidx, xpl0->sadb_x_policy_dir);
-	else
-		newsp = NULL;
-
-	if (newsp && (newsp->readonly || newsp->persist)) {
-		ipseclog((LOG_DEBUG,
-		    "key_spdadd: tried to alter readonly/persistent SP.\n"));
-		return key_senderror(so, m, EPERM);
-	}
-
-	if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE) {
-		if (newsp) {
-			key_sp_dead(newsp);
-			key_freesp(newsp);	/* ref gained by key_getsp */
-			key_sp_unlink(newsp);
-			newsp = NULL;
-		}
-	} else {
-		if (newsp != NULL) {
-			key_freesp(newsp);
-			ipseclog((LOG_DEBUG, "key_spdadd: a SP entry exists already.\n"));
-			return key_senderror(so, m, EEXIST);
-		}
-	}
-
-	/* allocation new SP entry */
-	if ((newsp = key_msg2sp(xpl0, PFKEY_EXTLEN(xpl0), &error)) == NULL) {
-		return key_senderror(so, m, error);
-	}
-
-	if (spidxmode) {
-		error = keydb_setsecpolicyindex(newsp, &spidx);
-		if (error) {
-			keydb_delsecpolicy(newsp);
-			return key_senderror(so, m, error);
-		}
-
-		/* sanity check on addr pair */
-		if (((struct sockaddr *)(src0 + 1))->sa_family !=
-				((struct sockaddr *)(dst0 + 1))->sa_family) {
-			keydb_delsecpolicy(newsp);
-			return key_senderror(so, m, EINVAL);
-		}
-		if (((struct sockaddr *)(src0 + 1))->sa_len !=
-				((struct sockaddr *)(dst0 + 1))->sa_len) {
-			keydb_delsecpolicy(newsp);
-			return key_senderror(so, m, EINVAL);
-		}
-	}
-
-	for (isr = newsp->req; isr; isr = isr->next) {
-		struct sockaddr *sa;
-
-		/*
-		 * port spec is not permitted for tunnel mode
-		 */
-		if (isr->saidx.mode == IPSEC_MODE_TUNNEL && src0 && dst0) {
-			sa = (struct sockaddr *)(src0 + 1);
-			switch (sa->sa_family) {
-			case AF_INET:
-				if (((struct sockaddr_in *)sa)->sin_port) {
-					keydb_delsecpolicy(newsp);
-					return key_senderror(so, m, EINVAL);
-				}
-				break;
-			case AF_INET6:
-				if (((struct sockaddr_in6 *)sa)->sin6_port) {
-					keydb_delsecpolicy(newsp);
-					return key_senderror(so, m, EINVAL);
-				}
-				break;
-			default:
-				break;
-			}
-			sa = (struct sockaddr *)(dst0 + 1);
-			switch (sa->sa_family) {
-			case AF_INET:
-				if (((struct sockaddr_in *)sa)->sin_port) {
-					keydb_delsecpolicy(newsp);
-					return key_senderror(so, m, EINVAL);
-				}
-				break;
-			case AF_INET6:
-				if (((struct sockaddr_in6 *)sa)->sin6_port) {
-					keydb_delsecpolicy(newsp);
-					return key_senderror(so, m, EINVAL);
-				}
-				break;
-			default:
-				break;
-			}
-		}
-	}
-
-	/*
-	 * bark if we have different address family on tunnel address
-	 * specification.  applies only if we decapsulate in RFC2401
-	 * IPsec (implementation limitation).
-	 */
-	for (isr = newsp->req; isr; isr = isr->next) {
-		struct sockaddr *sa;
-
-		if (isr->saidx.src.ss_family && src0) {
-			sa = (struct sockaddr *)(src0 + 1);
-			if (sa->sa_family != isr->saidx.src.ss_family) {
-				keydb_delsecpolicy(newsp);
-				return key_senderror(so, m, EINVAL);
-			}
-		}
-		if (isr->saidx.dst.ss_family && dst0) {
-			sa = (struct sockaddr *)(dst0 + 1);
-			if (sa->sa_family != isr->saidx.dst.ss_family) {
-				keydb_delsecpolicy(newsp);
-				return key_senderror(so, m, EINVAL);
-			}
-		}
-	}
-
-	newsp->created = time_second;
-	newsp->lastused = time_second;
-	newsp->lifetime = lft ? lft->sadb_lifetime_addtime : 0;
-	newsp->validtime = lft ? lft->sadb_lifetime_usetime : 0;
-
-	newsp->state = IPSEC_SPSTATE_ALIVE;
-	LIST_INSERT_TAIL(&sptree[newsp->dir], newsp, secpolicy, chain);
-
-	/* delete the entry in spacqtree */
-	if (mhp->msg->sadb_msg_type == SADB_X_SPDUPDATE &&
-	    mhp->ext[SADB_EXT_ADDRESS_SRC]) {
-		struct secspacq *spacq;
-		if ((spacq = key_getspacq(&spidx)) != NULL) {
-			/* reset counter in order to deletion by timehandler. */
-			spacq->created = time_second;
-			spacq->count = 0;
-		}
-    	}
-
-	/* invalidate all cached SPD pointers on pcb */
-	ipsec_invalpcbcacheall();
-
-    {
-	struct mbuf *n, *mpolicy;
-	struct sadb_msg *newmsg;
-	int off;
-
-	/* create new sadb_msg to reply. */
-	if (lft) {
-		n = key_gather_mbuf(m, mhp, 2, 5, SADB_EXT_RESERVED,
-		    SADB_X_EXT_POLICY, SADB_EXT_LIFETIME_HARD,
-		    SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST);
-	} else {
-		n = key_gather_mbuf(m, mhp, 2, 4, SADB_EXT_RESERVED,
-		    SADB_X_EXT_POLICY,
-		    SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST);
-	}
-	if (!n)
-		return key_senderror(so, m, ENOBUFS);
-
-	if (n->m_len < sizeof(*newmsg)) {
-		n = m_pullup(n, sizeof(*newmsg));
-		if (!n)
-			return key_senderror(so, m, ENOBUFS);
-	}
-	newmsg = mtod(n, struct sadb_msg *);
-	newmsg->sadb_msg_errno = 0;
-	newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len);
-
-	off = 0;
-	mpolicy = m_pulldown(n, PFKEY_ALIGN8(sizeof(struct sadb_msg)),
-	    sizeof(*xpl), &off);
-	if (mpolicy == NULL) {
-		/* n is already freed */
-		return key_senderror(so, m, ENOBUFS);
-	}
-	xpl = (struct sadb_x_policy *)(mtod(mpolicy, caddr_t) + off);
-	if (xpl->sadb_x_policy_exttype != SADB_X_EXT_POLICY) {
-		m_freem(n);
-		return key_senderror(so, m, EINVAL);
-	}
-	xpl->sadb_x_policy_id = newsp->id;
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
-    }
-}
-
-/*
- * SADB_SPDDELETE processing
- * receive
- *   <base, address(SD), policy(*)>
- * from the user(?), and set SADB_SASTATE_DEAD,
- * and send,
- *   <base, address(SD), policy(*)>
- * to the ikmpd.
- * policy(*) including the direction of the policy.
- *
- * m will always be freed.
- */
-static int
-key_spddelete(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_address *src0, *dst0;
-	struct sadb_x_policy *xpl0;
-	struct secpolicyindex spidx;
-	struct secpolicy *sp;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_spddelete: NULL pointer is passed.");
-
-	if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_DST] == NULL ||
-	    mhp->ext[SADB_X_EXT_POLICY] == NULL) {
-		ipseclog((LOG_DEBUG, "key_spddelete: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
-		ipseclog((LOG_DEBUG, "key_spddelete: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
-	dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
-	xpl0 = (struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY];
-
-	/* make secindex */
-	/* XXX boundary check against sa_len */
-	KEY_SETSECSPIDX(src0 + 1,
-	                dst0 + 1,
-	                src0->sadb_address_prefixlen,
-	                dst0->sadb_address_prefixlen,
-	                src0->sadb_address_proto,
-	                &spidx);
-
-	/* checking the direciton. */
-	switch (xpl0->sadb_x_policy_dir) {
-	case IPSEC_DIR_INBOUND:
-	case IPSEC_DIR_OUTBOUND:
-		break;
-	default:
-		ipseclog((LOG_DEBUG, "key_spddelete: Invalid SP direction.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	/* Is there SP in SPD ? */
-	if ((sp = key_getsp(&spidx, xpl0->sadb_x_policy_dir)) == NULL) {
-		ipseclog((LOG_DEBUG, "key_spddelete: no SP found.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (sp->persist) {
-		ipseclog((LOG_DEBUG,
-		    "key_spddelete2: attempt to remove persistent SP:%u.\n",
-		    sp->id));
-		key_freesp(sp);	/* ref gained by key_getsp */
-		return key_senderror(so, m, EPERM);
-	}
-
-	/* save policy id to be returned. */
-	xpl0->sadb_x_policy_id = sp->id;
-
-	key_sp_dead(sp);
-	key_freesp(sp);	/* ref gained by key_getsp */
-	key_sp_unlink(sp);
-	sp = NULL;
-
-	/* invalidate all cached SPD pointers on pcb */
-	ipsec_invalpcbcacheall();
-
-    {
-	struct mbuf *n;
-	struct sadb_msg *newmsg;
-
-	/* create new sadb_msg to reply. */
-	n = key_gather_mbuf(m, mhp, 1, 4, SADB_EXT_RESERVED,
-	    SADB_X_EXT_POLICY, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST);
-	if (!n)
-		return key_senderror(so, m, ENOBUFS);
-
-	newmsg = mtod(n, struct sadb_msg *);
-	newmsg->sadb_msg_errno = 0;
-	newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len);
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
-    }
-}
-
-/*
- * SADB_SPDDELETE2 processing
- * receive
- *   <base, policy(*)>
- * from the user(?), and set SADB_SASTATE_DEAD,
- * and send,
- *   <base, policy(*)>
- * to the ikmpd.
- * policy(*) including the policy id.
- *
- * m will always be freed.
- */
-static int
-key_spddelete2(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	u_int32_t id;
-	struct secpolicy *sp;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_spddelete2: NULL pointer is passed.");
-
-	if (mhp->ext[SADB_X_EXT_POLICY] == NULL ||
-	    mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
-		ipseclog((LOG_DEBUG, "key_spddelete2: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	id = ((struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id;
-
-	/* Is there SP in SPD ? */
-	if ((sp = key_getspbyid(id)) == NULL) {
-		ipseclog((LOG_DEBUG, "key_spddelete2: no SP found id:%u.\n",
-		    id));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (sp->persist) {
-		ipseclog((LOG_DEBUG,
-		    "key_spddelete2: attempt to remove persistent SP:%u.\n",
-		    id));
-		key_freesp(sp);	/* ref gained by key_getspbyid */
-		return key_senderror(so, m, EPERM);
-	}
-
-	key_sp_dead(sp);
-	key_freesp(sp);	/* ref gained by key_getspbyid */
-	key_sp_unlink(sp);
-	sp = NULL;
-
-	/* invalidate all cached SPD pointers on pcb */
-	ipsec_invalpcbcacheall();
-
-    {
-	struct mbuf *n, *nn;
-	struct sadb_msg *newmsg;
-	int off, len;
-
-	/* create new sadb_msg to reply. */
-	len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
-
-	if (len > MCLBYTES)
-		return key_senderror(so, m, ENOBUFS);
-	MGETHDR(n, M_DONTWAIT, MT_DATA);
-	if (n && len > MHLEN) {
-		MCLGET(n, M_DONTWAIT);
-		if ((n->m_flags & M_EXT) == 0) {
-			m_freem(n);
-			n = NULL;
-		}
-	}
-	if (!n)
-		return key_senderror(so, m, ENOBUFS);
-
-	n->m_len = len;
-	n->m_next = NULL;
-	off = 0;
-
-	m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off);
-	off += PFKEY_ALIGN8(sizeof(struct sadb_msg));
-
-#ifdef DIAGNOSTIC
-	if (off != len)
-		panic("length inconsistency in key_spddelete2");
-#endif
-
-	n->m_next = m_copym(m, mhp->extoff[SADB_X_EXT_POLICY],
-	    mhp->extlen[SADB_X_EXT_POLICY], M_DONTWAIT);
-	if (!n->m_next) {
-		m_freem(n);
-		return key_senderror(so, m, ENOBUFS);
-	}
-
-	n->m_pkthdr.len = 0;
-	for (nn = n; nn; nn = nn->m_next)
-		n->m_pkthdr.len += nn->m_len;
-
-	newmsg = mtod(n, struct sadb_msg *);
-	newmsg->sadb_msg_errno = 0;
-	newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len);
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
-    }
-}
-
-/*
- * SADB_X_SPDGET processing
- * receive
- *   <base, policy(*)>
- * from the user(?),
- * and send,
- *   <base, address(SD), policy>
- * to the ikmpd.
- * policy(*) including direction of policy.
- *
- * m will always be freed.
- */
-static int
-key_spdget(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	u_int32_t id;
-	struct secpolicy *sp;
-	struct mbuf *n;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_spdget: NULL pointer is passed.");
-
-	if (mhp->ext[SADB_X_EXT_POLICY] == NULL ||
-	    mhp->extlen[SADB_X_EXT_POLICY] < sizeof(struct sadb_x_policy)) {
-		ipseclog((LOG_DEBUG, "key_spdget: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	id = ((struct sadb_x_policy *)mhp->ext[SADB_X_EXT_POLICY])->sadb_x_policy_id;
-
-	/* Is there SP in SPD ? */
-	if ((sp = key_getspbyid(id)) == NULL) {
-		ipseclog((LOG_DEBUG, "key_spdget: no SP found id:%u.\n", id));
-		return key_senderror(so, m, ENOENT);
-	}
-
-	n = key_setdumpsp(sp, SADB_X_SPDGET, 0, mhp->msg->sadb_msg_pid);
-	key_freesp(sp);	/* ref gained by key_getspbyid */
-	if (n != NULL) {
-		m_freem(m);
-		return key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
-	} else
-		return key_senderror(so, m, ENOBUFS);
-}
-
-/*
- * SADB_X_SPDACQUIRE processing.
- * Acquire policy and SA(s) for a *OUTBOUND* packet.
- * send
- *   <base, policy(*)>
- * to KMD, and expect to receive
- *   <base> with SADB_X_SPDACQUIRE if error occured,
- * or
- *   <base, policy>
- * with SADB_X_SPDUPDATE from KMD by PF_KEY.
- * policy(*) is without policy requests.
- *
- *    0     : succeed
- *    others: error number
- */
-int
-key_spdacquire(sp)
-	struct secpolicy *sp;
-{
-	struct mbuf *result = NULL, *m;
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-	struct secspacq *newspacq;
-#endif
-	int error = -1;
-
-	/* sanity check */
-	if (sp == NULL)
-		panic("key_spdacquire: NULL pointer is passed.");
-	if (sp->req != NULL)
-		panic("key_spdacquire: called but there is request.");
-	if (sp->policy != IPSEC_POLICY_IPSEC)
-		panic("key_spdacquire: policy mismathed. IPsec is expected.");
-	if (!sp->spidx) {
-		error = EOPNOTSUPP;
-		goto fail;
-	}
-
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-	/* get an entry to check whether sent message or not. */
-	if ((newspacq = key_getspacq(sp->spidx)) != NULL) {
-		if (key_blockacq_count < newspacq->count) {
-			/* reset counter and do send message. */
-			newspacq->count = 0;
-		} else {
-			/* increment counter and do nothing. */
-			newspacq->count++;
-			return 0;
-		}
-	} else {
-		/* make new entry for blocking to send SADB_ACQUIRE. */
-		if ((newspacq = key_newspacq(sp->spidx)) == NULL)
-			return ENOBUFS;
-
-		/* add to acqtree */
-		LIST_INSERT_HEAD(&spacqtree, newspacq, chain);
-	}
-#endif
-
-	/* create new sadb_msg to reply. */
-	m = key_setsadbmsg(SADB_X_SPDACQUIRE, 0, 0, 0, 0, 0);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	result = m;
-
-	/* set sadb_x_policy */
-	if (sp) {
-		m = key_setsadbxpolicy(sp->policy, sp->dir, sp->id);
-		if (!m) {
-			error = ENOBUFS;
-			goto fail;
-		}
-		m_cat(result, m);
-	}
-
-	result->m_pkthdr.len = 0;
-	for (m = result; m; m = m->m_next)
-		result->m_pkthdr.len += m->m_len;
-
-	mtod(result, struct sadb_msg *)->sadb_msg_len =
-	    PFKEY_UNIT64(result->m_pkthdr.len);
-
-	return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED);
-
-fail:
-	if (result)
-		m_freem(result);
-	return error;
-}
-
-/*
- * SADB_SPDFLUSH processing
- * receive
- *   <base>
- * from the user, and free all entries in secpctree.
- * and send,
- *   <base>
- * to the user.
- * NOTE: what to do is only marking SADB_SASTATE_DEAD.
- *
- * m will always be freed.
- */
-static int
-key_spdflush(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_msg *newmsg;
-	struct secpolicy *sp, *nextsp;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_spdflush: NULL pointer is passed.");
-
-	if (m->m_len != PFKEY_ALIGN8(sizeof(struct sadb_msg)))
-		return key_senderror(so, m, EINVAL);
-
-	for (sp = TAILQ_FIRST(&sptailq); sp; sp = nextsp) {
-		nextsp = TAILQ_NEXT(sp, tailq);
-		if (sp->persist)
-			continue;
-		if (sp->state == IPSEC_SPSTATE_DEAD)
-			continue;
-		key_sp_dead(sp);
-		key_sp_unlink(sp);
-		sp = NULL;
-	}
-
-	/* invalidate all cached SPD pointers on pcb */
-	ipsec_invalpcbcacheall();
-
-	if (sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) {
-		ipseclog((LOG_DEBUG, "key_spdflush: No more memory.\n"));
-		return key_senderror(so, m, ENOBUFS);
-	}
-
-	if (m->m_next)
-		m_freem(m->m_next);
-	m->m_next = NULL;
-	m->m_pkthdr.len = m->m_len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
-	newmsg = mtod(m, struct sadb_msg *);
-	newmsg->sadb_msg_errno = 0;
-	newmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len);
-
-	return key_sendup_mbuf(so, m, KEY_SENDUP_ALL);
-}
-
-/*
- * SADB_SPDDUMP processing
- * receive
- *   <base>
- * from the user, and dump all SP leaves
- * and send,
- *   <base> .....
- * to the ikmpd.
- *
- * m will always be freed.
- */
-static int
-key_spddump(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct secpolicy *sp;
-	int cnt;
-	u_int dir;
-	struct mbuf *n;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_spddump: NULL pointer is passed.");
-
-	/* search SPD entry and get buffer size. */
-	cnt = 0;
-	for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
-		LIST_FOREACH(sp, &sptree[dir], chain) {
-			cnt++;
-		}
-	}
-
-	if (cnt == 0)
-		return key_senderror(so, m, ENOENT);
-
-	for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
-		LIST_FOREACH(sp, &sptree[dir], chain) {
-			--cnt;
-			n = key_setdumpsp(sp, SADB_X_SPDDUMP, cnt,
-			    mhp->msg->sadb_msg_pid);
-
-			if (n)
-				key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
-		}
-	}
-
-	m_freem(m);
-	return 0;
-}
-
-static struct mbuf *
-key_setdumpsp(sp, type, seq, pid)
-	struct secpolicy *sp;
-	u_int8_t type;
-	u_int32_t seq, pid;
-{
-	struct mbuf *result = NULL, *m;
-
-	m = key_setsadbmsg(type, 0, SADB_SATYPE_UNSPEC, seq, pid, sp->refcnt);
-	if (!m)
-		goto fail;
-	result = m;
-
-	if (sp->spidx) {
-		m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
-		    (struct sockaddr *)&sp->spidx->src, sp->spidx->prefs,
-		    sp->spidx->ul_proto);
-		if (!m)
-			goto fail;
-		m_cat(result, m);
-
-		m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
-		    (struct sockaddr *)&sp->spidx->dst, sp->spidx->prefd,
-		    sp->spidx->ul_proto);
-		if (!m)
-			goto fail;
-		m_cat(result, m);
-	}
-
-	m = key_sp2msg(sp);
-	if (!m)
-		goto fail;
-	m_cat(result, m);
-
-	m = key_setsadblifetime(SADB_EXT_LIFETIME_CURRENT,
-		0, 0, (u_int64_t)sp->created, (u_int64_t)sp->lastused);
-	if (!m)
-		goto fail;
-	m_cat(result, m);
-
-	m = key_setsadblifetime(SADB_EXT_LIFETIME_HARD,
-		0, 0, (u_int64_t)sp->lifetime, (u_int64_t)sp->validtime);
-	if (!m)
-		goto fail;
-	m_cat(result, m);
-
-	if ((result->m_flags & M_PKTHDR) == 0)
-		goto fail;
-
-	if (result->m_len < sizeof(struct sadb_msg)) {
-		result = m_pullup(result, sizeof(struct sadb_msg));
-		if (result == NULL)
-			goto fail;
-	}
-
-	result->m_pkthdr.len = 0;
-	for (m = result; m; m = m->m_next)
-		result->m_pkthdr.len += m->m_len;
-
-	mtod(result, struct sadb_msg *)->sadb_msg_len =
-	    PFKEY_UNIT64(result->m_pkthdr.len);
-
-	return result;
-
-fail:
-	m_freem(result);
-	return NULL;
-}
-
-/*
- * get PFKEY message length for security policy and request.
- */
-static u_int
-key_getspreqmsglen(sp)
-	struct secpolicy *sp;
-{
-	u_int tlen;
-
-	tlen = sizeof(struct sadb_x_policy);
-
-	/* if is the policy for ipsec ? */
-	if (sp->policy != IPSEC_POLICY_IPSEC)
-		return tlen;
-
-	/* get length of ipsec requests */
-    {
-	struct ipsecrequest *isr;
-	int len;
-
-	for (isr = sp->req; isr != NULL; isr = isr->next) {
-		len = sizeof(struct sadb_x_ipsecrequest)
-			+ isr->saidx.src.ss_len
-			+ isr->saidx.dst.ss_len;
-
-		tlen += PFKEY_ALIGN8(len);
-	}
-    }
-
-	return tlen;
-}
-
-/*
- * SADB_X_SPDEXPIRE processing
- * send
- *   <base, address(SD), lifetime(CH), policy>
- * to KMD by PF_KEY.
- *
- * OUT:	0	: succeed
- *	others	: error number
- */
-static int
-key_spdexpire(sp)
-	struct secpolicy *sp;
-{
-	int s;
-	struct mbuf *result = NULL, *m;
-	int len;
-	int error = -1;
-	struct sadb_lifetime *lt;
-
-	/* XXX: Why do we lock ? */
-	s = splnet();	/*called from softclock()*/
-
-	/* sanity check */
-	if (sp == NULL)
-		panic("key_spdexpire: NULL pointer is passed.");
-
-	/* set msg header */
-	m = key_setsadbmsg(SADB_X_SPDEXPIRE, 0, 0, 0, 0, 0);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	result = m;
-
-	/* create lifetime extension (current and hard) */
-	len = PFKEY_ALIGN8(sizeof(*lt)) * 2;
-	m = key_alloc_mbuf(len);
-	if (!m || m->m_next) {	/*XXX*/
-		if (m)
-			m_freem(m);
-		error = ENOBUFS;
-		goto fail;
-	}
-	bzero(mtod(m, caddr_t), len);
-	lt = mtod(m, struct sadb_lifetime *);
-	lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime));
-	lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
-	lt->sadb_lifetime_allocations = 0;
-	lt->sadb_lifetime_bytes = 0;
-	lt->sadb_lifetime_addtime = sp->created;
-	lt->sadb_lifetime_usetime = sp->lastused;
-	lt = (struct sadb_lifetime *)(mtod(m, caddr_t) + len / 2);
-	lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime));
-	lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_HARD;
-	lt->sadb_lifetime_allocations = 0;
-	lt->sadb_lifetime_bytes = 0;
-	lt->sadb_lifetime_addtime = sp->lifetime;
-	lt->sadb_lifetime_usetime = sp->validtime;
-	m_cat(result, m);
-
-	/* set sadb_address for source */
-	if (sp->spidx) {
-		m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
-		    (struct sockaddr *)&sp->spidx->src,
-		    sp->spidx->prefs, sp->spidx->ul_proto);
-		if (!m) {
-			error = ENOBUFS;
-			goto fail;
-		}
-		m_cat(result, m);
-
-		/* set sadb_address for destination */
-		m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
-		    (struct sockaddr *)&sp->spidx->dst,
-		    sp->spidx->prefd, sp->spidx->ul_proto);
-		if (!m) {
-			error = ENOBUFS;
-			goto fail;
-		}
-		m_cat(result, m);
-	}
-
-	/* set secpolicy */
-	m = key_sp2msg(sp);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	m_cat(result, m);
-
-	if ((result->m_flags & M_PKTHDR) == 0) {
-		error = EINVAL;
-		goto fail;
-	}
-
-	if (result->m_len < sizeof(struct sadb_msg)) {
-		result = m_pullup(result, sizeof(struct sadb_msg));
-		if (result == NULL) {
-			error = ENOBUFS;
-			goto fail;
-		}
-	}
-
-	result->m_pkthdr.len = 0;
-	for (m = result; m; m = m->m_next)
-		result->m_pkthdr.len += m->m_len;
-
-	mtod(result, struct sadb_msg *)->sadb_msg_len =
-	    PFKEY_UNIT64(result->m_pkthdr.len);
-
-	splx(s);
-	return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED);
-
- fail:
-	if (result)
-		m_freem(result);
-	splx(s);
-	return error;
-}
-
-/* %%% SAD management */
-/*
- * allocating a memory for new SA head, and copy from the values of mhp.
- * OUT:	NULL	: failure due to the lack of memory.
- *	others	: pointer to new SA head.
- */
-static struct secashead *
-key_newsah(saidx)
-	struct secasindex *saidx;
-{
-	struct secashead *newsah;
-
-	/* sanity check */
-	if (saidx == NULL)
-		panic("key_newsaidx: NULL pointer is passed.");
-
-	newsah = keydb_newsecashead();
-	if (newsah == NULL)
-		return NULL;
-
-	bcopy(saidx, &newsah->saidx, sizeof(newsah->saidx));
-
-	/* add to saidxtree */
-	newsah->state = SADB_SASTATE_MATURE;
-	LIST_INSERT_HEAD(&sahtree, newsah, chain);
-
-	return (newsah);
-}
-
-/*
- * delete SA index and all SA registerd.
- */
-static void
-key_delsah(sah)
-	struct secashead *sah;
-{
-	struct secasvar *sav, *nextsav;
-	u_int stateidx, state;
-	int s;
-	int zombie = 0;
-
-	/* sanity check */
-	if (sah == NULL)
-		panic("key_delsah: NULL pointer is passed.");
-
-	s = splnet();	/*called from softclock()*/
-
-	/* searching all SA registerd in the secindex. */
-	for (stateidx = 0;
-	     stateidx < _ARRAYLEN(saorder_state_any);
-	     stateidx++) {
-
-		state = saorder_state_any[stateidx];
-		for (sav = LIST_FIRST(&sah->savtree[state]);
-		     sav != NULL;
-		     sav = nextsav) {
-
-			nextsav = LIST_NEXT(sav, chain);
-
-			if (sav->refcnt > 0) {
-				/* give up to delete this sa */
-				zombie++;
-				continue;
-			}
-
-			/* sanity check */
-			KEY_CHKSASTATE(state, sav->state, "key_delsah");
-
-			/* remove back pointer */
-			sav->sah = NULL;
-
-			key_freesav(sav);
-
-			sav = NULL;
-		}
-	}
-
-	/* delete sah only if there's no sav. */
-	if (zombie) {
-		splx(s);
-		return;
-	}
-
-	if (sah->sa_route.ro_rt) {
-		RTFREE(sah->sa_route.ro_rt);
-		sah->sa_route.ro_rt = (struct rtentry *)NULL;
-	}
-
-	/* remove from tree of SA index */
-	if (__LIST_CHAINED(sah))
-		LIST_REMOVE(sah, chain);
-
-	KFREE(sah);
-
-	splx(s);
-	return;
-}
-
-/*
- * allocating a new SA with LARVAL state.  key_add() and key_getspi() call,
- * and copy the values of mhp into new buffer.
- * When SAD message type is GETSPI:
- *	to set sequence number from acq_seq++,
- *	to set zero to SPI.
- *	not to call key_setsava().
- * OUT:	NULL	: fail
- *	others	: pointer to new secasvar.
- *
- * does not modify mbuf.  does not free mbuf on error.
- */
-static struct secasvar *
-key_newsav(m, mhp, sah, errp)
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-	struct secashead *sah;
-	int *errp;
-{
-	struct secasvar *newsav;
-	const struct sadb_sa *xsa;
-
-	/* sanity check */
-	if (m == NULL || mhp == NULL || mhp->msg == NULL || sah == NULL)
-		panic("key_newsa: NULL pointer is passed.");
-
-	newsav = keydb_newsecasvar();
-	if (newsav == NULL) {
-		ipseclog((LOG_DEBUG, "key_newsa: No more memory.\n"));
-		*errp = ENOBUFS;
-		return NULL;
-	}
-
-	switch (mhp->msg->sadb_msg_type) {
-	case SADB_GETSPI:
-		key_setspi(newsav, 0);
-
-#ifdef IPSEC_DOSEQCHECK
-		/* sync sequence number */
-		if (mhp->msg->sadb_msg_seq == 0)
-			newsav->seq =
-				(acq_seq = (acq_seq == ~0 ? 1 : ++acq_seq));
-		else
-#endif
-			newsav->seq = mhp->msg->sadb_msg_seq;
-		break;
-
-	case SADB_ADD:
-		/* sanity check */
-		if (mhp->ext[SADB_EXT_SA] == NULL) {
-			KFREE(newsav);
-			ipseclog((LOG_DEBUG, "key_newsa: invalid message is passed.\n"));
-			*errp = EINVAL;
-			return NULL;
-		}
-		xsa = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA];
-		key_setspi(newsav, xsa->sadb_sa_spi);
-		newsav->seq = mhp->msg->sadb_msg_seq;
-		break;
-	default:
-		KFREE(newsav);
-		*errp = EINVAL;
-		return NULL;
-	}
-
-	/* copy sav values */
-	if (mhp->msg->sadb_msg_type != SADB_GETSPI) {
-		*errp = key_setsaval(newsav, m, mhp);
-		if (*errp) {
-			KFREE(newsav);
-			return NULL;
-		}
-	}
-
-	/* reset created */
-	newsav->created = time_second;
-
-	newsav->pid = mhp->msg->sadb_msg_pid;
-
-	/* add to satree */
-	newsav->sah = sah;
-	newsav->refcnt = 1;
-	newsav->state = SADB_SASTATE_LARVAL;
-	LIST_INSERT_TAIL(&sah->savtree[SADB_SASTATE_LARVAL], newsav,
-			secasvar, chain);
-
-	return newsav;
-}
-
-/*
- * search SAD.
- * OUT:
- *	NULL	: not found
- *	others	: found, pointer to a SA.
- */
-static struct secashead *
-key_getsah(saidx)
-	struct secasindex *saidx;
-{
-	struct secashead *sah;
-
-	LIST_FOREACH(sah, &sahtree, chain) {
-		if (sah->state == SADB_SASTATE_DEAD)
-			continue;
-		if (key_cmpsaidx(&sah->saidx, saidx, CMP_MODE_REQID))
-			return sah;
-	}
-
-	return NULL;
-}
-
-/*
- * check not to be duplicated SPI.
- * NOTE: this function is too slow due to searching all SAD.
- * OUT:
- *	NULL	: not found
- *	others	: found, pointer to a SA.
- */
-static struct secasvar *
-key_checkspidup(saidx, spi)
-	struct secasindex *saidx;
-	u_int32_t spi;
-{
-	struct secasvar *sav;
-	u_int stateidx, state;
-
-	/* check address family */
-	if (saidx->src.ss_family != saidx->dst.ss_family) {
-		ipseclog((LOG_DEBUG, "key_checkspidup: address family mismatched.\n"));
-		return NULL;
-	}
-
-	/* check all SAD */
-	LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) {
-		if (sav->spi != spi)
-			continue;
-		for (stateidx = 0;
-		     stateidx < _ARRAYLEN(saorder_state_alive);
-		     stateidx++) {
-			state = saorder_state_alive[stateidx];
-			if (sav->state == state &&
-			    key_ismyaddr((struct sockaddr *)&sav->sah->saidx.dst))
-				return sav;
-		}
-	}
-
-	return NULL;
-}
-
-static void
-key_setspi(sav, spi)
-	struct secasvar *sav;
-	u_int32_t spi;
-{
-	int s;
-
-	s = splnet();
-	sav->spi = spi;
-	if (sav->spihash.le_prev || sav->spihash.le_next)
-		LIST_REMOVE(sav, spihash);
-	LIST_INSERT_HEAD(&spihash[SPIHASH(spi)], sav, spihash);
-	splx(s);
-}
-
-/*
- * search SAD litmited alive SA, protocol, SPI.
- * OUT:
- *	NULL	: not found
- *	others	: found, pointer to a SA.
- */
-static struct secasvar *
-key_getsavbyspi(sah, spi)
-	struct secashead *sah;
-	u_int32_t spi;
-{
-	struct secasvar *sav, *match;
-	u_int stateidx, state, matchidx;
-
-	match = NULL;
-	matchidx = _ARRAYLEN(saorder_state_alive);
-	LIST_FOREACH(sav, &spihash[SPIHASH(spi)], spihash) {
-		if (sav->spi != spi)
-			continue;
-		if (sav->sah != sah)
-			continue;
-		for (stateidx = 0; stateidx < matchidx; stateidx++) {
-			state = saorder_state_alive[stateidx];
-			if (sav->state == state) {
-				match = sav;
-				matchidx = stateidx;
-				break;
-			}
-		}
-	}
-
-	return match;
-}
-
-/*
- * copy SA values from PF_KEY message except *SPI, SEQ, PID, STATE and TYPE*.
- * You must update these if need.
- * OUT:	0:	success.
- *	!0:	failure.
- *
- * does not modify mbuf.  does not free mbuf on error.
- */
-static int
-key_setsaval(sav, m, mhp)
-	struct secasvar *sav;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-#ifdef IPSEC_ESP
-	const struct esp_algorithm *algo;
-#endif
-	int error = 0;
-
-	/* sanity check */
-	if (m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_setsaval: NULL pointer is passed.");
-
-	/* initialization */
-	sav->replay = NULL;
-	sav->key_auth = NULL;
-	sav->key_enc = NULL;
-	sav->sched = NULL;
-	sav->schedlen = 0;
-	sav->iv = NULL;
-	sav->lft_c = NULL;
-	sav->lft_h = NULL;
-	sav->lft_s = NULL;
-
-	/* SA */
-	if (mhp->ext[SADB_EXT_SA] != NULL) {
-		const struct sadb_sa *sa0;
-
-		sa0 = (const struct sadb_sa *)mhp->ext[SADB_EXT_SA];
-		if (mhp->extlen[SADB_EXT_SA] < sizeof(*sa0)) {
-			error = EINVAL;
-			goto fail;
-		}
-
-		sav->alg_auth = sa0->sadb_sa_auth;
-		sav->alg_enc = sa0->sadb_sa_encrypt;
-		sav->flags = sa0->sadb_sa_flags;
-
-		/* replay window */
-		if ((sa0->sadb_sa_flags & SADB_X_EXT_OLD) == 0) {
-			sav->replay = keydb_newsecreplay(sa0->sadb_sa_replay);
-			if (sav->replay == NULL) {
-				ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n"));
-				error = ENOBUFS;
-				goto fail;
-			}
-		}
-	}
-
-	/* Authentication keys */
-	if (mhp->ext[SADB_EXT_KEY_AUTH] != NULL) {
-		const struct sadb_key *key0;
-		int len;
-
-		key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_AUTH];
-		len = mhp->extlen[SADB_EXT_KEY_AUTH];
-
-		error = 0;
-		if (len < sizeof(*key0)) {
-			error = EINVAL;
-			goto fail;
-		}
-		switch (mhp->msg->sadb_msg_satype) {
-		case SADB_SATYPE_AH:
-		case SADB_SATYPE_ESP:
-		case SADB_X_SATYPE_TCPSIGNATURE:
-			if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) &&
-			    sav->alg_auth != SADB_X_AALG_NULL)
-				error = EINVAL;
-			break;
-		case SADB_X_SATYPE_IPCOMP:
-		default:
-			error = EINVAL;
-			break;
-		}
-		if (error) {
-			ipseclog((LOG_DEBUG, "key_setsaval: invalid key_auth values.\n"));
-			goto fail;
-		}
-
-		sav->key_auth = (struct sadb_key *)key_newbuf(key0, len);
-		if (sav->key_auth == NULL) {
-			ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n"));
-			error = ENOBUFS;
-			goto fail;
-		}
-	}
-
-	/* Encryption key */
-	if (mhp->ext[SADB_EXT_KEY_ENCRYPT] != NULL) {
-		const struct sadb_key *key0;
-		int len;
-
-		key0 = (const struct sadb_key *)mhp->ext[SADB_EXT_KEY_ENCRYPT];
-		len = mhp->extlen[SADB_EXT_KEY_ENCRYPT];
-
-		error = 0;
-		if (len < sizeof(*key0)) {
-			error = EINVAL;
-			goto fail;
-		}
-		switch (mhp->msg->sadb_msg_satype) {
-		case SADB_SATYPE_ESP:
-			if (len == PFKEY_ALIGN8(sizeof(struct sadb_key)) &&
-			    sav->alg_enc != SADB_EALG_NULL) {
-				error = EINVAL;
-				break;
-			}
-			sav->key_enc = (struct sadb_key *)key_newbuf(key0, len);
-			if (sav->key_enc == NULL) {
-				ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n"));
-				error = ENOBUFS;
-				goto fail;
-			}
-			break;
-		case SADB_X_SATYPE_IPCOMP:
-			if (len != PFKEY_ALIGN8(sizeof(struct sadb_key)))
-				error = EINVAL;
-			sav->key_enc = NULL;	/*just in case*/
-			break;
-		case SADB_SATYPE_AH:
-		case SADB_X_SATYPE_TCPSIGNATURE:
-		default:
-			error = EINVAL;
-			break;
-		}
-		if (error) {
-			ipseclog((LOG_DEBUG, "key_setsatval: invalid key_enc value.\n"));
-			goto fail;
-		}
-	}
-
-	/* set iv */
-	sav->ivlen = 0;
-
-	switch (mhp->msg->sadb_msg_satype) {
-	case SADB_SATYPE_ESP:
-#ifdef IPSEC_ESP
-		algo = esp_algorithm_lookup(sav->alg_enc);
-		if (algo && algo->ivlen)
-			sav->ivlen = (*algo->ivlen)(algo, sav);
-		if (sav->ivlen == 0)
-			break;
-		KMALLOC(sav->iv, caddr_t, sav->ivlen);
-		if (sav->iv == 0) {
-			ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n"));
-			error = ENOBUFS;
-			goto fail;
-		}
-
-		/* initialize */
-		key_randomfill(sav->iv, sav->ivlen);
-#endif
-		break;
-	case SADB_SATYPE_AH:
-	case SADB_X_SATYPE_IPCOMP:
-	case SADB_X_SATYPE_TCPSIGNATURE:
-		break;
-	default:
-		ipseclog((LOG_DEBUG, "key_setsaval: invalid SA type.\n"));
-		error = EINVAL;
-		goto fail;
-	}
-
-	/* reset created */
-	sav->created = time_second;
-
-	/* make lifetime for CURRENT */
-	KMALLOC(sav->lft_c, struct sadb_lifetime *,
-	    sizeof(struct sadb_lifetime));
-	if (sav->lft_c == NULL) {
-		ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n"));
-		error = ENOBUFS;
-		goto fail;
-	}
-
-	sav->lft_c->sadb_lifetime_len =
-	    PFKEY_UNIT64(sizeof(struct sadb_lifetime));
-	sav->lft_c->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
-	sav->lft_c->sadb_lifetime_allocations = 0;
-	sav->lft_c->sadb_lifetime_bytes = 0;
-	sav->lft_c->sadb_lifetime_addtime = time_second;
-	sav->lft_c->sadb_lifetime_usetime = 0;
-
-	/* lifetimes for HARD and SOFT */
-    {
-	const struct sadb_lifetime *lft0;
-
-	lft0 = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_HARD];
-	if (lft0 != NULL) {
-		if (mhp->extlen[SADB_EXT_LIFETIME_HARD] < sizeof(*lft0)) {
-			error = EINVAL;
-			goto fail;
-		}
-		sav->lft_h = (struct sadb_lifetime *)key_newbuf(lft0,
-		    sizeof(*lft0));
-		if (sav->lft_h == NULL) {
-			ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n"));
-			error = ENOBUFS;
-			goto fail;
-		}
-		/* we no longer support byte lifetime */
-		if (sav->lft_h->sadb_lifetime_bytes) {
-			error = EINVAL;
-			goto fail;
-		}
-		/* initialize? */
-	}
-
-	lft0 = (struct sadb_lifetime *)mhp->ext[SADB_EXT_LIFETIME_SOFT];
-	if (lft0 != NULL) {
-		if (mhp->extlen[SADB_EXT_LIFETIME_SOFT] < sizeof(*lft0)) {
-			error = EINVAL;
-			goto fail;
-		}
-		sav->lft_s = (struct sadb_lifetime *)key_newbuf(lft0,
-		    sizeof(*lft0));
-		if (sav->lft_s == NULL) {
-			ipseclog((LOG_DEBUG, "key_setsaval: No more memory.\n"));
-			error = ENOBUFS;
-			goto fail;
-		}
-		/* we no longer support byte lifetime */
-		if (sav->lft_s->sadb_lifetime_bytes) {
-			error = EINVAL;
-			goto fail;
-		}
-		/* initialize? */
-	}
-    }
-
-	return 0;
-
- fail:
-	/* initialization */
-	if (sav->replay != NULL) {
-		keydb_delsecreplay(sav->replay);
-		sav->replay = NULL;
-	}
-	if (sav->key_auth != NULL) {
-		bzero(_KEYBUF(sav->key_auth), _KEYLEN(sav->key_auth));
-		KFREE(sav->key_auth);
-		sav->key_auth = NULL;
-	}
-	if (sav->key_enc != NULL) {
-		bzero(_KEYBUF(sav->key_enc), _KEYLEN(sav->key_enc));
-		KFREE(sav->key_enc);
-		sav->key_enc = NULL;
-	}
-	if (sav->sched) {
-		bzero(sav->sched, sav->schedlen);
-		KFREE(sav->sched);
-		sav->sched = NULL;
-	}
-	if (sav->iv != NULL) {
-		KFREE(sav->iv);
-		sav->iv = NULL;
-	}
-	if (sav->lft_c != NULL) {
-		KFREE(sav->lft_c);
-		sav->lft_c = NULL;
-	}
-	if (sav->lft_h != NULL) {
-		KFREE(sav->lft_h);
-		sav->lft_h = NULL;
-	}
-	if (sav->lft_s != NULL) {
-		KFREE(sav->lft_s);
-		sav->lft_s = NULL;
-	}
-
-	return error;
-}
-
-/*
- * validation with a secasvar entry, and set SADB_SATYPE_MATURE.
- * OUT:	0:	valid
- *	other:	errno
- */
-static int
-key_mature(sav)
-	struct secasvar *sav;
-{
-	int mature;
-	int checkmask = 0;	/* 2^0: ealg  2^1: aalg  2^2: calg */
-	int mustmask = 0;	/* 2^0: ealg  2^1: aalg  2^2: calg */
-
-	mature = 0;
-
-	/* check SPI value */
-	switch (sav->sah->saidx.proto) {
-	case IPPROTO_ESP:
-	case IPPROTO_AH:
-		if (ntohl(sav->spi) >= 0 && ntohl(sav->spi) <= 255) {
-			ipseclog((LOG_DEBUG,
-			    "key_mature: illegal range of SPI %u.\n",
-			    (u_int32_t)ntohl(sav->spi)));
-			return EINVAL;
-		}
-		break;
-	}
-
-	/* check satype */
-	switch (sav->sah->saidx.proto) {
-	case IPPROTO_ESP:
-		/* check flags */
-		if ((sav->flags & SADB_X_EXT_OLD) &&
-		    (sav->flags & SADB_X_EXT_DERIV)) {
-			ipseclog((LOG_DEBUG, "key_mature: "
-			    "invalid flag (derived) given to old-esp.\n"));
-			return EINVAL;
-		}
-		if (sav->alg_auth == SADB_AALG_NONE)
-			checkmask = 1;
-		else
-			checkmask = 3;
-		mustmask = 1;
-		break;
-	case IPPROTO_AH:
-		/* check flags */
-		if (sav->flags & SADB_X_EXT_DERIV) {
-			ipseclog((LOG_DEBUG, "key_mature: "
-			    "invalid flag (derived) given to AH SA.\n"));
-			return EINVAL;
-		}
-		if (sav->alg_enc != SADB_EALG_NONE) {
-			ipseclog((LOG_DEBUG, "key_mature: "
-			    "protocol and algorithm mismated.\n"));
-			return (EINVAL);
-		}
-		checkmask = 2;
-		mustmask = 2;
-		break;
-	case IPPROTO_IPCOMP:
-		if (sav->alg_auth != SADB_AALG_NONE) {
-			ipseclog((LOG_DEBUG, "key_mature: "
-				"protocol and algorithm mismated.\n"));
-			return (EINVAL);
-		}
-		if ((sav->flags & SADB_X_EXT_RAWCPI) == 0 &&
-		    ntohl(sav->spi) >= 0x10000) {
-			ipseclog((LOG_DEBUG, "key_mature: invalid cpi for IPComp.\n"));
-			return (EINVAL);
-		}
-		checkmask = 4;
-		mustmask = 4;
-		break;
-	case IPPROTO_TCP:
-		if (sav->alg_auth != SADB_X_AALG_TCP_MD5) {
-			ipseclog((LOG_DEBUG, "key_mature: unsupported authentication algorithm %u\n",
-			    sav->alg_auth));
-			return (EINVAL);
-		}
-		if (sav->alg_enc != SADB_EALG_NONE) {
-			ipseclog((LOG_DEBUG, "%s: protocol and algorithm "
-				"mismated.\n", __func__));
-			return(EINVAL);
-		}
-		if (sav->spi != htonl(0x1000)) {
-			ipseclog((LOG_DEBUG, "key_mature: SPI must be TCP_SIG_SPI (0x1000)\n"));
-			return (EINVAL);
-		}
-		checkmask = 2;
-		mustmask = 2;
-		break;
-	default:
-		ipseclog((LOG_DEBUG, "key_mature: Invalid satype.\n"));
-		return EPROTONOSUPPORT;
-	}
-
-	/* check authentication algorithm */
-	if ((checkmask & 2) != 0) {
-		const struct ah_algorithm *algo;
-		int keylen;
-
-		algo = ah_algorithm_lookup(sav->alg_auth);
-		if (!algo) {
-			ipseclog((LOG_DEBUG, "key_mature: "
-			    "unknown authentication algorithm.\n"));
-			return EINVAL;
-		}
-
-		/* algorithm-dependent check */
-		if (sav->key_auth)
-			keylen = sav->key_auth->sadb_key_bits;
-		else
-			keylen = 0;
-		if (keylen < algo->keymin || algo->keymax < keylen) {
-			ipseclog((LOG_DEBUG,
-			    "key_mature: invalid AH key length %d "
-			    "(%d-%d allowed)\n",
-			    keylen, algo->keymin, algo->keymax));
-			return EINVAL;
-		}
-
-		if (algo->mature) {
-			if ((*algo->mature)(sav)) {
-				/* message generated in per-algorithm function*/
-				return EINVAL;
-			} else
-				mature = SADB_SATYPE_AH;
-		}
-
-		if ((mustmask & 2) != 0 &&  mature != SADB_SATYPE_AH) {
-			ipseclog((LOG_DEBUG, "key_mature: no satisfy algorithm for AH\n"));
-			return EINVAL;
-		}
-	}
-
-	/* check encryption algorithm */
-	if ((checkmask & 1) != 0) {
-#ifdef IPSEC_ESP
-		const struct esp_algorithm *algo;
-		int keylen;
-
-		algo = esp_algorithm_lookup(sav->alg_enc);
-		if (!algo) {
-			ipseclog((LOG_DEBUG, "key_mature: unknown encryption algorithm.\n"));
-			return EINVAL;
-		}
-
-		/* algorithm-dependent check */
-		if (sav->key_enc)
-			keylen = sav->key_enc->sadb_key_bits;
-		else
-			keylen = 0;
-		if (keylen < algo->keymin || algo->keymax < keylen) {
-			ipseclog((LOG_DEBUG,
-			    "key_mature: invalid ESP key length %d "
-			    "(%d-%d allowed)\n",
-			    keylen, algo->keymin, algo->keymax));
-			return EINVAL;
-		}
-
-		if (algo->mature) {
-			if ((*algo->mature)(sav)) {
-				/* message generated in per-algorithm function*/
-				return EINVAL;
-			} else
-				mature = SADB_SATYPE_ESP;
-		}
-
-		if ((mustmask & 1) != 0 &&  mature != SADB_SATYPE_ESP) {
-			ipseclog((LOG_DEBUG, "key_mature: no satisfy algorithm for ESP\n"));
-			return EINVAL;
-		}
-#else /*IPSEC_ESP*/
-		ipseclog((LOG_DEBUG, "key_mature: ESP not supported in this configuration\n"));
-		return EINVAL;
-#endif
-	}
-
-	/* check compression algorithm */
-	if ((checkmask & 4) != 0) {
-		const struct ipcomp_algorithm *algo;
-
-		/* algorithm-dependent check */
-		algo = ipcomp_algorithm_lookup(sav->alg_enc);
-		if (!algo) {
-			ipseclog((LOG_DEBUG, "key_mature: unknown compression algorithm.\n"));
-			return EINVAL;
-		}
-	}
-
-	key_sa_chgstate(sav, SADB_SASTATE_MATURE);
-
-	return 0;
-}
-
-/*
- * subroutine for SADB_GET and SADB_DUMP.
- */
-static struct mbuf *
-key_setdumpsa(sav, type, satype, seq, pid)
-	struct secasvar *sav;
-	u_int8_t type, satype;
-	u_int32_t seq, pid;
-{
-	struct mbuf *result = NULL, *tres = NULL, *m;
-	int l = 0;
-	int i;
-	void *p;
-	int dumporder[] = {
-		SADB_EXT_SA, SADB_X_EXT_SA2,
-		SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT,
-		SADB_EXT_LIFETIME_CURRENT, SADB_EXT_ADDRESS_SRC,
-		SADB_EXT_ADDRESS_DST, SADB_EXT_ADDRESS_PROXY, SADB_EXT_KEY_AUTH,
-		SADB_EXT_KEY_ENCRYPT, SADB_EXT_IDENTITY_SRC,
-		SADB_EXT_IDENTITY_DST, SADB_EXT_SENSITIVITY,
-	};
-
-	m = key_setsadbmsg(type, 0, satype, seq, pid, sav->refcnt);
-	if (m == NULL)
-		goto fail;
-	result = m;
-
-	for (i = sizeof(dumporder)/sizeof(dumporder[0]) - 1; i >= 0; i--) {
-		m = NULL;
-		p = NULL;
-		switch (dumporder[i]) {
-		case SADB_EXT_SA:
-			m = key_setsadbsa(sav);
-			if (!m)
-				goto fail;
-			break;
-
-		case SADB_X_EXT_SA2:
-			m = key_setsadbxsa2(sav->sah->saidx.mode,
-			    sav->replay ? (sav->replay->count & 0xffffffff) : 0,
-			    sav->sah->saidx.reqid);
-			if (!m)
-				goto fail;
-			break;
-
-		case SADB_EXT_ADDRESS_SRC:
-			m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
-			    (struct sockaddr *)&sav->sah->saidx.src,
-			    FULLMASK, IPSEC_ULPROTO_ANY);
-			if (!m)
-				goto fail;
-			break;
-
-		case SADB_EXT_ADDRESS_DST:
-			m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
-			    (struct sockaddr *)&sav->sah->saidx.dst,
-			    FULLMASK, IPSEC_ULPROTO_ANY);
-			if (!m)
-				goto fail;
-			break;
-
-		case SADB_EXT_KEY_AUTH:
-			if (!sav->key_auth)
-				continue;
-			l = PFKEY_UNUNIT64(sav->key_auth->sadb_key_len);
-			p = sav->key_auth;
-			break;
-
-		case SADB_EXT_KEY_ENCRYPT:
-			if (!sav->key_enc)
-				continue;
-			l = PFKEY_UNUNIT64(sav->key_enc->sadb_key_len);
-			p = sav->key_enc;
-			break;
-
-		case SADB_EXT_LIFETIME_CURRENT:
-			if (!sav->lft_c)
-				continue;
-			l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_c)->sadb_ext_len);
-			p = sav->lft_c;
-			break;
-
-		case SADB_EXT_LIFETIME_HARD:
-			if (!sav->lft_h)
-				continue;
-			l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_h)->sadb_ext_len);
-			p = sav->lft_h;
-			break;
-
-		case SADB_EXT_LIFETIME_SOFT:
-			if (!sav->lft_s)
-				continue;
-			l = PFKEY_UNUNIT64(((struct sadb_ext *)sav->lft_s)->sadb_ext_len);
-			p = sav->lft_s;
-			break;
-
-		case SADB_EXT_ADDRESS_PROXY:
-		case SADB_EXT_IDENTITY_SRC:
-		case SADB_EXT_IDENTITY_DST:
-			/* XXX: should we brought from SPD ? */
-		case SADB_EXT_SENSITIVITY:
-		default:
-			continue;
-		}
-
-		if ((!m && !p) || (m && p))
-			goto fail;
-		if (p && tres) {
-			M_PREPEND(tres, l, M_DONTWAIT);
-			if (!tres)
-				goto fail;
-			bcopy(p, mtod(tres, caddr_t), l);
-			continue;
-		}
-		if (p) {
-			m = key_alloc_mbuf(l);
-			if (!m)
-				goto fail;
-			m_copyback(m, 0, l, p);
-		}
-
-		if (tres)
-			m_cat(m, tres);
-		tres = m;
-	}
-
-	m_cat(result, tres);
-
-	if (result->m_len < sizeof(struct sadb_msg)) {
-		result = m_pullup(result, sizeof(struct sadb_msg));
-		if (result == NULL)
-			goto fail;
-	}
-
-	result->m_pkthdr.len = 0;
-	for (m = result; m; m = m->m_next)
-		result->m_pkthdr.len += m->m_len;
-
-	mtod(result, struct sadb_msg *)->sadb_msg_len =
-	    PFKEY_UNIT64(result->m_pkthdr.len);
-
-	return result;
-
-fail:
-	m_freem(result);
-	m_freem(tres);
-	return NULL;
-}
-
-/*
- * set data into sadb_msg.
- */
-static struct mbuf *
-key_setsadbmsg(type, tlen, satype, seq, pid, reserved)
-	u_int8_t type, satype;
-	u_int16_t tlen;
-	u_int32_t seq;
-	pid_t pid;
-	u_int16_t reserved;
-{
-	struct mbuf *m;
-	struct sadb_msg *p;
-	int len;
-
-	len = PFKEY_ALIGN8(sizeof(struct sadb_msg));
-	if (len > MCLBYTES)
-		return NULL;
-	MGETHDR(m, M_DONTWAIT, MT_DATA);
-	if (m && len > MHLEN) {
-		MCLGET(m, M_DONTWAIT);
-		if ((m->m_flags & M_EXT) == 0) {
-			m_freem(m);
-			m = NULL;
-		}
-	}
-	if (!m)
-		return NULL;
-	m->m_pkthdr.len = m->m_len = len;
-	m->m_next = NULL;
-
-	p = mtod(m, struct sadb_msg *);
-
-	bzero(p, len);
-	p->sadb_msg_version = PF_KEY_V2;
-	p->sadb_msg_type = type;
-	p->sadb_msg_errno = 0;
-	p->sadb_msg_satype = satype;
-	p->sadb_msg_len = PFKEY_UNIT64(tlen);
-	p->sadb_msg_reserved = reserved;
-	p->sadb_msg_seq = seq;
-	p->sadb_msg_pid = (u_int32_t)pid;
-
-	return m;
-}
-
-/*
- * copy secasvar data into sadb_address.
- */
-static struct mbuf *
-key_setsadbsa(sav)
-	struct secasvar *sav;
-{
-	struct mbuf *m;
-	struct sadb_sa *p;
-	int len;
-
-	len = PFKEY_ALIGN8(sizeof(struct sadb_sa));
-	m = key_alloc_mbuf(len);
-	if (!m || m->m_next) {	/*XXX*/
-		if (m)
-			m_freem(m);
-		return NULL;
-	}
-
-	p = mtod(m, struct sadb_sa *);
-
-	bzero(p, len);
-	p->sadb_sa_len = PFKEY_UNIT64(len);
-	p->sadb_sa_exttype = SADB_EXT_SA;
-	p->sadb_sa_spi = sav->spi;
-	p->sadb_sa_replay = (sav->replay != NULL ? sav->replay->wsize : 0);
-	p->sadb_sa_state = sav->state;
-	p->sadb_sa_auth = sav->alg_auth;
-	p->sadb_sa_encrypt = sav->alg_enc;
-	p->sadb_sa_flags = sav->flags;
-
-	return m;
-}
-
-/*
- * set data into sadb_address.
- */
-static struct mbuf *
-key_setsadbaddr(exttype, saddr, prefixlen, ul_proto)
-	u_int16_t exttype;
-	struct sockaddr *saddr;
-	u_int8_t prefixlen;
-	u_int16_t ul_proto;
-{
-	struct mbuf *m;
-	struct sadb_address *p;
-	size_t len;
-
-	len = PFKEY_ALIGN8(sizeof(struct sadb_address)) +
-	    PFKEY_ALIGN8(saddr->sa_len);
-	m = key_alloc_mbuf(len);
-	if (!m || m->m_next) {	/*XXX*/
-		if (m)
-			m_freem(m);
-		return NULL;
-	}
-
-	p = mtod(m, struct sadb_address *);
-
-	bzero(p, len);
-	p->sadb_address_len = PFKEY_UNIT64(len);
-	p->sadb_address_exttype = exttype;
-	p->sadb_address_proto = ul_proto;
-	if (prefixlen == FULLMASK) {
-		switch (saddr->sa_family) {
-		case AF_INET:
-			prefixlen = sizeof(struct in_addr) << 3;
-			break;
-		case AF_INET6:
-			prefixlen = sizeof(struct in6_addr) << 3;
-			break;
-		default:
-			; /*XXX*/
-		}
-	}
-	p->sadb_address_prefixlen = prefixlen;
-	p->sadb_address_reserved = 0;
-
-	bcopy(saddr,
-	    mtod(m, caddr_t) + PFKEY_ALIGN8(sizeof(struct sadb_address)),
-	    saddr->sa_len);
-
-	return m;
-}
-
-#if 0
-/*
- * set data into sadb_ident.
- */
-static struct mbuf *
-key_setsadbident(exttype, idtype, string, stringlen, id)
-	u_int16_t exttype, idtype;
-	caddr_t string;
-	int stringlen;
-	u_int64_t id;
-{
-	struct mbuf *m;
-	struct sadb_ident *p;
-	size_t len;
-
-	len = PFKEY_ALIGN8(sizeof(struct sadb_ident)) + PFKEY_ALIGN8(stringlen);
-	m = key_alloc_mbuf(len);
-	if (!m || m->m_next) {	/*XXX*/
-		if (m)
-			m_freem(m);
-		return NULL;
-	}
-
-	p = mtod(m, struct sadb_ident *);
-
-	bzero(p, len);
-	p->sadb_ident_len = PFKEY_UNIT64(len);
-	p->sadb_ident_exttype = exttype;
-	p->sadb_ident_type = idtype;
-	p->sadb_ident_reserved = 0;
-	p->sadb_ident_id = id;
-
-	bcopy(string,
-	    mtod(m, caddr_t) + PFKEY_ALIGN8(sizeof(struct sadb_ident)),
-	    stringlen);
-
-	return m;
-}
-#endif
-
-/*
- * set data into sadb_x_sa2.
- */
-static struct mbuf *
-key_setsadbxsa2(mode, seq, reqid)
-	u_int8_t mode;
-	u_int32_t seq, reqid;
-{
-	struct mbuf *m;
-	struct sadb_x_sa2 *p;
-	size_t len;
-
-	len = PFKEY_ALIGN8(sizeof(struct sadb_x_sa2));
-	m = key_alloc_mbuf(len);
-	if (!m || m->m_next) {	/*XXX*/
-		if (m)
-			m_freem(m);
-		return NULL;
-	}
-
-	p = mtod(m, struct sadb_x_sa2 *);
-
-	bzero(p, len);
-	p->sadb_x_sa2_len = PFKEY_UNIT64(len);
-	p->sadb_x_sa2_exttype = SADB_X_EXT_SA2;
-	p->sadb_x_sa2_mode = mode;
-	p->sadb_x_sa2_reserved1 = 0;
-	p->sadb_x_sa2_reserved2 = 0;
-	p->sadb_x_sa2_sequence = seq;
-	p->sadb_x_sa2_reqid = reqid;
-
-	return m;
-}
-
-/*
- * set data into sadb_lifetime
- */
-static struct mbuf *
-key_setsadblifetime(type, alloc, bytes, addtime, usetime)
-	u_int16_t type;
-	u_int32_t alloc;
-	u_int64_t bytes, addtime, usetime;
-{
-	struct mbuf *m;
-	struct sadb_lifetime *p;
-	size_t len;
-
-	len = PFKEY_ALIGN8(sizeof(struct sadb_lifetime));
-	m = key_alloc_mbuf(len);
-	if (!m || m->m_next) {	/*XXX*/
-		if (m)
-			m_freem(m);
-		return NULL;
-	}
-
-	p = mtod(m, struct sadb_lifetime *);
-
-	bzero(p, len);
-	p->sadb_lifetime_len = PFKEY_UNIT64(len);
-	p->sadb_lifetime_exttype = type;
-	p->sadb_lifetime_allocations = alloc;
-	p->sadb_lifetime_bytes = bytes;
-	p->sadb_lifetime_addtime = addtime;
-	p->sadb_lifetime_usetime = usetime;
-
-	return m;
-}
-
-/*
- * set data into sadb_x_policy
- */
-static struct mbuf *
-key_setsadbxpolicy(type, dir, id)
-	u_int16_t type;
-	u_int8_t dir;
-	u_int32_t id;
-{
-	struct mbuf *m;
-	struct sadb_x_policy *p;
-	size_t len;
-
-	len = PFKEY_ALIGN8(sizeof(struct sadb_x_policy));
-	m = key_alloc_mbuf(len);
-	if (!m || m->m_next) {	/*XXX*/
-		if (m)
-			m_freem(m);
-		return NULL;
-	}
-
-	p = mtod(m, struct sadb_x_policy *);
-
-	bzero(p, len);
-	p->sadb_x_policy_len = PFKEY_UNIT64(len);
-	p->sadb_x_policy_exttype = SADB_X_EXT_POLICY;
-	p->sadb_x_policy_type = type;
-	p->sadb_x_policy_dir = dir;
-	p->sadb_x_policy_id = id;
-
-	return m;
-}
-
-/* %%% utilities */
-/*
- * copy a buffer into the new buffer allocated.
- */
-static void *
-key_newbuf(src, len)
-	const void *src;
-	u_int len;
-{
-	caddr_t new;
-
-	KMALLOC(new, caddr_t, len);
-	if (new == NULL) {
-		ipseclog((LOG_DEBUG, "key_newbuf: No more memory.\n"));
-		return NULL;
-	}
-	bcopy(src, new, len);
-
-	return new;
-}
-
-/* compare my own address
- * OUT:	1: true, i.e. my address.
- *	0: false
- */
-static int
-key_ismyaddr(sa)
-	struct sockaddr *sa;
-{
-#ifdef INET
-	struct sockaddr_in *sin;
-	struct in_ifaddr *ia;
-#endif
-
-	/* sanity check */
-	if (sa == NULL)
-		panic("key_ismyaddr: NULL pointer is passed.");
-
-	switch (sa->sa_family) {
-#ifdef INET
-	case AF_INET:
-		sin = (struct sockaddr_in *)sa;
-		for (ia = in_ifaddrhead.tqh_first; ia;
-		     ia = ia->ia_link.tqe_next)
-		{
-			if (sin->sin_family == ia->ia_addr.sin_family &&
-			    sin->sin_len == ia->ia_addr.sin_len &&
-			    sin->sin_addr.s_addr == ia->ia_addr.sin_addr.s_addr)
-			{
-				return 1;
-			}
-		}
-		break;
-#endif
-#ifdef INET6
-	case AF_INET6:
-		return key_ismyaddr6((struct sockaddr_in6 *)sa);
-#endif
-	}
-
-	return 0;
-}
-
-#ifdef INET6
-/*
- * compare my own address for IPv6.
- * 1: ours
- * 0: other
- * NOTE: derived ip6_input() in KAME. This is necessary to modify more.
- */
-#include <netinet6/in6_var.h>
-
-static int
-key_ismyaddr6(sin6)
-	struct sockaddr_in6 *sin6;
-{
-	struct in6_ifaddr *ia;
-	struct in6_multi *in6m;
-
-	if (sa6_embedscope(sin6, 0) != 0)
-		return 0;
-
-	for (ia = in6_ifaddr; ia; ia = ia->ia_next) {
-		if (key_sockaddrcmp((struct sockaddr *)&sin6,
-		    (struct sockaddr *)&ia->ia_addr, 0) == 0)
-			return 1;
-
-		/*
-		 * XXX Multicast
-		 * XXX why do we care about multlicast here while we don't care
-		 * about IPv4 multicast??
-		 */
-		in6m = NULL;
-		IN6_LOOKUP_MULTI(sin6->sin6_addr, ia->ia_ifp, in6m);
-		if (in6m)
-			return 1;
-	}
-
-	/* loopback, just for safety */
-	if (IN6_IS_ADDR_LOOPBACK(&sin6->sin6_addr))
-		return 1;
-
-	return 0;
-}
-#endif /*INET6*/
-
-/*
- * compare two secasindex structure.
- * flag can specify to compare 2 saidxes.
- * compare two secasindex structure without both mode and reqid.
- * don't compare port.
- * IN:  
- *      saidx0: source, it can be in SAD.
- *      saidx1: object.
- * OUT: 
- *      1 : equal
- *      0 : not equal
- */
-static int
-key_cmpsaidx(saidx0, saidx1, flag)
-	struct secasindex *saidx0, *saidx1;
-	int flag;
-{
-	/* sanity */
-	if (saidx0 == NULL && saidx1 == NULL)
-		return 1;
-
-	if (saidx0 == NULL || saidx1 == NULL)
-		return 0;
-
-	if (saidx0->proto != saidx1->proto)
-		return 0;
-
-	if (flag == CMP_EXACTLY) {
-		if (saidx0->mode != saidx1->mode)
-			return 0;
-		if (saidx0->reqid != saidx1->reqid)
-			return 0;
-		if (bcmp(&saidx0->src, &saidx1->src, saidx0->src.ss_len) != 0 ||
-		    bcmp(&saidx0->dst, &saidx1->dst, saidx0->dst.ss_len) != 0)
-			return 0;
-	} else {
-
-		/* CMP_MODE_REQID, CMP_HEAD */
-		if (flag == CMP_MODE_REQID) {
-			/*
-			 * If reqid of SPD is non-zero, unique SA is required.
-			 * The result must be of same reqid in this case.
-			 */
-			if (saidx1->reqid != 0 && saidx0->reqid != saidx1->reqid)
-				return 0;
-		}
-
-		if (flag == CMP_MODE_REQID) {
-			if (saidx0->mode != IPSEC_MODE_ANY &&
-			    saidx0->mode != saidx1->mode)
-				return 0;
-		}
-
-		if (key_sockaddrcmp((struct sockaddr *)&saidx0->src,
-				(struct sockaddr *)&saidx1->src, 0) != 0) {
-			return 0;
-		}
-		if (key_sockaddrcmp((struct sockaddr *)&saidx0->dst,
-				(struct sockaddr *)&saidx1->dst, 0) != 0) {
-			return 0;
-		}
-	}
-
-	return 1;
-}
-
-/*
- * compare two secindex structure exactly.
- * IN:
- *	spidx0: source, it is often in SPD.
- *	spidx1: object, it is often from PFKEY message.
- * OUT:
- *	1 : equal
- *	0 : not equal
- */
-int
-key_cmpspidx_exactly(spidx0, spidx1)
-	struct secpolicyindex *spidx0, *spidx1;
-{
-	/* sanity */
-	if (spidx0 == NULL && spidx1 == NULL)
-		return 1;
-
-	if (spidx0 == NULL || spidx1 == NULL)
-		return 0;
-
-	if (spidx0->prefs != spidx1->prefs || spidx0->prefd != spidx1->prefd ||
-	    spidx0->ul_proto != spidx1->ul_proto)
-		return 0;
-
-	if (key_sockaddrcmp((struct sockaddr *)&spidx0->src,
-	    (struct sockaddr *)&spidx1->src, 1) != 0) {
-		return 0;
-	}
-	if (key_sockaddrcmp((struct sockaddr *)&spidx0->dst,
-	    (struct sockaddr *)&spidx1->dst, 1) != 0) {
-		return 0;
-	}
-
-	return 1;
-}
-
-/*
- * compare two secindex structure with mask.
- * IN:
- *	spidx0: source, it is often in SPD.
- *	spidx1: object, it is often from IP header.
- * OUT:
- *	1 : equal
- *	0 : not equal
- */
-int
-key_cmpspidx_withmask(spidx0, spidx1)
-	struct secpolicyindex *spidx0, *spidx1;
-{
-	/* sanity */
-	if (spidx0 == NULL && spidx1 == NULL)
-		return 1;
-
-	if (spidx0 == NULL || spidx1 == NULL)
-		return 0;
-
-	if (spidx0->src.ss_family != spidx1->src.ss_family ||
-	    spidx0->dst.ss_family != spidx1->dst.ss_family ||
-	    spidx0->src.ss_len != spidx1->src.ss_len ||
-	    spidx0->dst.ss_len != spidx1->dst.ss_len)
-		return 0;
-
-	/* if spidx.ul_proto == IPSEC_ULPROTO_ANY, ignore. */
-	if (spidx0->ul_proto != (u_int16_t)IPSEC_ULPROTO_ANY &&
-	    spidx0->ul_proto != spidx1->ul_proto)
-		return 0;
-
-	switch (spidx0->src.ss_family) {
-	case AF_INET:
-		if (satosin(&spidx0->src)->sin_port != IPSEC_PORT_ANY &&
-		    satosin(&spidx0->src)->sin_port !=
-		    satosin(&spidx1->src)->sin_port)
-			return 0;
-		if (!key_bbcmp((caddr_t)&satosin(&spidx0->src)->sin_addr,
-		    (caddr_t)&satosin(&spidx1->src)->sin_addr, spidx0->prefs))
-			return 0;
-		break;
-	case AF_INET6:
-		if (satosin6(&spidx0->src)->sin6_port != IPSEC_PORT_ANY &&
-		    satosin6(&spidx0->src)->sin6_port !=
-		    satosin6(&spidx1->src)->sin6_port)
-			return 0;
-		/*
-		 * scope_id check. if sin6_scope_id is 0, we regard it
-		 * as a wildcard scope, which matches any scope zone ID. 
-		 */
-		if (satosin6(&spidx0->src)->sin6_scope_id &&
-		    satosin6(&spidx1->src)->sin6_scope_id &&
-		    satosin6(&spidx0->src)->sin6_scope_id !=
-		    satosin6(&spidx1->src)->sin6_scope_id)
-			return 0;
-		if (!key_bbcmp((caddr_t)&satosin6(&spidx0->src)->sin6_addr,
-		    (caddr_t)&satosin6(&spidx1->src)->sin6_addr, spidx0->prefs))
-			return 0;
-		break;
-	default:
-		/* XXX */
-		if (bcmp(&spidx0->src, &spidx1->src, spidx0->src.ss_len) != 0)
-			return 0;
-		break;
-	}
-
-	switch (spidx0->dst.ss_family) {
-	case AF_INET:
-		if (satosin(&spidx0->dst)->sin_port != IPSEC_PORT_ANY &&
-		    satosin(&spidx0->dst)->sin_port !=
-		    satosin(&spidx1->dst)->sin_port)
-			return 0;
-		if (!key_bbcmp((caddr_t)&satosin(&spidx0->dst)->sin_addr,
-		    (caddr_t)&satosin(&spidx1->dst)->sin_addr, spidx0->prefd))
-			return 0;
-		break;
-	case AF_INET6:
-		if (satosin6(&spidx0->dst)->sin6_port != IPSEC_PORT_ANY &&
-		    satosin6(&spidx0->dst)->sin6_port !=
-		    satosin6(&spidx1->dst)->sin6_port)
-			return 0;
-		/*
-		 * scope_id check. if sin6_scope_id is 0, we regard it
-		 * as a wildcard scope, which matches any scope zone ID. 
-		 */
-		if (satosin6(&spidx0->src)->sin6_scope_id &&
-		    satosin6(&spidx1->src)->sin6_scope_id &&
-		    satosin6(&spidx0->dst)->sin6_scope_id !=
-		    satosin6(&spidx1->dst)->sin6_scope_id)
-			return 0;
-		if (!key_bbcmp((caddr_t)&satosin6(&spidx0->dst)->sin6_addr,
-		    (caddr_t)&satosin6(&spidx1->dst)->sin6_addr, spidx0->prefd))
-			return 0;
-		break;
-	default:
-		/* XXX */
-		if (bcmp(&spidx0->dst, &spidx1->dst, spidx0->dst.ss_len) != 0)
-			return 0;
-		break;
-	}
-
-	/* XXX Do we check other field ?  e.g. flowinfo */
-
-	return 1;
-}
-
-/* returns 0 on match */
-static int
-key_sockaddrcmp(sa1, sa2, port)
-	struct sockaddr *sa1;
-	struct sockaddr *sa2;
-	int port;
-{
-	if (sa1->sa_family != sa2->sa_family || sa1->sa_len != sa2->sa_len)
-		return 1;
-
-	switch (sa1->sa_family) {
-	case AF_INET:
-		if (sa1->sa_len != sizeof(struct sockaddr_in))
-			return 1;
-		if (satosin(sa1)->sin_addr.s_addr !=
-		    satosin(sa2)->sin_addr.s_addr) {
-			return 1;
-		}
-		if (port && satosin(sa1)->sin_port != satosin(sa2)->sin_port)
-			return 1;
-		break;
-	case AF_INET6:
-		if (sa1->sa_len != sizeof(struct sockaddr_in6))
-			return 1;	/*EINVAL*/
-		if (satosin6(sa1)->sin6_scope_id !=
-		    satosin6(sa2)->sin6_scope_id) {
-			return 1;
-		}
-		if (!IN6_ARE_ADDR_EQUAL(&satosin6(sa1)->sin6_addr,
-		    &satosin6(sa2)->sin6_addr)) {
-			return 1;
-		}
-		if (port &&
-		    satosin6(sa1)->sin6_port != satosin6(sa2)->sin6_port) {
-			return 1;
-		}
-		break;
-	default:
-		if (bcmp(sa1, sa2, sa1->sa_len) != 0)
-			return 1;
-		break;
-	}
-
-	return 0;
-}
-
-/*
- * compare two buffers with mask.
- * IN:
- *	addr1: source
- *	addr2: object
- *	bits:  Number of bits to compare
- * OUT:
- *	1 : equal
- *	0 : not equal
- */
-static int
-key_bbcmp(p1, p2, bits)
-	caddr_t p1, p2;
-	u_int bits;
-{
-	u_int8_t mask;
-
-	/* XXX: This could be considerably faster if we compare a word
-	 * at a time, but it is complicated on LSB Endian machines */
-
-	/* Handle null pointers */
-	if (p1 == NULL || p2 == NULL)
-		return (p1 == p2);
-
-	while (bits >= 8) {
-		if (*p1++ != *p2++)
-			return 0;
-		bits -= 8;
-	}
-
-	if (bits > 0) {
-		mask = ~((1<<(8-bits))-1);
-		if ((*p1 & mask) != (*p2 & mask))
-			return 0;
-	}
-	return 1;	/* Match! */
-}
-
-/*
- * time handler.
- * scanning SPD and SAD to check status for each entries,
- * and do to remove or to expire.
- * XXX: year 2038 problem may remain.
- */
-void
-key_timehandler(arg)
-	void *arg;
-{
-	u_int dir;
-	int s;
-	struct timeval tv;
-
-	microtime(&tv);
-
-	s = splnet();	/*called from softclock()*/
-
-	/* SPD */
-    {
-	struct secpolicy *sp, *nextsp;
-
-	for (dir = 0; dir < IPSEC_DIR_MAX; dir++) {
-		for (sp = LIST_FIRST(&sptree[dir]);
-		     sp != NULL;
-		     sp = nextsp) {
-			nextsp = LIST_NEXT(sp, chain);
-
-			if (sp->state == IPSEC_SPSTATE_DEAD) {
-				key_sp_unlink(sp);	/*XXX*/
-				sp = NULL;
-				continue;
-			}
-
-			if (sp->lifetime == 0 && sp->validtime == 0)
-				continue;
-
-			/* the deletion will occur next time */
-			if ((sp->lifetime &&
-			     tv.tv_sec - sp->created > sp->lifetime) ||
-			    (sp->validtime &&
-			     tv.tv_sec - sp->lastused > sp->validtime)) {
-				key_sp_dead(sp);
-				key_spdexpire(sp);
-				continue;
-			}
-		}
-	}
-
-	/* invalidate all cached SPD pointers on pcb */
-	ipsec_invalpcbcacheall();
-    }
-
-	/* SAD */
-    {
-	struct secashead *sah, *nextsah;
-	struct secasvar *sav, *nextsav;
-
-	for (sah = LIST_FIRST(&sahtree);
-	     sah != NULL;
-	     sah = nextsah) {
-
-		nextsah = LIST_NEXT(sah, chain);
-
-		/* if sah has been dead, then delete it and process next sah. */
-		if (sah->state == SADB_SASTATE_DEAD) {
-			key_delsah(sah);
-			continue;
-		}
-
-		/* if LARVAL entry doesn't become MATURE, delete it. */
-		for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_LARVAL]);
-		     sav != NULL;
-		     sav = nextsav) {
-
-			nextsav = LIST_NEXT(sav, chain);
-
-			if (tv.tv_sec - sav->created > key_larval_lifetime) {
-				key_freesav(sav);
-			}
-		}
-
-		/*
-		 * check MATURE entry to start to send expire message
-		 * whether or not.
-		 */
-		for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_MATURE]);
-		     sav != NULL;
-		     sav = nextsav) {
-
-			nextsav = LIST_NEXT(sav, chain);
-
-			/* we don't need to check. */
-			if (sav->lft_s == NULL)
-				continue;
-
-			/* sanity check */
-			if (sav->lft_c == NULL) {
-				ipseclog((LOG_DEBUG, "key_timehandler: "
-					"There is no CURRENT time, why?\n"));
-				continue;
-			}
-
-			/* check SOFT lifetime */
-			if (sav->lft_s->sadb_lifetime_addtime != 0 &&
-			    tv.tv_sec - sav->created > sav->lft_s->sadb_lifetime_addtime) {
-				/*
-				 * check the SA if it has been used.
-				 * when it hasn't been used, delete it.
-				 * i don't think such SA will be used.
-				 */
-				if (sav->lft_c->sadb_lifetime_usetime == 0) {
-					key_sa_chgstate(sav, SADB_SASTATE_DEAD);
-					key_freesav(sav);
-					sav = NULL;
-				} else {
-					key_sa_chgstate(sav, SADB_SASTATE_DYING);
-					/*
-					 * XXX If we keep to send expire
-					 * message in the status of
-					 * DYING. Do remove below code.
-					 */
-					key_expire(sav);
-				}
-			}
-
-			/* check SOFT lifetime by bytes */
-			/*
-			 * XXX I don't know the way to delete this SA
-			 * when new SA is installed.  Caution when it's
-			 * installed too big lifetime by time.
-			 */
-			else if (sav->lft_s->sadb_lifetime_bytes != 0
-			      && sav->lft_s->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) {
-
-				key_sa_chgstate(sav, SADB_SASTATE_DYING);
-				/*
-				 * XXX If we keep to send expire
-				 * message in the status of
-				 * DYING. Do remove below code.
-				 */
-				key_expire(sav);
-			}
-		}
-
-		/* check DYING entry to change status to DEAD. */
-		for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DYING]);
-		     sav != NULL;
-		     sav = nextsav) {
-
-			nextsav = LIST_NEXT(sav, chain);
-
-			/* we don't need to check. */
-			if (sav->lft_h == NULL)
-				continue;
-
-			/* sanity check */
-			if (sav->lft_c == NULL) {
-				ipseclog((LOG_DEBUG, "key_timehandler: "
-					"There is no CURRENT time, why?\n"));
-				continue;
-			}
-
-			if (sav->lft_h->sadb_lifetime_addtime != 0 &&
-			    tv.tv_sec - sav->created > sav->lft_h->sadb_lifetime_addtime) {
-				key_sa_chgstate(sav, SADB_SASTATE_DEAD);
-				key_freesav(sav);
-				sav = NULL;
-			}
-#if 0	/* XXX Should we keep to send expire message until HARD lifetime ? */
-			else if (sav->lft_s != NULL
-			      && sav->lft_s->sadb_lifetime_addtime != 0
-			      && tv.tv_sec - sav->created > sav->lft_s->sadb_lifetime_addtime) {
-				/*
-				 * XXX: should be checked to be
-				 * installed the valid SA.
-				 */
-
-				/*
-				 * If there is no SA then sending
-				 * expire message.
-				 */
-				key_expire(sav);
-			}
-#endif
-			/* check HARD lifetime by bytes */
-			else if (sav->lft_h->sadb_lifetime_bytes != 0
-			      && sav->lft_h->sadb_lifetime_bytes < sav->lft_c->sadb_lifetime_bytes) {
-				key_sa_chgstate(sav, SADB_SASTATE_DEAD);
-				key_freesav(sav);
-				sav = NULL;
-			}
-		}
-
-		/* delete entry in DEAD */
-		for (sav = LIST_FIRST(&sah->savtree[SADB_SASTATE_DEAD]);
-		     sav != NULL;
-		     sav = nextsav) {
-
-			nextsav = LIST_NEXT(sav, chain);
-
-			/* sanity check */
-			if (sav->state != SADB_SASTATE_DEAD) {
-				ipseclog((LOG_DEBUG, "key_timehandler: "
-					"invalid sav->state "
-					"(queue: %u SA: %u): "
-					"kill it anyway\n",
-					SADB_SASTATE_DEAD, sav->state));
-			}
-
-			/*
-			 * do not call key_freesav() here.
-			 * sav should already be freed, and sav->refcnt
-			 * shows other references to sav
-			 * (such as from SPD).
-			 */
-		}
-	}
-    }
-
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-	/* ACQ tree */
-    {
-	struct secacq *acq, *nextacq;
-
-	for (acq = LIST_FIRST(&acqtree);
-	     acq != NULL;
-	     acq = nextacq) {
-
-		nextacq = LIST_NEXT(acq, chain);
-
-		if (tv.tv_sec - acq->created > key_blockacq_lifetime &&
-		    __LIST_CHAINED(acq)) {
-			LIST_REMOVE(acq, chain);
-			KFREE(acq);
-		}
-	}
-    }
-#endif
-
-	/* SP ACQ tree */
-    {
-	struct secspacq *acq, *nextacq;
-
-	for (acq = LIST_FIRST(&spacqtree);
-	     acq != NULL;
-	     acq = nextacq) {
-
-		nextacq = LIST_NEXT(acq, chain);
-
-		if (tv.tv_sec - acq->created > key_blockacq_lifetime &&
-		    __LIST_CHAINED(acq)) {
-			LIST_REMOVE(acq, chain);
-			KFREE(acq);
-		}
-	}
-    }
-
-	/*
-	 * should set timeout based on the most closest timer expiration.
-	 * we don't bother to do that yet.
-	 */
-	callout_reset(&key_timehandler_ch, hz, key_timehandler, (void *)0);
-
-	splx(s);
-	return;
-}
-
-static u_long
-key_random()
-{
-	u_long value;
-
-	key_randomfill(&value, sizeof(value));
-	return value;
-}
-
-void
-key_randomfill(p, l)
-	void *p;
-	size_t l;
-{
-	size_t n;
-	u_long v;
-	static int warn = 1;
-
-	n = 0;
-	n = (size_t)read_random(p, (u_int)l);
-	/* last resort */
-	while (n < l) {
-		v = random();
-		bcopy(&v, (u_int8_t *)p + n,
-		    l - n < sizeof(v) ? l - n : sizeof(v));
-		n += sizeof(v);
-
-		if (warn) {
-			printf("WARNING: pseudo-random number generator "
-			    "used for IPsec processing\n");
-			warn = 0;
-		}
-	}
-}
-
-/*
- * map SADB_SATYPE_* to IPPROTO_*.
- * if satype == SADB_SATYPE then satype is mapped to ~0.
- * OUT:
- *	0: invalid satype.
- */
-static u_int16_t
-key_satype2proto(satype)
-	u_int8_t satype;
-{
-	switch (satype) {
-	case SADB_SATYPE_UNSPEC:
-		return IPSEC_PROTO_ANY;
-	case SADB_SATYPE_AH:
-		return IPPROTO_AH;
-	case SADB_SATYPE_ESP:
-		return IPPROTO_ESP;
-	case SADB_X_SATYPE_IPCOMP:
-		return IPPROTO_IPCOMP;
-	case SADB_X_SATYPE_TCPSIGNATURE:
-		return IPPROTO_TCP;
-	default:
-		return 0;
-	}
-	/* NOTREACHED */
-}
-
-/*
- * map IPPROTO_* to SADB_SATYPE_*
- * OUT:
- *	0: invalid protocol type.
- */
-static u_int8_t
-key_proto2satype(proto)
-	u_int16_t proto;
-{
-	switch (proto) {
-	case IPPROTO_AH:
-		return SADB_SATYPE_AH;
-	case IPPROTO_ESP:
-		return SADB_SATYPE_ESP;
-	case IPPROTO_IPCOMP:
-		return SADB_X_SATYPE_IPCOMP;
-	case IPPROTO_TCP:
-		return SADB_X_SATYPE_TCPSIGNATURE;
-	default:
-		return 0;
-	}
-	/* NOTREACHED */
-}
-
-/* %%% PF_KEY */
-/*
- * SADB_GETSPI processing is to receive
- *	<base, (SA2), src address, dst address, (SPI range)>
- * from the IKMPd, to assign a unique spi value, to hang on the INBOUND
- * tree with the status of LARVAL, and send
- *	<base, SA(*), address(SD)>
- * to the IKMPd.
- *
- * IN:	mhp: pointer to the pointer to each header.
- * OUT:	NULL if fail.
- *	other if success, return pointer to the message to send.
- */
-static int
-key_getspi(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_address *src0, *dst0;
-	struct secasindex saidx;
-	struct secashead *newsah;
-	struct secasvar *newsav;
-	u_int8_t proto;
-	u_int32_t spi;
-	u_int8_t mode;
-	u_int32_t reqid;
-	int error;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_getspi: NULL pointer is passed.");
-
-	if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) {
-		ipseclog((LOG_DEBUG, "key_getspi: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
-		ipseclog((LOG_DEBUG, "key_getspi: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->ext[SADB_X_EXT_SA2] != NULL) {
-		mode = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
-		reqid = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_reqid;
-	} else {
-		mode = IPSEC_MODE_ANY;
-		reqid = 0;
-	}
-
-	src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
-	dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
-
-	/* map satype to proto */
-	if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
-		ipseclog((LOG_DEBUG, "key_getspi: invalid satype is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	/* make sure if port number is zero. */
-	switch (((struct sockaddr *)(src0 + 1))->sa_family) {
-	case AF_INET:
-		if (((struct sockaddr *)(src0 + 1))->sa_len !=
-		    sizeof(struct sockaddr_in))
-			return key_senderror(so, m, EINVAL);
-		((struct sockaddr_in *)(src0 + 1))->sin_port = 0;
-		break;
-	case AF_INET6:
-		if (((struct sockaddr *)(src0 + 1))->sa_len !=
-		    sizeof(struct sockaddr_in6))
-			return key_senderror(so, m, EINVAL);
-		((struct sockaddr_in6 *)(src0 + 1))->sin6_port = 0;
-		break;
-	default:
-		; /*???*/
-	}
-	switch (((struct sockaddr *)(dst0 + 1))->sa_family) {
-	case AF_INET:
-		if (((struct sockaddr *)(dst0 + 1))->sa_len !=
-		    sizeof(struct sockaddr_in))
-			return key_senderror(so, m, EINVAL);
-		((struct sockaddr_in *)(dst0 + 1))->sin_port = 0;
-		break;
-	case AF_INET6:
-		if (((struct sockaddr *)(dst0 + 1))->sa_len !=
-		    sizeof(struct sockaddr_in6))
-			return key_senderror(so, m, EINVAL);
-		((struct sockaddr_in6 *)(dst0 + 1))->sin6_port = 0;
-		break;
-	default:
-		; /*???*/
-	}
-
-	/* XXX boundary check against sa_len */
-	KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx);
-
-	/* SPI allocation */
-	spi = key_do_getnewspi((struct sadb_spirange *)mhp->ext[SADB_EXT_SPIRANGE],
-	                       &saidx);
-	if (spi == 0)
-		return key_senderror(so, m, EINVAL);
-
-	/* get a SA index */
-	if ((newsah = key_getsah(&saidx)) == NULL) {
-		/* create a new SA index */
-		if ((newsah = key_newsah(&saidx)) == NULL) {
-			ipseclog((LOG_DEBUG, "key_getspi: No more memory.\n"));
-			return key_senderror(so, m, ENOBUFS);
-		}
-	}
-
-	/* get a new SA */
-	/* XXX rewrite */
-	newsav = key_newsav(m, mhp, newsah, &error);
-	if (newsav == NULL) {
-		/* XXX don't free new SA index allocated in above. */
-		return key_senderror(so, m, error);
-	}
-
-	/* set spi */
-	key_setspi(newsav, htonl(spi));
-
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-	/* delete the entry in acqtree */
-	if (mhp->msg->sadb_msg_seq != 0) {
-		struct secacq *acq;
-		if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq)) != NULL) {
-			/* reset counter in order to deletion by timehandler. */
-			acq->created = time_second;
-			acq->count = 0;
-		}
-    	}
-#endif
-
-    {
-	struct mbuf *n, *nn;
-	struct sadb_sa *m_sa;
-	struct sadb_msg *newmsg;
-	int off, len;
-
-	/* create new sadb_msg to reply. */
-	len = PFKEY_ALIGN8(sizeof(struct sadb_msg)) +
-	    PFKEY_ALIGN8(sizeof(struct sadb_sa));
-	if (len > MCLBYTES)
-		return key_senderror(so, m, ENOBUFS);
-
-	MGETHDR(n, M_DONTWAIT, MT_DATA);
-	if (len > MHLEN) {
-		MCLGET(n, M_DONTWAIT);
-		if ((n->m_flags & M_EXT) == 0) {
-			m_freem(n);
-			n = NULL;
-		}
-	}
-	if (!n)
-		return key_senderror(so, m, ENOBUFS);
-
-	n->m_len = len;
-	n->m_next = NULL;
-	off = 0;
-
-	m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off);
-	off += PFKEY_ALIGN8(sizeof(struct sadb_msg));
-
-	m_sa = (struct sadb_sa *)(mtod(n, caddr_t) + off);
-	m_sa->sadb_sa_len = PFKEY_UNIT64(sizeof(struct sadb_sa));
-	m_sa->sadb_sa_exttype = SADB_EXT_SA;
-	m_sa->sadb_sa_spi = htonl(spi);
-	off += PFKEY_ALIGN8(sizeof(struct sadb_sa));
-
-#ifdef DIAGNOSTIC
-	if (off != len)
-		panic("length inconsistency in key_getspi");
-#endif
-
-	n->m_next = key_gather_mbuf(m, mhp, 0, 2, SADB_EXT_ADDRESS_SRC,
-	    SADB_EXT_ADDRESS_DST);
-	if (!n->m_next) {
-		m_freem(n);
-		return key_senderror(so, m, ENOBUFS);
-	}
-
-	if (n->m_len < sizeof(struct sadb_msg)) {
-		n = m_pullup(n, sizeof(struct sadb_msg));
-		if (n == NULL)
-			return key_sendup_mbuf(so, m, KEY_SENDUP_ONE);
-	}
-
-	n->m_pkthdr.len = 0;
-	for (nn = n; nn; nn = nn->m_next)
-		n->m_pkthdr.len += nn->m_len;
-
-	newmsg = mtod(n, struct sadb_msg *);
-	newmsg->sadb_msg_seq = newsav->seq;
-	newmsg->sadb_msg_errno = 0;
-	newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len);
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
-    }
-}
-
-/*
- * allocating new SPI
- * called by key_getspi().
- * OUT:
- *	0:	failure.
- *	others: success.
- */
-static u_int32_t
-key_do_getnewspi(spirange, saidx)
-	struct sadb_spirange *spirange;
-	struct secasindex *saidx;
-{
-	u_int32_t newspi;
-	u_int32_t min, max;
-	int count = key_spi_trycnt;
-
-	/* set spi range to allocate */
-	if (spirange != NULL) {
-		min = spirange->sadb_spirange_min;
-		max = spirange->sadb_spirange_max;
-	} else {
-		min = key_spi_minval;
-		max = key_spi_maxval;
-	}
-	/* IPCOMP needs 2-byte SPI */
-	if (saidx->proto == IPPROTO_IPCOMP) {
-		u_int32_t t;
-		if (min >= 0x10000)
-			min = 0xffff;
-		if (max >= 0x10000)
-			max = 0xffff;
-		if (min > max) {
-			t = min; min = max; max = t;
-		}
-	}
-
-	if (min == max) {
-		if (key_checkspidup(saidx, min) != NULL) {
-			ipseclog((LOG_DEBUG, "key_do_getnewspi: SPI %u exists already.\n", min));
-			return 0;
-		}
-
-		count--; /* taking one cost. */
-		newspi = min;
-
-	} else {
-
-		/* init SPI */
-		newspi = 0;
-
-		/* when requesting to allocate spi ranged */
-		while (count--) {
-			/* generate pseudo-random SPI value ranged. */
-			newspi = min + (key_random() % (max - min + 1));
-
-			if (key_checkspidup(saidx, newspi) == NULL)
-				break;
-		}
-
-		if (count == 0 || newspi == 0) {
-			ipseclog((LOG_DEBUG, "key_do_getnewspi: to allocate spi is failed.\n"));
-			return 0;
-		}
-	}
-
-	/* statistics */
-	keystat.getspi_count =
-		(keystat.getspi_count + key_spi_trycnt - count) / 2;
-
-	return newspi;
-}
-
-/*
- * SADB_UPDATE processing
- * receive
- *   <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
- *       key(AE), (identity(SD),) (sensitivity)>
- * from the ikmpd, and update a secasvar entry whose status is SADB_SASTATE_LARVAL.
- * and send
- *   <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
- *       (identity(SD),) (sensitivity)>
- * to the ikmpd.
- *
- * m will always be freed.
- */
-static int
-key_update(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_sa *sa0;
-	struct sadb_address *src0, *dst0;
-	struct secasindex saidx;
-	struct secashead *sah;
-	struct secasvar *sav;
-	u_int16_t proto;
-	u_int8_t mode;
-	u_int32_t reqid;
-	int error;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_update: NULL pointer is passed.");
-
-	/* map satype to proto */
-	if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
-		ipseclog((LOG_DEBUG, "key_update: invalid satype is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (mhp->ext[SADB_EXT_SA] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_DST] == NULL ||
-	    (mhp->msg->sadb_msg_satype == SADB_SATYPE_ESP &&
-	     mhp->ext[SADB_EXT_KEY_ENCRYPT] == NULL) ||
-	    (mhp->msg->sadb_msg_satype == SADB_SATYPE_AH &&
-	     mhp->ext[SADB_EXT_KEY_AUTH] == NULL) ||
-	    (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL &&
-	     mhp->ext[SADB_EXT_LIFETIME_SOFT] == NULL) ||
-	    (mhp->ext[SADB_EXT_LIFETIME_HARD] == NULL &&
-	     mhp->ext[SADB_EXT_LIFETIME_SOFT] != NULL)) {
-		ipseclog((LOG_DEBUG, "key_update: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
-		ipseclog((LOG_DEBUG, "key_update: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->ext[SADB_X_EXT_SA2] != NULL) {
-		mode = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
-		reqid = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_reqid;
-	} else {
-		mode = IPSEC_MODE_ANY;
-		reqid = 0;
-	}
-	/* XXX boundary checking for other extensions */
-
-	sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA];
-	src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
-	dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
-
-	/* XXX boundary check against sa_len */
-	KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx);
-
-	/* get a SA header */
-	if ((sah = key_getsah(&saidx)) == NULL) {
-		ipseclog((LOG_DEBUG, "key_update: no SA index found.\n"));
-		return key_senderror(so, m, ENOENT);
-	}
-
-	/* set spidx if there */
-	/* XXX rewrite */
-	error = key_setident(sah, m, mhp);
-	if (error)
-		return key_senderror(so, m, error);
-
-	/* find a SA with sequence number. */
-#ifdef IPSEC_DOSEQCHECK
-	if (mhp->msg->sadb_msg_seq != 0 &&
-	    (sav = key_getsavbyseq(sah, mhp->msg->sadb_msg_seq)) == NULL) {
-		ipseclog((LOG_DEBUG,
-		    "key_update: no larval SA with sequence %u exists.\n",
-		    mhp->msg->sadb_msg_seq));
-		return key_senderror(so, m, ENOENT);
-	}
-#else
-	if ((sav = key_getsavbyspi(sah, sa0->sadb_sa_spi)) == NULL) {
-		ipseclog((LOG_DEBUG,
-		    "key_update: no such a SA found (spi:%u)\n",
-		    (u_int32_t)ntohl(sa0->sadb_sa_spi)));
-		return key_senderror(so, m, EINVAL);
-	}
-#endif
-
-	/* validity check */
-	if (sav->sah->saidx.proto != proto) {
-		ipseclog((LOG_DEBUG,
-		    "key_update: protocol mismatched (DB=%u param=%u)\n",
-		    sav->sah->saidx.proto, proto));
-		return key_senderror(so, m, EINVAL);
-	}
-#ifdef IPSEC_DOSEQCHECK
-	if (sav->spi != sa0->sadb_sa_spi) {
-		ipseclog((LOG_DEBUG,
-		    "key_update: SPI mismatched (DB:%u param:%u)\n",
-		    (u_int32_t)ntohl(sav->spi),
-		    (u_int32_t)ntohl(sa0->sadb_sa_spi)));
-		return key_senderror(so, m, EINVAL);
-	}
-#endif
-	if (sav->pid != mhp->msg->sadb_msg_pid) {
-		ipseclog((LOG_DEBUG,
-		    "key_update: pid mismatched (DB:%u param:%u)\n",
-		    sav->pid, mhp->msg->sadb_msg_pid));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	/* copy sav values */
-	error = key_setsaval(sav, m, mhp);
-	if (error) {
-		key_freesav(sav);
-		return key_senderror(so, m, error);
-	}
-
-	/* check SA values to be mature. */
-	if ((error = key_mature(sav)) != 0) {
-		key_freesav(sav);
-		return key_senderror(so, m, error);
-	}
-
-    {
-	struct mbuf *n;
-
-	/* set msg buf from mhp */
-	n = key_getmsgbuf_x1(m, mhp);
-	if (n == NULL) {
-		ipseclog((LOG_DEBUG, "key_update: No more memory.\n"));
-		return key_senderror(so, m, ENOBUFS);
-	}
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
-    }
-}
-
-/*
- * search SAD with sequence for a SA which state is SADB_SASTATE_LARVAL.
- * only called by key_update().
- * OUT:
- *	NULL	: not found
- *	others	: found, pointer to a SA.
- */
-#ifdef IPSEC_DOSEQCHECK
-static struct secasvar *
-key_getsavbyseq(sah, seq)
-	struct secashead *sah;
-	u_int32_t seq;
-{
-	struct secasvar *sav;
-	u_int state;
-
-	state = SADB_SASTATE_LARVAL;
-
-	/* search SAD with sequence number ? */
-	LIST_FOREACH(sav, &sah->savtree[state], chain) {
-
-		KEY_CHKSASTATE(state, sav->state, "key_getsabyseq");
-
-		if (sav->seq == seq) {
-			sav->refcnt++;
-			KEYDEBUG(KEYDEBUG_IPSEC_STAMP,
-				printf("DP key_getsavbyseq cause "
-					"refcnt++:%d SA:%p\n",
-					sav->refcnt, sav));
-			return sav;
-		}
-	}
-
-	return NULL;
-}
-#endif
-
-/*
- * SADB_ADD processing
- * add an entry to SA database, when received
- *   <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
- *       key(AE), (identity(SD),) (sensitivity)>
- * from the ikmpd,
- * and send
- *   <base, SA, (SA2), (lifetime(HSC),) address(SD), (address(P),)
- *       (identity(SD),) (sensitivity)>
- * to the ikmpd.
- *
- * IGNORE identity and sensitivity messages.
- *
- * m will always be freed.
- */
-static int
-key_add(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_sa *sa0;
-	struct sadb_address *src0, *dst0;
-	struct secasindex saidx;
-	struct secashead *newsah;
-	struct secasvar *newsav;
-	u_int16_t proto;
-	u_int8_t mode;
-	u_int32_t reqid;
-	int error;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_add: NULL pointer is passed.");
-
-	/* map satype to proto */
-	if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
-		ipseclog((LOG_DEBUG, "key_add: invalid satype is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (mhp->ext[SADB_EXT_SA] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_DST] == NULL ||
-	    (mhp->msg->sadb_msg_satype == SADB_SATYPE_ESP &&
-	     mhp->ext[SADB_EXT_KEY_ENCRYPT] == NULL) ||
-	    (mhp->msg->sadb_msg_satype == SADB_SATYPE_AH &&
-	     mhp->ext[SADB_EXT_KEY_AUTH] == NULL) ||
-	    (mhp->ext[SADB_EXT_LIFETIME_HARD] != NULL &&
-	     mhp->ext[SADB_EXT_LIFETIME_SOFT] == NULL) ||
-	    (mhp->ext[SADB_EXT_LIFETIME_HARD] == NULL &&
-	     mhp->ext[SADB_EXT_LIFETIME_SOFT] != NULL)) {
-		ipseclog((LOG_DEBUG, "key_add: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
-		/* XXX need more */
-		ipseclog((LOG_DEBUG, "key_add: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->ext[SADB_X_EXT_SA2] != NULL) {
-		mode = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_mode;
-		reqid = ((struct sadb_x_sa2 *)mhp->ext[SADB_X_EXT_SA2])->sadb_x_sa2_reqid;
-	} else {
-		mode = IPSEC_MODE_ANY;
-		reqid = 0;
-	}
-
-	sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA];
-	src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
-	dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
-
-	/* XXX boundary check against sa_len */
-	KEY_SETSECASIDX(proto, mode, reqid, src0 + 1, dst0 + 1, &saidx);
-
-	/* get a SA header */
-	if ((newsah = key_getsah(&saidx)) == NULL) {
-		/* create a new SA header */
-		if ((newsah = key_newsah(&saidx)) == NULL) {
-			ipseclog((LOG_DEBUG, "key_add: No more memory.\n"));
-			return key_senderror(so, m, ENOBUFS);
-		}
-	}
-
-	/* set spidx if there */
-	/* XXX rewrite */
-	error = key_setident(newsah, m, mhp);
-	if (error) {
-		return key_senderror(so, m, error);
-	}
-
-	/* create new SA entry. */
-	/* We can create new SA only if SPI is differenct. */
-	if (key_getsavbyspi(newsah, sa0->sadb_sa_spi)) {
-		ipseclog((LOG_DEBUG, "key_add: SA already exists.\n"));
-		return key_senderror(so, m, EEXIST);
-	}
-	newsav = key_newsav(m, mhp, newsah, &error);
-	if (newsav == NULL) {
-		return key_senderror(so, m, error);
-	}
-
-	/* check SA values to be mature. */
-	if ((error = key_mature(newsav)) != 0) {
-		key_freesav(newsav);
-		return key_senderror(so, m, error);
-	}
-
-	/*
-	 * don't call key_freesav() here, as we would like to keep the SA
-	 * in the database on success.
-	 */
-
-    {
-	struct mbuf *n;
-
-	/* set msg buf from mhp */
-	n = key_getmsgbuf_x1(m, mhp);
-	if (n == NULL) {
-		ipseclog((LOG_DEBUG, "key_update: No more memory.\n"));
-		return key_senderror(so, m, ENOBUFS);
-	}
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
-    }
-}
-
-/* m is retained */
-static int
-key_setident(sah, m, mhp)
-	struct secashead *sah;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	const struct sadb_ident *idsrc, *iddst;
-	int idsrclen, iddstlen;
-
-	/* sanity check */
-	if (sah == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_setident: NULL pointer is passed.");
-
-	/* don't make buffer if not there */
-	if (mhp->ext[SADB_EXT_IDENTITY_SRC] == NULL &&
-	    mhp->ext[SADB_EXT_IDENTITY_DST] == NULL) {
-		sah->idents = NULL;
-		sah->identd = NULL;
-		return 0;
-	}
-	
-	if (mhp->ext[SADB_EXT_IDENTITY_SRC] == NULL ||
-	    mhp->ext[SADB_EXT_IDENTITY_DST] == NULL) {
-		ipseclog((LOG_DEBUG, "key_setident: invalid identity.\n"));
-		return EINVAL;
-	}
-
-	idsrc = (const struct sadb_ident *)mhp->ext[SADB_EXT_IDENTITY_SRC];
-	iddst = (const struct sadb_ident *)mhp->ext[SADB_EXT_IDENTITY_DST];
-	idsrclen = mhp->extlen[SADB_EXT_IDENTITY_SRC];
-	iddstlen = mhp->extlen[SADB_EXT_IDENTITY_DST];
-
-	/* validity check */
-	if (idsrc->sadb_ident_type != iddst->sadb_ident_type) {
-		ipseclog((LOG_DEBUG, "key_setident: ident type mismatch.\n"));
-		return EINVAL;
-	}
-
-	switch (idsrc->sadb_ident_type) {
-	case SADB_IDENTTYPE_PREFIX:
-	case SADB_IDENTTYPE_FQDN:
-	case SADB_IDENTTYPE_USERFQDN:
-	default:
-		/* XXX do nothing */
-		sah->idents = NULL;
-		sah->identd = NULL;
-	 	return 0;
-	}
-
-	/* make structure */
-	KMALLOC(sah->idents, struct sadb_ident *, idsrclen);
-	if (sah->idents == NULL) {
-		ipseclog((LOG_DEBUG, "key_setident: No more memory.\n"));
-		return ENOBUFS;
-	}
-	KMALLOC(sah->identd, struct sadb_ident *, iddstlen);
-	if (sah->identd == NULL) {
-		KFREE(sah->idents);
-		sah->idents = NULL;
-		ipseclog((LOG_DEBUG, "key_setident: No more memory.\n"));
-		return ENOBUFS;
-	}
-	bcopy(idsrc, sah->idents, idsrclen);
-	bcopy(iddst, sah->identd, iddstlen);
-
-	return 0;
-}
-
-/*
- * m will not be freed on return.
- * it is caller's responsibility to free the result. 
- */
-static struct mbuf *
-key_getmsgbuf_x1(m, mhp)
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct mbuf *n;
-
-	/* sanity check */
-	if (m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_getmsgbuf_x1: NULL pointer is passed.");
-
-	/* create new sadb_msg to reply. */
-	n = key_gather_mbuf(m, mhp, 1, 9, SADB_EXT_RESERVED,
-	    SADB_EXT_SA, SADB_X_EXT_SA2,
-	    SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST,
-	    SADB_EXT_LIFETIME_HARD, SADB_EXT_LIFETIME_SOFT,
-	    SADB_EXT_IDENTITY_SRC, SADB_EXT_IDENTITY_DST);
-	if (!n)
-		return NULL;
-
-	if (n->m_len < sizeof(struct sadb_msg)) {
-		n = m_pullup(n, sizeof(struct sadb_msg));
-		if (n == NULL)
-			return NULL;
-	}
-	mtod(n, struct sadb_msg *)->sadb_msg_errno = 0;
-	mtod(n, struct sadb_msg *)->sadb_msg_len =
-	    PFKEY_UNIT64(n->m_pkthdr.len);
-
-	return n;
-}
-
-static int key_delete_all(struct socket *, struct mbuf *,
-	const struct sadb_msghdr *, u_int16_t);
-
-/*
- * SADB_DELETE processing
- * receive
- *   <base, SA(*), address(SD)>
- * from the ikmpd, and set SADB_SASTATE_DEAD,
- * and send,
- *   <base, SA(*), address(SD)>
- * to the ikmpd.
- *
- * m will always be freed.
- */
-static int
-key_delete(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_sa *sa0;
-	struct sadb_address *src0, *dst0;
-	struct secasindex saidx;
-	struct secashead *sah;
-	struct secasvar *sav = NULL;
-	u_int16_t proto;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_delete: NULL pointer is passed.");
-
-	/* map satype to proto */
-	if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
-		ipseclog((LOG_DEBUG, "key_delete: invalid satype is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) {
-		ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
-		ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (mhp->ext[SADB_EXT_SA] == NULL) {
-		/*
-		 * Caller wants us to delete all non-LARVAL SAs
-		 * that match the src/dst.  This is used during
-		 * IKE INITIAL-CONTACT.
-		 */
-		ipseclog((LOG_DEBUG, "key_delete: doing delete all.\n"));
-		return key_delete_all(so, m, mhp, proto);
-	} else if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa)) {
-		ipseclog((LOG_DEBUG, "key_delete: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA];
-	src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
-	dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
-
-	/* XXX boundary check against sa_len */
-	KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
-
-	/* get a SA header */
-	LIST_FOREACH(sah, &sahtree, chain) {
-		if (sah->state == SADB_SASTATE_DEAD)
-			continue;
-		if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
-			continue;
-
-		/* get a SA with SPI. */
-		sav = key_getsavbyspi(sah, sa0->sadb_sa_spi);
-		if (sav)
-			break;
-	}
-	if (sah == NULL) {
-		ipseclog((LOG_DEBUG, "key_delete: no SA found.\n"));
-		return key_senderror(so, m, ENOENT);
-	}
-
-	key_sa_chgstate(sav, SADB_SASTATE_DEAD);
-	key_freesav(sav);
-	sav = NULL;
-
-    {
-	struct mbuf *n;
-	struct sadb_msg *newmsg;
-
-	/* create new sadb_msg to reply. */
-	n = key_gather_mbuf(m, mhp, 1, 4, SADB_EXT_RESERVED,
-	    SADB_EXT_SA, SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST);
-	if (!n)
-		return key_senderror(so, m, ENOBUFS);
-
-	if (n->m_len < sizeof(struct sadb_msg)) {
-		n = m_pullup(n, sizeof(struct sadb_msg));
-		if (n == NULL)
-			return key_senderror(so, m, ENOBUFS);
-	}
-	newmsg = mtod(n, struct sadb_msg *);
-	newmsg->sadb_msg_errno = 0;
-	newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len);
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
-    }
-}
-
-/*
- * delete all SAs for src/dst.  Called from key_delete().
- */
-static int
-key_delete_all(so, m, mhp, proto)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-	u_int16_t proto;
-{
-	struct sadb_address *src0, *dst0;
-	struct secasindex saidx;
-	struct secashead *sah;
-	struct secasvar *sav, *nextsav;
-	u_int stateidx, state;
-
-	src0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_SRC]);
-	dst0 = (struct sadb_address *)(mhp->ext[SADB_EXT_ADDRESS_DST]);
-
-	/* XXX boundary check against sa_len */
-	KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
-
-	LIST_FOREACH(sah, &sahtree, chain) {
-		if (sah->state == SADB_SASTATE_DEAD)
-			continue;
-		if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
-			continue;
-
-		/* Delete all non-LARVAL SAs. */
-		for (stateidx = 0;
-		     stateidx < _ARRAYLEN(saorder_state_alive);
-		     stateidx++) {
-			state = saorder_state_alive[stateidx];
-			if (state == SADB_SASTATE_LARVAL)
-				continue;
-			for (sav = LIST_FIRST(&sah->savtree[state]);
-			     sav != NULL; sav = nextsav) {
-				nextsav = LIST_NEXT(sav, chain);
-				/* sanity check */
-				if (sav->state != state) {
-					ipseclog((LOG_DEBUG, "key_delete_all: "
-					       "invalid sav->state "
-					       "(queue: %u SA: %u)\n",
-					       state, sav->state));
-					continue;
-				}
-				
-				key_sa_chgstate(sav, SADB_SASTATE_DEAD);
-				key_freesav(sav);
-			}
-		}
-	}
-    {
-	struct mbuf *n;
-	struct sadb_msg *newmsg;
-
-	/* create new sadb_msg to reply. */
-	n = key_gather_mbuf(m, mhp, 1, 3, SADB_EXT_RESERVED,
-	    SADB_EXT_ADDRESS_SRC, SADB_EXT_ADDRESS_DST);
-	if (!n)
-		return key_senderror(so, m, ENOBUFS);
-
-	if (n->m_len < sizeof(struct sadb_msg)) {
-		n = m_pullup(n, sizeof(struct sadb_msg));
-		if (n == NULL)
-			return key_senderror(so, m, ENOBUFS);
-	}
-	newmsg = mtod(n, struct sadb_msg *);
-	newmsg->sadb_msg_errno = 0;
-	newmsg->sadb_msg_len = PFKEY_UNIT64(n->m_pkthdr.len);
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_ALL);
-    }
-}
-
-/*
- * SADB_GET processing
- * receive
- *   <base, SA(*), address(SD)>
- * from the ikmpd, and get a SP and a SA to respond,
- * and send,
- *   <base, SA, (lifetime(HSC),) address(SD), (address(P),) key(AE),
- *       (identity(SD),) (sensitivity)>
- * to the ikmpd.
- *
- * m will always be freed.
- */
-static int
-key_get(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_sa *sa0;
-	struct sadb_address *src0, *dst0;
-	struct secasindex saidx;
-	struct secashead *sah;
-	struct secasvar *sav = NULL;
-	u_int16_t proto;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_get: NULL pointer is passed.");
-
-	/* map satype to proto */
-	if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
-		ipseclog((LOG_DEBUG, "key_get: invalid satype is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (mhp->ext[SADB_EXT_SA] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_DST] == NULL) {
-		ipseclog((LOG_DEBUG, "key_get: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->extlen[SADB_EXT_SA] < sizeof(struct sadb_sa) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address)) {
-		ipseclog((LOG_DEBUG, "key_get: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	sa0 = (struct sadb_sa *)mhp->ext[SADB_EXT_SA];
-	src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
-	dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
-
-	/* XXX boundary check against sa_len */
-	KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
-
-	/* get a SA header */
-	LIST_FOREACH(sah, &sahtree, chain) {
-		if (sah->state == SADB_SASTATE_DEAD)
-			continue;
-		if (key_cmpsaidx(&sah->saidx, &saidx, CMP_HEAD) == 0)
-			continue;
-
-		/* get a SA with SPI. */
-		sav = key_getsavbyspi(sah, sa0->sadb_sa_spi);
-		if (sav)
-			break;
-	}
-	if (sah == NULL) {
-		ipseclog((LOG_DEBUG, "key_get: no SA found.\n"));
-		return key_senderror(so, m, ENOENT);
-	}
-
-    {
-	struct mbuf *n;
-	u_int8_t satype;
-
-	/* map proto to satype */
-	if ((satype = key_proto2satype(sah->saidx.proto)) == 0) {
-		ipseclog((LOG_DEBUG, "key_get: there was invalid proto in SAD.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	/* create new sadb_msg to reply. */
-	n = key_setdumpsa(sav, SADB_GET, satype, mhp->msg->sadb_msg_seq,
-	    mhp->msg->sadb_msg_pid);
-	if (!n)
-		return key_senderror(so, m, ENOBUFS);
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
-    }
-}
-
-/* XXX make it sysctl-configurable? */
-static void
-key_getcomb_setlifetime(comb)
-	struct sadb_comb *comb;
-{
-
-	comb->sadb_comb_soft_allocations = 1;
-	comb->sadb_comb_hard_allocations = 1;
-	comb->sadb_comb_soft_bytes = 0;
-	comb->sadb_comb_hard_bytes = 0;
-	comb->sadb_comb_hard_addtime = 86400;	/* 1 day */
-	comb->sadb_comb_soft_addtime = comb->sadb_comb_hard_addtime * 80 / 100;
-	comb->sadb_comb_hard_usetime = 28800;	/* 8 hours */
-	comb->sadb_comb_soft_usetime = comb->sadb_comb_hard_usetime * 80 / 100;
-}
-
-#ifdef IPSEC_ESP
-/*
- * XXX reorder combinations by preference
- * XXX no idea if the user wants ESP authentication or not
- */
-static struct mbuf *
-key_getcomb_esp()
-{
-	struct sadb_comb *comb;
-	const struct esp_algorithm *algo;
-	struct mbuf *result = NULL, *m, *n;
-	int encmin;
-	int i, off, o;
-	int totlen;
-	const int l = PFKEY_ALIGN8(sizeof(struct sadb_comb));
-
-	m = NULL;
-	for (i = 1; i <= SADB_EALG_MAX; i++) {
-		algo = esp_algorithm_lookup(i);
-		if (!algo)
-			continue;
-
-		if (algo->keymax < ipsec_esp_keymin)
-			continue;
-		if (algo->keymin < ipsec_esp_keymin)
-			encmin = ipsec_esp_keymin;
-		else
-			encmin = algo->keymin;
-
-		if (ipsec_esp_auth)
-			m = key_getcomb_ah();
-		else {
-#ifdef DIAGNOSTIC
-			if (l > MLEN)
-				panic("assumption failed in key_getcomb_esp");
-#endif
-			MGET(m, M_DONTWAIT, MT_DATA);
-			if (m) {
-				M_ALIGN(m, l);
-				m->m_len = l;
-				m->m_next = NULL;
-				bzero(mtod(m, caddr_t), m->m_len);
-			}
-		}
-		if (!m)
-			goto fail;
-
-		totlen = 0;
-		for (n = m; n; n = n->m_next)
-			totlen += n->m_len;
-#ifdef DIAGNOSTIC
-		if (totlen % l)
-			panic("assumption failed in key_getcomb_esp");
-#endif
-
-		for (off = 0; off < totlen; off += l) {
-			n = m_pulldown(m, off, l, &o);
-			if (!n) {
-				/* m is already freed */
-				goto fail;
-			}
-			comb = (struct sadb_comb *)(mtod(n, caddr_t) + o);
-			bzero(comb, sizeof(*comb));
-			key_getcomb_setlifetime(comb);
-			comb->sadb_comb_encrypt = i;
-			comb->sadb_comb_encrypt_minbits = encmin;
-			comb->sadb_comb_encrypt_maxbits = algo->keymax;
-		}
-
-		if (!result)
-			result = m;
-		else
-			m_cat(result, m);
-	}
-
-	return result;
-
- fail:
-	if (result)
-		m_freem(result);
-	return NULL;
-}
-#endif
-
-/*
- * XXX reorder combinations by preference
- */
-static struct mbuf *
-key_getcomb_ah()
-{
-	struct sadb_comb *comb;
-	const struct ah_algorithm *algo;
-	struct mbuf *m;
-	int min;
-	int i;
-	const int l = PFKEY_ALIGN8(sizeof(struct sadb_comb));
-
-	m = NULL;
-	for (i = 1; i <= SADB_AALG_MAX; i++) {
-#if 1
-		/* we prefer HMAC algorithms, not old algorithms */
-		if (i != SADB_AALG_SHA1HMAC && i != SADB_AALG_MD5HMAC)
-			continue;
-#endif
-		algo = ah_algorithm_lookup(i);
-		if (!algo)
-			continue;
-
-		if (algo->keymax < ipsec_ah_keymin)
-			continue;
-		if (algo->keymin < ipsec_ah_keymin)
-			min = ipsec_ah_keymin;
-		else
-			min = algo->keymin;
-
-		if (!m) {
-#ifdef DIAGNOSTIC
-			if (l > MLEN)
-				panic("assumption failed in key_getcomb_ah");
-#endif
-			MGET(m, M_DONTWAIT, MT_DATA);
-			if (m) {
-				M_ALIGN(m, l);
-				m->m_len = l;
-				m->m_next = NULL;
-			}
-		} else
-			M_PREPEND(m, l, M_DONTWAIT);
-		if (!m)
-			return NULL;
-
-		comb = mtod(m, struct sadb_comb *);
-		bzero(comb, sizeof(*comb));
-		key_getcomb_setlifetime(comb);
-		comb->sadb_comb_auth = i;
-		comb->sadb_comb_auth_minbits = min;
-		comb->sadb_comb_auth_maxbits = algo->keymax;
-	}
-
-	return m;
-}
-
-/*
- * not really an official behavior.  discussed in pf_key at inner.net in Sep2000.
- * XXX reorder combinations by preference
- */
-static struct mbuf *
-key_getcomb_ipcomp()
-{
-	struct sadb_comb *comb;
-	const struct ipcomp_algorithm *algo;
-	struct mbuf *m;
-	int i;
-	const int l = PFKEY_ALIGN8(sizeof(struct sadb_comb));
-
-	m = NULL;
-	for (i = 1; i <= SADB_X_CALG_MAX; i++) {
-		algo = ipcomp_algorithm_lookup(i);
-		if (!algo)
-			continue;
-
-		if (!m) {
-#ifdef DIAGNOSTIC
-			if (l > MLEN)
-				panic("assumption failed in key_getcomb_ipcomp");
-#endif
-			MGET(m, M_DONTWAIT, MT_DATA);
-			if (m) {
-				M_ALIGN(m, l);
-				m->m_len = l;
-				m->m_next = NULL;
-			}
-		} else
-			M_PREPEND(m, l, M_DONTWAIT);
-		if (!m)
-			return NULL;
-
-		comb = mtod(m, struct sadb_comb *);
-		bzero(comb, sizeof(*comb));
-		key_getcomb_setlifetime(comb);
-		comb->sadb_comb_encrypt = i;
-		/* what should we set into sadb_comb_*_{min,max}bits? */
-	}
-
-	return m;
-}
-
-/*
- * XXX no way to pass mode (transport/tunnel) to userland
- * XXX replay checking?
- * XXX sysctl interface to ipsec_{ah,esp}_keymin
- */
-static struct mbuf *
-key_getprop(saidx)
-	const struct secasindex *saidx;
-{
-	struct sadb_prop *prop;
-	struct mbuf *m, *n;
-	const int l = PFKEY_ALIGN8(sizeof(struct sadb_prop));
-	int totlen;
-
-	switch (saidx->proto)  {
-#ifdef IPSEC_ESP
-	case IPPROTO_ESP:
-		m = key_getcomb_esp();
-		break;
-#endif
-	case IPPROTO_AH:
-		m = key_getcomb_ah();
-		break;
-	case IPPROTO_IPCOMP:
-		m = key_getcomb_ipcomp();
-		break;
-	default:
-		return NULL;
-	}
-
-	if (!m)
-		return NULL;
-	M_PREPEND(m, l, M_DONTWAIT);
-	if (!m)
-		return NULL;
-
-	totlen = 0;
-	for (n = m; n; n = n->m_next)
-		totlen += n->m_len;
-
-	prop = mtod(m, struct sadb_prop *);
-	bzero(prop, sizeof(*prop));
-	prop->sadb_prop_len = PFKEY_UNIT64(totlen);
-	prop->sadb_prop_exttype = SADB_EXT_PROPOSAL;
-	prop->sadb_prop_replay = 32;	/* XXX */
-
-	return m;
-}
-
-/*
- * SADB_ACQUIRE processing called by key_checkrequest() and key_acquire2().
- * send
- *   <base, SA, address(SD), (address(P)), x_policy,
- *       (identity(SD),) (sensitivity,) proposal>
- * to KMD, and expect to receive
- *   <base> with SADB_ACQUIRE if error occured,
- * or
- *   <base, src address, dst address, (SPI range)> with SADB_GETSPI
- * from KMD by PF_KEY.
- *
- * XXX x_policy is outside of RFC2367 (KAME extension).
- * XXX sensitivity is not supported.
- * XXX for ipcomp, RFC2367 does not define how to fill in proposal.
- * see comment for key_getcomb_ipcomp().
- *
- * OUT:
- *    0     : succeed
- *    others: error number
- */
-static int
-key_acquire(saidx, sp)
-	struct secasindex *saidx;
-	struct secpolicy *sp;
-{
-	struct mbuf *result = NULL, *m;
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-	struct secacq *newacq;
-#endif
-	u_int8_t satype;
-	int error = -1;
-	u_int32_t seq;
-
-	/* sanity check */
-	if (saidx == NULL)
-		panic("key_acquire: NULL pointer is passed.");
-	if ((satype = key_proto2satype(saidx->proto)) == 0)
-		panic("key_acquire: invalid proto is passed.");
-
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-	/*
-	 * We never do anything about acquirng SA.  There is anather
-	 * solution that kernel blocks to send SADB_ACQUIRE message until
-	 * getting something message from IKEd.  In later case, to be
-	 * managed with ACQUIRING list.
-	 */
-	/* get an entry to check whether sending message or not. */
-	if ((newacq = key_getacq(saidx)) != NULL) {
-		if (key_blockacq_count < newacq->count) {
-			/* reset counter and do send message. */
-			newacq->count = 0;
-		} else {
-			/* increment counter and do nothing. */
-			newacq->count++;
-			return 0;
-		}
-	} else {
-		/* make new entry for blocking to send SADB_ACQUIRE. */
-		if ((newacq = key_newacq(saidx)) == NULL)
-			return ENOBUFS;
-
-		/* add to acqtree */
-		LIST_INSERT_HEAD(&acqtree, newacq, chain);
-	}
-#endif
-
-
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-	seq = newacq->seq;
-#else
-	seq = (acq_seq = (acq_seq == ~0 ? 1 : ++acq_seq));
-#endif
-	m = key_setsadbmsg(SADB_ACQUIRE, 0, satype, seq, 0, 0);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	result = m;
-
-	/* set sadb_address for saidx's. */
-	m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
-	    (struct sockaddr *)&saidx->src, FULLMASK, IPSEC_ULPROTO_ANY);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	m_cat(result, m);
-
-	m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
-	    (struct sockaddr *)&saidx->dst, FULLMASK, IPSEC_ULPROTO_ANY);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	m_cat(result, m);
-
-	/* XXX proxy address (optional) */
-
-	/* set sadb_x_policy */
-	if (sp) {
-		m = key_setsadbxpolicy(sp->policy, sp->dir, sp->id);
-		if (!m) {
-			error = ENOBUFS;
-			goto fail;
-		}
-		m_cat(result, m);
-	}
-
-	/* XXX identity (optional) */
-#if 0
-	if (idexttype && fqdn) {
-		/* create identity extension (FQDN) */
-		struct sadb_ident *id;
-		int fqdnlen;
-
-		fqdnlen = strlen(fqdn) + 1;	/* +1 for terminating-NUL */
-		id = (struct sadb_ident *)p;
-		bzero(id, sizeof(*id) + PFKEY_ALIGN8(fqdnlen));
-		id->sadb_ident_len = PFKEY_UNIT64(sizeof(*id) + PFKEY_ALIGN8(fqdnlen));
-		id->sadb_ident_exttype = idexttype;
-		id->sadb_ident_type = SADB_IDENTTYPE_FQDN;
-		bcopy(fqdn, id + 1, fqdnlen);
-		p += sizeof(struct sadb_ident) + PFKEY_ALIGN8(fqdnlen);
-	}
-
-	if (idexttype) {
-		/* create identity extension (USERFQDN) */
-		struct sadb_ident *id;
-		int userfqdnlen;
-
-		if (userfqdn) {
-			/* +1 for terminating-NUL */
-			userfqdnlen = strlen(userfqdn) + 1;
-		} else
-			userfqdnlen = 0;
-		id = (struct sadb_ident *)p;
-		bzero(id, sizeof(*id) + PFKEY_ALIGN8(userfqdnlen));
-		id->sadb_ident_len = PFKEY_UNIT64(sizeof(*id) + PFKEY_ALIGN8(userfqdnlen));
-		id->sadb_ident_exttype = idexttype;
-		id->sadb_ident_type = SADB_IDENTTYPE_USERFQDN;
-		/* XXX is it correct? */
-		if (curproc && curproc->p_cred)
-			id->sadb_ident_id = curproc->p_cred->p_ruid;
-		if (userfqdn && userfqdnlen)
-			bcopy(userfqdn, id + 1, userfqdnlen);
-		p += sizeof(struct sadb_ident) + PFKEY_ALIGN8(userfqdnlen);
-	}
-#endif
-
-	/* XXX sensitivity (optional) */
-
-	/* create proposal/combination extension */
-	m = key_getprop(saidx);
-#if 0
-	/*
-	 * spec conformant: always attach proposal/combination extension,
-	 * the problem is that we have no way to attach it for ipcomp,
-	 * due to the way sadb_comb is declared in RFC2367.
-	 */
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	m_cat(result, m);
-#else
-	/*
-	 * outside of spec; make proposal/combination extension optional.
-	 */
-	if (m)
-		m_cat(result, m);
-#endif
-
-	if ((result->m_flags & M_PKTHDR) == 0) {
-		error = EINVAL;
-		goto fail;
-	}
-
-	if (result->m_len < sizeof(struct sadb_msg)) {
-		result = m_pullup(result, sizeof(struct sadb_msg));
-		if (result == NULL) {
-			error = ENOBUFS;
-			goto fail;
-		}
-	}
-
-	result->m_pkthdr.len = 0;
-	for (m = result; m; m = m->m_next)
-		result->m_pkthdr.len += m->m_len;
-
-	mtod(result, struct sadb_msg *)->sadb_msg_len =
-	    PFKEY_UNIT64(result->m_pkthdr.len);
-
-	return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED);
-
- fail:
-	if (result)
-		m_freem(result);
-	return error;
-}
-
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-static struct secacq *
-key_newacq(saidx)
-	struct secasindex *saidx;
-{
-	struct secacq *newacq;
-
-	/* get new entry */
-	KMALLOC(newacq, struct secacq *, sizeof(struct secacq));
-	if (newacq == NULL) {
-		ipseclog((LOG_DEBUG, "key_newacq: No more memory.\n"));
-		return NULL;
-	}
-	bzero(newacq, sizeof(*newacq));
-
-	/* copy secindex */
-	bcopy(saidx, &newacq->saidx, sizeof(newacq->saidx));
-	newacq->seq = (acq_seq == ~0 ? 1 : ++acq_seq);
-	newacq->created = time_second;
-	newacq->count = 0;
-
-	return newacq;
-}
-
-static struct secacq *
-key_getacq(saidx)
-	struct secasindex *saidx;
-{
-	struct secacq *acq;
-
-	LIST_FOREACH(acq, &acqtree, chain) {
-		if (key_cmpsaidx(saidx, &acq->saidx, CMP_EXACTLY))
-			return acq;
-	}
-
-	return NULL;
-}
-
-static struct secacq *
-key_getacqbyseq(seq)
-	u_int32_t seq;
-{
-	struct secacq *acq;
-
-	LIST_FOREACH(acq, &acqtree, chain) {
-		if (acq->seq == seq)
-			return acq;
-	}
-
-	return NULL;
-}
-#endif
-
-static struct secspacq *
-key_newspacq(spidx)
-	struct secpolicyindex *spidx;
-{
-	struct secspacq *acq;
-
-	if (!spidx)
-		return NULL;
-
-	/* get new entry */
-	KMALLOC(acq, struct secspacq *, sizeof(struct secspacq));
-	if (acq == NULL) {
-		ipseclog((LOG_DEBUG, "key_newspacq: No more memory.\n"));
-		return NULL;
-	}
-	bzero(acq, sizeof(*acq));
-
-	/* copy secindex */
-	bcopy(spidx, &acq->spidx, sizeof(acq->spidx));
-	acq->created = time_second;
-	acq->count = 1;
-
-	return acq;
-}
-
-static struct secspacq *
-key_getspacq(spidx)
-	struct secpolicyindex *spidx;
-{
-	struct secspacq *acq;
-
-	if (!spidx)
-		return NULL;
-
-	LIST_FOREACH(acq, &spacqtree, chain) {
-		if (key_cmpspidx_exactly(spidx, &acq->spidx))
-			return acq;
-	}
-
-	return NULL;
-}
-
-/*
- * SADB_ACQUIRE processing,
- * in first situation, is receiving
- *   <base>
- * from the ikmpd, and clear sequence of its secasvar entry.
- *
- * In second situation, is receiving
- *   <base, address(SD), (address(P),) (identity(SD),) (sensitivity,) proposal>
- * from a user land process, and return
- *   <base, address(SD), (address(P),) (identity(SD),) (sensitivity,) proposal>
- * to the socket.
- *
- * m will always be freed.
- */
-static int
-key_acquire2(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_address *src0, *dst0;
-	struct secasindex saidx;
-	struct secashead *sah;
-	u_int16_t proto;
-	int error;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_acquire2: NULL pointer is passed.");
-
-	/*
-	 * Error message from KMd.
-	 * We assume that if error was occured in IKEd, the length of PFKEY
-	 * message is equal to the size of sadb_msg structure.
-	 * We do not raise error even if error occured in this function.
-	 */
-	if (mhp->msg->sadb_msg_len == PFKEY_UNIT64(sizeof(struct sadb_msg))) {
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-		struct secacq *acq;
-
-		/* check sequence number */
-		if (mhp->msg->sadb_msg_seq == 0) {
-			ipseclog((LOG_DEBUG, "key_acquire2: must specify sequence number.\n"));
-			m_freem(m);
-			return 0;
-		}
-
-		if ((acq = key_getacqbyseq(mhp->msg->sadb_msg_seq)) == NULL) {
-			/*
-			 * the specified larval SA is already gone, or we got
-			 * a bogus sequence number.  we can silently ignore it.
-			 */
-			m_freem(m);
-			return 0;
-		}
-
-		/* reset acq counter in order to deletion by timehander. */
-		acq->created = time_second;
-		acq->count = 0;
-#endif
-		m_freem(m);
-		return 0;
-	}
-
-	/*
-	 * This message is from user land.
-	 */
-
-	/* map satype to proto */
-	if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
-		ipseclog((LOG_DEBUG, "key_acquire2: invalid satype is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	if (mhp->ext[SADB_EXT_ADDRESS_SRC] == NULL ||
-	    mhp->ext[SADB_EXT_ADDRESS_DST] == NULL ||
-	    mhp->ext[SADB_EXT_PROPOSAL] == NULL) {
-		/* error */
-		ipseclog((LOG_DEBUG, "key_acquire2: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-	if (mhp->extlen[SADB_EXT_ADDRESS_SRC] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_EXT_ADDRESS_DST] < sizeof(struct sadb_address) ||
-	    mhp->extlen[SADB_EXT_PROPOSAL] < sizeof(struct sadb_prop)) {
-		/* error */
-		ipseclog((LOG_DEBUG, "key_acquire2: invalid message is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	src0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_SRC];
-	dst0 = (struct sadb_address *)mhp->ext[SADB_EXT_ADDRESS_DST];
-
-	/* XXX boundary check against sa_len */
-	KEY_SETSECASIDX(proto, IPSEC_MODE_ANY, 0, src0 + 1, dst0 + 1, &saidx);
-
-	/* get a SA index */
-	LIST_FOREACH(sah, &sahtree, chain) {
-		if (sah->state == SADB_SASTATE_DEAD)
-			continue;
-		if (key_cmpsaidx(&sah->saidx, &saidx, CMP_MODE_REQID))
-			break;
-	}
-	if (sah != NULL) {
-		ipseclog((LOG_DEBUG, "key_acquire2: a SA exists already.\n"));
-		return key_senderror(so, m, EEXIST);
-	}
-
-	error = key_acquire(&saidx, NULL);
-	if (error != 0) {
-		ipseclog((LOG_DEBUG, "key_acquire2: error %d returned "
-			"from key_acquire.\n", mhp->msg->sadb_msg_errno));
-		return key_senderror(so, m, error);
-	}
-
-	return key_sendup_mbuf(so, m, KEY_SENDUP_REGISTERED);
-}
-
-/*
- * SADB_REGISTER processing.
- * If SATYPE_UNSPEC has been passed as satype, only return sabd_supported.
- * receive
- *   <base>
- * from the ikmpd, and register a socket to send PF_KEY messages,
- * and send
- *   <base, supported>
- * to KMD by PF_KEY.
- * If socket is detached, must free from regnode.
- *
- * m will always be freed.
- */
-static int
-key_register(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct secreg *reg, *newreg = 0;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_register: NULL pointer is passed.");
-
-	/* check for invalid register message */
-	if (mhp->msg->sadb_msg_satype >= sizeof(regtree)/sizeof(regtree[0]))
-		return key_senderror(so, m, EINVAL);
-
-	/* When SATYPE_UNSPEC is specified, only return sabd_supported. */
-	if (mhp->msg->sadb_msg_satype == SADB_SATYPE_UNSPEC)
-		goto setmsg;
-
-	/* check whether existing or not */
-	LIST_FOREACH(reg, &regtree[mhp->msg->sadb_msg_satype], chain) {
-		if (reg->so == so) {
-			ipseclog((LOG_DEBUG, "key_register: socket exists already.\n"));
-			return key_senderror(so, m, EEXIST);
-		}
-	}
-
-	/* create regnode */
-	KMALLOC(newreg, struct secreg *, sizeof(*newreg));
-	if (newreg == NULL) {
-		ipseclog((LOG_DEBUG, "key_register: No more memory.\n"));
-		return key_senderror(so, m, ENOBUFS);
-	}
-	bzero((caddr_t)newreg, sizeof(*newreg));
-
-	newreg->so = so;
-	((struct keycb *)sotorawcb(so))->kp_registered++;
-
-	/* add regnode to regtree. */
-	LIST_INSERT_HEAD(&regtree[mhp->msg->sadb_msg_satype], newreg, chain);
-
-  setmsg:
-    {
-	struct mbuf *n;
-	struct sadb_msg *newmsg;
-	struct sadb_supported *sup;
-	u_int len, alen, elen;
-	int off;
-	int i;
-	struct sadb_alg *alg;
-
-	/* create new sadb_msg to reply. */
-	alen = 0;
-	for (i = 1; i <= SADB_AALG_MAX; i++) {
-		if (ah_algorithm_lookup(i))
-			alen += sizeof(struct sadb_alg);
-	}
-	if (alen)
-		alen += sizeof(struct sadb_supported);
-	elen = 0;
-#ifdef IPSEC_ESP
-	for (i = 1; i <= SADB_EALG_MAX; i++) {
-		if (esp_algorithm_lookup(i))
-			elen += sizeof(struct sadb_alg);
-	}
-	if (elen)
-		elen += sizeof(struct sadb_supported);
-#endif
-
-	len = sizeof(struct sadb_msg) + alen + elen;
-
-	if (len > MCLBYTES)
-		return key_senderror(so, m, ENOBUFS);
-
-	MGETHDR(n, M_DONTWAIT, MT_DATA);
-	if (len > MHLEN) {
-		MCLGET(n, M_DONTWAIT);
-		if ((n->m_flags & M_EXT) == 0) {
-			m_freem(n);
-			n = NULL;
-		}
-	}
-	if (!n)
-		return key_senderror(so, m, ENOBUFS);
-
-	n->m_pkthdr.len = n->m_len = len;
-	n->m_next = NULL;
-	off = 0;
-
-	m_copydata(m, 0, sizeof(struct sadb_msg), mtod(n, caddr_t) + off);
-	newmsg = mtod(n, struct sadb_msg *);
-	newmsg->sadb_msg_errno = 0;
-	newmsg->sadb_msg_len = PFKEY_UNIT64(len);
-	off += PFKEY_ALIGN8(sizeof(struct sadb_msg));
-
-	/* for authentication algorithm */
-	if (alen) {
-		sup = (struct sadb_supported *)(mtod(n, caddr_t) + off);
-		sup->sadb_supported_len = PFKEY_UNIT64(alen);
-		sup->sadb_supported_exttype = SADB_EXT_SUPPORTED_AUTH;
-		off += PFKEY_ALIGN8(sizeof(*sup));
-
-		for (i = 1; i <= SADB_AALG_MAX; i++) {
-			const struct ah_algorithm *aalgo;
-
-			aalgo = ah_algorithm_lookup(i);
-			if (!aalgo)
-				continue;
-			alg = (struct sadb_alg *)(mtod(n, caddr_t) + off);
-			alg->sadb_alg_id = i;
-			alg->sadb_alg_ivlen = 0;
-			alg->sadb_alg_minbits = aalgo->keymin;
-			alg->sadb_alg_maxbits = aalgo->keymax;
-			off += PFKEY_ALIGN8(sizeof(*alg));
-		}
-	}
-
-#ifdef IPSEC_ESP
-	/* for encryption algorithm */
-	if (elen) {
-		sup = (struct sadb_supported *)(mtod(n, caddr_t) + off);
-		sup->sadb_supported_len = PFKEY_UNIT64(elen);
-		sup->sadb_supported_exttype = SADB_EXT_SUPPORTED_ENCRYPT;
-		off += PFKEY_ALIGN8(sizeof(*sup));
-
-		for (i = 1; i <= SADB_EALG_MAX; i++) {
-			const struct esp_algorithm *ealgo;
-
-			ealgo = esp_algorithm_lookup(i);
-			if (!ealgo)
-				continue;
-			alg = (struct sadb_alg *)(mtod(n, caddr_t) + off);
-			alg->sadb_alg_id = i;
-			if (ealgo && ealgo->ivlen) {
-				/*
-				 * give NULL to get the value preferred by
-				 * algorithm XXX SADB_X_EXT_DERIV ?
-				 */
-				alg->sadb_alg_ivlen =
-				    (*ealgo->ivlen)(ealgo, NULL);
-			} else
-				alg->sadb_alg_ivlen = 0;
-			alg->sadb_alg_minbits = ealgo->keymin;
-			alg->sadb_alg_maxbits = ealgo->keymax;
-			off += PFKEY_ALIGN8(sizeof(struct sadb_alg));
-		}
-	}
-#endif
-
-#ifdef DIGAGNOSTIC
-	if (off != len)
-		panic("length assumption failed in key_register");
-#endif
-
-	m_freem(m);
-	return key_sendup_mbuf(so, n, KEY_SENDUP_REGISTERED);
-    }
-}
-
-/*
- * free secreg entry registered.
- * XXX: I want to do free a socket marked done SADB_RESIGER to socket.
- */
-void
-key_freereg(so)
-	struct socket *so;
-{
-	struct secreg *reg;
-	int i;
-
-	/* sanity check */
-	if (so == NULL)
-		panic("key_freereg: NULL pointer is passed.");
-
-	/*
-	 * check whether existing or not.
-	 * check all type of SA, because there is a potential that
-	 * one socket is registered to multiple type of SA.
-	 */
-	for (i = 0; i <= SADB_SATYPE_MAX; i++) {
-		LIST_FOREACH(reg, &regtree[i], chain) {
-			if (reg->so == so && __LIST_CHAINED(reg)) {
-				LIST_REMOVE(reg, chain);
-				KFREE(reg);
-				break;
-			}
-		}
-	}
-	
-	return;
-}
-
-/*
- * SADB_EXPIRE processing
- * send
- *   <base, SA, SA2, lifetime(C and one of HS), address(SD)>
- * to KMD by PF_KEY.
- * NOTE: We send only soft lifetime extension.
- *
- * OUT:	0	: succeed
- *	others	: error number
- */
-static int
-key_expire(sav)
-	struct secasvar *sav;
-{
-	int s;
-	int satype;
-	struct mbuf *result = NULL, *m;
-	int len;
-	int error = -1;
-	struct sadb_lifetime *lt;
-
-	/* XXX: Why do we lock ? */
-	s = splnet();	/*called from softclock()*/
-
-	/* sanity check */
-	if (sav == NULL)
-		panic("key_expire: NULL pointer is passed.");
-	if (sav->sah == NULL)
-		panic("key_expire: Why was SA index in SA NULL.");
-	if ((satype = key_proto2satype(sav->sah->saidx.proto)) == 0)
-		panic("key_expire: invalid proto is passed.");
-
-	/* set msg header */
-	m = key_setsadbmsg(SADB_EXPIRE, 0, satype, sav->seq, 0, sav->refcnt);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	result = m;
-
-	/* create SA extension */
-	m = key_setsadbsa(sav);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	m_cat(result, m);
-
-	/* create SA extension */
-	m = key_setsadbxsa2(sav->sah->saidx.mode,
-	    sav->replay ? (sav->replay->count & 0xffffffff) : 0,
-	    sav->sah->saidx.reqid);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	m_cat(result, m);
-
-	/* create lifetime extension (current and soft) */
-	len = PFKEY_ALIGN8(sizeof(*lt)) * 2;
-	m = key_alloc_mbuf(len);
-	if (!m || m->m_next) {	/*XXX*/
-		if (m)
-			m_freem(m);
-		error = ENOBUFS;
-		goto fail;
-	}
-	bzero(mtod(m, caddr_t), len);
-	lt = mtod(m, struct sadb_lifetime *);
-	lt->sadb_lifetime_len = PFKEY_UNIT64(sizeof(struct sadb_lifetime));
-	lt->sadb_lifetime_exttype = SADB_EXT_LIFETIME_CURRENT;
-	lt->sadb_lifetime_allocations = sav->lft_c->sadb_lifetime_allocations;
-	lt->sadb_lifetime_bytes = sav->lft_c->sadb_lifetime_bytes;
-	lt->sadb_lifetime_addtime = sav->lft_c->sadb_lifetime_addtime;
-	lt->sadb_lifetime_usetime = sav->lft_c->sadb_lifetime_usetime;
-	lt = (struct sadb_lifetime *)(mtod(m, caddr_t) + len / 2);
-	bcopy(sav->lft_s, lt, sizeof(*lt));
-	m_cat(result, m);
-
-	/* set sadb_address for source */
-	m = key_setsadbaddr(SADB_EXT_ADDRESS_SRC,
-	    (struct sockaddr *)&sav->sah->saidx.src,
-	    FULLMASK, IPSEC_ULPROTO_ANY);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	m_cat(result, m);
-
-	/* set sadb_address for destination */
-	m = key_setsadbaddr(SADB_EXT_ADDRESS_DST,
-	    (struct sockaddr *)&sav->sah->saidx.dst,
-	    FULLMASK, IPSEC_ULPROTO_ANY);
-	if (!m) {
-		error = ENOBUFS;
-		goto fail;
-	}
-	m_cat(result, m);
-
-	if ((result->m_flags & M_PKTHDR) == 0) {
-		error = EINVAL;
-		goto fail;
-	}
-
-	if (result->m_len < sizeof(struct sadb_msg)) {
-		result = m_pullup(result, sizeof(struct sadb_msg));
-		if (result == NULL) {
-			error = ENOBUFS;
-			goto fail;
-		}
-	}
-
-	result->m_pkthdr.len = 0;
-	for (m = result; m; m = m->m_next)
-		result->m_pkthdr.len += m->m_len;
-
-	mtod(result, struct sadb_msg *)->sadb_msg_len =
-	    PFKEY_UNIT64(result->m_pkthdr.len);
-
-	splx(s);
-	return key_sendup_mbuf(NULL, result, KEY_SENDUP_REGISTERED);
-
- fail:
-	if (result)
-		m_freem(result);
-	splx(s);
-	return error;
-}
-
-/*
- * SADB_FLUSH processing
- * receive
- *   <base>
- * from the ikmpd, and free all entries in secastree.
- * and send,
- *   <base>
- * to the ikmpd.
- * NOTE: to do is only marking SADB_SASTATE_DEAD.
- *
- * m will always be freed.
- */
-static int
-key_flush(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct sadb_msg *newmsg;
-	struct secashead *sah, *nextsah;
-	struct secasvar *sav, *nextsav;
-	u_int16_t proto;
-	u_int8_t state;
-	u_int stateidx;
-
-	/* sanity check */
-	if (so == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_flush: NULL pointer is passed.");
-
-	/* map satype to proto */
-	if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
-		ipseclog((LOG_DEBUG, "key_flush: invalid satype is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	/* no SATYPE specified, i.e. flushing all SA. */
-	for (sah = LIST_FIRST(&sahtree); sah != NULL; sah = nextsah) {
-		nextsah = LIST_NEXT(sah, chain);
-
-		if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC &&
-		    proto != sah->saidx.proto)
-			continue;
-
-		for (stateidx = 0;
-		     stateidx < _ARRAYLEN(saorder_state_alive);
-		     stateidx++) {
-			state = saorder_state_any[stateidx];
-			for (sav = LIST_FIRST(&sah->savtree[state]);
-			     sav != NULL;
-			     sav = nextsav) {
-
-				nextsav = LIST_NEXT(sav, chain);
-
-				key_sa_chgstate(sav, SADB_SASTATE_DEAD);
-				key_freesav(sav);
-			}
-		}
-
-		sah->state = SADB_SASTATE_DEAD;
-	}
-
-	if (m->m_len < sizeof(struct sadb_msg) ||
-	    sizeof(struct sadb_msg) > m->m_len + M_TRAILINGSPACE(m)) {
-		ipseclog((LOG_DEBUG, "key_flush: No more memory.\n"));
-		return key_senderror(so, m, ENOBUFS);
-	}
-
-	if (m->m_next)
-		m_freem(m->m_next);
-	m->m_next = NULL;
-	m->m_pkthdr.len = m->m_len = sizeof(struct sadb_msg);
-	newmsg = mtod(m, struct sadb_msg *);
-	newmsg->sadb_msg_errno = 0;
-	newmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len);
-
-	return key_sendup_mbuf(so, m, KEY_SENDUP_ALL);
-}
-
-/*
- * SADB_DUMP processing
- * dump all entries including status of DEAD in SAD.
- * receive
- *   <base>
- * from the ikmpd, and dump all secasvar leaves
- * and send,
- *   <base> .....
- * to the ikmpd.
- *
- * m will always be freed.
- */
-static int
-key_dump(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	struct secashead *sah;
-	struct secasvar *sav;
-	u_int16_t proto;
-	u_int stateidx;
-	u_int8_t satype;
-	u_int8_t state;
-	int cnt;
-	struct mbuf *n;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_dump: NULL pointer is passed.");
-
-	/* map satype to proto */
-	if ((proto = key_satype2proto(mhp->msg->sadb_msg_satype)) == 0) {
-		ipseclog((LOG_DEBUG, "key_dump: invalid satype is passed.\n"));
-		return key_senderror(so, m, EINVAL);
-	}
-
-	/* count sav entries to be sent to the userland. */
-	cnt = 0;
-	LIST_FOREACH(sah, &sahtree, chain) {
-		if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC &&
-		    proto != sah->saidx.proto)
-			continue;
-
-		for (stateidx = 0;
-		     stateidx < _ARRAYLEN(saorder_state_any);
-		     stateidx++) {
-			state = saorder_state_any[stateidx];
-			LIST_FOREACH(sav, &sah->savtree[state], chain) {
-				cnt++;
-			}
-		}
-	}
-
-	if (cnt == 0)
-		return key_senderror(so, m, ENOENT);
-
-	/* send this to the userland, one at a time. */
-	LIST_FOREACH(sah, &sahtree, chain) {
-		if (mhp->msg->sadb_msg_satype != SADB_SATYPE_UNSPEC &&
-		    proto != sah->saidx.proto)
-			continue;
-
-		/* map proto to satype */
-		if ((satype = key_proto2satype(sah->saidx.proto)) == 0) {
-			ipseclog((LOG_DEBUG, "key_dump: there was invalid proto in SAD.\n"));
-			return key_senderror(so, m, EINVAL);
-		}
-
-		for (stateidx = 0;
-		     stateidx < _ARRAYLEN(saorder_state_any);
-		     stateidx++) {
-			state = saorder_state_any[stateidx];
-			LIST_FOREACH(sav, &sah->savtree[state], chain) {
-				n = key_setdumpsa(sav, SADB_DUMP, satype,
-				    --cnt, mhp->msg->sadb_msg_pid);
-				if (!n)
-					return key_senderror(so, m, ENOBUFS);
-
-				key_sendup_mbuf(so, n, KEY_SENDUP_ONE);
-			}
-		}
-	}
-
-	m_freem(m);
-	return 0;
-}
-
-/*
- * SADB_X_PROMISC processing
- *
- * m will always be freed.
- */
-static int
-key_promisc(so, m, mhp)
-	struct socket *so;
-	struct mbuf *m;
-	const struct sadb_msghdr *mhp;
-{
-	int olen;
-
-	/* sanity check */
-	if (so == NULL || m == NULL || mhp == NULL || mhp->msg == NULL)
-		panic("key_promisc: NULL pointer is passed.");
-
-	olen = PFKEY_UNUNIT64(mhp->msg->sadb_msg_len);
-
-	if (olen < sizeof(struct sadb_msg)) {
-#if 1
-		return key_senderror(so, m, EINVAL);
-#else
-		m_freem(m);
-		return 0;
-#endif
-	} else if (olen == sizeof(struct sadb_msg)) {
-		/* enable/disable promisc mode */
-		struct keycb *kp;
-
-		if ((kp = (struct keycb *)sotorawcb(so)) == NULL)
-			return key_senderror(so, m, EINVAL);
-		mhp->msg->sadb_msg_errno = 0;
-		switch (mhp->msg->sadb_msg_satype) {
-		case 0:
-		case 1:
-			kp->kp_promisc = mhp->msg->sadb_msg_satype;
-			break;
-		default:
-			return key_senderror(so, m, EINVAL);
-		}
-
-		/* send the original message back to everyone */
-		mhp->msg->sadb_msg_errno = 0;
-		return key_sendup_mbuf(so, m, KEY_SENDUP_ALL);
-	} else {
-		/* send packet as is */
-
-		m_adj(m, PFKEY_ALIGN8(sizeof(struct sadb_msg)));
-
-		/* TODO: if sadb_msg_seq is specified, send to specific pid */
-		return key_sendup_mbuf(so, m, KEY_SENDUP_ALL);
-	}
-}
-
-static int (*key_typesw[])(struct socket *, struct mbuf *,
-		const struct sadb_msghdr *) = {
-	NULL,		/* SADB_RESERVED */
-	key_getspi,	/* SADB_GETSPI */
-	key_update,	/* SADB_UPDATE */
-	key_add,	/* SADB_ADD */
-	key_delete,	/* SADB_DELETE */
-	key_get,	/* SADB_GET */
-	key_acquire2,	/* SADB_ACQUIRE */
-	key_register,	/* SADB_REGISTER */
-	NULL,		/* SADB_EXPIRE */
-	key_flush,	/* SADB_FLUSH */
-	key_dump,	/* SADB_DUMP */
-	key_promisc,	/* SADB_X_PROMISC */
-	NULL,		/* SADB_X_PCHANGE */
-	key_spdadd,	/* SADB_X_SPDUPDATE */
-	key_spdadd,	/* SADB_X_SPDADD */
-	key_spddelete,	/* SADB_X_SPDDELETE */
-	key_spdget,	/* SADB_X_SPDGET */
-	NULL,		/* SADB_X_SPDACQUIRE */
-	key_spddump,	/* SADB_X_SPDDUMP */
-	key_spdflush,	/* SADB_X_SPDFLUSH */
-	key_spdadd,	/* SADB_X_SPDSETIDX */
-	NULL,		/* SADB_X_SPDEXPIRE */
-	key_spddelete2,	/* SADB_X_SPDDELETE2 */
-};
-
-/*
- * parse sadb_msg buffer to process PFKEYv2,
- * and create a data to response if needed.
- * I think to be dealed with mbuf directly.
- * IN:
- *     msgp  : pointer to pointer to a received buffer pulluped.
- *             This is rewrited to response.
- *     so    : pointer to socket.
- * OUT:
- *    length for buffer to send to user process.
- */
-int
-key_parse(m, so)
-	struct mbuf *m;
-	struct socket *so;
-{
-	struct sadb_msg *msg;
-	struct sadb_msghdr mh;
-	u_int orglen;
-	int error;
-	int target;
-#ifdef INET6
-	struct sockaddr_in6 *sin6;
-#endif
-
-	/* sanity check */
-	if (m == NULL || so == NULL)
-		panic("key_parse: NULL pointer is passed.");
-
-#if 0	/*kdebug_sadb assumes msg in linear buffer*/
-	KEYDEBUG(KEYDEBUG_KEY_DUMP,
-		ipseclog((LOG_DEBUG, "key_parse: passed sadb_msg\n"));
-		kdebug_sadb(msg));
-#endif
-
-	if (m->m_len < sizeof(struct sadb_msg)) {
-		m = m_pullup(m, sizeof(struct sadb_msg));
-		if (!m)
-			return ENOBUFS;
-	}
-	msg = mtod(m, struct sadb_msg *);
-	orglen = PFKEY_UNUNIT64(msg->sadb_msg_len);
-	target = KEY_SENDUP_ONE;
-
-	if ((m->m_flags & M_PKTHDR) == 0 ||
-	    m->m_pkthdr.len != m->m_pkthdr.len) {
-		ipseclog((LOG_DEBUG, "key_parse: invalid message length.\n"));
-		pfkeystat.out_invlen++;
-		error = EINVAL;
-		goto senderror;
-	}
-
-	if (msg->sadb_msg_version != PF_KEY_V2) {
-		ipseclog((LOG_DEBUG,
-		    "key_parse: PF_KEY version %u is mismatched.\n",
-		    msg->sadb_msg_version));
-		pfkeystat.out_invver++;
-		error = EINVAL;
-		goto senderror;
-	}
-
-	if (msg->sadb_msg_type > SADB_MAX) {
-		ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n",
-		    msg->sadb_msg_type));
-		pfkeystat.out_invmsgtype++;
-		error = EINVAL;
-		goto senderror;
-	}
-
-	/* for old-fashioned code - should be nuked */
-	if (m->m_pkthdr.len > MCLBYTES) {
-		m_freem(m);
-		return ENOBUFS;
-	}
-	if (m->m_next) {
-		struct mbuf *n;
-
-		MGETHDR(n, M_DONTWAIT, MT_DATA);
-		if (n && m->m_pkthdr.len > MHLEN) {
-			MCLGET(n, M_DONTWAIT);
-			if ((n->m_flags & M_EXT) == 0) {
-				m_free(n);
-				n = NULL;
-			}
-		}
-		if (!n) {
-			m_freem(m);
-			return ENOBUFS;
-		}
-		m_copydata(m, 0, m->m_pkthdr.len, mtod(n, caddr_t));
-		n->m_pkthdr.len = n->m_len = m->m_pkthdr.len;
-		n->m_next = NULL;
-		m_freem(m);
-		m = n;
-	}
-
-	/* align the mbuf chain so that extensions are in contiguous region. */
-	error = key_align(m, &mh);
-	if (error)
-		return error;
-
-	msg = mh.msg;
-
-	/* check SA type */
-	switch (msg->sadb_msg_satype) {
-	case SADB_SATYPE_UNSPEC:
-		switch (msg->sadb_msg_type) {
-		case SADB_GETSPI:
-		case SADB_UPDATE:
-		case SADB_ADD:
-		case SADB_DELETE:
-		case SADB_GET:
-		case SADB_ACQUIRE:
-		case SADB_EXPIRE:
-			ipseclog((LOG_DEBUG, "key_parse: must specify satype "
-			    "when msg type=%u.\n", msg->sadb_msg_type));
-			pfkeystat.out_invsatype++;
-			error = EINVAL;
-			goto senderror;
-		}
-		break;
-	case SADB_SATYPE_AH:
-	case SADB_SATYPE_ESP:
-	case SADB_X_SATYPE_IPCOMP:
-	case SADB_X_SATYPE_TCPSIGNATURE:
-		switch (msg->sadb_msg_type) {
-		case SADB_X_SPDADD:
-		case SADB_X_SPDDELETE:
-		case SADB_X_SPDGET:
-		case SADB_X_SPDDUMP:
-		case SADB_X_SPDFLUSH:
-		case SADB_X_SPDSETIDX:
-		case SADB_X_SPDUPDATE:
-		case SADB_X_SPDDELETE2:
-			ipseclog((LOG_DEBUG, "key_parse: illegal satype=%u\n",
-			    msg->sadb_msg_type));
-			pfkeystat.out_invsatype++;
-			error = EINVAL;
-			goto senderror;
-		}
-		break;
-	case SADB_SATYPE_RSVP:
-	case SADB_SATYPE_OSPFV2:
-	case SADB_SATYPE_RIPV2:
-	case SADB_SATYPE_MIP:
-		ipseclog((LOG_DEBUG, "key_parse: type %u isn't supported.\n",
-		    msg->sadb_msg_satype));
-		pfkeystat.out_invsatype++;
-		error = EOPNOTSUPP;
-		goto senderror;
-	case 1:	/* XXX: What does it do? */
-		if (msg->sadb_msg_type == SADB_X_PROMISC)
-			break;
-		/*FALLTHROUGH*/
-	default:
-		ipseclog((LOG_DEBUG, "key_parse: invalid type %u is passed.\n",
-		    msg->sadb_msg_satype));
-		pfkeystat.out_invsatype++;
-		error = EINVAL;
-		goto senderror;
-	}
-
-	/* check field of upper layer protocol and address family */
-	if (mh.ext[SADB_EXT_ADDRESS_SRC] != NULL &&
-	    mh.ext[SADB_EXT_ADDRESS_DST] != NULL) {
-		struct sadb_address *src0, *dst0;
-		u_int plen;
-
-		src0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_SRC]);
-		dst0 = (struct sadb_address *)(mh.ext[SADB_EXT_ADDRESS_DST]);
-
-		/* check upper layer protocol */
-		if (src0->sadb_address_proto != dst0->sadb_address_proto) {
-			ipseclog((LOG_DEBUG, "key_parse: upper layer protocol mismatched.\n"));
-			pfkeystat.out_invaddr++;
-			error = EINVAL;
-			goto senderror;
-		}
-
-		/* check family */
-		if (PFKEY_ADDR_SADDR(src0)->sa_family !=
-		    PFKEY_ADDR_SADDR(dst0)->sa_family) {
-			ipseclog((LOG_DEBUG, "key_parse: address family mismatched.\n"));
-			pfkeystat.out_invaddr++;
-			error = EINVAL;
-			goto senderror;
-		}
-		if (PFKEY_ADDR_SADDR(src0)->sa_len !=
-		    PFKEY_ADDR_SADDR(dst0)->sa_len) {
-			ipseclog((LOG_DEBUG,
-			    "key_parse: address struct size mismatched.\n"));
-			pfkeystat.out_invaddr++;
-			error = EINVAL;
-			goto senderror;
-		}
-
-		switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
-		case AF_INET:
-			if (PFKEY_ADDR_SADDR(src0)->sa_len !=
-			    sizeof(struct sockaddr_in)) {
-				pfkeystat.out_invaddr++;
-				error = EINVAL;
-				goto senderror;
-			}
-			break;
-		case AF_INET6:
-			if (PFKEY_ADDR_SADDR(src0)->sa_len !=
-			    sizeof(struct sockaddr_in6)) {
-				pfkeystat.out_invaddr++;
-				error = EINVAL;
-				goto senderror;
-			}
-#ifdef INET6
-			/*
-			 * Check validity of the scope zone ID of the
-			 * addresses, and embed the zone ID into the address
-			 * if necessary.
-			 */
-			sin6 = (struct sockaddr_in6 *)PFKEY_ADDR_SADDR(src0);
-			if ((error = sa6_embedscope(sin6, 0)) != 0)
-				goto senderror;
-			sin6 = (struct sockaddr_in6 *)PFKEY_ADDR_SADDR(dst0);
-			if ((error = sa6_embedscope(sin6, 0)) != 0)
-				goto senderror;
-#endif
-			break;
-		default:
-			ipseclog((LOG_DEBUG,
-			    "key_parse: unsupported address family.\n"));
-			pfkeystat.out_invaddr++;
-			error = EAFNOSUPPORT;
-			goto senderror;
-		}
-
-		switch (PFKEY_ADDR_SADDR(src0)->sa_family) {
-		case AF_INET:
-			plen = sizeof(struct in_addr) << 3;
-			break;
-		case AF_INET6:
-			plen = sizeof(struct in6_addr) << 3;
-			break;
-		default:
-			plen = 0;	/*fool gcc*/
-			break;
-		}
-
-		/* check max prefix length */
-		if (src0->sadb_address_prefixlen > plen ||
-		    dst0->sadb_address_prefixlen > plen) {
-			ipseclog((LOG_DEBUG,
-			    "key_parse: illegal prefixlen.\n"));
-			pfkeystat.out_invaddr++;
-			error = EINVAL;
-			goto senderror;
-		}
-
-		/*
-		 * prefixlen == 0 is valid because there can be a case when
-		 * all addresses are matched.
-		 */
-	}
-
-	if (msg->sadb_msg_type >= sizeof(key_typesw)/sizeof(key_typesw[0]) ||
-	    key_typesw[msg->sadb_msg_type] == NULL) {
-		pfkeystat.out_invmsgtype++;
-		error = EINVAL;
-		goto senderror;
-	}
-
-	return (*key_typesw[msg->sadb_msg_type])(so, m, &mh);
-
-senderror:
-	msg->sadb_msg_errno = error;
-	return key_sendup_mbuf(so, m, target);
-}
-
-static int
-key_senderror(so, m, code)
-	struct socket *so;
-	struct mbuf *m;
-	int code;
-{
-	struct sadb_msg *msg;
-
-	if (m->m_len < sizeof(struct sadb_msg))
-		panic("invalid mbuf passed to key_senderror");
-
-	msg = mtod(m, struct sadb_msg *);
-	msg->sadb_msg_errno = code;
-	return key_sendup_mbuf(so, m, KEY_SENDUP_ONE);
-}
-
-/*
- * set the pointer to each header into message buffer.
- * m will be freed on error.
- * XXX larger-than-MCLBYTES extension?
- */
-static int
-key_align(m, mhp)
-	struct mbuf *m;
-	struct sadb_msghdr *mhp;
-{
-	struct mbuf *n;
-	struct sadb_ext *ext;
-	size_t off, end;
-	int extlen;
-	int toff;
-
-	/* sanity check */
-	if (m == NULL || mhp == NULL)
-		panic("key_align: NULL pointer is passed.");
-	if (m->m_len < sizeof(struct sadb_msg))
-		panic("invalid mbuf passed to key_align");
-
-	/* initialize */
-	bzero(mhp, sizeof(*mhp));
-
-	mhp->msg = mtod(m, struct sadb_msg *);
-	mhp->ext[0] = (struct sadb_ext *)mhp->msg;	/*XXX backward compat */
-
-	end = PFKEY_UNUNIT64(mhp->msg->sadb_msg_len);
-	extlen = end;	/*just in case extlen is not updated*/
-	for (off = sizeof(struct sadb_msg); off < end; off += extlen) {
-		n = m_pulldown(m, off, sizeof(struct sadb_ext), &toff);
-		if (!n) {
-			/* m is already freed */
-			return ENOBUFS;
-		}
-		ext = (struct sadb_ext *)(mtod(n, caddr_t) + toff);
-
-		/* set pointer */
-		switch (ext->sadb_ext_type) {
-		case SADB_EXT_SA:
-		case SADB_EXT_ADDRESS_SRC:
-		case SADB_EXT_ADDRESS_DST:
-		case SADB_EXT_ADDRESS_PROXY:
-		case SADB_EXT_LIFETIME_CURRENT:
-		case SADB_EXT_LIFETIME_HARD:
-		case SADB_EXT_LIFETIME_SOFT:
-		case SADB_EXT_KEY_AUTH:
-		case SADB_EXT_KEY_ENCRYPT:
-		case SADB_EXT_IDENTITY_SRC:
-		case SADB_EXT_IDENTITY_DST:
-		case SADB_EXT_SENSITIVITY:
-		case SADB_EXT_PROPOSAL:
-		case SADB_EXT_SUPPORTED_AUTH:
-		case SADB_EXT_SUPPORTED_ENCRYPT:
-		case SADB_EXT_SPIRANGE:
-		case SADB_X_EXT_POLICY:
-		case SADB_X_EXT_SA2:
-			/* duplicate check */
-			/*
-			 * XXX Are there duplication payloads of either
-			 * KEY_AUTH or KEY_ENCRYPT ?
-			 */
-			if (mhp->ext[ext->sadb_ext_type] != NULL) {
-				ipseclog((LOG_DEBUG,
-				    "key_align: duplicate ext_type %u "
-				    "is passed.\n", ext->sadb_ext_type));
-				m_freem(m);
-				pfkeystat.out_dupext++;
-				return EINVAL;
-			}
-			break;
-		default:
-			ipseclog((LOG_DEBUG,
-			    "key_align: invalid ext_type %u is passed.\n",
-			    ext->sadb_ext_type));
-			m_freem(m);
-			pfkeystat.out_invexttype++;
-			return EINVAL;
-		}
-
-		extlen = PFKEY_UNUNIT64(ext->sadb_ext_len);
-
-		if (key_validate_ext(ext, extlen)) {
-			m_freem(m);
-			pfkeystat.out_invlen++;
-			return EINVAL;
-		}
-
-		n = m_pulldown(m, off, extlen, &toff);
-		if (!n) {
-			/* m is already freed */
-			return ENOBUFS;
-		}
-		ext = (struct sadb_ext *)(mtod(n, caddr_t) + toff);
-
-		mhp->ext[ext->sadb_ext_type] = ext;
-		mhp->extoff[ext->sadb_ext_type] = off;
-		mhp->extlen[ext->sadb_ext_type] = extlen;
-	}
-
-	if (off != end) {
-		m_freem(m);
-		pfkeystat.out_invlen++;
-		return EINVAL;
-	}
-
-	return 0;
-}
-
-static int
-key_validate_ext(ext, len)
-	struct sadb_ext *ext;
-	int len;
-{
-	struct sockaddr *sa;
-	enum { NONE, ADDR } checktype = NONE;
-	int baselen = 0;
-	const int sal = offsetof(struct sockaddr, sa_len) + sizeof(sa->sa_len);
-
-	if (len != PFKEY_UNUNIT64(ext->sadb_ext_len))
-		return EINVAL;
-
-	/* if it does not match minimum/maximum length, bail */
-	if (ext->sadb_ext_type >= sizeof(minsize) / sizeof(minsize[0]) ||
-	    ext->sadb_ext_type >= sizeof(maxsize) / sizeof(maxsize[0]))
-		return EINVAL;
-	if (!minsize[ext->sadb_ext_type] || len < minsize[ext->sadb_ext_type])
-		return EINVAL;
-	if (maxsize[ext->sadb_ext_type] && len > maxsize[ext->sadb_ext_type])
-		return EINVAL;
-
-	/* more checks based on sadb_ext_type XXX need more */
-	switch (ext->sadb_ext_type) {
-	case SADB_EXT_ADDRESS_SRC:
-	case SADB_EXT_ADDRESS_DST:
-	case SADB_EXT_ADDRESS_PROXY:
-		baselen = PFKEY_ALIGN8(sizeof(struct sadb_address));
-		checktype = ADDR;
-		break;
-	case SADB_EXT_IDENTITY_SRC:
-	case SADB_EXT_IDENTITY_DST:
-		if (((struct sadb_ident *)ext)->sadb_ident_type ==
-		    SADB_X_IDENTTYPE_ADDR) {
-			baselen = PFKEY_ALIGN8(sizeof(struct sadb_ident));
-			checktype = ADDR;
-		} else
-			checktype = NONE;
-		break;
-	default:
-		checktype = NONE;
-		break;
-	}
-
-	switch (checktype) {
-	case NONE:
-		break;
-	case ADDR:
-		sa = (struct sockaddr *)((caddr_t)ext + baselen);
-		if (len < baselen + sal)
-			return EINVAL;
-		if (baselen + PFKEY_ALIGN8(sa->sa_len) != len)
-			return EINVAL;
-		break;
-	}
-
-	return 0;
-}
-
-void
-key_init()
-{
-	int i;
-
-	bzero((caddr_t)&key_cb, sizeof(key_cb));
-
-	callout_init(&key_timehandler_ch, 0);
-
-	for (i = 0; i < IPSEC_DIR_MAX; i++)
-		LIST_INIT(&sptree[i]);
-
-	LIST_INIT(&sahtree);
-
-	for (i = 0; i <= SADB_SATYPE_MAX; i++)
-		LIST_INIT(&regtree[i]);
-
-	for (i = 0; i < SPIHASHSIZE; i++)
-		LIST_INIT(&spihash[i]);
-
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-	LIST_INIT(&acqtree);
-#endif
-	LIST_INIT(&spacqtree);
-
-	TAILQ_INIT(&satailq);
-	TAILQ_INIT(&sptailq);
-
-	/* system default */
-#ifdef INET
-	ip4_def_policy = key_newsp(0);
-	if (!ip4_def_policy)
-		panic("could not initialize IPv4 default security policy");
-	ip4_def_policy->state = IPSEC_SPSTATE_ALIVE;
-	ip4_def_policy->policy = IPSEC_POLICY_NONE;
-	ip4_def_policy->dir = IPSEC_DIR_ANY;
-	ip4_def_policy->readonly = 1;
-	ip4_def_policy->persist = 1;
-#endif
-#ifdef INET6
-	ip6_def_policy = key_newsp(0);
-	if (!ip6_def_policy)
-		panic("could not initialize IPv6 default security policy");
-	ip6_def_policy->state = IPSEC_SPSTATE_ALIVE;
-	ip6_def_policy->policy = IPSEC_POLICY_NONE;
-	ip6_def_policy->dir = IPSEC_DIR_ANY;
-	ip6_def_policy->readonly = 1;
-	ip6_def_policy->persist = 1;
-#endif
-
-	callout_reset(&key_timehandler_ch, hz, key_timehandler, (void *)0);
-
-	/* initialize key statistics */
-	keystat.getspi_count = 1;
-
-	printf("IPsec: Initialized Security Association Processing.\n");
-
-	return;
-}
-
-/*
- * XXX: maybe This function is called after INBOUND IPsec processing.
- *
- * Special check for tunnel-mode packets.
- * We must make some checks for consistency between inner and outer IP header.
- *
- * xxx more checks to be provided
- */
-int
-key_checktunnelsanity(sav, family, src, dst)
-	struct secasvar *sav;
-	u_int family;
-	caddr_t src;
-	caddr_t dst;
-{
-	/* sanity check */
-	if (sav->sah == NULL)
-		panic("sav->sah == NULL at key_checktunnelsanity");
-
-	/* XXX: check inner IP header */
-
-	return 1;
-}
-
-#if 0
-/*
- * Get FQDN for the host.
- * If the administrator configured hostname (by hostname(1)) without
- * domain name, returns nothing.
- */
-static const char *
-key_getfqdn()
-{
-	int i;
-	int hasdot;
-	static char fqdn[MAXHOSTNAMELEN + 1];
-	int hostnamelen = strlen(hostname);
-
-	if (!hostnamelen)
-		return NULL;
-
-	/* check if it comes with domain name. */
-	hasdot = 0;
-	for (i = 0; i < hostnamelen; i++) {
-		if (hostname[i] == '.')
-			hasdot++;
-	}
-	if (!hasdot)
-		return NULL;
-
-	/* NOTE: hostname may not be NUL-terminated. */
-	bzero(fqdn, sizeof(fqdn));
-	bcopy(hostname, fqdn, hostnamelen);
-	fqdn[hostnamelen] = '\0';
-	return fqdn;
-}
-
-/*
- * get username at FQDN for the host/user.
- */
-static const char *
-key_getuserfqdn()
-{
-	const char *host;
-	static char userfqdn[MAXHOSTNAMELEN + MAXLOGNAME + 2];
-	struct proc *p = curproc;
-	char *q;
-
-	PROC_LOCK(p);
-	if (!p || !p->p_pgrp || !p->p_pgrp->pg_session) {
-		PROC_UNLOCK(p);
-		return NULL;
-	}
-	if (!(host = key_getfqdn())) {
-		PROC_UNLOCK(p);
-		return NULL;
-	}
-
-	/* NOTE: s_login may not be-NUL terminated. */
-	bzero(userfqdn, sizeof(userfqdn));
-	SESS_LOCK(p->p_session);
-	bcopy(p->p_pgrp->pg_session->s_login, userfqdn, MAXLOGNAME);
-	SESS_UNLOCK(p->p_session);
-	PROC_UNLOCK(p);
-	userfqdn[MAXLOGNAME] = '\0';	/* safeguard */
-	q = userfqdn + strlen(userfqdn);
-	*q++ = '@';
-	bcopy(host, q, strlen(host));
-	q += strlen(host);
-	*q++ = '\0';
-
-	return userfqdn;
-}
-#endif
-
-/* record data transfer on SA, and update timestamps */
-void
-key_sa_recordxfer(sav, m)
-	struct secasvar *sav;
-	struct mbuf *m;
-{
-	if (!sav)
-		panic("key_sa_recordxfer called with sav == NULL");
-	if (!m)
-		panic("key_sa_recordxfer called with m == NULL");
-	if (!sav->lft_c)
-		return;
-
-	/*
-	 * XXX Currently, there is a difference of bytes size
-	 * between inbound and outbound processing.
-	 */
-	sav->lft_c->sadb_lifetime_bytes += m->m_pkthdr.len;
-	/* to check bytes lifetime is done in key_timehandler(). */
-
-	/*
-	 * We use the number of packets as the unit of
-	 * sadb_lifetime_allocations.  We increment the variable
-	 * whenever {esp,ah}_{in,out}put is called.
-	 */
-	sav->lft_c->sadb_lifetime_allocations++;
-	/* XXX check for expires? */
-
-	/*
-	 * NOTE: We record CURRENT sadb_lifetime_usetime by using wall clock,
-	 * in seconds.  HARD and SOFT lifetime are measured by the time
-	 * difference (again in seconds) from sadb_lifetime_usetime.
-	 *
-	 *	usetime
-	 *	v     expire   expire
-	 * -----+-----+--------+---> t
-	 *	<--------------> HARD
-	 *	<-----> SOFT
-	 */
-    {
-	sav->lft_c->sadb_lifetime_usetime = time_second;
-	/* XXX check for expires? */
-    }
-
-	return;
-}
-
-/* dumb version */
-void
-key_sa_routechange(dst)
-	struct sockaddr *dst;
-{
-	struct secashead *sah;
-	struct route *ro;
-
-	LIST_FOREACH(sah, &sahtree, chain) {
-		ro = &sah->sa_route;
-		if (ro->ro_rt && dst->sa_len == ro->ro_dst.sa_len &&
-		    bcmp(dst, &ro->ro_dst, dst->sa_len) == 0) {
-			RTFREE(ro->ro_rt);
-			ro->ro_rt = (struct rtentry *)NULL;
-		}
-	}
-
-	return;
-}
-
-static void
-key_sa_chgstate(sav, state)
-	struct secasvar *sav;
-	u_int8_t state;
-{
-	if (sav == NULL)
-		panic("key_sa_chgstate called with sav == NULL");
-
-	if (sav->state == state)
-		return;
-
-	if (__LIST_CHAINED(sav))
-		LIST_REMOVE(sav, chain);
-
-	sav->state = state;
-	LIST_INSERT_HEAD(&sav->sah->savtree[state], sav, chain);
-}
-
-void
-key_sa_stir_iv(sav)
-	struct secasvar *sav;
-{
-
-	if (!sav->iv)
-		panic("key_sa_stir_iv called with sav == NULL");
-	key_randomfill(sav->iv, sav->ivlen);
-}
-
-static void
-key_sp_dead(sp)
-	struct secpolicy *sp;
-{
-
-	/* mark the SP dead */
-	sp->state = IPSEC_SPSTATE_DEAD;
-}
-
-static void
-key_sp_unlink(sp)
-	struct secpolicy *sp;
-{
-
-	/* remove from SP index */
-	if (__LIST_CHAINED(sp)) {
-		LIST_REMOVE(sp, chain);
-		key_freesp(sp);
-	}
-}
-
-/* XXX too much? */
-static struct mbuf *
-key_alloc_mbuf(l)
-	int l;
-{
-	struct mbuf *m = NULL, *n;
-	int len, t;
-
-	len = l;
-	while (len > 0) {
-		MGET(n, M_DONTWAIT, MT_DATA);
-		if (n && len > MLEN)
-			MCLGET(n, M_DONTWAIT);
-		if (!n) {
-			m_freem(m);
-			return NULL;
-		}
-
-		n->m_next = NULL;
-		n->m_len = 0;
-		n->m_len = M_TRAILINGSPACE(n);
-		/* use the bottom of mbuf, hoping we can prepend afterwards */
-		if (n->m_len > len) {
-			t = (n->m_len - len) & ~(sizeof(long) - 1);
-			n->m_data += t;
-			n->m_len = len;
-		}
-
-		len -= n->m_len;
-
-		if (m)
-			m_cat(m, n);
-		else
-			m = n;
-	}
-
-	return m;
-}
--- sys/netkey/key_debug.c
+++ /dev/null
@@ -1,843 +0,0 @@
-/*	$KAME: key_debug.c,v 1.38 2003/09/06 05:15:44 itojun Exp $	*/
-
-/*-
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netkey/key_debug.c,v 1.25 2005/01/07 01:45:48 imp Exp $");
-
-#ifdef _KERNEL
-#include "opt_inet.h"
-#include "opt_inet6.h"
-#include "opt_ipsec.h"
-#endif
-
-#include <sys/types.h>
-#include <sys/param.h>
-#ifdef _KERNEL
-#include <sys/systm.h>
-#include <sys/mbuf.h>
-#include <sys/queue.h>
-#endif
-#include <sys/socket.h>
-
-#include <net/route.h>
-
-#include <netkey/key_var.h>
-#include <netkey/key_debug.h>
-
-#include <netinet/in.h>
-#include <netinet6/ipsec.h>
-
-#ifndef _KERNEL
-#include <ctype.h>
-#include <stdio.h>
-#include <stdlib.h>
-#endif /* !_KERNEL */
-
-struct typestr {
-	const char	*string;
-	u_int		type;
-};
-#define TYPESTR(x)	{ "SADB_" #x, SADB_ ## x }
-
-static const char *kdebug_typestr(u_int, const struct typestr *);
-static const char *kdebug_sadb_msg_typestr(u_int);
-static const char *kdebug_sadb_ext_typestr(u_int);
-static void kdebug_sadb_prop(struct sadb_ext *);
-static void kdebug_sadb_identity(struct sadb_ext *);
-static void kdebug_sadb_supported(struct sadb_ext *);
-static void kdebug_sadb_lifetime(struct sadb_ext *);
-static void kdebug_sadb_sa(struct sadb_ext *);
-static void kdebug_sadb_address(struct sadb_ext *);
-static void kdebug_sadb_key(struct sadb_ext *);
-static void kdebug_sadb_x_sa2(struct sadb_ext *);
-
-#ifdef _KERNEL
-static void kdebug_secreplay(struct secreplay *);
-#endif
-
-#ifndef _KERNEL
-#define panic(param)	{ printf(param); exit(1); }
-#endif
-
-static const char *
-kdebug_typestr(type, list)
-	u_int type;
-	const struct typestr *list;
-{
-	static char buf[32];
-
-	while (list->string != NULL) {
-		if (type == list->type)
-			return (list->string);
-		list++;
-	}
-	snprintf(buf, sizeof(buf), "%u", type);
-
-	return (buf);
-}
-
-static const char *
-kdebug_sadb_msg_typestr(type)
-	u_int type;
-{
-	static const struct typestr list[] = {
-		TYPESTR(RESERVED),
-		TYPESTR(GETSPI),
-		TYPESTR(UPDATE),
-		TYPESTR(ADD),
-		TYPESTR(DELETE),
-		TYPESTR(GET),
-		TYPESTR(ACQUIRE),
-		TYPESTR(REGISTER),
-		TYPESTR(EXPIRE),
-		TYPESTR(FLUSH),
-		TYPESTR(DUMP),
-		TYPESTR(X_PROMISC),
-		TYPESTR(X_PCHANGE),
-		TYPESTR(X_SPDUPDATE),
-		TYPESTR(X_SPDADD),
-		TYPESTR(X_SPDDELETE),
-		TYPESTR(X_SPDGET),
-		TYPESTR(X_SPDACQUIRE),
-		TYPESTR(X_SPDDUMP),
-		TYPESTR(X_SPDFLUSH),
-		TYPESTR(X_SPDSETIDX),
-		TYPESTR(X_SPDEXPIRE),
-		TYPESTR(X_SPDDELETE2),
-		{ NULL }
-	};
-
-	return kdebug_typestr(type, list);
-}
-
-static const char *
-kdebug_sadb_ext_typestr(type)
-	u_int type;
-{
-	static const struct typestr list[] = {
-		TYPESTR(EXT_RESERVED),
-		TYPESTR(EXT_SA),
-		TYPESTR(EXT_LIFETIME_CURRENT),
-		TYPESTR(EXT_LIFETIME_HARD),
-		TYPESTR(EXT_LIFETIME_SOFT),
-		TYPESTR(EXT_ADDRESS_SRC),
-		TYPESTR(EXT_ADDRESS_DST),
-		TYPESTR(EXT_ADDRESS_PROXY),
-		TYPESTR(EXT_KEY_AUTH),
-		TYPESTR(EXT_KEY_ENCRYPT),
-		TYPESTR(EXT_IDENTITY_SRC),
-		TYPESTR(EXT_IDENTITY_DST),
-		TYPESTR(EXT_SENSITIVITY),
-		TYPESTR(EXT_PROPOSAL),
-		TYPESTR(EXT_SUPPORTED_AUTH),
-		TYPESTR(EXT_SUPPORTED_ENCRYPT),
-		TYPESTR(EXT_SPIRANGE),
-		TYPESTR(X_EXT_KMPRIVATE),
-		TYPESTR(X_EXT_POLICY),
-		TYPESTR(X_EXT_SA2),
-		{ NULL }
-	};
-
-	return kdebug_typestr(type, list);
-}
-
-/* NOTE: host byte order */
-
-/* %%%: about struct sadb_msg */
-void
-kdebug_sadb(base)
-	struct sadb_msg *base;
-{
-	struct sadb_ext *ext;
-	int tlen, extlen;
-
-	/* sanity check */
-	if (base == NULL)
-		panic("kdebug_sadb: NULL pointer was passed.");
-
-	printf("sadb_msg{ version=%u type=%s errno=%u satype=%u\n",
-	    base->sadb_msg_version,
-	    kdebug_sadb_msg_typestr(base->sadb_msg_type),
-	    base->sadb_msg_errno, base->sadb_msg_satype);
-	printf("  len=%u reserved=%u seq=%u pid=%u\n",
-	    base->sadb_msg_len, base->sadb_msg_reserved,
-	    base->sadb_msg_seq, base->sadb_msg_pid);
-
-	tlen = PFKEY_UNUNIT64(base->sadb_msg_len) - sizeof(struct sadb_msg);
-	ext = (struct sadb_ext *)((caddr_t)base + sizeof(struct sadb_msg));
-
-	while (tlen > 0) {
-		printf("sadb_ext{ len=%u type=%s }\n",
-		    ext->sadb_ext_len,
-		    kdebug_sadb_ext_typestr(ext->sadb_ext_type));
-
-		if (ext->sadb_ext_len == 0) {
-			printf("kdebug_sadb: invalid ext_len=0 was passed.\n");
-			return;
-		}
-		if (ext->sadb_ext_len > tlen) {
-			printf("kdebug_sadb: ext_len exceeds end of buffer.\n");
-			return;
-		}
-
-		switch (ext->sadb_ext_type) {
-		case SADB_EXT_SA:
-			kdebug_sadb_sa(ext);
-			break;
-		case SADB_EXT_LIFETIME_CURRENT:
-		case SADB_EXT_LIFETIME_HARD:
-		case SADB_EXT_LIFETIME_SOFT:
-			kdebug_sadb_lifetime(ext);
-			break;
-		case SADB_EXT_ADDRESS_SRC:
-		case SADB_EXT_ADDRESS_DST:
-		case SADB_EXT_ADDRESS_PROXY:
-			kdebug_sadb_address(ext);
-			break;
-		case SADB_EXT_KEY_AUTH:
-		case SADB_EXT_KEY_ENCRYPT:
-			kdebug_sadb_key(ext);
-			break;
-		case SADB_EXT_IDENTITY_SRC:
-		case SADB_EXT_IDENTITY_DST:
-			kdebug_sadb_identity(ext);
-			break;
-		case SADB_EXT_SENSITIVITY:
-			break;
-		case SADB_EXT_PROPOSAL:
-			kdebug_sadb_prop(ext);
-			break;
-		case SADB_EXT_SUPPORTED_AUTH:
-		case SADB_EXT_SUPPORTED_ENCRYPT:
-			kdebug_sadb_supported(ext);
-			break;
-		case SADB_EXT_SPIRANGE:
-		case SADB_X_EXT_KMPRIVATE:
-			break;
-		case SADB_X_EXT_POLICY:
-			kdebug_sadb_x_policy(ext);
-			break;
-		case SADB_X_EXT_SA2:
-			kdebug_sadb_x_sa2(ext);
-			break;
-		default:
-			printf("kdebug_sadb: invalid ext_type %u was passed.\n",
-			    ext->sadb_ext_type);
-			return;
-		}
-
-		extlen = PFKEY_UNUNIT64(ext->sadb_ext_len);
-		tlen -= extlen;
-		ext = (struct sadb_ext *)((caddr_t)ext + extlen);
-	}
-
-	return;
-}
-
-static void
-kdebug_sadb_prop(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_prop *prop = (struct sadb_prop *)ext;
-	struct sadb_comb *comb;
-	int len;
-
-	/* sanity check */
-	if (ext == NULL)
-		panic("kdebug_sadb_prop: NULL pointer was passed.");
-
-	len = (PFKEY_UNUNIT64(prop->sadb_prop_len) - sizeof(*prop))
-		/ sizeof(*comb);
-	comb = (struct sadb_comb *)(prop + 1);
-	printf("sadb_prop{ replay=%u\n", prop->sadb_prop_replay);
-
-	while (len--) {
-		printf("sadb_comb{ auth=%u encrypt=%u "
-			"flags=0x%04x reserved=0x%08x\n",
-			comb->sadb_comb_auth, comb->sadb_comb_encrypt,
-			comb->sadb_comb_flags, comb->sadb_comb_reserved);
-
-		printf("  auth_minbits=%u auth_maxbits=%u "
-			"encrypt_minbits=%u encrypt_maxbits=%u\n",
-			comb->sadb_comb_auth_minbits,
-			comb->sadb_comb_auth_maxbits,
-			comb->sadb_comb_encrypt_minbits,
-			comb->sadb_comb_encrypt_maxbits);
-
-		printf("  soft_alloc=%u hard_alloc=%u "
-			"soft_bytes=%lu hard_bytes=%lu\n",
-			comb->sadb_comb_soft_allocations,
-			comb->sadb_comb_hard_allocations,
-			(unsigned long)comb->sadb_comb_soft_bytes,
-			(unsigned long)comb->sadb_comb_hard_bytes);
-
-		printf("  soft_alloc=%lu hard_alloc=%lu "
-			"soft_bytes=%lu hard_bytes=%lu }\n",
-			(unsigned long)comb->sadb_comb_soft_addtime,
-			(unsigned long)comb->sadb_comb_hard_addtime,
-			(unsigned long)comb->sadb_comb_soft_usetime,
-			(unsigned long)comb->sadb_comb_hard_usetime);
-		comb++;
-	}
-	printf("}\n");
-
-	return;
-}
-
-static void
-kdebug_sadb_identity(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_ident *id = (struct sadb_ident *)ext;
-	int len;
-
-	/* sanity check */
-	if (ext == NULL)
-		panic("kdebug_sadb_identity: NULL pointer was passed.");
-
-	len = PFKEY_UNUNIT64(id->sadb_ident_len) - sizeof(*id);
-	printf("sadb_ident_%s{",
-	    id->sadb_ident_exttype == SADB_EXT_IDENTITY_SRC ? "src" : "dst");
-	switch (id->sadb_ident_type) {
-	default:
-		printf(" type=%u id=%lu",
-			id->sadb_ident_type, (u_long)id->sadb_ident_id);
-		if (len) {
-#ifdef _KERNEL
-			ipsec_hexdump((caddr_t)(id + 1), len); /*XXX cast ?*/
-#else
-			char *p, *ep;
-			printf("\n  str=\"");
-			p = (char *)(id + 1);
-			ep = p + len;
-			for (/*nothing*/; *p && p < ep; p++) {
-				if (isprint(*p))
-					printf("%c", *p & 0xff);
-				else
-					printf("\\%03o", *p & 0xff);
-			}
-#endif
-			printf("\"");
-		}
-		break;
-	}
-
-	printf(" }\n");
-
-	return;
-}
-
-static void
-kdebug_sadb_supported(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_supported *sup = (struct sadb_supported *)ext;
-	struct sadb_alg *alg;
-	int len;
-
-	/* sanity check */
-	if (ext == NULL)
-		panic("kdebug_sadb_supported: NULL pointer was passed.");
-
-	len = (PFKEY_UNUNIT64(sup->sadb_supported_len) - sizeof(*sup))
-		/ sizeof(*alg);
-	alg = (struct sadb_alg *)(sup + 1);
-	printf("sadb_sup{\n");
-	while (len--) {
-		printf("  { id=%u ivlen=%u min=%u max=%u }\n",
-			alg->sadb_alg_id, alg->sadb_alg_ivlen,
-			alg->sadb_alg_minbits, alg->sadb_alg_maxbits);
-		alg++;
-	}
-	printf("}\n");
-
-	return;
-}
-
-static void
-kdebug_sadb_lifetime(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_lifetime *lft = (struct sadb_lifetime *)ext;
-
-	/* sanity check */
-	if (ext == NULL)
-		printf("kdebug_sadb_lifetime: NULL pointer was passed.\n");
-
-	printf("sadb_lifetime{ alloc=%u, bytes=%u\n",
-		lft->sadb_lifetime_allocations,
-		(u_int32_t)lft->sadb_lifetime_bytes);
-	printf("  addtime=%u, usetime=%u }\n",
-		(u_int32_t)lft->sadb_lifetime_addtime,
-		(u_int32_t)lft->sadb_lifetime_usetime);
-
-	return;
-}
-
-static void
-kdebug_sadb_sa(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_sa *sa = (struct sadb_sa *)ext;
-
-	/* sanity check */
-	if (ext == NULL)
-		panic("kdebug_sadb_sa: NULL pointer was passed.");
-
-	printf("sadb_sa{ spi=%u replay=%u state=%u\n",
-	    (u_int32_t)ntohl(sa->sadb_sa_spi), sa->sadb_sa_replay,
-	    sa->sadb_sa_state);
-	printf("  auth=%u encrypt=%u flags=0x%08x }\n",
-	    sa->sadb_sa_auth, sa->sadb_sa_encrypt, sa->sadb_sa_flags);
-
-	return;
-}
-
-static void
-kdebug_sadb_address(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_address *addr = (struct sadb_address *)ext;
-
-	/* sanity check */
-	if (ext == NULL)
-		panic("kdebug_sadb_address: NULL pointer was passed.");
-
-	printf("sadb_address{ proto=%u prefixlen=%u reserved=0x%02x%02x }\n",
-	    addr->sadb_address_proto, addr->sadb_address_prefixlen,
-	    ((u_char *)&addr->sadb_address_reserved)[0],
-	    ((u_char *)&addr->sadb_address_reserved)[1]);
-
-	kdebug_sockaddr((struct sockaddr *)((caddr_t)ext + sizeof(*addr)));
-
-	return;
-}
-
-static void
-kdebug_sadb_key(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_key *key = (struct sadb_key *)ext;
-
-	/* sanity check */
-	if (ext == NULL)
-		panic("kdebug_sadb_key: NULL pointer was passed.");
-
-	printf("sadb_key{ bits=%u reserved=%u\n",
-	    key->sadb_key_bits, key->sadb_key_reserved);
-	printf("  key=");
-
-	/* sanity check 2 */
-	if ((key->sadb_key_bits >> 3) >
-		(PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key))) {
-		printf("kdebug_sadb_key: key length mismatch, bit:%u len:%ld.\n",
-			key->sadb_key_bits >> 3,
-			(long)PFKEY_UNUNIT64(key->sadb_key_len) - sizeof(struct sadb_key));
-	}
-
-	ipsec_hexdump((caddr_t)key + sizeof(struct sadb_key),
-	              key->sadb_key_bits >> 3);
-	printf(" }\n");
-	return;
-}
-
-static void
-kdebug_sadb_x_sa2(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_x_sa2 *sa2 = (struct sadb_x_sa2 *)ext;
-
-	/* sanity check */
-	if (ext == NULL)
-		panic("kdebug_sadb_x_sa2: NULL pointer was passed.");
-
-	printf("sadb_x_sa2{ mode=%u reqid=%u\n",
-	    sa2->sadb_x_sa2_mode, sa2->sadb_x_sa2_reqid);
-	printf("  reserved1=%u reserved2=%u sequence=%u }\n",
-	    sa2->sadb_x_sa2_reserved1, sa2->sadb_x_sa2_reserved2,
-	    sa2->sadb_x_sa2_sequence);
-
-	return;
-}
-
-void
-kdebug_sadb_x_policy(ext)
-	struct sadb_ext *ext;
-{
-	struct sadb_x_policy *xpl = (struct sadb_x_policy *)ext;
-	struct sockaddr *addr;
-
-	/* sanity check */
-	if (ext == NULL)
-		panic("kdebug_sadb_x_policy: NULL pointer was passed.");
-
-	printf("sadb_x_policy{ type=%u dir=%u id=%x }\n",
-		xpl->sadb_x_policy_type, xpl->sadb_x_policy_dir,
-		xpl->sadb_x_policy_id);
-
-	if (xpl->sadb_x_policy_type == IPSEC_POLICY_IPSEC) {
-		int tlen;
-		struct sadb_x_ipsecrequest *xisr;
-
-		tlen = PFKEY_UNUNIT64(xpl->sadb_x_policy_len) - sizeof(*xpl);
-		xisr = (struct sadb_x_ipsecrequest *)(xpl + 1);
-
-		while (tlen > 0) {
-			printf(" { len=%u proto=%u mode=%u level=%u reqid=%u\n",
-				xisr->sadb_x_ipsecrequest_len,
-				xisr->sadb_x_ipsecrequest_proto,
-				xisr->sadb_x_ipsecrequest_mode,
-				xisr->sadb_x_ipsecrequest_level,
-				xisr->sadb_x_ipsecrequest_reqid);
-
-			if (xisr->sadb_x_ipsecrequest_len > sizeof(*xisr)) {
-				addr = (struct sockaddr *)(xisr + 1);
-				kdebug_sockaddr(addr);
-				addr = (struct sockaddr *)((caddr_t)addr
-							+ addr->sa_len);
-				kdebug_sockaddr(addr);
-			}
-
-			printf(" }\n");
-
-			/* prevent infinite loop */
-			if (xisr->sadb_x_ipsecrequest_len <= 0) {
-				printf("kdebug_sadb_x_policy: wrong policy struct.\n");
-				return;
-			}
-			/* prevent overflow */
-			if (xisr->sadb_x_ipsecrequest_len > tlen) {
-				printf("invalid ipsec policy length\n");
-				return;
-			}
-
-			tlen -= xisr->sadb_x_ipsecrequest_len;
-
-			xisr = (struct sadb_x_ipsecrequest *)((caddr_t)xisr
-			                + xisr->sadb_x_ipsecrequest_len);
-		}
-
-		if (tlen != 0)
-			panic("kdebug_sadb_x_policy: wrong policy struct.");
-	}
-
-	return;
-}
-
-#ifdef _KERNEL
-/* %%%: about SPD and SAD */
-void
-kdebug_secpolicy(sp)
-	struct secpolicy *sp;
-{
-	/* sanity check */
-	if (sp == NULL)
-		panic("kdebug_secpolicy: NULL pointer was passed.");
-
-	printf("secpolicy{ refcnt=%u state=%u policy=%u dir=%u\n",
-		sp->refcnt, sp->state, sp->policy, sp->dir);
-
-	if (sp->spidx)
-		kdebug_secpolicyindex(sp->spidx);
-
-	switch (sp->policy) {
-	case IPSEC_POLICY_DISCARD:
-		printf("  type=discard }\n");
-		break;
-	case IPSEC_POLICY_NONE:
-		printf("  type=none }\n");
-		break;
-	case IPSEC_POLICY_IPSEC:
-	    {
-		struct ipsecrequest *isr;
-		for (isr = sp->req; isr != NULL; isr = isr->next) {
-
-			printf("  level=%u\n", isr->level);
-			kdebug_secasindex(&isr->saidx);
-
-			if (isr->sav != NULL)
-				kdebug_secasv(isr->sav);
-		}
-		printf("  }\n");
-	    }
-		break;
-	case IPSEC_POLICY_BYPASS:
-		printf("  type=bypass }\n");
-		break;
-	case IPSEC_POLICY_ENTRUST:
-		printf("  type=entrust }\n");
-		break;
-	default:
-		printf("kdebug_secpolicy: Invalid policy found. %u\n",
-			sp->policy);
-		break;
-	}
-
-	return;
-}
-
-void
-kdebug_secpolicyindex(spidx)
-	struct secpolicyindex *spidx;
-{
-	/* sanity check */
-	if (spidx == NULL)
-		panic("kdebug_secpolicyindex: NULL pointer was passed.");
-
-	printf("secpolicyindex{ prefs=%u prefd=%u ul_proto=%u\n",
-	    spidx->prefs, spidx->prefd, spidx->ul_proto);
-
-	ipsec_hexdump((caddr_t)&spidx->src,
-		((struct sockaddr *)&spidx->src)->sa_len);
-	printf("\n");
-	ipsec_hexdump((caddr_t)&spidx->dst,
-		((struct sockaddr *)&spidx->dst)->sa_len);
-	printf("}\n");
-
-	return;
-}
-
-void
-kdebug_secasindex(saidx)
-	struct secasindex *saidx;
-{
-	/* sanity check */
-	if (saidx == NULL)
-		panic("kdebug_secpolicyindex: NULL pointer was passed.");
-
-	printf("secasindex{ mode=%u proto=%u\n", saidx->mode, saidx->proto);
-
-	ipsec_hexdump((caddr_t)&saidx->src,
-		((struct sockaddr *)&saidx->src)->sa_len);
-	printf("\n");
-	ipsec_hexdump((caddr_t)&saidx->dst,
-		((struct sockaddr *)&saidx->dst)->sa_len);
-	printf("\n");
-
-	return;
-}
-
-void
-kdebug_secasv(sav)
-	struct secasvar *sav;
-{
-	/* sanity check */
-	if (sav == NULL)
-		panic("kdebug_secasv: NULL pointer was passed.");
-
-	printf("secas{");
-	kdebug_secasindex(&sav->sah->saidx);
-
-	printf("  refcnt=%u state=%u auth=%u enc=%u\n",
-	    sav->refcnt, sav->state, sav->alg_auth, sav->alg_enc);
-	printf("  spi=%u flags=%u\n",
-	    (u_int32_t)ntohl(sav->spi), sav->flags);
-
-	if (sav->key_auth != NULL)
-		kdebug_sadb_key((struct sadb_ext *)sav->key_auth);
-	if (sav->key_enc != NULL)
-		kdebug_sadb_key((struct sadb_ext *)sav->key_enc);
-	if (sav->iv != NULL) {
-		printf("  iv=");
-		ipsec_hexdump(sav->iv, sav->ivlen ? sav->ivlen : 8);
-		printf("\n");
-	}
-
-	if (sav->replay != NULL)
-		kdebug_secreplay(sav->replay);
-	if (sav->lft_c != NULL)
-		kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_c);
-	if (sav->lft_h != NULL)
-		kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_h);
-	if (sav->lft_s != NULL)
-		kdebug_sadb_lifetime((struct sadb_ext *)sav->lft_s);
-
-#if notyet
-	/* XXX: misc[123] ? */
-#endif
-
-	return;
-}
-
-static void
-kdebug_secreplay(rpl)
-	struct secreplay *rpl;
-{
-	int len, l;
-
-	/* sanity check */
-	if (rpl == NULL)
-		panic("kdebug_secreplay: NULL pointer was passed.");
-
-	printf(" secreplay{ count=%llu wsize=%u seq=%llu lastseq=%llu",
-	    (unsigned long long)rpl->count, rpl->wsize,
-	    (unsigned long long)rpl->seq, (unsigned long long)rpl->lastseq);
-
-	if (rpl->bitmap == NULL) {
-		printf(" }\n");
-		return;
-	}
-
-	printf("\n   bitmap { ");
-
-	for (len = 0; len < rpl->wsize; len++) {
-		for (l = 7; l >= 0; l--)
-			printf("%u", (((rpl->bitmap)[len] >> l) & 1) ? 1 : 0);
-	}
-	printf(" }\n");
-
-	return;
-}
-
-void
-kdebug_mbufhdr(m)
-	struct mbuf *m;
-{
-	/* sanity check */
-	if (m == NULL)
-		return;
-
-	printf("mbuf(%p){ m_next:%p m_nextpkt:%p m_data:%p "
-	       "m_len:%d m_type:0x%02x m_flags:0x%02x }\n",
-		m, m->m_next, m->m_nextpkt, m->m_data,
-		m->m_len, m->m_type, m->m_flags);
-
-	if (m->m_flags & M_PKTHDR) {
-		printf("  m_pkthdr{ len:%d rcvif:%p }\n",
-		    m->m_pkthdr.len, m->m_pkthdr.rcvif);
-	}
-
-	if (m->m_flags & M_EXT) {
-		printf("  m_ext{ ext_buf:%p ext_free:%p "
-		       "ext_size:%u }\n",
-			m->m_ext.ext_buf, m->m_ext.ext_free,
-			m->m_ext.ext_size);
-	}
-
-	return;
-}
-
-void
-kdebug_mbuf(m0)
-	struct mbuf *m0;
-{
-	struct mbuf *m = m0;
-	int i, j;
-
-	for (j = 0; m; m = m->m_next) {
-		kdebug_mbufhdr(m);
-		printf("  m_data:\n");
-		for (i = 0; i < m->m_len; i++) {
-			if (i && i % 32 == 0)
-				printf("\n");
-			if (i % 4 == 0)
-				printf(" ");
-			printf("%02x", mtod(m, u_char *)[i]);
-			j++;
-		}
-		printf("\n");
-	}
-
-	return;
-}
-#endif /* _KERNEL */
-
-void
-kdebug_sockaddr(addr)
-	struct sockaddr *addr;
-{
-	struct sockaddr_in *sin4;
-#ifdef INET6
-	struct sockaddr_in6 *sin6;
-#endif
-
-	/* sanity check */
-	if (addr == NULL)
-		panic("kdebug_sockaddr: NULL pointer was passed.");
-
-	/* NOTE: We deal with port number as host byte order. */
-	printf("sockaddr{ len=%u family=%u", addr->sa_len, addr->sa_family);
-
-	switch (addr->sa_family) {
-	case AF_INET:
-		sin4 = (struct sockaddr_in *)addr;
-		printf(" port=%u\n", ntohs(sin4->sin_port));
-		ipsec_hexdump((caddr_t)&sin4->sin_addr, sizeof(sin4->sin_addr));
-		break;
-#ifdef INET6
-	case AF_INET6:
-		sin6 = (struct sockaddr_in6 *)addr;
-		printf(" port=%u\n", ntohs(sin6->sin6_port));
-		printf("  flowinfo=0x%08x, scope_id=0x%08x\n",
-		    sin6->sin6_flowinfo, sin6->sin6_scope_id);
-		ipsec_hexdump((caddr_t)&sin6->sin6_addr,
-		    sizeof(sin6->sin6_addr));
-		break;
-#endif
-	}
-
-	printf("  }\n");
-
-	return;
-}
-
-void
-ipsec_bindump(buf, len)
-	caddr_t buf;
-	int len;
-{
-	int i;
-
-	for (i = 0; i < len; i++)
-		printf("%c", (unsigned char)buf[i]);
-
-	return;
-}
-
-
-void
-ipsec_hexdump(buf, len)
-	caddr_t buf;
-	int len;
-{
-	int i;
-
-	for (i = 0; i < len; i++) {
-		if (i != 0 && i % 32 == 0) printf("\n");
-		if (i % 4 == 0) printf(" ");
-		printf("%02x", (unsigned char)buf[i]);
-	}
-#if 0
-	if (i % 32 != 0) printf("\n");
-#endif
-
-	return;
-}
--- sys/netkey/key.h
+++ /dev/null
@@ -1,96 +0,0 @@
-/*	$FreeBSD: src/sys/netkey/key.h,v 1.12 2005/01/07 01:45:48 imp Exp $	*/
-/*	$KAME: key.h,v 1.32 2003/09/07 05:25:20 itojun Exp $	*/
-
-/*-
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _NETKEY_KEY_H_
-#define _NETKEY_KEY_H_
-
-#ifdef _KERNEL
-
-#include <sys/queue.h>
-
-extern struct key_cb key_cb;
-
-extern TAILQ_HEAD(_satailq, secasvar) satailq;
-extern TAILQ_HEAD(_sptailq, secpolicy) sptailq;
-
-struct secpolicy;
-struct secpolicyindex;
-struct ipsecrequest;
-struct secasvar;
-struct sockaddr;
-struct socket;
-struct sadb_msg;
-struct sadb_x_policy;
-union sockaddr_union;
-
-extern struct secpolicy *key_allocsp(u_int16_t, struct secpolicyindex *,
-	u_int);
-extern struct secpolicy *key_gettunnel(struct sockaddr *,
-	struct sockaddr *, struct sockaddr *, struct sockaddr *);
-extern int key_checkrequest
-	(struct ipsecrequest *isr, struct secasindex *);
-extern struct secasvar *key_allocsa(u_int, caddr_t, caddr_t, u_int, u_int32_t);
-extern void key_freesp(struct secpolicy *);
-extern void key_freesav(struct secasvar *);
-extern struct secpolicy *key_newsp(u_int32_t);
-extern struct secpolicy *key_msg2sp(struct sadb_x_policy *, size_t, int *);
-extern struct mbuf *key_sp2msg(struct secpolicy *);
-extern int key_cmpspidx_exactly
-	(struct secpolicyindex *, struct secpolicyindex *);
-extern int key_cmpspidx_withmask
-	(struct secpolicyindex *, struct secpolicyindex *);
-extern int key_spdacquire(struct secpolicy *);
-extern void key_timehandler(void *);
-extern void key_randomfill(void *, size_t);
-extern void key_freereg(struct socket *);
-extern int key_parse(struct mbuf *, struct socket *);
-extern void key_init(void);
-extern int key_checktunnelsanity(struct secasvar *, u_int, caddr_t, caddr_t);
-extern void key_sa_recordxfer(struct secasvar *, struct mbuf *);
-extern void key_sa_routechange(struct sockaddr *);
-extern void key_sa_stir_iv(struct secasvar *);
-
-/* to keep compatibility with FAST_IPSEC */
-#define	KEY_ALLOCSA(dst, proto, spi)	\
-	key_allocsa(((struct sockaddr *)(dst))->sa_family,\
-		    (caddr_t)&(((struct sockaddr_in *)(dst))->sin_addr),\
-		    (caddr_t)&(((struct sockaddr_in *)(dst))->sin_addr),\
-		    proto, spi)
-#define	KEY_FREESAV(psav)					\
-	key_freesav(*psav)
-
-#ifdef MALLOC_DECLARE
-MALLOC_DECLARE(M_SECA);
-#endif /* MALLOC_DECLARE */
-
-#endif /* defined(_KERNEL) */
-#endif /* _NETKEY_KEY_H_ */
--- sys/netkey/key_var.h
+++ /dev/null
@@ -1,58 +0,0 @@
-/*	$FreeBSD: src/sys/netkey/key_var.h,v 1.8 2005/01/07 01:45:48 imp Exp $	*/
-/*	$KAME: key_var.h,v 1.12 2001/11/06 03:48:29 itojun Exp $	*/
-
-/*-
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _NETKEY_KEY_VAR_H_
-#define _NETKEY_KEY_VAR_H_
-
-/* sysctl */
-#define KEYCTL_DEBUG_LEVEL		1
-#define KEYCTL_SPI_TRY			2
-#define KEYCTL_SPI_MIN_VALUE		3
-#define KEYCTL_SPI_MAX_VALUE		4
-#define KEYCTL_RANDOM_INT		5
-#define KEYCTL_LARVAL_LIFETIME		6
-#define KEYCTL_BLOCKACQ_COUNT		7
-#define KEYCTL_BLOCKACQ_LIFETIME	8
-#define KEYCTL_ESP_KEYMIN		9
-#define KEYCTL_ESP_AUTH			10
-#define KEYCTL_AH_KEYMIN		11
-#define KEYCTL_PREFERED_OLDSA		12
-#define KEYCTL_MAXID			13
-
-#ifdef _KERNEL
-#define _ARRAYLEN(p) (sizeof(p)/sizeof(p[0]))
-#define _KEYLEN(key) ((u_int)((key)->sadb_key_bits >> 3))
-#define _KEYBITS(key) ((u_int)((key)->sadb_key_bits))
-#define _KEYBUF(key) ((caddr_t)((caddr_t)(key) + sizeof(struct sadb_key)))
-#endif /*_KERNEL*/
-
-#endif /* _NETKEY_KEY_VAR_H_ */
--- sys/netkey/keysock.c
+++ /dev/null
@@ -1,506 +0,0 @@
-/*	$KAME: keysock.c,v 1.32 2003/08/22 05:45:08 itojun Exp $	*/
-
-/*-
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netkey/keysock.c,v 1.30.2.2 2006/01/27 21:50:11 bz Exp $");
-
-#include "opt_ipsec.h"
-
-/* This code has derived from sys/net/rtsock.c on FreeBSD 2.2.5 */
-
-#include <sys/types.h>
-#include <sys/param.h>
-#include <sys/domain.h>
-#include <sys/errno.h>
-#include <sys/kernel.h>
-#include <sys/lock.h>
-#include <sys/malloc.h>
-#include <sys/mbuf.h>
-#include <sys/mutex.h>
-#include <sys/protosw.h>
-#include <sys/signalvar.h>
-#include <sys/socket.h>
-#include <sys/socketvar.h>
-#include <sys/sysctl.h>
-#include <sys/systm.h>
-
-#include <net/raw_cb.h>
-#include <net/route.h>
-#include <netinet/in.h>
-
-#include <net/pfkeyv2.h>
-#include <netkey/keydb.h>
-#include <netkey/key.h>
-#include <netkey/keysock.h>
-#include <netkey/key_debug.h>
-
-#include <machine/stdarg.h>
-
-struct sockaddr key_dst = { 2, PF_KEY, };
-struct sockaddr key_src = { 2, PF_KEY, };
-
-static int key_sendup0(struct rawcb *, struct mbuf *, int);
-
-struct pfkeystat pfkeystat;
-
-/*
- * key_output()
- */
-int
-key_output(struct mbuf *m, struct socket *so)
-{
-	struct sadb_msg *msg;
-	int len, error = 0;
-	int s;
-
-	if (m == 0)
-		panic("key_output: NULL pointer was passed.");
-
-	pfkeystat.out_total++;
-	pfkeystat.out_bytes += m->m_pkthdr.len;
-
-	len = m->m_pkthdr.len;
-	if (len < sizeof(struct sadb_msg)) {
-		pfkeystat.out_tooshort++;
-		error = EINVAL;
-		goto end;
-	}
-
-	if (m->m_len < sizeof(struct sadb_msg)) {
-		if ((m = m_pullup(m, sizeof(struct sadb_msg))) == 0) {
-			pfkeystat.out_nomem++;
-			error = ENOBUFS;
-			goto end;
-		}
-	}
-
-	M_ASSERTPKTHDR(m);
-
-	KEYDEBUG(KEYDEBUG_KEY_DUMP, kdebug_mbuf(m));
-
-	msg = mtod(m, struct sadb_msg *);
-	pfkeystat.out_msgtype[msg->sadb_msg_type]++;
-	if (len != PFKEY_UNUNIT64(msg->sadb_msg_len)) {
-		pfkeystat.out_invlen++;
-		error = EINVAL;
-		goto end;
-	}
-
-	/*XXX giant lock*/
-	s = splnet();
-	error = key_parse(m, so);
-	m = NULL;
-	splx(s);
-end:
-	if (m)
-		m_freem(m);
-	return error;
-}
-
-/*
- * send message to the socket.
- */
-static int
-key_sendup0(rp, m, promisc)
-	struct rawcb *rp;
-	struct mbuf *m;
-	int promisc;
-{
-	int error;
-
-	if (promisc) {
-		struct sadb_msg *pmsg;
-
-		M_PREPEND(m, sizeof(struct sadb_msg), M_DONTWAIT);
-		if (m && m->m_len < sizeof(struct sadb_msg))
-			m = m_pullup(m, sizeof(struct sadb_msg));
-		if (!m) {
-			pfkeystat.in_nomem++;
-			return ENOBUFS;
-		}
-		m->m_pkthdr.len += sizeof(*pmsg);
-
-		pmsg = mtod(m, struct sadb_msg *);
-		bzero(pmsg, sizeof(*pmsg));
-		pmsg->sadb_msg_version = PF_KEY_V2;
-		pmsg->sadb_msg_type = SADB_X_PROMISC;
-		pmsg->sadb_msg_len = PFKEY_UNIT64(m->m_pkthdr.len);
-		/* pid and seq? */
-
-		pfkeystat.in_msgtype[pmsg->sadb_msg_type]++;
-	}
-
-	if (!sbappendaddr(&rp->rcb_socket->so_rcv, (struct sockaddr *)&key_src,
-	    m, NULL)) {
-		pfkeystat.in_nomem++;
-		m_freem(m);
-		error = ENOBUFS;
-	} else
-		error = 0;
-	sorwakeup(rp->rcb_socket);
-	return error;
-}
-
-/* so can be NULL if target != KEY_SENDUP_ONE */
-int
-key_sendup_mbuf(so, m, target)
-	struct socket *so;
-	struct mbuf *m;
-	int target;
-{
-	struct mbuf *n;
-	struct keycb *kp;
-	int sendup;
-	struct rawcb *rp;
-	int error = 0;
-
-	if (m == NULL)
-		panic("key_sendup_mbuf: NULL pointer was passed.");
-	if (so == NULL && target == KEY_SENDUP_ONE)
-		panic("key_sendup_mbuf: NULL pointer was passed.");
-
-	pfkeystat.in_total++;
-	pfkeystat.in_bytes += m->m_pkthdr.len;
-	if (m->m_len < sizeof(struct sadb_msg)) {
-		m = m_pullup(m, sizeof(struct sadb_msg));
-		if (m == NULL) {
-			pfkeystat.in_nomem++;
-			return ENOBUFS;
-		}
-	}
-	if (m->m_len >= sizeof(struct sadb_msg)) {
-		struct sadb_msg *msg;
-		msg = mtod(m, struct sadb_msg *);
-		pfkeystat.in_msgtype[msg->sadb_msg_type]++;
-	}
-
-	LIST_FOREACH(rp, &rawcb_list, list) {
-		if (rp->rcb_proto.sp_family != PF_KEY)
-			continue;
-		if (rp->rcb_proto.sp_protocol &&
-		    rp->rcb_proto.sp_protocol != PF_KEY_V2) {
-			continue;
-		}
-
-		kp = (struct keycb *)rp;
-
-		/*
-		 * If you are in promiscuous mode, and when you get broadcasted
-		 * reply, you'll get two PF_KEY messages.
-		 * (based on pf_key at inner.net message on 14 Oct 1998)
-		 */
-		if (((struct keycb *)rp)->kp_promisc) {
-			if ((n = m_copy(m, 0, (int)M_COPYALL)) != NULL) {
-				(void)key_sendup0(rp, n, 1);
-				n = NULL;
-			}
-		}
-
-		/* the exact target will be processed later */
-		if (so && sotorawcb(so) == rp)
-			continue;
-
-		sendup = 0;
-		switch (target) {
-		case KEY_SENDUP_ONE:
-			/* the statement has no effect */
-			if (so && sotorawcb(so) == rp)
-				sendup++;
-			break;
-		case KEY_SENDUP_ALL:
-			sendup++;
-			break;
-		case KEY_SENDUP_REGISTERED:
-			if (kp->kp_registered)
-				sendup++;
-			break;
-		}
-		pfkeystat.in_msgtarget[target]++;
-
-		if (!sendup)
-			continue;
-
-		if ((n = m_copy(m, 0, (int)M_COPYALL)) == NULL) {
-			m_freem(m);
-			pfkeystat.in_nomem++;
-			return ENOBUFS;
-		}
-
-		/*
-		 * ignore error even if queue is full.  PF_KEY does not
-		 * guarantee the delivery of the message.
-		 * this is important when target == KEY_SENDUP_ALL.
-		 */
-		key_sendup0(rp, n, 0);
-
-		n = NULL;
-	}
-
-	if (so) {
-		error = key_sendup0(sotorawcb(so), m, 0);
-		m = NULL;
-	} else {
-		error = 0;
-		m_freem(m);
-	}
-	return error;
-}
-
-/*
- * key_abort()
- * derived from net/rtsock.c:rts_abort()
- */
-static int
-key_abort(struct socket *so)
-{
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_abort(so);
-	splx(s);
-	return error;
-}
-
-/*
- * key_attach()
- * derived from net/rtsock.c:rts_attach()
- */
-static int
-key_attach(struct socket *so, int proto, struct thread *p)
-{
-	struct keycb *kp;
-	int s, error;
-
-	if (sotorawcb(so) != 0)
-		return EISCONN;	/* XXX panic? */
-	kp = (struct keycb *)malloc(sizeof *kp, M_PCB, M_WAITOK); /* XXX */
-	if (kp == 0)
-		return ENOBUFS;
-	bzero(kp, sizeof *kp);
-
-	/*
-	 * The splnet() is necessary to block protocols from sending
-	 * error notifications (like RTM_REDIRECT or RTM_LOSING) while
-	 * this PCB is extant but incompletely initialized.
-	 * Probably we should try to do more of this work beforehand and
-	 * eliminate the spl.
-	 */
-	s = splnet();
-	so->so_pcb = (caddr_t)kp;
-	error = raw_usrreqs.pru_attach(so, proto, p);
-	kp = (struct keycb *)sotorawcb(so);
-	if (error) {
-		free(kp, M_PCB);
-		so->so_pcb = (caddr_t) 0;
-		splx(s);
-		return error;
-	}
-
-	kp->kp_promisc = kp->kp_registered = 0;
-
-	if (kp->kp_raw.rcb_proto.sp_protocol == PF_KEY) /* XXX: AF_KEY */
-		key_cb.key_count++;
-	key_cb.any_count++;
-	kp->kp_raw.rcb_laddr = &key_src;
-	kp->kp_raw.rcb_faddr = &key_dst;
-	soisconnected(so);
-	so->so_options |= SO_USELOOPBACK;
-
-	splx(s);
-	return 0;
-}
-
-/*
- * key_bind()
- * derived from net/rtsock.c:rts_bind()
- */
-static int
-key_bind(struct socket *so, struct sockaddr *nam, struct thread *p)
-{
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_bind(so, nam, p); /* xxx just EINVAL */
-	splx(s);
-	return error;
-}
-
-/*
- * key_connect()
- * derived from net/rtsock.c:rts_connect()
- */
-static int
-key_connect(struct socket *so, struct sockaddr *nam, struct thread *p)
-{
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_connect(so, nam, p); /* XXX just EINVAL */
-	splx(s);
-	return error;
-}
-
-/*
- * key_detach()
- * derived from net/rtsock.c:rts_detach()
- */
-static int
-key_detach(struct socket *so)
-{
-	struct keycb *kp = (struct keycb *)sotorawcb(so);
-	int s, error;
-
-	s = splnet();
-	if (kp != 0) {
-		if (kp->kp_raw.rcb_proto.sp_protocol
-		    == PF_KEY) /* XXX: AF_KEY */
-			key_cb.key_count--;
-		key_cb.any_count--;
-
-		key_freereg(so);
-	}
-	error = raw_usrreqs.pru_detach(so);
-	splx(s);
-	return error;
-}
-
-/*
- * key_disconnect()
- * derived from net/rtsock.c:key_disconnect()
- */
-static int
-key_disconnect(struct socket *so)
-{
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_disconnect(so);
-	splx(s);
-	return error;
-}
-
-/*
- * key_peeraddr()
- * derived from net/rtsock.c:rts_peeraddr()
- */
-static int
-key_peeraddr(struct socket *so, struct sockaddr **nam)
-{
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_peeraddr(so, nam);
-	splx(s);
-	return error;
-}
-
-/*
- * key_send()
- * derived from net/rtsock.c:rts_send()
- */
-static int
-key_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *nam,
-	 struct mbuf *control, struct thread *p)
-{
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_send(so, flags, m, nam, control, p);
-	splx(s);
-	return error;
-}
-
-/*
- * key_shutdown()
- * derived from net/rtsock.c:rts_shutdown()
- */
-static int
-key_shutdown(struct socket *so)
-{
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_shutdown(so);
-	splx(s);
-	return error;
-}
-
-/*
- * key_sockaddr()
- * derived from net/rtsock.c:rts_sockaddr()
- */
-static int
-key_sockaddr(struct socket *so, struct sockaddr **nam)
-{
-	int s, error;
-	s = splnet();
-	error = raw_usrreqs.pru_sockaddr(so, nam);
-	splx(s);
-	return error;
-}
-
-struct pr_usrreqs key_usrreqs = {
-	.pru_abort =		key_abort,
-	.pru_attach =		key_attach,
-	.pru_bind =		key_bind,
-	.pru_connect =		key_connect,
-	.pru_detach =		key_detach,
-	.pru_disconnect =	key_disconnect,
-	.pru_peeraddr =		key_peeraddr,
-	.pru_send = 		key_send,
-	.pru_shutdown =		key_shutdown,
-	.pru_sockaddr =		key_sockaddr,
-};
-
-/* sysctl */
-SYSCTL_NODE(_net, PF_KEY, key, CTLFLAG_RW, 0, "Key Family");
-
-/*
- * Definitions of protocols supported in the KEY domain.
- */
-
-extern struct domain keydomain;
-
-struct protosw keysw[] = {
-{
-	.pr_type =		SOCK_RAW,
-	.pr_domain =		&keydomain,
-	.pr_protocol =		PF_KEY_V2,
-	.pr_flags =		PR_ATOMIC|PR_ADDR,
-	.pr_output =		key_output,
-	.pr_ctlinput =		raw_ctlinput,
-	.pr_init =		raw_init,
-	.pr_usrreqs =		&key_usrreqs
-}
-};
-
-struct domain keydomain = {
-	.dom_family =		PF_KEY,
-	.dom_name =		"key",
-	.dom_init =		key_init,
-	.dom_protosw =		keysw,
-	.dom_protoswNPROTOSW =	&keysw[sizeof(keysw)/sizeof(keysw[0])]
-};
-
-DOMAIN_SET(key);
--- sys/netkey/keysock.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*	$FreeBSD: src/sys/netkey/keysock.h,v 1.8.2.1 2006/01/27 21:50:11 bz Exp $	*/
-/*	$KAME: keysock.h,v 1.9 2002/03/21 14:00:14 itojun Exp $	*/
-
-/*-
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _NETKEY_KEYSOCK_H_
-#define _NETKEY_KEYSOCK_H_
-
-/* statistics for pfkey socket */
-struct pfkeystat {
-	/* userland -> kernel */
-	u_quad_t out_total;		/* # of total calls */
-	u_quad_t out_bytes;		/* total bytecount */
-	u_quad_t out_msgtype[256];	/* message type histogram */
-	u_quad_t out_invlen;		/* invalid length field */
-	u_quad_t out_invver;		/* invalid version field */
-	u_quad_t out_invmsgtype;	/* invalid message type field */
-	u_quad_t out_tooshort;		/* msg too short */
-	u_quad_t out_nomem;		/* memory allocation failure */
-	u_quad_t out_dupext;		/* duplicate extension */
-	u_quad_t out_invexttype;	/* invalid extension type */
-	u_quad_t out_invsatype;		/* invalid sa type */
-	u_quad_t out_invaddr;		/* invalid address extension */
-	/* kernel -> userland */
-	u_quad_t in_total;		/* # of total calls */
-	u_quad_t in_bytes;		/* total bytecount */
-	u_quad_t in_msgtype[256];	/* message type histogram */
-	u_quad_t in_msgtarget[3];	/* one/all/registered */
-	u_quad_t in_nomem;		/* memory allocation failure */
-	/* others */
-	u_quad_t sockerr;		/* # of socket related errors */
-};
-
-#define KEY_SENDUP_ONE		0
-#define KEY_SENDUP_ALL		1
-#define KEY_SENDUP_REGISTERED	2
-
-#ifdef _KERNEL
-struct keycb {
-	struct rawcb kp_raw;	/* rawcb */
-	int kp_promisc;		/* promiscuous mode */
-	int kp_registered;	/* registered socket */
-};
-
-extern struct pfkeystat pfkeystat;
-
-extern int key_output(struct mbuf *m, struct socket *so);
-extern int key_usrreq(struct socket *,
-	int, struct mbuf *, struct mbuf *, struct mbuf *);
-
-extern int key_sendup_mbuf(struct socket *, struct mbuf *, int);
-#endif /* _KERNEL */
-
-#endif /*_NETKEY_KEYSOCK_H_*/
--- sys/netkey/keydb.h
+++ /dev/null
@@ -1,184 +0,0 @@
-/*	$FreeBSD: src/sys/netkey/keydb.h,v 1.12 2005/01/07 01:45:48 imp Exp $	*/
-/*	$KAME: keydb.h,v 1.24 2003/09/07 15:12:10 itojun Exp $	*/
-
-/*-
- * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in the
- *    documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the project nor the names of its contributors
- *    may be used to endorse or promote products derived from this software
- *    without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#ifndef _NETKEY_KEYDB_H_
-#define _NETKEY_KEYDB_H_
-
-#ifdef _KERNEL
-
-#include <netkey/key_var.h>
-
-#ifndef _SOCKADDR_UNION_DEFINED
-#define	_SOCKADDR_UNION_DEFINED
-/*
- * The union of all possible address formats we handle.
- */
-union sockaddr_union {
-	struct sockaddr		sa;
-	struct sockaddr_in	sin;
-	struct sockaddr_in6	sin6;
-};
-#endif /* _SOCKADDR_UNION_DEFINED */
-
-/* Security Assocciation Index */
-/* NOTE: Ensure to be same address family */
-struct secasindex {
-	struct sockaddr_storage src;	/* srouce address for SA */
-	struct sockaddr_storage dst;	/* destination address for SA */
-	u_int16_t proto;		/* IPPROTO_ESP or IPPROTO_AH */
-	u_int8_t mode;			/* mode of protocol, see ipsec.h */
-	u_int32_t reqid;		/* reqid id who owned this SA */
-					/* see IPSEC_MANUAL_REQID_MAX. */
-};
-
-/* Security Association Data Base */
-struct secashead {
-	LIST_ENTRY(secashead) chain;
-
-	struct secasindex saidx;
-
-	struct sadb_ident *idents;	/* source identity */
-	struct sadb_ident *identd;	/* destination identity */
-					/* XXX I don't know how to use them. */
-
-	u_int8_t state;			/* MATURE or DEAD. */
-	LIST_HEAD(_satree, secasvar) savtree[SADB_SASTATE_MAX+1];
-					/* SA chain */
-					/* The first of this list is newer SA */
-
-	union {
-		struct route sau_route;
-		struct route_in6 sau_route6;
-	} sa_u;
-#define sa_route sa_u.sau_route
-};
-
-/* Security Association */
-struct secasvar {
-	TAILQ_ENTRY(secasvar) tailq;
-	LIST_ENTRY(secasvar) chain;
-	LIST_ENTRY(secasvar) spihash;
-
-	int refcnt;			/* reference count */
-	u_int8_t state;			/* Status of this Association */
-
-	u_int8_t alg_auth;		/* Authentication Algorithm Identifier*/
-	u_int8_t alg_enc;		/* Cipher Algorithm Identifier */
-	u_int32_t spi;			/* SPI Value, network byte order */
-	u_int32_t flags;		/* holder for SADB_KEY_FLAGS */
-
-	struct sadb_key *key_auth;	/* Key for Authentication */
-	struct sadb_key *key_enc;	/* Key for Encryption */
-	caddr_t iv;			/* Initilization Vector */
-	u_int ivlen;			/* length of IV */
-	void *sched;			/* intermediate encryption key */
-	size_t schedlen;
-
-	struct secreplay *replay;	/* replay prevention */
-	long created;			/* for lifetime */
-
-	struct sadb_lifetime *lft_c;	/* CURRENT lifetime, it's constant. */
-	struct sadb_lifetime *lft_h;	/* HARD lifetime */
-	struct sadb_lifetime *lft_s;	/* SOFT lifetime */
-
-	u_int64_t seq;			/* sequence number */
-	pid_t pid;			/* message's pid */
-
-	struct secashead *sah;		/* back pointer to the secashead */
-
-	u_int32_t id;			/* SA id */
-};
-
-/* replay prevention */
-struct secreplay {
-	u_int64_t count;
-	u_int wsize;		/* window size, i.g. 4 bytes */
-	u_int64_t seq;		/* used by sender */
-	u_int64_t lastseq;	/* used by receiver */
-	u_int8_t *bitmap;	/* used by receiver */
-	int overflow;		/* what round does the counter take. */
-};
-
-/* socket table due to send PF_KEY messages. */
-struct secreg {
-	LIST_ENTRY(secreg) chain;
-
-	struct socket *so;
-};
-
-#ifndef IPSEC_NONBLOCK_ACQUIRE
-/* acquiring list table. */
-struct secacq {
-	LIST_ENTRY(secacq) chain;
-
-	struct secasindex saidx;
-
-	u_int32_t seq;		/* sequence number */
-	long created;		/* for lifetime */
-	int count;		/* for lifetime */
-};
-#endif
-
-/* Sensitivity Level Specification */
-/* nothing */
-
-#define SADB_KILL_INTERVAL	600	/* six seconds */
-
-struct key_cb {
-	int key_count;
-	int any_count;
-};
-
-/* secpolicy */
-struct secpolicy;
-struct secpolicyindex;
-extern struct secpolicy *keydb_newsecpolicy(void);
-extern u_int32_t keydb_newspid(void);
-extern void keydb_delsecpolicy(struct secpolicy *);
-extern int keydb_setsecpolicyindex
-	(struct secpolicy *, struct secpolicyindex *);
-/* secashead */
-extern struct secashead *keydb_newsecashead(void);
-extern void keydb_delsecashead(struct secashead *);
-/* secasvar */
-extern struct secasvar *keydb_newsecasvar(void);
-extern void keydb_delsecasvar(struct secasvar *);
-/* secreplay */
-extern struct secreplay *keydb_newsecreplay(size_t);
-extern void keydb_delsecreplay(struct secreplay *);
-/* secreg */
-extern struct secreg *keydb_newsecreg(void);
-extern void keydb_delsecreg(struct secreg *);
-
-#endif /* _KERNEL */
-
-#endif /* _NETKEY_KEYDB_H_ */
Index: natm_pcb.c
===================================================================
RCS file: /home/cvs/src/sys/netnatm/natm_pcb.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netnatm/natm_pcb.c -L sys/netnatm/natm_pcb.c -u -r1.1.1.1 -r1.2
--- sys/netnatm/natm_pcb.c
+++ sys/netnatm/natm_pcb.c
@@ -1,6 +1,4 @@
-/*	$NetBSD: natm_pcb.c,v 1.4 1996/11/09 03:26:27 chuck Exp $	*/
 /*-
- *
  * Copyright (c) 1996 Charles D. Cranor and Washington University.
  * All rights reserved.
  *
@@ -29,6 +27,8 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $NetBSD: natm_pcb.c,v 1.4 1996/11/09 03:26:27 chuck Exp $
  */
 
 /*
@@ -36,12 +36,15 @@
  * from trying to use each other's VCs.
  */
 
+#include "opt_ddb.h"
+
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netnatm/natm_pcb.c,v 1.15.2.1 2005/08/15 09:51:15 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netnatm/natm_pcb.c,v 1.18 2007/01/08 22:30:39 rwatson Exp $");
 
 #include <sys/param.h>
-#include <sys/systm.h>
+#include <sys/kernel.h>
 #include <sys/malloc.h>
+#include <sys/systm.h>
 #include <sys/socket.h>
 #include <sys/socketvar.h>
 
@@ -51,6 +54,8 @@
 
 #include <netnatm/natm.h>
 
+#include <ddb/ddb.h>
+
 struct npcblist natm_pcbs;
 
 /*
@@ -63,12 +68,6 @@
 	struct natmpcb *npcb;
 
 	npcb = malloc(sizeof(*npcb), M_PCB, wait | M_ZERO);
-
-#ifdef DIAGNOSTIC
-	if (wait == M_WAITOK && npcb == NULL)
-		panic("npcb_alloc: malloc didn't wait");
-#endif
-
 	if (npcb != NULL)
 		npcb->npcb_flags = NPCB_FREE;
 	return (npcb);
@@ -150,20 +149,16 @@
 }
 
 #ifdef DDB
-
-int
-npcb_dump(void)
+DB_SHOW_COMMAND(natm, db_show_natm)
 {
 	struct natmpcb *cpcb;
 
-	printf("npcb dump:\n");
+	db_printf("npcb dump:\n");
 	LIST_FOREACH(cpcb, &natm_pcbs, pcblist) {
-		printf("if=%s, vci=%d, vpi=%d, IP=0x%x, sock=%p, flags=0x%x, "
-		    "inq=%d\n", cpcb->npcb_ifp->if_xname, cpcb->npcb_vci,
-		    cpcb->npcb_vpi, cpcb->ipaddr.s_addr, cpcb->npcb_socket, 
-		    cpcb->npcb_flags, cpcb->npcb_inq);
+		db_printf("if=%s, vci=%d, vpi=%d, IP=0x%x, sock=%p, "
+		    "flags=0x%x, inq=%d\n", cpcb->npcb_ifp->if_xname,
+		    cpcb->npcb_vci, cpcb->npcb_vpi, cpcb->ipaddr.s_addr,
+		    cpcb->npcb_socket, cpcb->npcb_flags, cpcb->npcb_inq);
 	}
-	printf("done\n");
-	return (0);
 }
 #endif
Index: natm_proto.c
===================================================================
RCS file: /home/cvs/src/sys/netnatm/natm_proto.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netnatm/natm_proto.c -L sys/netnatm/natm_proto.c -u -r1.1.1.1 -r1.2
--- sys/netnatm/natm_proto.c
+++ sys/netnatm/natm_proto.c
@@ -1,6 +1,4 @@
-/*	$NetBSD: natm_proto.c,v 1.3 1996/09/18 00:56:41 chuck Exp $	*/
 /*-
- *
  * Copyright (c) 1996 Charles D. Cranor and Washington University.
  * All rights reserved.
  *
@@ -29,6 +27,8 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $NetBSD: natm_proto.c,v 1.3 1996/09/18 00:56:41 chuck Exp $
  */
 
 /*
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netnatm/natm_proto.c,v 1.15.2.3 2005/11/16 10:31:23 ru Exp $");
+__FBSDID("$FreeBSD: src/sys/netnatm/natm_proto.c,v 1.20 2007/01/08 22:30:39 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -52,10 +52,10 @@
 
 #include <netnatm/natm.h>
 
-extern	struct domain natmdomain;
-
 static	void natm_init(void);
 
+static struct domain natmdomain;
+
 static struct protosw natmsw[] = {
 {
 	.pr_type =		SOCK_STREAM,
Index: natm.c
===================================================================
RCS file: /home/cvs/src/sys/netnatm/natm.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netnatm/natm.c -L sys/netnatm/natm.c -u -r1.1.1.1 -r1.2
--- sys/netnatm/natm.c
+++ sys/netnatm/natm.c
@@ -1,8 +1,29 @@
-/*	$NetBSD: natm.c,v 1.5 1996/11/09 03:26:26 chuck Exp $	*/
 /*-
+ * Copyright (c) 2005-2006 Robert N. M. Watson
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
  *
  * Copyright (c) 1996 Charles D. Cranor and Washington University.
- * Copyright (c) 2005 Robert N. M. Watson
  * All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
@@ -30,14 +51,16 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $NetBSD: natm.c,v 1.5 1996/11/09 03:26:26 chuck Exp $
  */
 
 /*
- * natm.c: native mode ATM access (both aal0 and aal5).
+ * natm.c: Native mode ATM access (both aal0 and aal5).
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/netnatm/natm.c,v 1.37.2.3 2005/08/25 05:01:23 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/netnatm/natm.c,v 1.49 2007/01/08 22:30:39 rwatson Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -62,333 +85,300 @@
 
 #include <netnatm/natm.h>
 
-static const u_long natm5_sendspace = 16*1024;
-static const u_long natm5_recvspace = 16*1024;
+static const u_long	natm5_sendspace = 16*1024;
+static const u_long	natm5_recvspace = 16*1024;
 
-static const u_long natm0_sendspace = 16*1024;
-static const u_long natm0_recvspace = 16*1024;
+static const u_long	natm0_sendspace = 16*1024;
+static const u_long	natm0_recvspace = 16*1024;
 
-struct mtx natm_mtx;
+/*
+ * netnatm global subsystem lock, protects all global data structures in
+ * netnatm.
+ */
+struct mtx	natm_mtx;
 
 /*
- * user requests
+ * User socket requests.
  */
-static int natm_usr_attach(struct socket *, int, d_thread_t *);
-static int natm_usr_detach(struct socket *);
-static int natm_usr_connect(struct socket *, struct sockaddr *, d_thread_t *);
-static int natm_usr_disconnect(struct socket *);
-static int natm_usr_shutdown(struct socket *);
-static int natm_usr_send(struct socket *, int, struct mbuf *,
-    struct sockaddr *, struct mbuf *, d_thread_t *);
-static int natm_usr_peeraddr(struct socket *, struct sockaddr **);
-static int natm_usr_control(struct socket *, u_long, caddr_t,
-    struct ifnet *, d_thread_t *);
-static int natm_usr_abort(struct socket *);
-static int natm_usr_bind(struct socket *, struct sockaddr *, d_thread_t *);
-static int natm_usr_sockaddr(struct socket *, struct sockaddr **);
+static int	natm_usr_attach(struct socket *, int, d_thread_t *);
+static void	natm_usr_detach(struct socket *);
+static int	natm_usr_connect(struct socket *, struct sockaddr *,
+		    d_thread_t *);
+static int	natm_usr_disconnect(struct socket *);
+static int	natm_usr_shutdown(struct socket *);
+static int	natm_usr_send(struct socket *, int, struct mbuf *,
+		    struct sockaddr *, struct mbuf *, d_thread_t *);
+static int	natm_usr_peeraddr(struct socket *, struct sockaddr **);
+static int	natm_usr_control(struct socket *, u_long, caddr_t,
+		    struct ifnet *, d_thread_t *);
+static void	natm_usr_abort(struct socket *);
+static int	natm_usr_bind(struct socket *, struct sockaddr *,
+		    d_thread_t *);
+static int	natm_usr_sockaddr(struct socket *, struct sockaddr **);
 
 static int
 natm_usr_attach(struct socket *so, int proto, d_thread_t *p)
 {
-    struct natmpcb *npcb;
-    int error = 0;
-
-    npcb = (struct natmpcb *)so->so_pcb;
+	struct natmpcb *npcb;
+	int error = 0;
 
-    KASSERT(npcb == NULL, ("natm_usr_attach: so_pcb != NULL"));
+	npcb = (struct natmpcb *)so->so_pcb;
+	KASSERT(npcb == NULL, ("natm_usr_attach: so_pcb != NULL"));
 
-    if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
-	if (proto == PROTO_NATMAAL5) 
-	    error = soreserve(so, natm5_sendspace, natm5_recvspace);
-	else
-	    error = soreserve(so, natm0_sendspace, natm0_recvspace);
-        if (error)
-          goto out;
-    }
-
-    so->so_pcb = (caddr_t) (npcb = npcb_alloc(M_WAITOK));
-    npcb->npcb_socket = so;
-out:
-    return (error);
+	if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
+		if (proto == PROTO_NATMAAL5) 
+			error = soreserve(so, natm5_sendspace,
+			    natm5_recvspace);
+		else
+			error = soreserve(so, natm0_sendspace,
+			    natm0_recvspace);
+		if (error)
+			return (error);
+	}
+	so->so_pcb = npcb = npcb_alloc(M_WAITOK);
+	npcb->npcb_socket = so;
+	return (error);
 }
 
-static int
+static void
 natm_usr_detach(struct socket *so)
 {
-    struct natmpcb *npcb;
-    int error = 0;
+	struct natmpcb *npcb;
+
+	npcb = (struct natmpcb *)so->so_pcb;
+	KASSERT(npcb != NULL, ("natm_usr_detach: npcb == NULL"));
 
-    NATM_LOCK();
-    npcb = (struct natmpcb *)so->so_pcb;
-    if (npcb == NULL) {
-	/* XXXRW: Does this case ever actually happen? */
-	error = EINVAL;
-	goto out;
-    }
-
-    /*
-     * we turn on 'drain' *before* we sofree.
-     */
-    npcb_free(npcb, NPCB_DESTROY);	/* drain */
-    ACCEPT_LOCK();
-    SOCK_LOCK(so);
-    so->so_pcb = NULL;
-    sotryfree(so);
- out:
-    NATM_UNLOCK();
-    return (error);
+	NATM_LOCK();
+	npcb_free(npcb, NPCB_DESTROY);	/* drain */
+	so->so_pcb = NULL;
+	NATM_UNLOCK();
 }
 
 static int
 natm_usr_connect(struct socket *so, struct sockaddr *nam, d_thread_t *p)
 {
-    struct natmpcb *npcb;
-    struct sockaddr_natm *snatm;
-    struct atmio_openvcc op;
-    struct ifnet *ifp;
-    int error = 0;
-    int proto = so->so_proto->pr_protocol;
-
-    NATM_LOCK();
-    npcb = (struct natmpcb *)so->so_pcb;
-    if (npcb == NULL) {
-	/* XXXRW: Does this case ever actually happen? */
-	error = EINVAL;
-	goto out;
-    }
-
-    /*
-     * validate nam and npcb
-     */
-    snatm = (struct sockaddr_natm *)nam;
-    if (snatm->snatm_len != sizeof(*snatm) ||
-	(npcb->npcb_flags & NPCB_FREE) == 0) {
-	error = EINVAL;
-	goto out;
-    }
-    if (snatm->snatm_family != AF_NATM) {
-	error = EAFNOSUPPORT;
-	goto out;
-    }
+	struct natmpcb *npcb;
+	struct sockaddr_natm *snatm;
+	struct atmio_openvcc op;
+	struct ifnet *ifp;
+	int error = 0;
+	int proto = so->so_proto->pr_protocol;
+
+	npcb = (struct natmpcb *)so->so_pcb;
+	KASSERT(npcb != NULL, ("natm_usr_connect: npcb == NULL"));
+
+	/*
+	 * Validate nam and npcb.
+	 */
+	NATM_LOCK();
+	snatm = (struct sockaddr_natm *)nam;
+	if (snatm->snatm_len != sizeof(*snatm) ||
+		(npcb->npcb_flags & NPCB_FREE) == 0) {
+		NATM_UNLOCK();
+		return (EINVAL);
+	}
+	if (snatm->snatm_family != AF_NATM) {
+		NATM_UNLOCK();
+		return (EAFNOSUPPORT);
+	}
 
-    snatm->snatm_if[IFNAMSIZ - 1] = '\0';	/* XXX ensure null termination
+	snatm->snatm_if[IFNAMSIZ - 1] = '\0';	/* XXX ensure null termination
 						   since ifunit() uses strcmp */
 
-    /*
-     * convert interface string to ifp, validate.
-     */
-    ifp = ifunit(snatm->snatm_if);
-    if (ifp == NULL || (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
-	error = ENXIO;
-	goto out;
-    }
-    if (ifp->if_output != atm_output) {
-	error = EAFNOSUPPORT;
-	goto out;
-    }
-
-    /*
-     * register us with the NATM PCB layer
-     */
-    if (npcb_add(npcb, ifp, snatm->snatm_vci, snatm->snatm_vpi) != npcb) {
-        error = EADDRINUSE;
-        goto out;
-    }
-    NATM_UNLOCK();
-
-    /*
-     * open the channel
-     */
-    bzero(&op, sizeof(op));
-    op.rxhand = npcb;
-    op.param.flags = ATMIO_FLAG_PVC;
-    op.param.vpi = npcb->npcb_vpi;
-    op.param.vci = npcb->npcb_vci;
-    op.param.rmtu = op.param.tmtu = ifp->if_mtu;
-    op.param.aal = (proto == PROTO_NATMAAL5) ? ATMIO_AAL_5 : ATMIO_AAL_0;
-    op.param.traffic = ATMIO_TRAFFIC_UBR;
-
-    IFF_LOCKGIANT(ifp);
-    if (ifp->if_ioctl == NULL || 
-	ifp->if_ioctl(ifp, SIOCATMOPENVCC, (caddr_t)&op) != 0) {
+	/*
+	 * Convert interface string to ifp, validate.
+	 */
+	ifp = ifunit(snatm->snatm_if);
+	if (ifp == NULL || (ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
+		NATM_UNLOCK();
+		return (ENXIO);
+	}
+	if (ifp->if_output != atm_output) {
+		NATM_UNLOCK();
+		return (EAFNOSUPPORT);
+	}
+
+	/*
+	 * Register us with the NATM PCB layer.
+	 */
+	if (npcb_add(npcb, ifp, snatm->snatm_vci, snatm->snatm_vpi) != npcb) {
+		NATM_UNLOCK();
+		return (EADDRINUSE);
+	}
+
+	/*
+	 * Open the channel.
+	 *
+	 * XXXRW: Eventually desirable to hold mutex over ioctl?
+	 */
+	bzero(&op, sizeof(op));
+	op.rxhand = npcb;
+	op.param.flags = ATMIO_FLAG_PVC;
+	op.param.vpi = npcb->npcb_vpi;
+	op.param.vci = npcb->npcb_vci;
+	op.param.rmtu = op.param.tmtu = ifp->if_mtu;
+	op.param.aal = (proto == PROTO_NATMAAL5) ? ATMIO_AAL_5 : ATMIO_AAL_0;
+	op.param.traffic = ATMIO_TRAFFIC_UBR;
+	NATM_UNLOCK();
+
+	IFF_LOCKGIANT(ifp);
+	if (ifp->if_ioctl == NULL || 
+	    ifp->if_ioctl(ifp, SIOCATMOPENVCC, (caddr_t)&op) != 0) {
+		IFF_UNLOCKGIANT(ifp);
+		return (EIO);
+	}
 	IFF_UNLOCKGIANT(ifp);
-	NATM_LOCK();
-	npcb_free(npcb, NPCB_REMOVE);
-        error = EIO;
-	goto out;
-    }
-    IFF_UNLOCKGIANT(ifp);
-
-    NATM_LOCK();
-    soisconnected(so);
-
- out:
-    NATM_UNLOCK();
-    return (error);
+	soisconnected(so);
+	return (error);
 }
 
 static int
 natm_usr_disconnect(struct socket *so)
 {
-    struct natmpcb *npcb;
-    struct atmio_closevcc cl;
-    struct ifnet *ifp;
-    int error = 0;
-
-    NATM_LOCK();
-    npcb = (struct natmpcb *)so->so_pcb;
-    if (npcb == NULL) {
-	/* XXXRW: Does this case ever actually happen? */
-	error = EINVAL;
-	goto out;
-    }
-
-    if ((npcb->npcb_flags & NPCB_CONNECTED) == 0) {
-        printf("natm: disconnected check\n");
-        error = EIO;
-	goto out;
-    }
-    ifp = npcb->npcb_ifp;
-
-    /*
-     * disable rx
-     */
-    cl.vpi = npcb->npcb_vpi;
-    cl.vci = npcb->npcb_vci;
-    NATM_UNLOCK();
-    if (ifp->if_ioctl != NULL) {
-	IFF_LOCKGIANT(ifp);
-	ifp->if_ioctl(ifp, SIOCATMCLOSEVCC, (caddr_t)&cl);
-	IFF_UNLOCKGIANT(ifp);
-    }
-    NATM_LOCK();
+	struct natmpcb *npcb;
+	struct atmio_closevcc cl;
+	struct ifnet *ifp;
+	int error = 0;
 
-    npcb_free(npcb, NPCB_REMOVE);
-    soisdisconnected(so);
+	npcb = (struct natmpcb *)so->so_pcb;
+	KASSERT(npcb != NULL, ("natm_usr_disconnect: npcb == NULL"));
+
+	NATM_LOCK();
+	if ((npcb->npcb_flags & NPCB_CONNECTED) == 0) {
+		NATM_UNLOCK();
+		printf("natm: disconnected check\n");
+		return (EIO);
+	}
+	ifp = npcb->npcb_ifp;
 
- out:
-    NATM_UNLOCK();
-    return (error);
+	/*
+	 * Disable rx.
+	 *
+	 * XXXRW: Eventually desirable to hold mutex over ioctl?
+	 */
+	cl.vpi = npcb->npcb_vpi;
+	cl.vci = npcb->npcb_vci;
+	NATM_UNLOCK();
+	if (ifp->if_ioctl != NULL) {
+		IFF_LOCKGIANT(ifp);
+		ifp->if_ioctl(ifp, SIOCATMCLOSEVCC, (caddr_t)&cl);
+		IFF_UNLOCKGIANT(ifp);
+	}
+	soisdisconnected(so);
+	return (error);
 }
 
 static int
 natm_usr_shutdown(struct socket *so)
 {
-    socantsendmore(so);
-    return (0);
+
+	socantsendmore(so);
+	return (0);
 }
 
 static int
 natm_usr_send(struct socket *so, int flags, struct mbuf *m, 
-    struct sockaddr *nam, struct mbuf *control, d_thread_t *p)
+	struct sockaddr *nam, struct mbuf *control, d_thread_t *p)
 {
-    struct natmpcb *npcb;
-    struct atm_pseudohdr *aph;
-    int error = 0;
-    int proto = so->so_proto->pr_protocol;
-
-    NATM_LOCK();
-    npcb = (struct natmpcb *)so->so_pcb;
-    if (npcb == NULL) {
-	/* XXXRW: Does this case ever actually happen? */
-	error = EINVAL;
-	goto out;
-    }
-
-    if (control && control->m_len) {
-	m_freem(control);
-	m_freem(m);
-	error = EINVAL;
-	goto out;
-    }
-
-    /*
-     * send the data.   we must put an atm_pseudohdr on first
-     */
-    M_PREPEND(m, sizeof(*aph), M_DONTWAIT);
-    if (m == NULL) {
-        error = ENOBUFS;
-	goto out;
-    }
-    aph = mtod(m, struct atm_pseudohdr *);
-    ATM_PH_VPI(aph) = npcb->npcb_vpi;
-    ATM_PH_SETVCI(aph, npcb->npcb_vci);
-    ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0;
-
-    error = atm_output(npcb->npcb_ifp, m, NULL, NULL);
-
- out:
-    NATM_UNLOCK();
-    return (error);
+	struct natmpcb *npcb;
+	struct atm_pseudohdr *aph;
+	int error = 0;
+	int proto = so->so_proto->pr_protocol;
+
+	npcb = (struct natmpcb *)so->so_pcb;
+	KASSERT(npcb != NULL, ("natm_usr_send: npcb == NULL"));
+
+	NATM_LOCK();
+	if (control && control->m_len) {
+		NATM_UNLOCK();
+		m_freem(control);
+		m_freem(m);
+		return (EINVAL);
+	}
+
+	/*
+	 * Send the data.  We must put an atm_pseudohdr on first.
+	 */
+	M_PREPEND(m, sizeof(*aph), M_DONTWAIT);
+	if (m == NULL) {
+		NATM_UNLOCK();
+		m_freem(control);
+		return (ENOBUFS);
+	}
+	aph = mtod(m, struct atm_pseudohdr *);
+	ATM_PH_VPI(aph) = npcb->npcb_vpi;
+	ATM_PH_SETVCI(aph, npcb->npcb_vci);
+	ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0;
+	error = atm_output(npcb->npcb_ifp, m, NULL, NULL);
+	NATM_UNLOCK();
+	return (error);
 }
 
 static int
 natm_usr_peeraddr(struct socket *so, struct sockaddr **nam)
 {
-    struct natmpcb *npcb;
-    struct sockaddr_natm *snatm, ssnatm;
+	struct natmpcb *npcb;
+	struct sockaddr_natm *snatm, ssnatm;
 
-    NATM_LOCK();
-    npcb = (struct natmpcb *)so->so_pcb;
-    if (npcb == NULL) {
-	/* XXXRW: Does this case ever actually happen? */
-    	NATM_UNLOCK();
-	return (EINVAL);
-    }
-
-    snatm = &ssnatm;
-    bzero(snatm, sizeof(*snatm));
-    snatm->snatm_len = sizeof(*snatm);
-    snatm->snatm_family = AF_NATM;
-    strlcpy(snatm->snatm_if, npcb->npcb_ifp->if_xname,
-        sizeof(snatm->snatm_if));
-    snatm->snatm_vci = npcb->npcb_vci;
-    snatm->snatm_vpi = npcb->npcb_vpi;
-    NATM_UNLOCK();
-    *nam = sodupsockaddr((struct sockaddr *)snatm, M_WAITOK);
-    return (0);
+	npcb = (struct natmpcb *)so->so_pcb;
+	KASSERT(npcb != NULL, ("natm_usr_peeraddr: npcb == NULL"));
+
+	NATM_LOCK();
+	snatm = &ssnatm;
+	bzero(snatm, sizeof(*snatm));
+	snatm->snatm_len = sizeof(*snatm);
+	snatm->snatm_family = AF_NATM;
+	strlcpy(snatm->snatm_if, npcb->npcb_ifp->if_xname,
+	    sizeof(snatm->snatm_if));
+	snatm->snatm_vci = npcb->npcb_vci;
+	snatm->snatm_vpi = npcb->npcb_vpi;
+	NATM_UNLOCK();
+	*nam = sodupsockaddr((struct sockaddr *)snatm, M_WAITOK);
+	return (0);
 }
 
 static int
 natm_usr_control(struct socket *so, u_long cmd, caddr_t arg,
-    struct ifnet *ifp, d_thread_t *p)
+	struct ifnet *ifp, d_thread_t *p)
 {
-    struct natmpcb *npcb;
-    int error;
-
-    /*
-     * XXXRW: Does this case ever actually happen?  And does it even matter
-     * given that npcb is unused?
-     */
-    npcb = (struct natmpcb *)so->so_pcb;
-    if (npcb == NULL)
-	return (EINVAL);
+	struct natmpcb *npcb;
+	int error;
 
-    if (ifp == NULL || ifp->if_ioctl == NULL)
-	return (EOPNOTSUPP);
+	npcb = (struct natmpcb *)so->so_pcb;
+	KASSERT(npcb != NULL, ("natm_usr_control: npcb == NULL"));
 
-    IFF_LOCKGIANT(ifp);
-    error = ((*ifp->if_ioctl)(ifp, cmd, arg));
-    IFF_UNLOCKGIANT(ifp);
-    return (error);
+	if (ifp == NULL || ifp->if_ioctl == NULL)
+		return (EOPNOTSUPP);
+	IFF_LOCKGIANT(ifp);
+	error = ((*ifp->if_ioctl)(ifp, cmd, arg));
+	IFF_UNLOCKGIANT(ifp);
+	return (error);
 }
 
-static int
+static void
 natm_usr_abort(struct socket *so)
 {
-    return (natm_usr_shutdown(so));
+
+}
+
+static void
+natm_usr_close(struct socket *so)
+{
+
 }
 
 static int
 natm_usr_bind(struct socket *so, struct sockaddr *nam, d_thread_t *p)
 {
-    return (EOPNOTSUPP);
+
+	return (EOPNOTSUPP);
 }
 
 static int
 natm_usr_sockaddr(struct socket *so, struct sockaddr **nam)
 {
-    return (EOPNOTSUPP);
+
+	return (EOPNOTSUPP);
 }
 
 /* xxx - should be const */
@@ -404,14 +394,15 @@
 	.pru_send =		natm_usr_send,
 	.pru_shutdown =		natm_usr_shutdown,
 	.pru_sockaddr =		natm_usr_sockaddr,
+	.pru_close =		natm_usr_close,
 };
 
 /*
  * natmintr: interrupt
  *
- * note: we expect a socket pointer in rcvif rather than an interface
- * pointer.    we can get the interface pointer from the so's PCB if
- * we really need it.
+ * Note: we expect a socket pointer in rcvif rather than an interface
+ * pointer.  We can get the interface pointer from the so's PCB if we really
+ * need it.
  */
 void
 natmintr(struct mbuf *m)
@@ -476,6 +467,7 @@
 int
 natm0_sysctl(SYSCTL_HANDLER_ARGS)
 {
+
 	/* All sysctl names at this level are terminal. */
 	return (ENOENT);
 }
@@ -487,6 +479,7 @@
 int
 natm5_sysctl(SYSCTL_HANDLER_ARGS)
 {
+
 	/* All sysctl names at this level are terminal. */
 	return (ENOENT);
 }
Index: natm.h
===================================================================
RCS file: /home/cvs/src/sys/netnatm/natm.h,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/netnatm/natm.h -L sys/netnatm/natm.h -u -r1.1.1.1 -r1.2
--- sys/netnatm/natm.h
+++ sys/netnatm/natm.h
@@ -1,8 +1,4 @@
-/*	$NetBSD: natm.h,v 1.1 1996/07/04 03:20:12 chuck Exp $	*/
-/* $FreeBSD: src/sys/netnatm/natm.h,v 1.10.2.2 2005/08/15 09:52:22 rwatson Exp $ */
-
 /*-
- *
  * Copyright (c) 1996 Charles D. Cranor and Washington University.
  * All rights reserved.
  *
@@ -31,6 +27,9 @@
  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * $NetBSD: natm.h,v 1.1 1996/07/04 03:20:12 chuck Exp $
+ * $FreeBSD: src/sys/netnatm/natm.h,v 1.14 2007/04/16 12:31:35 pjd Exp $
  */
 
 /*
@@ -75,7 +74,7 @@
 #define	NPCB_FREE	0x01		/* free (not on any list) */
 #define	NPCB_CONNECTED	0x02		/* connected */
 #define	NPCB_IP		0x04		/* used by IP */
-#define	NPCB_DRAIN	0x08		/* destory as soon as inq == 0 */
+#define	NPCB_DRAIN	0x08		/* destroy as soon as inq == 0 */
 
 /* flag arg to npcb_free */
 #define	NPCB_REMOVE	0		/* remove from global list */
Index: md5.h
===================================================================
RCS file: /home/cvs/src/sys/sys/md5.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -L sys/sys/md5.h -L sys/sys/md5.h -u -r1.3 -r1.4
--- sys/sys/md5.h
+++ sys/sys/md5.h
@@ -1,4 +1,5 @@
 /* MD5.H - header file for MD5C.C
+ * $MidnightBSD$
  * $FreeBSD: src/sys/sys/md5.h,v 1.20 2006/03/15 19:47:12 andre Exp $
  */
 


More information about the Midnightbsd-cvs mailing list