diff options
-rw-r--r-- | sys/net/pf.c | 8 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 41 | ||||
-rw-r--r-- | sys/net/pfvar.h | 4 |
3 files changed, 23 insertions, 30 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index 692ca171cdc..6db652ac3a4 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.328 2003/03/21 12:47:36 cedric Exp $ */ +/* $OpenBSD: pf.c,v 1.329 2003/03/31 13:15:27 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -505,9 +505,11 @@ pf_purge_expired_states(void) pfsync_delete_state(cur->state); #endif if (cur->state->rule.ptr != NULL) - cur->state->rule.ptr->states--; + if (--cur->state->rule.ptr->states <= 0) + pf_rm_rule(NULL, cur->state->rule.ptr); if (cur->state->nat_rule != NULL) - cur->state->nat_rule->states--; + if (--cur->state->nat_rule->states <= 0) + pf_rm_rule(NULL, cur->state->nat_rule); pool_put(&pf_state_pl, cur->state); pool_put(&pf_tree_pl, cur); pool_put(&pf_tree_pl, peer); diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index eab5b763a28..fc41e5a7bd8 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.50 2003/03/11 13:26:09 dhartmei Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.51 2003/03/31 13:15:27 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -80,7 +80,6 @@ struct pf_ruleset *pf_find_or_create_ruleset(char *, char *); void pf_remove_if_empty_ruleset(struct pf_ruleset *); void pf_mv_pool(struct pf_palist *, struct pf_palist *); void pf_empty_pool(struct pf_palist *); -void pf_rm_rule(struct pf_rulequeue *, struct pf_rule *); int pfioctl(dev_t, u_long, caddr_t, int, struct proc *); extern struct timeout pf_expire_to; @@ -362,13 +361,17 @@ pf_empty_pool(struct pf_palist *poola) void pf_rm_rule(struct pf_rulequeue *rulequeue, struct pf_rule *rule) { + if (rulequeue != NULL) { + TAILQ_REMOVE(rulequeue, rule, entries); + rule->entries.tqe_prev = NULL; + } + if (rule->states > 0 || rule->entries.tqe_prev != NULL) + return; pf_dynaddr_remove(&rule->src.addr); pf_dynaddr_remove(&rule->dst.addr); pf_tbladdr_remove(&rule->src.addr); pf_tbladdr_remove(&rule->dst.addr); pf_empty_pool(&rule->rpool.list); - if (rulequeue != NULL) - TAILQ_REMOVE(rulequeue, rule, entries); pool_put(&pf_rule_pl, rule); } @@ -535,6 +538,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) rule->anchor = NULL; rule->ifp = NULL; TAILQ_INIT(&rule->rpool.list); + /* initialize refcounting */ + rule->states = 0; + rule->entries.tqe_prev = NULL; #ifndef INET if (rule->af == AF_INET) { pool_put(&pf_rule_pl, rule); @@ -598,7 +604,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) struct pf_ruleset *ruleset; struct pf_rulequeue *old_rules; struct pf_rule *rule; - struct pf_tree_node *n; int rs_num; ruleset = pf_find_ruleset(pr->anchor, pr->ruleset); @@ -618,17 +623,6 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) /* Swap rules, keep the old. */ s = splsoftnet(); - /* - * Rules are about to get freed, clear rule pointers in states - */ - if (rs_num == PF_RULESET_FILTER) { - if (ruleset == &pf_main_ruleset) - RB_FOREACH(n, pf_state_tree, &tree_ext_gwy) - n->state->rule.ptr = NULL; - } else if ((rs_num == PF_RULESET_NAT) || - (rs_num == PF_RULESET_BINAT) || (rs_num == PF_RULESET_RDR)) - RB_FOREACH(n, pf_state_tree, &tree_ext_gwy) - n->state->nat_rule = NULL; old_rules = ruleset->rules[rs_num].active.ptr; ruleset->rules[rs_num].active.ptr = ruleset->rules[rs_num].inactive.ptr; @@ -767,6 +761,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } bcopy(&pcr->rule, newrule, sizeof(struct pf_rule)); TAILQ_INIT(&newrule->rpool.list); + /* initialize refcounting */ + newrule->states = 0; + newrule->entries.tqe_prev = NULL; #ifndef INET if (newrule->af == AF_INET) { pool_put(&pf_rule_pl, newrule); @@ -842,17 +839,9 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } - if (pcr->action == PF_CHANGE_REMOVE) { - struct pf_tree_node *n; - - RB_FOREACH(n, pf_state_tree, &tree_ext_gwy) { - if (n->state->rule.ptr == oldrule) - n->state->rule.ptr = NULL; - if (n->state->nat_rule == oldrule) - n->state->nat_rule = NULL; - } + if (pcr->action == PF_CHANGE_REMOVE) pf_rm_rule(ruleset->rules[rs_num].active.ptr, oldrule); - } else { + else { if (oldrule == NULL) TAILQ_INSERT_TAIL( ruleset->rules[rs_num].active.ptr, diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 25deb2de2a6..e7bb4ec08e5 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.136 2003/03/03 14:33:17 cedric Exp $ */ +/* $OpenBSD: pfvar.h,v 1.137 2003/03/31 13:15:27 cedric Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -975,6 +975,8 @@ extern struct ifnet *status_ifp; extern int *pftm_timeouts[PFTM_MAX]; extern void pf_addrcpy(struct pf_addr *, struct pf_addr *, u_int8_t); +void pf_rm_rule(struct pf_rulequeue *, + struct pf_rule *); #ifdef INET int pf_test(int, struct ifnet *, struct mbuf **); |