make PF lkm working. from Peter Postma and Joel Wilsson.

remove pf_ioctl_head/pf_newif_head, which was never used.
This commit is contained in:
itojun 2004-06-29 04:42:54 +00:00
parent 6e1b89d727
commit 0407dd42ae
11 changed files with 159 additions and 304 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: if_pflog.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */
/* $NetBSD: if_pflog.c,v 1.3 2004/06/29 04:42:55 itojun Exp $ */
/* $OpenBSD: if_pflog.c,v 1.11 2003/12/31 11:18:25 cedric Exp $ */
/*
* The authors of this code are John Ioannidis (ji@tla.org),
@ -80,6 +80,9 @@
struct pflog_softc pflogif[NPFLOG];
void pflogattach(int);
#ifdef _LKM
void pflogdetach(void);
#endif
int pflogoutput(struct ifnet *, struct mbuf *, struct sockaddr *,
struct rtentry *);
int pflogioctl(struct ifnet *, u_long, caddr_t);
@ -121,6 +124,21 @@ pflogattach(int npflog)
}
}
#ifdef _LKM
void
pflogdetach(void)
{
struct ifnet *ifp;
int i;
for (i = 0; i < NPFLOG; i++) {
ifp = &pflogif[i].sc_if;
bpfdetach(ifp);
if_detach(ifp);
}
}
#endif
/*
* Start output on the pflog interface.
*/

View File

