add /kern/ipsecsa and /kern/ipsecsp, which can be inspected by setkey(8).

it allows easier access to ipsecsa/sp.  it works around problem where
setkey -D does not work with large number of ipsec SAs due to socket buffer
size.
This commit is contained in:
itojun 2003-09-08 06:51:53 +00:00
parent 140fe23a05
commit 8ca90bd4e4
9 changed files with 1191 additions and 324 deletions

View File

@ -1,4 +1,4 @@
.\" $NetBSD: mount_kernfs.8,v 1.13 2003/08/07 10:04:28 agc Exp $
.\" $NetBSD: mount_kernfs.8,v 1.14 2003/09/08 06:52:00 itojun Exp $
.\"
.\" Copyright (c) 1992, 1993, 1994
.\" The Regents of the University of California. All rights reserved.
@ -33,7 +33,7 @@
.\"
.\" @(#)mount_kernfs.8 8.2 (Berkeley) 3/27/94
.\"
.Dd March 27, 1994
.Dd September 8, 2003
.Dt MOUNT_KERNFS 8
.Os
.Sh NAME
@ -83,6 +83,20 @@ The hostname can be changed by writing to this file.
A trailing newline will be stripped from the hostname being written.
.It Pa hz
the frequency of the system clock (decimal ASCII).
.It Pa ipsecsa
the directory contains IPsec security associations (SA) in
.Dv PF_KEY
format.
Filenames are SPI in decimal number.
The content of files can be inspected by using
.Xr setkey 8 .
.It Pa ipsecsp
the directory contains IPsec security policies in
.Dv PF_KEY
format.
Filenames are security policy ID in decimal number.
The content of files can be inspected by using
.Xr setkey 8 .
.It Pa loadavg
the 1, 5 and 15 minute load average in kernel fixed-point format.
The final integer is the fix-point scaling factor.
@ -124,9 +138,11 @@ can be generated by running:
.Sh SEE ALSO
.Xr mount 2 ,
.Xr unmount 2 ,
.Xr ipsec 4 ,
.Xr fstab 5 ,
.Xr dmesg 8 ,
.Xr mount 8 ,
.Xr setkey 8 ,
.Xr syslogd 8
.Sh HISTORY
The
@ -135,3 +151,6 @@ utility first appeared in
.Bx 4.4 .
.Sh BUGS
This filesystem may not be NFS-exported.
.Pp
.Xr lkm 4
version does not support IPsec-related files/directories.

View File

@ -1,4 +1,4 @@
# $NetBSD: Makefile,v 1.10 2001/12/12 12:06:48 lukem Exp $
# $NetBSD: Makefile,v 1.11 2003/09/08 06:51:59 itojun Exp $
.include "../Makefile.inc"
@ -7,6 +7,6 @@
KMOD= kernfs
SRCS= lkminit_vfs.c
SRCS+= kernfs_vfsops.c kernfs_vnops.c
SRCS+= kernfs_vfsops.c kernfs_vnops.c kernfs_subr.c
.include <bsd.kmod.mk>

View File

@ -1,6 +1,7 @@
# $NetBSD: files.kernfs,v 1.1 2002/04/16 23:14:07 thorpej Exp $
# $NetBSD: files.kernfs,v 1.2 2003/09/08 06:51:53 itojun Exp $
deffs fs_kernfs.h KERNFS # XXX
file miscfs/kernfs/kernfs_subr.c kernfs
file miscfs/kernfs/kernfs_vfsops.c kernfs
file miscfs/kernfs/kernfs_vnops.c kernfs

View File

