[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, ¬runc);
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, ®tree[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(®tree[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, ®tree[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(®tree[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