@ -1,4 +1,4 @@
/* $NetBSD: pf_if.c,v 1.2 2004/06/22 14:17:07 itojun Exp $ */
/* $NetBSD: pf_if.c,v 1.3 2004/06/29 04:42:55 itojun Exp $ */
/* $OpenBSD: pf_if.c,v 1.11 2004/03/15 11:38:23 cedric Exp $ */
/*
@ -114,9 +114,6 @@ static void hook_disestablish(struct hook_desc_head *, void *);
#define HOOK_REMOVE 0x01
#define HOOK_FREE 0x02
POOL_INIT(pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0, "pfiaddrpl",
&pool_allocator_nointr);
#endif
void
@ -126,10 +123,8 @@ pfi_initialize(void)
return;
TAILQ_INIT(&pfi_statehead);
#ifdef __OpenBSD__
pool_init(&pfi_addr_pl, sizeof(struct pfi_dynaddr), 0, 0, 0,
"pfiaddrpl", &pool_allocator_nointr);
#endif
pfi_buffer_max = 64;
pfi_buffer = malloc(pfi_buffer_max * sizeof(*pfi_buffer),
PFI_MTYPE, M_WAITOK);
@ -137,6 +132,22 @@ pfi_initialize(void)
pfi_dynamic_drivers();
}
#ifdef _LKM
void
pfi_destroy(void)
{
struct pfi_kif *p;
while ((p = TAILQ_FIRST(&pfi_statehead)) != NULL) {
TAILQ_REMOVE(&pfi_statehead, p, pfik_w_states);
free(p, PFI_MTYPE);
}
pool_destroy(&pfi_addr_pl);
pfi_self = NULL;
}
#endif
void
pfi_attach_clone(struct if_clone *ifc)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: pf_ioctl.c,v 1.5 2004/06/25 13:17:01 itojun Exp $ */
/* $NetBSD: pf_ioctl.c,v 1.6 2004/06/29 04:42:55 itojun Exp $ */
/* $OpenBSD: pf_ioctl.c,v 1.112 2004/03/22 04:54:18 mcbride Exp $ */
/*
@ -98,7 +98,9 @@
#endif
void pfattach(int);
int pfdetach(void);
#ifdef _LKM
void pfdetach(void);
#endif
int pfopen(dev_t, int, int, struct proc *);
int pfclose(dev_t, int, int, struct proc *);
struct pf_pool *pf_get_pool(char *, char *, u_int32_t,
@ -126,14 +128,7 @@ const struct cdevsw pf_cdevsw = {
static int pf_pfil_attach(void);
static int pf_pfil_detach(void);
POOL_INIT(pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl",
&pool_allocator_nointr);
POOL_INIT(pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0,
"pfsrctrpl", NULL);
POOL_INIT(pf_state_pl, sizeof(struct pf_state), 0, 0, 0, "pfstatepl", NULL);
POOL_INIT(pf_altq_pl, sizeof(struct pf_altq), 0, 0, 0, "pfaltqpl", NULL);
POOL_INIT(pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
"pfpooladdrpl", NULL);
static int pf_pfil_attached = 0;
#endif
#ifdef __OpenBSD__
@ -158,8 +153,6 @@ static void tag_unref(struct pf_tags *, u_int16_t);
#define DPFPRINTF(n, x) if (pf_status.debug >= (n)) printf x
#ifdef __NetBSD__
struct pfil_head pf_ioctl_head;
struct pfil_head pf_newif_head;
extern struct pfil_head if_pfil;
#endif
@ -168,12 +161,6 @@ pfattach(int num)
{
u_int32_t *timeout = pf_default_rule.timeout;
#ifdef __NetBSD__
pfil_head_register(&pf_ioctl_head);
pfil_head_register(&pf_newif_head);
#endif
#ifdef __OpenBSD__
pool_init(&pf_rule_pl, sizeof(struct pf_rule), 0, 0, 0, "pfrulepl",
&pool_allocator_nointr);
pool_init(&pf_src_tree_pl, sizeof(struct pf_src_node), 0, 0, 0,
@ -184,7 +171,7 @@ pfattach(int num)
NULL);
pool_init(&pf_pooladdr_pl, sizeof(struct pf_pooladdr), 0, 0, 0,
"pfpooladdrpl", NULL);
#endif
pfr_initialize();
pfi_initialize();
pf_osfp_initialize();
@ -243,6 +230,44 @@ pfattach(int num)
pf_status.hostid = arc4random();
}
#ifdef _LKM
#define TAILQ_DRAIN(list, element) \
do { \
while ((element = TAILQ_FIRST(list)) != NULL) { \
TAILQ_REMOVE(list, element, entries); \
free(element, M_TEMP); \
} \
} while (0)
void
pfdetach(void)
{
struct pf_pooladdr *pooladdr_e;
struct pf_altq *altq_e;
struct pf_anchor *anchor_e;
(void)pf_pfil_detach();
callout_stop(&pf_expire_to);
pf_normalize_destroy();
pf_osfp_destroy();
pfi_destroy();
TAILQ_DRAIN(&pf_pabuf, pooladdr_e);
TAILQ_DRAIN(&pf_altqs[1], altq_e);
TAILQ_DRAIN(&pf_altqs[0], altq_e);
TAILQ_DRAIN(&pf_anchors, anchor_e);
pf_remove_if_empty_ruleset(&pf_main_ruleset);
pfr_destroy();
pool_destroy(&pf_pooladdr_pl);
pool_destroy(&pf_altq_pl);
pool_destroy(&pf_state_pl);
pool_destroy(&pf_rule_pl);
pool_destroy(&pf_src_tree_pl);
}
#endif
int
pfopen(dev_t dev, int flags, int fmt, struct proc *p)
{
@ -251,12 +276,6 @@ pfopen(dev_t dev, int flags, int fmt, struct proc *p)
return (0);
}
int
pfdetach(void)
{
return pf_pfil_detach();
}
int
pfclose(dev_t dev, int flags, int fmt, struct proc *p)
{
@ -2811,6 +2830,9 @@ pf_pfil_attach(void)
int error;
int i;
if (pf_pfil_attached)
return (0);
error = pfil_add_hook(pfil_if_wrapper, NULL, PFIL_IFADDR|PFIL_NEWIF,
&if_pfil);
if (error)
@ -2847,6 +2869,7 @@ pf_pfil_attach(void)
if (ifindex2ifnet[i])
pfi_attach_ifnet(ifindex2ifnet[i]);
}
pf_pfil_attached = 1;
}
return (error);
}
@ -2860,6 +2883,9 @@ pf_pfil_detach(void)
#endif
int i;
if (pf_pfil_attached == 0)
return (0);
for (i = 0; i < if_indexlim; i++) {
if (pfi_index2kif[i])
pfi_detach_ifnet(ifindex2ifnet[i]);
@ -2872,10 +2898,12 @@ pf_pfil_detach(void)
PFIL_IN|PFIL_OUT, ph_inet);
#ifdef INET6
ph_inet6 = pfil_head_get(PFIL_TYPE_AF, AF_INET6);
if (ph_inet)
if (ph_inet6)
pfil_remove_hook((void *)pfil6_wrapper, NULL,
PFIL_IN|PFIL_OUT, ph_inet6);
#endif
pf_pfil_attached = 0;
return (0);
}
#endif

View File

@ -1,4 +1,4 @@
/* $NetBSD: pf_norm.c,v 1.2 2004/06/22 14:17:08 itojun Exp $ */
/* $NetBSD: pf_norm.c,v 1.3 2004/06/29 04:42:55 itojun Exp $ */
/* $OpenBSD: pf_norm.c,v 1.80 2004/03/09 21:44:41 mcbride Exp $ */
/*
@ -135,19 +135,10 @@ struct pool pf_frent_pl, pf_frag_pl, pf_cache_pl, pf_cent_pl;
struct pool pf_state_scrub_pl;
int pf_nfrents, pf_ncache;
#ifdef __NetBSD__
POOL_INIT(pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent", NULL);
POOL_INIT(pf_frag_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrag", NULL);
POOL_INIT(pf_cache_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrcache", NULL);
POOL_INIT(pf_cent_pl, sizeof(struct pf_frcache), 0, 0, 0, "pffrcent", NULL);
POOL_INIT(pf_state_scrub_pl, sizeof(struct pf_state_scrub), 0, 0, 0,
"pfstscr", NULL);
#endif
void
pf_normalize_init(void)
{
#ifdef __OpenBSD__
pool_init(&pf_frent_pl, sizeof(struct pf_frent), 0, 0, 0, "pffrent",
NULL);
pool_init(&pf_frag_pl, sizeof(struct pf_fragment), 0, 0, 0, "pffrag",
@ -158,7 +149,6 @@ pf_normalize_init(void)
NULL);
pool_init(&pf_state_scrub_pl, sizeof(struct pf_state_scrub), 0, 0, 0,
"pfstscr", NULL);
#endif
pool_sethiwat(&pf_frag_pl, PFFRAG_FRAG_HIWAT);
pool_sethardlimit(&pf_frent_pl, PFFRAG_FRENT_HIWAT, NULL, 0);
@ -169,6 +159,29 @@ pf_normalize_init(void)
TAILQ_INIT(&pf_cachequeue);
}
#ifdef _LKM
#define TAILQ_DRAIN(list, element) \
do { \
while ((element = TAILQ_FIRST(list)) != NULL) \
TAILQ_REMOVE(list, element, frag_next); \
} while (0)
void
pf_normalize_destroy(void)
{
struct pf_fragment *fragment_e;
TAILQ_DRAIN(&pf_fragqueue, fragment_e);
TAILQ_DRAIN(&pf_cachequeue, fragment_e);
pool_destroy(&pf_state_scrub_pl);
pool_destroy(&pf_cent_pl);
pool_destroy(&pf_cache_pl);
pool_destroy(&pf_frag_pl);
pool_destroy(&pf_frent_pl);
}
#endif
static __inline int
pf_frag_compare(struct pf_fragment *a, struct pf_fragment *b)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: pf_osfp.c,v 1.2 2004/06/22 14:17:08 itojun Exp $ */
/* $NetBSD: pf_osfp.c,v 1.3 2004/06/29 04:42:55 itojun Exp $ */
/* $OpenBSD: pf_osfp.c,v 1.9 2004/01/04 20:08:42 pvalchev Exp $ */
/*
@ -244,6 +244,17 @@ pf_osfp_initialize(void)
SLIST_INIT(&pf_osfp_list);
}
#ifdef _LKM
void
pf_osfp_destroy(void)
{
pf_osfp_flush();
pool_destroy(&pf_osfp_pl);
pool_destroy(&pf_osfp_entry_pl);
}
#endif
/* Flush the fingerprint list */
void
pf_osfp_flush(void)