@ -1,4 +1,4 @@
/* $NetBSD: kernfs.h,v 1.17 2003/08/07 16:32:37 agc Exp $ */
/* $NetBSD: kernfs.h,v 1.18 2003/09/08 06:51:53 itojun Exp $ */
/*
* Copyright (c) 1992, 1993
@ -37,36 +37,87 @@
#define _PATH_KERNFS "/kern" /* Default mountpoint */
#ifdef _KERNEL
struct kernfs_mount {
struct vnode *kf_root; /* Root node */
};
#include <sys/queue.h>
/*
* The different types of node in a kernfs filesystem
*/
typedef enum {
Pkern, /* the filesystem itself (.) */
Proot, /* the filesystem root (..) */
Pnull, /* none aplicable */
Ptime, /* boottime */
Pint, /* integer */
Pstring, /* string */
Phostname, /* hostname */
Pavenrun, /* loadavg */
Pdevice, /* device file (rootdev/rrootdev) */
Pmsgbuf, /* msgbuf */
Pipsecsadir, /* ipsec security association (top dir) */
Pipsecspdir, /* ipsec security policy (top dir) */
Pipsecsa, /* ipsec security association entry */
Pipsecsp, /* ipsec security policy entry */
} kfstype;
/*
* control data for the kern file system.
*/
struct kern_target {
u_char kt_type;
u_char kt_namlen;
const char *kt_name;
void *kt_data;
#define KTT_NULL 1
#define KTT_TIME 5
#define KTT_INT 17
#define KTT_STRING 31
#define KTT_HOSTNAME 47
#define KTT_AVENRUN 53
#define KTT_DEVICE 71
#define KTT_MSGBUF 89
u_char kt_tag;
u_char kt_vtype;
mode_t kt_mode;
u_char kt_type;
u_char kt_namlen;
const char *kt_name;
void *kt_data;
kfstype kt_tag;
u_char kt_vtype;
mode_t kt_mode;
};
struct kernfs_node {
const struct kern_target *kf_kt;
LIST_ENTRY(kernfs_node) kfs_hash; /* hash chain */
TAILQ_ENTRY(kernfs_node) kfs_list; /* flat list */
struct vnode *kfs_vnode; /* vnode associated with this pfsnode */
kfstype kfs_type; /* type of procfs node */
mode_t kfs_mode; /* mode bits for stat() */
long kfs_fileno; /* unique file id */
u_int32_t kfs_value; /* SA id or SP id (Pint) */
const struct kern_target *kfs_kt;
void *kfs_v; /* pointer to secasvar/secpolicy/mbuf */
long kfs_cookie; /* fileno cookie */
};
#define VFSTOKERNFS(mp) ((struct kernfs_mount *)((mp)->mnt_data))
#define VTOKERN(vp) ((struct kernfs_node *)(vp)->v_data)
struct kernfs_mount {
TAILQ_HEAD(, kernfs_node) nodelist;
long fileno_cookie;
};
#define UIO_MX 32
#define KERNFS_FILENO(kt, typ, cookie) \
((kt) ? 2 + ((kt) - &kern_targets[0]) \
: (((cookie) << 6) | ((typ) + nkern_targets)))
#define VFSTOKERNFS(mp) ((struct kernfs_mount *)((mp)->mnt_data))
#define VTOKERN(vp) ((struct kernfs_node *)(vp)->v_data)
#define KERNFSTOV(kfs) ((kfs)->kfs_vnode)
extern const struct kern_target kern_targets[];
extern int nkern_targets;
extern int (**kernfs_vnodeop_p) __P((void *));
extern struct vfsops kernfs_vfsops;
extern dev_t rrootdev;
struct secasvar;
struct secpolicy;
int kernfs_root __P((struct mount *, struct vnode **));
void kernfs_hashinit __P((void));
void kernfs_hashreinit __P((void));
void kernfs_hashdone __P((void));
int kernfs_freevp __P((struct vnode *));
int kernfs_allocvp __P((struct mount *, struct vnode **, kfstype,
const struct kern_target *, u_int32_t));
void kernfs_revoke_sa __P((struct secasvar *));
void kernfs_revoke_sp __P((struct secpolicy *));
#endif /* _KERNEL */

View File

