diff options
author | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2008-11-24 13:22:10 +0000 |
---|---|---|
committer | Mike Belopuhov <mikeb@cvs.openbsd.org> | 2008-11-24 13:22:10 +0000 |
commit | 36580920274bab4e2f28c6728c957e14dc9f3fcf (patch) | |
tree | 97e8af6483ac8ae73383974c2463411ec3a6c634 | |
parent | ee7448c97382f6524f4bea35169d58d19086ed4d (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.c | 4 | ||||
-rw-r--r-- | sys/net/pf_if.c | 4 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 6 | ||||
-rw-r--r-- | sys/net/pf_table.c | 38 | ||||
-rw-r--r-- | sys/net/pfvar.h | 4 |
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); |