propagate a flag to the pfr_create_ktable reflecting whether we were called from the interrupt context.
ok? Index: net/pf.c =================================================================== RCS file: /cvs/src/sys/net/pf.c,v retrieving revision 1.2 diff -u -r1.2 pf.c --- net/pf.c 26 Dec 2008 18:51:52 -0000 1.2 +++ net/pf.c 13 Aug 2009 08:05:13 -0000 @@ -1141,7 +1141,7 @@ { 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); } Index: net/pf_if.c =================================================================== RCS file: /cvs/src/sys/net/pf_if.c,v retrieving revision 1.2 diff -u -r1.2 pf_if.c --- net/pf_if.c 26 Dec 2008 18:51:52 -0000 1.2 +++ net/pf_if.c 13 Aug 2009 08:05:13 -0000 @@ -366,7 +366,7 @@ 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; } Index: net/pf_ioctl.c =================================================================== RCS file: /cvs/src/sys/net/pf_ioctl.c,v retrieving revision 1.2 diff -u -r1.2 pf_ioctl.c --- net/pf_ioctl.c 26 Dec 2008 18:51:52 -0000 1.2 +++ net/pf_ioctl.c 13 Aug 2009 08:05:14 -0000 @@ -1163,7 +1163,7 @@ 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 |= @@ -1400,7 +1400,7 @@ 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 Index: net/pf_table.c =================================================================== RCS file: /cvs/src/sys/net/pf_table.c,v retrieving revision 1.2 diff -u -r1.2 pf_table.c --- net/pf_table.c 26 Dec 2008 18:51:52 -0000 1.2 +++ net/pf_table.c 13 Aug 2009 08:05:14 -0000 @@ -166,7 +166,7 @@ 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 *, @@ -258,7 +258,8 @@ 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); @@ -430,7 +431,8 @@ 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); @@ -1187,7 +1189,8 @@ 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) { @@ -1213,7 +1216,8 @@ } } 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); @@ -1517,7 +1521,8 @@ 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); @@ -1533,7 +1538,8 @@ 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); @@ -1543,7 +1549,7 @@ } 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); @@ -1894,12 +1900,16 @@ } 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; @@ -2066,7 +2076,7 @@ } 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; @@ -2078,14 +2088,14 @@ 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); Index: net/pfvar.h =================================================================== RCS file: /cvs/src/sys/net/pfvar.h,v retrieving revision 1.2 diff -u -r1.2 pfvar.h --- net/pfvar.h 26 Dec 2008 18:51:53 -0000 1.2 +++ net/pfvar.h 13 Aug 2009 08:05:14 -0000 @@ -1692,7 +1692,7 @@ 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);