View File

@ -1,4 +1,4 @@
/* $NetBSD: pf_table.c,v 1.2 2004/06/22 14:17:08 itojun Exp $ */
/* $NetBSD: pf_table.c,v 1.3 2004/06/29 04:42:55 itojun Exp $ */
/* $OpenBSD: pf_table.c,v 1.47 2004/03/09 21:44:41 mcbride Exp $ */
/*
@ -190,20 +190,13 @@ struct pfr_ktablehead pfr_ktables;
struct pfr_table pfr_nulltable;
int pfr_ktable_cnt;
#ifdef __NetBSD__
POOL_INIT(pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0, "pfrktable", NULL);
POOL_INIT(pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0, "pfrkentry", NULL);
#endif
void
pfr_initialize(void)
{
#ifdef __OpenBSD__
pool_init(&pfr_ktable_pl, sizeof(struct pfr_ktable), 0, 0, 0,
"pfrktable", NULL);
pool_init(&pfr_kentry_pl, sizeof(struct pfr_kentry), 0, 0, 0,
"pfrkentry", NULL);
#endif
pfr_sin.sin_len = sizeof(pfr_sin);
pfr_sin.sin_family = AF_INET;
@ -213,6 +206,15 @@ pfr_initialize(void)
memset(&pfr_ffaddr, 0xff, sizeof(pfr_ffaddr));
}
#ifdef _LKM
void
pfr_destroy(void)
{
pool_destroy(&pfr_ktable_pl);
pool_destroy(&pfr_kentry_pl);
}
#endif
int
pfr_clr_addrs(struct pfr_table *tbl, int *ndel, int flags)
{

View File

@ -1,4 +1,4 @@
/* $NetBSD: pfvar.h,v 1.2 2004/06/22 14:17:08 itojun Exp $ */
/* $NetBSD: pfvar.h,v 1.3 2004/06/29 04:42:55 itojun Exp $ */
/* $OpenBSD: pfvar.h,v 1.187 2004/03/22 04:54:18 mcbride Exp $ */
/*
@ -1383,6 +1383,9 @@ int pf_match_uid(u_int8_t, uid_t, uid_t, uid_t);
int pf_match_gid(u_int8_t, gid_t, gid_t, gid_t);
void pf_normalize_init(void);
#ifdef _LKM
void pf_normalize_destroy(void);
#endif
int pf_normalize_ip(struct mbuf **, int, struct pfi_kif *, u_short *);
int pf_normalize_ip6(struct mbuf **, int, struct pfi_kif *, u_short *);
int pf_normalize_tcp(int, struct pfi_kif *, struct mbuf *, int, int, void *,
@ -1398,6 +1401,9 @@ u_int32_t
void pf_purge_expired_fragments(void);
int pf_routable(struct pf_addr *addr, sa_family_t af);
void pfr_initialize(void);
#ifdef _LKM
void pfr_destroy(void);
#endif
int pfr_match_addr(struct pfr_ktable *, struct pf_addr *, sa_family_t);
void pfr_update_stats(struct pfr_ktable *, struct pf_addr *, sa_family_t,
u_int64_t, int, int, int);
@ -1434,6 +1440,9 @@ int pfr_ina_define(struct pfr_table *, struct pfr_addr *, int, int *,
int *, u_int32_t, int);
void pfi_initialize(void);
#ifdef _LKM
void pfi_destroy(void);
#endif
void pfi_attach_clone(struct if_clone *);
void pfi_attach_ifnet(struct ifnet *);
void pfi_detach_ifnet(struct ifnet *);
@ -1491,6 +1500,9 @@ struct pf_osfp_enlist *
void pf_osfp_flush(void);
int pf_osfp_get(struct pf_osfp_ioctl *);
void pf_osfp_initialize(void);
#ifdef _LKM
void pf_osfp_destroy(void);
#endif
int pf_osfp_match(struct pf_osfp_enlist *, pf_osfp_t);
struct pf_os_fingerprint *
pf_osfp_validate(void);

View File

@ -1,3 +1,3 @@
SUBDIR= bsdcomp deflate
SUBDIR= bsdcomp deflate pf
.include <bsd.subdir.mk>

View File

@ -1,12 +1,14 @@
# $NetBSD: Makefile,v 1.2 2004/06/22 18:04:05 christos Exp $
# $NetBSD: Makefile,v 1.3 2004/06/29 04:42:54 itojun Exp $
.include "../Makefile.inc"
CPPFLAGS+= -I$S/dist/pf -I$S/dist/pf/net -I$S -DINET6 -DINET
KMOD= pf_lkm
SRCS= if_pflog.c pf.c pf_ioctl.c pf_osfp.c pf_if.c \
pf_norm.c pf_table.c mln_pf.c
CPPFLAGS+= -I$S/dist/pf -I$S -DINET6 -DINET
KMOD= pf
SRCS= if_pflog.c pf_real.c pf_ioctl.c pf_osfp.c pf_if.c \
pf_norm.c pf_table.c pf_lkm.c
.PATH: $S/dist/pf/net
BUILDSYMLINKS+= $S/dist/pf/net/pf.c pf_real.c
.include <bsd.kmod.mk>

View File

@ -1,3 +1,3 @@
/* $NetBSD: bpfilter.h,v 1.1 2004/06/22 14:18:58 itojun Exp $ */
/* $NetBSD: bpfilter.h,v 1.2 2004/06/29 04:42:54 itojun Exp $ */
#define NBPFILTER 0
#define NBPFILTER 8

