summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Belopuhov <mikeb@cvs.openbsd.org>2008-11-24 13:22:10 +0000
committerMike Belopuhov <mikeb@cvs.openbsd.org>2008-11-24 13:22:10 +0000
commit36580920274bab4e2f28c6728c957e14dc9f3fcf (patch)
tree97e8af6483ac8ae73383974c2463411ec3a6c634
parentee7448c97382f6524f4bea35169d58d19086ed4d (diff)
Fix splasserts seen in pr 5987 by propagating a flag that discribes
whether we're called from the interrupt context to the functions performing allocations. Looked at by mpf@ and henning@, tested by mpf@ and Antti Harri, the pr originator. ok tedu
-rw-r--r--sys/net/pf.c4
-rw-r--r--sys/net/pf_if.c4
-rw-r--r--sys/net/pf_ioctl.c6
-rw-r--r--sys/net/pf_table.c38
-rw-r--r--sys/net/pfvar.h4
5 files changed, 33 insertions, 23 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c
index 35200c96fc3..a876a0edc48 100644
--- a/sys/net/pf.c
+++ b/sys/net/pf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf.c,v 1.626 2008/11/21 18:01:30 claudio Exp $ */
+/* $OpenBSD: pf.c,v 1.627 2008/11/24 13:22:09 mikeb Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1183,7 +1183,7 @@ pf_tbladdr_setup(struct pf_ruleset *rs, struct pf_addr_wrap *aw)
{
if (aw->type != PF_ADDR_TABLE)
return (0);
- if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname)) == NULL)
+ if ((aw->p.tbl = pfr_attach_table(rs, aw->v.tblname, 1)) == NULL)
return (1);
return (0);
}
diff --git a/sys/net/pf_if.c b/sys/net/pf_if.c
index e39a9d6501e..ddf5cec4d2f 100644
--- a/sys/net/pf_if.c
+++ b/sys/net/pf_if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_if.c,v 1.54 2008/06/14 16:55:28 mk Exp $ */
+/* $OpenBSD: pf_if.c,v 1.55 2008/11/24 13:22:09 mikeb Exp $ */
/*
* Copyright 2005 Henning Brauer <henning@openbsd.org>
@@ -367,7 +367,7 @@ pfi_dynaddr_setup(struct pf_addr_wrap *aw, sa_family_t af)
goto _bad;
}
- if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname)) == NULL) {
+ if ((dyn->pfid_kt = pfr_attach_table(ruleset, tblname, 1)) == NULL) {
rv = 1;
goto _bad;
}
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index 5f0c35be052..408b60f76f6 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.210 2008/10/23 22:22:44 deraadt Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.211 2008/11/24 13:22:09 mikeb Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1164,7 +1164,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (rule->overload_tblname[0]) {
if ((rule->overload_tbl = pfr_attach_table(ruleset,
- rule->overload_tblname)) == NULL)
+ rule->overload_tblname, 0)) == NULL)
error = EINVAL;
else
rule->overload_tbl->pfrkt_flags |=
@@ -1401,7 +1401,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (newrule->overload_tblname[0]) {
if ((newrule->overload_tbl = pfr_attach_table(
- ruleset, newrule->overload_tblname)) ==
+ ruleset, newrule->overload_tblname, 0)) ==
NULL)
error = EINVAL;
else
diff --git a/sys/net/pf_table.c b/sys/net/pf_table.c
index 4d1e0fd9939..2369a2993c0 100644
--- a/sys/net/pf_table.c
+++ b/sys/net/pf_table.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_table.c,v 1.79 2008/10/08 06:24:50 mcbride Exp $ */
+/* $OpenBSD: pf_table.c,v 1.80 2008/11/24 13:22:09 mikeb Exp $ */
/*
* Copyright (c) 2002 Cedric Berger
@@ -166,7 +166,7 @@ void pfr_setflags_ktable(struct pfr_ktable *, int);
void pfr_clstats_ktables(struct pfr_ktableworkq *, long,
int);
void pfr_clstats_ktable(struct pfr_ktable *, long, int);
-struct pfr_ktable *pfr_create_ktable(struct pfr_table *, long, int);
+struct pfr_ktable *pfr_create_ktable(struct pfr_table *, long, int, int);
void pfr_destroy_ktables(struct pfr_ktableworkq *, int);
void pfr_destroy_ktable(struct pfr_ktable *, int);
int pfr_ktable_compare(struct pfr_ktable *,
@@ -256,7 +256,8 @@ pfr_add_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
return (ESRCH);
if (kt->pfrkt_flags & PFR_TFLAG_CONST)
return (EPERM);
- tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0);
+ tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
+ !(flags & PFR_FLAG_USERIOCTL));
if (tmpkt == NULL)
return (ENOMEM);
SLIST_INIT(&workq);
@@ -428,7 +429,8 @@ pfr_set_addrs(struct pfr_table *tbl, struct pfr_addr *addr, int size,
return (ESRCH);
if (kt->pfrkt_flags & PFR_TFLAG_CONST)
return (EPERM);
- tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0);
+ tmpkt = pfr_create_ktable(&pfr_nulltable, 0, 0,
+ !(flags & PFR_FLAG_USERIOCTL));
if (tmpkt == NULL)
return (ENOMEM);
pfr_mark_addrs(kt);
@@ -1181,7 +1183,8 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
key.pfrkt_flags |= PFR_TFLAG_ACTIVE;
p = RB_FIND(pfr_ktablehead, &pfr_ktables, &key);
if (p == NULL) {
- p = pfr_create_ktable(&key.pfrkt_t, tzero, 1);
+ p = pfr_create_ktable(&key.pfrkt_t, tzero, 1,
+ !(flags & PFR_FLAG_USERIOCTL));
if (p == NULL)
senderr(ENOMEM);
SLIST_FOREACH(q, &addq, pfrkt_workq) {
@@ -1207,7 +1210,8 @@ pfr_add_tables(struct pfr_table *tbl, int size, int *nadd, int flags)
}
}
key.pfrkt_flags = 0;
- r = pfr_create_ktable(&key.pfrkt_t, 0, 1);
+ r = pfr_create_ktable(&key.pfrkt_t, 0, 1,
+ !(flags & PFR_FLAG_USERIOCTL));
if (r == NULL)
senderr(ENOMEM);
SLIST_INSERT_HEAD(&addq, r, pfrkt_workq);
@@ -1511,7 +1515,8 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
SLIST_INIT(&tableq);
kt = RB_FIND(pfr_ktablehead, &pfr_ktables, (struct pfr_ktable *)tbl);
if (kt == NULL) {
- kt = pfr_create_ktable(tbl, 0, 1);
+ kt = pfr_create_ktable(tbl, 0, 1,
+ !(flags & PFR_FLAG_USERIOCTL));
if (kt == NULL)
return (ENOMEM);
SLIST_INSERT_HEAD(&tableq, kt, pfrkt_workq);
@@ -1527,7 +1532,8 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
kt->pfrkt_root = rt;
goto _skip;
}
- rt = pfr_create_ktable(&key.pfrkt_t, 0, 1);
+ rt = pfr_create_ktable(&key.pfrkt_t, 0, 1,
+ !(flags & PFR_FLAG_USERIOCTL));
if (rt == NULL) {
pfr_destroy_ktables(&tableq, 0);
return (ENOMEM);
@@ -1537,7 +1543,7 @@ pfr_ina_define(struct pfr_table *tbl, struct pfr_addr *addr, int size,
} else if (!(kt->pfrkt_flags & PFR_TFLAG_INACTIVE))
xadd++;
_skip:
- shadow = pfr_create_ktable(tbl, 0, 0);
+ shadow = pfr_create_ktable(tbl, 0, 0, !(flags & PFR_FLAG_USERIOCTL));
if (shadow == NULL) {
pfr_destroy_ktables(&tableq, 0);
return (ENOMEM);
@@ -1888,12 +1894,16 @@ pfr_clstats_ktable(struct pfr_ktable *kt, long tzero, int recurse)
}
struct pfr_ktable *
-pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset)
+pfr_create_ktable(struct pfr_table *tbl, long tzero, int attachruleset,
+ int intr)
{
struct pfr_ktable *kt;
struct pf_ruleset *rs;
- kt = pool_get(&pfr_ktable_pl, PR_WAITOK | PR_ZERO | PR_LIMITFAIL);
+ if (intr)
+ kt = pool_get(&pfr_ktable_pl, PR_NOWAIT|PR_ZERO|PR_LIMITFAIL);
+ else
+ kt = pool_get(&pfr_ktable_pl, PR_WAITOK|PR_ZERO|PR_LIMITFAIL);
if (kt == NULL)
return (NULL);
kt->pfrkt_t = *tbl;
@@ -2060,7 +2070,7 @@ pfr_update_stats(struct pfr_ktable *kt, struct pf_addr *a, sa_family_t af,
}
struct pfr_ktable *
-pfr_attach_table(struct pf_ruleset *rs, char *name)
+pfr_attach_table(struct pf_ruleset *rs, char *name, int intr)
{
struct pfr_ktable *kt, *rt;
struct pfr_table tbl;
@@ -2072,14 +2082,14 @@ pfr_attach_table(struct pf_ruleset *rs, char *name)
strlcpy(tbl.pfrt_anchor, ac->path, sizeof(tbl.pfrt_anchor));
kt = pfr_lookup_table(&tbl);
if (kt == NULL) {
- kt = pfr_create_ktable(&tbl, time_second, 1);
+ kt = pfr_create_ktable(&tbl, time_second, 1, intr);
if (kt == NULL)
return (NULL);
if (ac != NULL) {
bzero(tbl.pfrt_anchor, sizeof(tbl.pfrt_anchor));
rt = pfr_lookup_table(&tbl);
if (rt == NULL) {
- rt = pfr_create_ktable(&tbl, 0, 1);
+ rt = pfr_create_ktable(&tbl, 0, 1, intr);
if (rt == NULL) {
pfr_destroy_ktable(kt, 0);
return (NULL);
diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h
index e8ed133845a..9a87295b82c 100644
--- a/sys/net/pfvar.h
+++ b/sys/net/pfvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: pfvar.h,v 1.280 2008/10/08 06:24:50 mcbride Exp $ */
+/* $OpenBSD: pfvar.h,v 1.281 2008/11/24 13:22:09 mikeb Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -1696,7 +1696,7 @@ int pfr_pool_get(struct pfr_ktable *, int *, struct pf_addr *,
struct pf_addr **, struct pf_addr **, sa_family_t);
void pfr_dynaddr_update(struct pfr_ktable *, struct pfi_dynaddr *);
struct pfr_ktable *
- pfr_attach_table(struct pf_ruleset *, char *);
+ pfr_attach_table(struct pf_ruleset *, char *, int);
void pfr_detach_table(struct pfr_ktable *);
int pfr_clr_tables(struct pfr_table *, int *, int);
int pfr_add_tables(struct pfr_table *, int, int *, int);