diff options
author | Henning Brauer <henning@cvs.openbsd.org> | 2003-04-11 14:40:58 +0000 |
---|---|---|
committer | Henning Brauer <henning@cvs.openbsd.org> | 2003-04-11 14:40:58 +0000 |
commit | 866fc69bd8f9208577b8ac2725d227b4ff30de41 (patch) | |
tree | 77641cece26b2bd658b6d33587e9a730c6b19f05 | |
parent | c341e62e40dcf89b30d4a2bcf64d515b776dee81 (diff) |
set/update the queue IDs on filter rules (qid and pqid) on
-DIOCCHANGERULE (just the affected rule)
-DIOCCOMMITRULES (all filter rules that get committed - one anchor or main rs)
-DIOCCOMMITALTQS (all filter rules, main set plus all anchors)
This fixes a whole bunch of issues.
previously, this was done in userland at load time. This worked fine for the
usual case, full ruleset load. It did not work inside anchors, as the queue
name <-> queue ID mapping is unknown there. Also, if the queue definitions
were changed without reloading the rules too (pfctl -A), the queue IDs on
the rules were not updated.
The three ioctls mentioned above are all entry points where the mapping is
touched.
helpful discussion with dhartmei@ and cedric@ helped verifying my approach
for this fix was right.
ok dhartmei@ cedric@
-rw-r--r-- | sys/net/pf.c | 31 | ||||
-rw-r--r-- | sys/net/pf_ioctl.c | 32 | ||||
-rw-r--r-- | sys/net/pfvar.h | 4 |
3 files changed, 64 insertions, 3 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index 083975704f4..a735b475f4f 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.336 2003/04/09 18:21:58 henning Exp $ */ +/* $OpenBSD: pf.c,v 1.337 2003/04/11 14:40:57 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -180,6 +180,8 @@ int pf_test_state_other(struct pf_state **, int, void *pf_pull_hdr(struct mbuf *, int, void *, int, u_short *, u_short *, sa_family_t); void pf_calc_skip_steps(struct pf_rulequeue *); +void pf_rule_set_qid(struct pf_rulequeue *); +u_int32_t pf_qname_to_qid(char *); #ifdef INET6 void pf_poolmask(struct pf_addr *, struct pf_addr*, @@ -806,6 +808,33 @@ pf_calc_skip_steps(struct pf_rulequeue *rules) } void +pf_rule_set_qid(struct pf_rulequeue *rules) +{ + struct pf_rule *rule; + + TAILQ_FOREACH(rule, rules, entries) + if (rule->qname[0] != 0) { + rule->qid = pf_qname_to_qid(rule->qname); + if (rule->pqname[0] != 0) + rule->pqid = pf_qname_to_qid(rule->pqname); + else + rule->pqid = rule->qid; + } +} + +u_int32_t +pf_qname_to_qid(char *qname) +{ + struct pf_altq *altq; + + TAILQ_FOREACH(altq, pf_altqs_active, entries) + if (!strcmp(altq->qname, qname)) + return (altq->qid); + + return (0); +} + +void pf_update_anchor_rules() { struct pf_rule *rule; diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c index 528161a68f0..da941a94575 100644 --- a/sys/net/pf_ioctl.c +++ b/sys/net/pf_ioctl.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf_ioctl.c,v 1.57 2003/04/09 15:32:59 cedric Exp $ */ +/* $OpenBSD: pf_ioctl.c,v 1.58 2003/04/11 14:40:57 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -654,6 +654,12 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } +#ifdef ALTQ + /* set queue IDs */ + if (rs_num == PF_RULESET_FILTER) + pf_rule_set_qid(ruleset->rules[rs_num].inactive.ptr); +#endif + /* Swap rules, keep the old. */ s = splsoftnet(); old_rules = ruleset->rules[rs_num].active.ptr; @@ -825,6 +831,17 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } else newrule->ifp = NULL; +#ifdef ALTQ + /* set queue IDs */ + if (newrule->qname[0] != 0) { + newrule->qid = pf_qname_to_qid(newrule->qname); + if (newrule->pqname[0] != 0) + newrule->pqid = + pf_qname_to_qid(newrule->pqname); + else + newrule->pqid = newrule->qid; + } +#endif if (newrule->rt && !newrule->direction) error = EINVAL; if (pf_dynaddr_setup(&newrule->src.addr, newrule->af)) @@ -1361,6 +1378,8 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) u_int32_t *ticket = (u_int32_t *)addr; struct pf_altqqueue *old_altqs; struct pf_altq *altq; + struct pf_anchor *anchor; + struct pf_ruleset *ruleset; int err; if (*ticket != ticket_altqs_inactive) { @@ -1402,6 +1421,17 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) pool_put(&pf_altq_pl, altq); } splx(s); + + /* update queue IDs */ + pf_rule_set_qid( + pf_main_ruleset.rules[PF_RULESET_FILTER].active.ptr); + TAILQ_FOREACH(anchor, &pf_anchors, entries) { + TAILQ_FOREACH(ruleset, &anchor->rulesets, entries) { + pf_rule_set_qid( + ruleset->rules[PF_RULESET_FILTER].active.ptr + ); + } + } break; } diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 6bbf3182de8..c732bdf4174 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.139 2003/04/09 15:32:59 cedric Exp $ */ +/* $OpenBSD: pfvar.h,v 1.140 2003/04/11 14:40:57 henning Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -961,6 +961,8 @@ extern int pf_dynaddr_setup(struct pf_addr_wrap *, extern void pf_dynaddr_copyout(struct pf_addr_wrap *); extern void pf_dynaddr_remove(struct pf_addr_wrap *); extern void pf_calc_skip_steps(struct pf_rulequeue *); +extern void pf_rule_set_qid(struct pf_rulequeue *); +extern u_int32_t pf_qname_to_qid(char *); extern void pf_update_anchor_rules(void); extern struct pool pf_tree_pl, pf_rule_pl, pf_addr_pl; extern struct pool pf_state_pl, pf_altq_pl, pf_pooladdr_pl; |