View File

@ -1,242 +0,0 @@
/* $NetBSD: mln_pf.c,v 1.2 2004/06/22 18:04:05 christos Exp $ */
/*
* Copyright (C) 2003 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.
*/
/*
* Copyright (C) 1993-2001 by Darren Reed.
*
* See the IPFILTER.LICENCE file for details on licencing.
*/
#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: mln_pf.c,v 1.2 2004/06/22 18:04:05 christos Exp $");
#include <sys/param.h>
/*
* Post NetBSD 1.2 has the PFIL interface for packet filters. This turns
* on those hooks. We don't need any special mods with this!
*/
#include <sys/systm.h>
#include <sys/conf.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/proc.h>
#include <sys/uio.h>
#include <sys/kernel.h>
#include <sys/vnode.h>
#include <sys/namei.h>
#include <sys/malloc.h>
#include <sys/mount.h>
#include <sys/exec.h>
#include <sys/mbuf.h>
#include <net/if.h>
#include <netinet/in_systm.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <net/route.h>
#include <netinet/ip_var.h>
#include <netinet/tcp.h>
#include <netinet/tcpip.h>
#include <sys/lkm.h>
#include <net/pfvar.h>
extern int lkmenodev __P((void));
int pf_lkm_lkmentry __P((struct lkm_table *, int, int));
static int pf_unload __P((void));
static int pf_load __P((void));
static int pf_remove __P((void));
static int pfaction __P((struct lkm_table *, int));
static char *ipf_devfiles[] = { "/dev/pf" };
extern void pfattach(int);
extern int pfdetach(void);
#ifdef DEBUG
#define DPRINTF(a) printf a
#else
#define DPRINTF(a)
#endif
extern const struct cdevsw pf_cdevsw;
int pf_major = 0;
MOD_DEV("pf", "pf", NULL, -1, &pf_cdevsw, -1);
extern int vd_unuseddev __P((void));
extern struct cdevsw cdevsw[];
extern int nchrdev;
int pf_lkm_lkmentry(lkmtp, cmd, ver)
struct lkm_table *lkmtp;
int cmd, ver;
{
DISPATCH(lkmtp, cmd, ver, pfaction, pfaction, pfaction);
}
static int pfaction(lkmtp, cmd)
struct lkm_table *lkmtp;
int cmd;
{
struct lkm_dev *args = lkmtp->private.lkm_dev;
int error = 0;
switch (cmd) {
case LKM_E_LOAD :
if (lkmexists(lkmtp)) {
DPRINTF(("lkm exists\n"));
return EEXIST;
}
error = devsw_attach(args->lkm_devname,
args->lkm_bdev, &args->lkm_bdevmaj,
args->lkm_cdev, &args->lkm_cdevmaj);
if (error != 0) {
DPRINTF(("devsw_attach(%s, %u, %u) failed %d\n",
args->lkm_devname, (unsigned)args->lkm_bdev,
(unsigned)args->lkm_cdev, error));
return error;
}
if ((error = pf_load()) != 0) {
DPRINTF(("pf_load failed %d\n", error));
devsw_detach(args->lkm_bdev, args->lkm_cdev);
return error;
}
pf_major = args->lkm_cdevmaj;
printf("PF: loaded into slot %d\n", pf_major);
break;
case LKM_E_UNLOAD :
devsw_detach(args->lkm_bdev, args->lkm_cdev);
args->lkm_bdevmaj = -1;
args->lkm_cdevmaj = -1;
if ((error = pf_unload()) != 0) {
DPRINTF(("unload failed %d\n", error));
return error;
}
printf("PF: unloaded from slot %d\n", pf_major);
break;
case LKM_E_STAT :
break;
default:
DPRINTF(("unknown command %d\n", cmd));
error = EIO;
break;
}
return 0;
}
static int pf_remove()
{
char *name;
struct nameidata nd;
int error, i;
for (i = 0; (name = ipf_devfiles[i]); i++) {
NDINIT(&nd, DELETE, LOCKPARENT|LOCKLEAF, UIO_SYSSPACE,
name, curproc);
if ((error = namei(&nd)) != 0) {
DPRINTF(("namei failed %d\n", error));
return error;
}
VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
VOP_LEASE(nd.ni_vp, curproc, curproc->p_ucred, LEASE_WRITE);
(void) VOP_REMOVE(nd.ni_dvp, nd.ni_vp, &nd.ni_cnd);
}
return 0;
}
static int pf_unload()
{
int error = 0;
/*
* Unloading - remove the filter rule check from the IP
* input/output stream.
*/
if ((error = pfdetach()) != 0) {
DPRINTF(("Detach failed %d\n", error));
return error;
}
if ((error = pf_remove()) != 0) {
DPRINTF(("Remove failed %d\n", error));
return error;
}
printf("PF unloaded\n");
return 0;
}
static int pf_load()
{
struct nameidata nd;
struct vattr vattr;
int error = 0, fmode = S_IFCHR|0600, i;
char *name;
/*
* XXX Remove existing device nodes prior to creating new ones
* XXX using the assigned LKM device slot's major number. In a
* XXX perfect world we could use the ones specified by cdevsw[].
*/
(void)pf_remove();
pfattach(1);
for (i = 0; (error == 0) && (name = ipf_devfiles[i]); i++) {
NDINIT(&nd, CREATE, LOCKPARENT, UIO_SYSSPACE, name, curproc);
if ((error = namei(&nd)) != 0)
break;
if (nd.ni_vp != NULL) {
VOP_ABORTOP(nd.ni_dvp, &nd.ni_cnd);
if (nd.ni_dvp == nd.ni_vp)
vrele(nd.ni_dvp);
else
vput(nd.ni_dvp);
vrele(nd.ni_vp);
error = EEXIST;
break;
}
VATTR_NULL(&vattr);
vattr.va_type = VCHR;
vattr.va_mode = (fmode & 07777);
vattr.va_rdev = (pf_major << 8) | i;
VOP_LEASE(nd.ni_dvp, curproc, curproc->p_ucred, LEASE_WRITE);
error = VOP_MKNOD(nd.ni_dvp, &nd.ni_vp, &nd.ni_cnd, &vattr);
if (error == 0)
vput(nd.ni_vp);
}
if (error == 0)
printf("PF initialized.");
return error;
}