@ -0,0 +1,438 @@
/* $NetBSD: kernfs_subr.c,v 1.1 2003/09/08 06:51:53 itojun Exp $ */
/*
* Copyright (c) 1993
* The Regents of the University of California. All rights reserved.
*
* This code is derived from software contributed to Berkeley by
* Jan-Simon Pendry.
*
* 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 University 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 REGENTS 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 REGENTS 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.
*
* @(#)kernfs_subr.c 8.6 (Berkeley) 5/14/95
*/
/*
* Copyright (c) 1994 Christopher G. Demetriou. All rights reserved.
* Copyright (c) 1993 Jan-Simon Pendry
*
* This code is derived from software contributed to Berkeley by
* Jan-Simon Pendry.
*
* 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. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University 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 REGENTS 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 REGENTS 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.
*
* @(#)kernfs_subr.c 8.6 (Berkeley) 5/14/95
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kernfs_subr.c,v 1.1 2003/09/08 06:51:53 itojun Exp $");
#ifdef _KERNEL_OPT
#include "opt_ipsec.h"
#endif
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/time.h>
#include <sys/kernel.h>
#include <sys/proc.h>
#include <sys/vnode.h>
#include <sys/malloc.h>
#include <sys/stat.h>
#include <sys/file.h>
#include <sys/filedesc.h>
#include <sys/mount.h>
#include <miscfs/kernfs/kernfs.h>
#ifdef IPSEC
#include <sys/mbuf.h>
#include <net/route.h>
#include <netinet/in.h>
#include <netinet6/ipsec.h>
#include <netkey/keydb.h>
#include <netkey/key.h>
#endif
void kernfs_hashins __P((struct kernfs_node *));
void kernfs_hashrem __P((struct kernfs_node *));
struct vnode *kernfs_hashget __P((kfstype, struct mount *, u_int32_t));
static LIST_HEAD(kfs_hashhead, kernfs_node) *kfs_hashtbl;
static u_long kfs_ihash; /* size of hash table - 1 */
#define KFSVALUEHASH(v) ((v) & kfs_ihash)
static struct lock kfs_hashlock;
static struct simplelock kfs_hash_slock;
#define ISSET(t, f) ((t) & (f))
/*
* allocate a kfsnode/vnode pair. the vnode is
* referenced, and locked.
*
* the kfs_type, kfs_value and mount point uniquely
* identify a kfsnode. the mount point is needed
* because someone might mount this filesystem
* twice.
*
* all kfsnodes are maintained on a singly-linked
* list. new nodes are only allocated when they cannot
* be found on this list. entries on the list are
* removed when the vfs reclaim entry is called.
*
* a single lock is kept for the entire list. this is
* needed because the getnewvnode() function can block
* waiting for a vnode to become free, in which case there
* may be more than one process trying to get the same
* vnode. this lock is only taken if we are going to
* call getnewvnode, since the kernel itself is single-threaded.
*
* if an entry is found on the list, then call vget() to
* take a reference. this is done because there may be
* zero references to it and so it needs to removed from
* the vnode free list.
*/
int
kernfs_allocvp(mp, vpp, kfs_type, kt, value)
struct mount *mp;
struct vnode **vpp;
kfstype kfs_type;
const struct kern_target *kt;
u_int32_t value;
{
struct kernfs_node *kfs = NULL, *kfsp;
struct vnode *vp = NULL;
int error;
long *cookie;
do {
if ((*vpp = kernfs_hashget(kfs_type, mp, value)) != NULL)
return (0);
} while (lockmgr(&kfs_hashlock, LK_EXCLUSIVE|LK_SLEEPFAIL, 0));
if (kfs_type == Pdevice) {
/* /kern/rootdev = look for device and obey */
/* /kern/rrootdev = look for device and obey */
dev_t *dp;
struct vnode *fvp;
#ifdef DIAGNOSTIC
if (!kt)
panic("kernfs: kt == NULL for Pdevice");
#endif
dp = kt->kt_data;
loop:
if (*dp == NODEV || !vfinddev(*dp, kt->kt_vtype, &fvp)) {
lockmgr(&kfs_hashlock, LK_RELEASE, NULL);
return (ENOENT);
}
vp = fvp;
if (vget(fvp, LK_EXCLUSIVE))
goto loop;
*vpp = vp;
lockmgr(&kfs_hashlock, LK_RELEASE, NULL);
return (0);
}
if ((error = getnewvnode(VT_KERNFS, mp, kernfs_vnodeop_p, &vp)) != 0) {
*vpp = NULL;
lockmgr(&kfs_hashlock, LK_RELEASE, NULL);
return (error);
}
MALLOC(kfs, void *, sizeof(struct kernfs_node), M_TEMP, M_WAITOK);
memset(kfs, 0, sizeof(*kfs));
vp->v_data = kfs;
cookie = &(VFSTOKERNFS(mp)->fileno_cookie);
again:
TAILQ_FOREACH(kfsp, &VFSTOKERNFS(mp)->nodelist, kfs_list) {
if (kfsp->kfs_cookie == *cookie) {
(*cookie) ++;
goto again;
}
if (TAILQ_NEXT(kfsp, kfs_list)) {
if (kfsp->kfs_cookie < *cookie &&
*cookie < TAILQ_NEXT(kfsp, kfs_list)->kfs_cookie)
break;
if (kfsp->kfs_cookie + 1 <
TAILQ_NEXT(kfsp, kfs_list)->kfs_cookie) {
*cookie = kfsp->kfs_cookie + 1;
break;
}
}
}
kfs->kfs_cookie = *cookie;
if (kfsp)
TAILQ_INSERT_AFTER(&VFSTOKERNFS(mp)->nodelist, kfsp, kfs,
kfs_list);
else
TAILQ_INSERT_TAIL(&VFSTOKERNFS(mp)->nodelist, kfs, kfs_list);
kfs->kfs_type = kfs_type;
kfs->kfs_vnode = vp;
kfs->kfs_fileno = KERNFS_FILENO(kt, kfs_type, kfs->kfs_cookie);
kfs->kfs_value = value;
kfs->kfs_kt = kt;
switch (kfs_type) {
case Pkern: /* /kern = dr-xr-xr-x */
kfs->kfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
vp->v_type = VDIR;
vp->v_flag = VROOT;
break;
case Pnull: /* /kern/?? = -r--r--r-- */
case Ptime: /* /kern/time = -r--r--r-- */
case Pint: /* /kern/?? = -r--r--r-- */
case Pstring: /* /kern/?? = -r--r--r-- */
case Pavenrun: /* /kern/loadavg = -r--r--r-- */
case Pmsgbuf: /* /kern/msgbuf = -r--r--r-- */
kfs->kfs_mode = S_IRUSR|S_IRGRP|S_IROTH;
vp->v_type = VREG;
break;
case Pipsecsadir: /* /kern/ipsecsa = dr-x------ */
case Pipsecspdir: /* /kern/ipsecsp = dr-x------ */
kfs->kfs_mode = S_IRUSR|S_IXUSR;
vp->v_type = VDIR;
break;
case Pipsecsa: /* /kern/ipsecsa/N = -r-------- */
case Pipsecsp: /* /kern/ipsecsp/N = -r-------- */
kfs->kfs_mode = S_IRUSR;
vp->v_type = VREG;
break;
case Phostname: /* /kern/hostname = -rw------- */
kfs->kfs_mode = S_IRUSR|S_IWUSR;
vp->v_type = VREG;
break;
default:
panic("kernfs_allocvp");
}
kernfs_hashins(kfs);
uvm_vnp_setsize(vp, 0);
lockmgr(&kfs_hashlock, LK_RELEASE, NULL);
*vpp = vp;
return (0);
}
int
kernfs_freevp(vp)
struct vnode *vp;
{
struct kernfs_node *kfs = VTOKERN(vp);
kernfs_hashrem(kfs);
TAILQ_REMOVE(&VFSTOKERNFS(vp->v_mount)->nodelist, kfs, kfs_list);
FREE(vp->v_data, M_TEMP);
vp->v_data = 0;
return (0);
}
/*
* Initialize kfsnode hash table.
*/
void
kernfs_hashinit()
{
lockinit(&kfs_hashlock, PINOD, "kfs_hashlock", 0, 0);
kfs_hashtbl = hashinit(desiredvnodes / 4, HASH_LIST, M_UFSMNT,
M_WAITOK, &kfs_ihash);
simple_lock_init(&kfs_hash_slock);
}
void
kernfs_hashreinit()
{
struct kernfs_node *pp;
struct kfs_hashhead *oldhash, *hash;
u_long i, oldmask, mask, val;
hash = hashinit(desiredvnodes / 4, HASH_LIST, M_UFSMNT, M_WAITOK,
&mask);
simple_lock(&kfs_hash_slock);
oldhash = kfs_hashtbl;
oldmask = kfs_ihash;
kfs_hashtbl = hash;
kfs_ihash = mask;
for (i = 0; i <= oldmask; i++) {
while ((pp = LIST_FIRST(&oldhash[i])) != NULL) {
LIST_REMOVE(pp, kfs_hash);
val = KFSVALUEHASH(pp->kfs_value);
LIST_INSERT_HEAD(&hash[val], pp, kfs_hash);
}
}
simple_unlock(&kfs_hash_slock);
hashdone(oldhash, M_UFSMNT);
}
/*
* Free kfsnode hash table.
*/
void
kernfs_hashdone()
{
hashdone(kfs_hashtbl, M_UFSMNT);
}
struct vnode *
kernfs_hashget(type, mp, value)
kfstype type;
struct mount *mp;
u_int32_t value;
{
struct kfs_hashhead *ppp;
struct kernfs_node *pp;
struct vnode *vp;
loop:
simple_lock(&kfs_hash_slock);
ppp = &kfs_hashtbl[KFSVALUEHASH(value)];
LIST_FOREACH(pp, ppp, kfs_hash) {
vp = KERNFSTOV(pp);
if (pp->kfs_type == type && vp->v_mount == mp &&
pp->kfs_value == value) {
simple_lock(&vp->v_interlock);
simple_unlock(&kfs_hash_slock);
if (vget(vp, LK_EXCLUSIVE | LK_INTERLOCK))
goto loop;
return (vp);
}
}
simple_unlock(&kfs_hash_slock);
return (NULL);
}
/*
* Insert the kfsnode into the hash table and lock it.
*/
void
kernfs_hashins(pp)
struct kernfs_node *pp;
{
struct kfs_hashhead *ppp;
/* lock the kfsnode, then put it on the appropriate hash list */
lockmgr(&pp->kfs_vnode->v_lock, LK_EXCLUSIVE, (struct simplelock *)0);
simple_lock(&kfs_hash_slock);
ppp = &kfs_hashtbl[KFSVALUEHASH(pp->kfs_value)];
LIST_INSERT_HEAD(ppp, pp, kfs_hash);
simple_unlock(&kfs_hash_slock);
}
/*
* Remove the kfsnode from the hash table.
*/
void
kernfs_hashrem(pp)
struct kernfs_node *pp;
{
simple_lock(&kfs_hash_slock);
LIST_REMOVE(pp, kfs_hash);
simple_unlock(&kfs_hash_slock);
}
#ifdef IPSEC
void
kernfs_revoke_sa(sav)
struct secasvar *sav;
{
struct kernfs_node *kfs, *pnext;
struct vnode *vp;
struct kfs_hashhead *ppp;
struct mbuf *m;
ppp = &kfs_hashtbl[KFSVALUEHASH(ntohl(sav->spi))];
for (kfs = LIST_FIRST(ppp); kfs; kfs = pnext) {
vp = KERNFSTOV(kfs);
pnext = LIST_NEXT(kfs, kfs_hash);
if (vp->v_usecount > 0 && kfs->kfs_type == Pipsecsa &&
kfs->kfs_value == ntohl(sav->spi)) {
m = key_setdumpsa_spi(sav->spi);
if (!m)
VOP_REVOKE(vp, REVOKEALL);
else
m_freem(m);
break;
}
}
}
void
kernfs_revoke_sp(sp)
struct secpolicy *sp;
{
struct kernfs_node *kfs, *pnext;
struct vnode *vp;
struct kfs_hashhead *ppp;
ppp = &kfs_hashtbl[KFSVALUEHASH(sp->id)];
for (kfs = LIST_FIRST(ppp); kfs; kfs = pnext) {
vp = KERNFSTOV(kfs);
pnext = LIST_NEXT(kfs, kfs_hash);
if (vp->v_usecount > 0 && kfs->kfs_type == Pipsecsa &&
kfs->kfs_value == sp->id)
VOP_REVOKE(vp, REVOKEALL);
}
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: kernfs_vfsops.c,v 1.53 2003/08/07 16:32:37 agc Exp $ */
/* $NetBSD: kernfs_vfsops.c,v 1.54 2003/09/08 06:51:54 itojun Exp $ */
/*
* Copyright (c) 1992, 1993, 1995
@ -39,9 +39,9 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: kernfs_vfsops.c,v 1.53 2003/08/07 16:32:37 agc Exp $");
__KERNEL_RCSID(0, "$NetBSD: kernfs_vfsops.c,v 1.54 2003/09/08 06:51:54 itojun Exp $");
#if defined(_KERNEL_OPT)
#ifdef _KERNEL_OPT
#include "opt_compat_netbsd.h"
#endif
@ -53,6 +53,7 @@ __KERNEL_RCSID(0, "$NetBSD: kernfs_vfsops.c,v 1.53 2003/08/07 16:32:37 agc Exp $
#include <sys/mount.h>
#include <sys/namei.h>
#include <sys/malloc.h>
#include <sys/syslog.h>
#include <miscfs/specfs/specdev.h>
#include <miscfs/kernfs/kernfs.h>
@ -62,13 +63,13 @@ MALLOC_DEFINE(M_KERNFSMNT, "kernfs mount", "kernfs mount structures");
dev_t rrootdev = NODEV;
void kernfs_init __P((void));
void kernfs_reinit __P((void));
void kernfs_done __P((void));
void kernfs_get_rrootdev __P((void));
int kernfs_mount __P((struct mount *, const char *, void *,
struct nameidata *, struct proc *));
int kernfs_start __P((struct mount *, int, struct proc *));
int kernfs_unmount __P((struct mount *, int, struct proc *));
int kernfs_root __P((struct mount *, struct vnode **));
int kernfs_statfs __P((struct mount *, struct statfs *, struct proc *));
int kernfs_quotactl __P((struct mount *, int, uid_t, caddr_t,
struct proc *));
@ -87,6 +88,13 @@ kernfs_init()
#ifdef _LKM
malloc_type_attach(M_KERNFSMNT);
#endif
kernfs_hashinit();
}
void
kernfs_reinit()
{
kernfs_hashreinit();
}
void
@ -95,6 +103,7 @@ kernfs_done()
#ifdef _LKM
malloc_type_detach(M_KERNFSMNT);
#endif
kernfs_hashdone();
}
void
@ -111,13 +120,8 @@ kernfs_get_rrootdev()
if (rootdev == NODEV)
return;
rrootdev = devsw_blk2chr(rootdev);
if (rrootdev != NODEV) {
#ifdef KERNFS_DIAGNOSTIC
printf("kernfs_mount: rootdev = %u.%u; rrootdev = %u.%u\n",
major(rootdev), minor(rootdev), major(rrootdev), minor(rrootdev));
#endif
if (rrootdev != NODEV)
return;
}
rrootdev = NODEV;
printf("kernfs_get_rrootdev: no raw root device\n");
}
@ -135,11 +139,11 @@ kernfs_mount(mp, path, data, ndp, p)
{
int error = 0;
struct kernfs_mount *fmp;
struct vnode *rvp;
#ifdef KERNFS_DIAGNOSTIC
printf("kernfs_mount(mp = %p)\n", mp);
#endif
if (UIO_MX & (UIO_MX - 1)) {
log(LOG_ERR, "kernfs: invalid directory entry size");
return (EINVAL);
}
if (mp->mnt_flag & MNT_GETARGS)
return 0;
@ -149,27 +153,17 @@ kernfs_mount(mp, path, data, ndp, p)
if (mp->mnt_flag & MNT_UPDATE)
return (EOPNOTSUPP);
error = getnewvnode(VT_KERNFS, mp, kernfs_vnodeop_p, &rvp);
if (error)
return (error);
MALLOC(fmp, struct kernfs_mount *, sizeof(struct kernfs_mount),
M_KERNFSMNT, M_WAITOK);
rvp->v_type = VDIR;
rvp->v_flag |= VROOT;
#ifdef KERNFS_DIAGNOSTIC
printf("kernfs_mount: root vp = %p\n", rvp);
#endif
fmp->kf_root = rvp;
mp->mnt_flag |= MNT_LOCAL;
memset(fmp, 0, sizeof(*fmp));
TAILQ_INIT(&fmp->nodelist);
mp->mnt_data = fmp;
mp->mnt_flag |= MNT_LOCAL;
vfs_getnewfsid(mp);
error = set_statfs_info(path, UIO_USERSPACE, "kernfs", UIO_SYSSPACE,
mp, p);
#ifdef KERNFS_DIAGNOSTIC
printf("kernfs_mount: at %s\n", mp->mnt_stat.f_mntonname);
#endif
kernfs_get_rrootdev();
return error;
@ -193,36 +187,13 @@ kernfs_unmount(mp, mntflags, p)
{
int error;
int flags = 0;
struct vnode *rootvp = VFSTOKERNFS(mp)->kf_root;
#ifdef KERNFS_DIAGNOSTIC
printf("kernfs_unmount(mp = %p)\n", mp);
#endif
if (mntflags & MNT_FORCE)
if (mntflags & MNT_FORCE)
flags |= FORCECLOSE;
/*
* Clear out buffer cache. I don't think we
* ever get anything cached at this level at the
* moment, but who knows...
*/
if (rootvp->v_usecount > 1)
return (EBUSY);
#ifdef KERNFS_DIAGNOSTIC
printf("kernfs_unmount: calling vflush\n");
#endif
if ((error = vflush(mp, rootvp, flags)) != 0)
if ((error = vflush(mp, 0, flags)) != 0)
return (error);
#ifdef KERNFS_DIAGNOSTIC
vprint("kernfs root", rootvp);
#endif
/*
* Clean out the old root vnode for reuse.
*/
vrele(rootvp);
vgone(rootvp);
/*
* Finally, throw away the kernfs_mount structure
*/
@ -236,20 +207,9 @@ kernfs_root(mp, vpp)
struct mount *mp;
struct vnode **vpp;
{
struct vnode *vp;
#ifdef KERNFS_DIAGNOSTIC
printf("kernfs_root(mp = %p)\n", mp);
#endif
/*
* Return locked reference to root.
*/
vp = VFSTOKERNFS(mp)->kf_root;
VREF(vp);
vn_lock(vp, LK_EXCLUSIVE | LK_RETRY);
*vpp = vp;
return (0);
/* setup "." */
return (kernfs_allocvp(mp, vpp, Pkern, &kern_targets[0], 0));
}
int
@ -271,17 +231,13 @@ kernfs_statfs(mp, sbp, p)
struct proc *p;
{
#ifdef KERNFS_DIAGNOSTIC
printf("kernfs_statfs(mp = %p)\n", mp);
#endif
sbp->f_bsize = DEV_BSIZE;
sbp->f_iosize = DEV_BSIZE;
sbp->f_blocks = 2; /* 1K to keep df happy */
sbp->f_bfree = 0;
sbp->f_bavail = 0;
sbp->f_files = 0;
sbp->f_ffree = 0;
sbp->f_files = 1024; /* XXX lie */
sbp->f_ffree = 128; /* XXX lie */
#ifdef COMPAT_09
sbp->f_type = 7;
#else
@ -383,7 +339,7 @@ struct vfsops kernfs_vfsops = {
kernfs_fhtovp,
kernfs_vptofh,
kernfs_init,
NULL,
kernfs_reinit,
kernfs_done,
kernfs_sysctl,
NULL, /* vfs_mountroot */

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,5 @@
/* $NetBSD: key.c,v 1.92 2003/09/08 01:55:09 itojun Exp $ */
/* $KAME: key.c,v 1.308 2003/09/07 20:35:59 itojun Exp $ */
/* $NetBSD: key.c,v 1.93 2003/09/08 06:51:56 itojun Exp $ */
/* $KAME: key.c,v 1.310 2003/09/08 02:23:44 itojun Exp $ */
/*
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -35,10 +35,11 @@
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.92 2003/09/08 01:55:09 itojun Exp $");
__KERNEL_RCSID(0, "$NetBSD: key.c,v 1.93 2003/09/08 06:51:56 itojun Exp $");
#include "opt_inet.h"
#include "opt_ipsec.h"
#include "fs_kernfs.h"
#include <sys/param.h>
#include <sys/systm.h>
@ -91,6 +92,10 @@ __KERNEL_RCSID(0, "$NetBSD: key.c,v 1.92 2003/09/08 01:55:09 itojun Exp $");
#endif
#include <netinet6/ipcomp.h>
#ifdef KERNFS
#include <miscfs/kernfs/kernfs.h>
#endif
#include <machine/stdarg.h>
#include "rnd.h"
@ -312,7 +317,6 @@ static struct secasvar *key_do_allocsa_policy __P((struct secashead *, u_int));
static void key_delsav __P((struct secasvar *));
static void key_delsp __P((struct secpolicy *));
static struct secpolicy *key_getsp __P((struct secpolicyindex *, int));
static struct secpolicy *key_getspbyid __P((u_int32_t));
static u_int32_t key_newreqid __P((void));
static struct mbuf *key_gather_mbuf __P((struct mbuf *,
const struct sadb_msghdr *, int, int, ...));
@ -328,8 +332,6 @@ static int key_spdflush __P((struct socket *, struct mbuf *,
const struct sadb_msghdr *));
static int key_spddump __P((struct socket *, struct mbuf *,
const struct sadb_msghdr *));
static struct mbuf *key_setdumpsp __P((struct secpolicy *,
u_int8_t, u_int32_t, u_int32_t));
static u_int key_getspreqmsglen __P((struct secpolicy *));
static int key_spdexpire __P((struct secpolicy *));
static struct secashead *key_newsah __P((struct secasindex *));
@ -969,6 +971,10 @@ key_delsp(sp)
s = splsoftnet(); /*called from softclock()*/
#ifdef KERNFS
kernfs_revoke_sp(sp);
#endif
{
struct ipsecrequest *isr = sp->req, *nextisr;
@ -1027,7 +1033,7 @@ key_getsp(spidx, dir)
* OUT: NULL : not found
* others : found, pointer to a SP.
*/
static struct secpolicy *
struct secpolicy *
key_getspbyid(id)
u_int32_t id;
{
@ -2199,7 +2205,7 @@ key_spddump(so, m, mhp)
return 0;
}
static struct mbuf *
struct mbuf *
key_setdumpsp(sp, type, seq, pid)
struct secpolicy *sp;
u_int8_t type;
@ -6548,6 +6554,49 @@ key_dump(so, m, mhp)
return 0;
}
struct mbuf *
key_setdumpsa_spi(spi)
u_int32_t spi;
{
struct mbuf *m, *n;
struct secasvar *sav;
u_int8_t satype;
int cnt;
cnt = 0;
LIST_FOREACH(sav, &spihash[spi % SPIHASHSIZE], spihash) {
if (sav->spi != spi)
continue;
cnt++;
}
if (cnt == 0)
return NULL;
m = NULL;
LIST_FOREACH(sav, &spihash[spi % SPIHASHSIZE], spihash) {
if (sav->spi != spi)
continue;
satype = key_proto2satype(sav->sah->saidx.proto);
n = key_setdumpsa(sav, SADB_DUMP, satype, --cnt, 0);
if (!m)
m = n;
else if (n)
m_cat(m, n);
}
if (!m)
return NULL;
if ((m->m_flags & M_PKTHDR) != 0) {
m->m_pkthdr.len = 0;
for (n = m; n; n = n->m_next)
m->m_pkthdr.len += n->m_len;
}
return m;
}
/*
* SADB_X_PROMISC processing
*

View File

@ -1,4 +1,4 @@
/* $NetBSD: key.h,v 1.15 2003/09/07 15:59:38 itojun Exp $ */
/* $NetBSD: key.h,v 1.16 2003/09/08 06:51:59 itojun Exp $ */
/* $KAME: key.h,v 1.32 2003/09/07 05:25:20 itojun Exp $ */
/*
@ -56,6 +56,7 @@ extern int key_checkrequest
__P((struct ipsecrequest *isr, struct secasindex *));
extern struct secasvar *key_allocsa __P((u_int, caddr_t, caddr_t,
u_int, u_int32_t));
extern struct secpolicy *key_getspbyid __P((u_int32_t));
extern void key_freesp __P((struct secpolicy *));
extern void key_freesav __P((struct secasvar *));
extern struct secpolicy *key_newsp __P((u_int32_t));
@ -67,9 +68,12 @@ extern int key_cmpspidx_exactly
extern int key_cmpspidx_withmask
__P((struct secpolicyindex *, struct secpolicyindex *));
extern int key_spdacquire __P((struct secpolicy *));
extern struct mbuf *key_setdumpsp __P((struct secpolicy *,
u_int8_t, u_int32_t, u_int32_t));
extern void key_timehandler __P((void *));
extern void key_randomfill __P((void *, size_t));
extern void key_freereg __P((struct socket *));
struct mbuf *key_setdumpsa_spi __P((u_int32_t));
extern int key_parse __P((struct mbuf *, struct socket *));
extern void key_init __P((void));
extern int key_checktunnelsanity __P((struct secasvar *, u_int,