summaryrefslogtreecommitdiff
path: root/sys/net/pf_ioctl.c
diff options
context:
space:
mode:
authorRyan Thomas McBride <mcbride@cvs.openbsd.org>2008-06-29 08:42:16 +0000
committerRyan Thomas McBride <mcbride@cvs.openbsd.org>2008-06-29 08:42:16 +0000
commit99e04e378e33075d748641da5140863b7b7f982d (patch)
treeae0b5cd3428dd52812e443fd85393c2d10f690e5 /sys/net/pf_ioctl.c
parent5e873aaaca6fb4b1a29dc92c01173dbf221481c3 (diff)
Simplify state creation code; merge state import/export code between pfsync
and the state-related pf(4) ioctls, and make functions in state creation and destruction paths more robust in error conditions. All values in struct pfsync_state now in network byte order, as with pfsync. testing by david ok henning, systat parts ok canacar
Diffstat (limited to 'sys/net/pf_ioctl.c')
-rw-r--r--sys/net/pf_ioctl.c148
1 files changed, 4 insertions, 144 deletions
diff --git a/sys/net/pf_ioctl.c b/sys/net/pf_ioctl.c
index 733ce7ffde7..4c1e18c89d6 100644
--- a/sys/net/pf_ioctl.c
+++ b/sys/net/pf_ioctl.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: pf_ioctl.c,v 1.208 2008/06/22 13:01:33 mcbride Exp $ */
+/* $OpenBSD: pf_ioctl.c,v 1.209 2008/06/29 08:42:15 mcbride Exp $ */
/*
* Copyright (c) 2001 Daniel Hartmeier
@@ -110,11 +110,6 @@ int pf_setup_pfsync_matching(struct pf_ruleset *);
void pf_hash_rule(MD5_CTX *, struct pf_rule *);
void pf_hash_rule_addr(MD5_CTX *, struct pf_rule_addr *);
int pf_commit_rules(u_int32_t, int, char *);
-void pf_state_export(struct pfsync_state *,
- struct pf_state *);
-void pf_state_import(struct pfsync_state *,
- struct pf_state_key *,
- struct pf_state_key *, struct pf_state *);
int pf_addr_setup(struct pf_ruleset *,
struct pf_addr_wrap *, sa_family_t);
void pf_addr_copyout(struct pf_addr_wrap *);
@@ -848,97 +843,6 @@ pf_commit_rules(u_int32_t ticket, int rs_num, char *anchor)
return (0);
}
-void
-pf_state_export(struct pfsync_state *sp, struct pf_state *s)
-{
- int secs = time_second;
- bzero(sp, sizeof(struct pfsync_state));
-
- /* copy from state key */
- sp->key[PF_SK_WIRE].addr[0] = s->key[PF_SK_WIRE]->addr[0];
- sp->key[PF_SK_WIRE].addr[1] = s->key[PF_SK_WIRE]->addr[1];
- sp->key[PF_SK_WIRE].port[0] = s->key[PF_SK_WIRE]->port[0];
- sp->key[PF_SK_WIRE].port[1] = s->key[PF_SK_WIRE]->port[1];
- sp->key[PF_SK_STACK].addr[0] = s->key[PF_SK_STACK]->addr[0];
- sp->key[PF_SK_STACK].addr[1] = s->key[PF_SK_STACK]->addr[1];
- sp->key[PF_SK_STACK].port[0] = s->key[PF_SK_STACK]->port[0];
- sp->key[PF_SK_STACK].port[1] = s->key[PF_SK_STACK]->port[1];
- sp->proto = s->key[PF_SK_WIRE]->proto;
- sp->af = s->key[PF_SK_WIRE]->af;
- sp->direction = s->direction;
-
- /* copy from state */
- memcpy(&sp->id, &s->id, sizeof(sp->id));
- sp->creatorid = s->creatorid;
- strlcpy(sp->ifname, s->kif->pfik_name, sizeof(sp->ifname));
- pf_state_peer_to_pfsync(&s->src, &sp->src);
- pf_state_peer_to_pfsync(&s->dst, &sp->dst);
-
- sp->rule = s->rule.ptr->nr;
- sp->nat_rule = (s->nat_rule.ptr == NULL) ? -1 : s->nat_rule.ptr->nr;
- sp->anchor = (s->anchor.ptr == NULL) ? -1 : s->anchor.ptr->nr;
-
- pf_state_counter_to_pfsync(s->bytes[0], sp->bytes[0]);
- pf_state_counter_to_pfsync(s->bytes[1], sp->bytes[1]);
- pf_state_counter_to_pfsync(s->packets[0], sp->packets[0]);
- pf_state_counter_to_pfsync(s->packets[1], sp->packets[1]);
- sp->creation = secs - s->creation;
- sp->expire = pf_state_expires(s);
- sp->log = s->log;
- sp->state_flags = s->state_flags;
- sp->timeout = s->timeout;
-
- if (s->src_node)
- sp->sync_flags |= PFSYNC_FLAG_SRCNODE;
- if (s->nat_src_node)
- sp->sync_flags |= PFSYNC_FLAG_NATSRCNODE;
-
- if (sp->expire > secs)
- sp->expire -= secs;
- else
- sp->expire = 0;
-
-}
-
-void
-pf_state_import(struct pfsync_state *sp, struct pf_state_key *skw,
- struct pf_state_key *sks, struct pf_state *s)
-{
- /* copy to state key(s) */
- skw->addr[0] = sp->key[PF_SK_WIRE].addr[0];
- skw->addr[1] = sp->key[PF_SK_WIRE].addr[1];
- skw->port[0] = sp->key[PF_SK_WIRE].port[0];
- skw->port[1] = sp->key[PF_SK_WIRE].port[1];
- skw->proto = sp->proto;
- skw->af = sp->af;
- if (sks != skw) {
- sks->addr[0] = sp->key[PF_SK_STACK].addr[0];
- sks->addr[1] = sp->key[PF_SK_STACK].addr[1];
- sks->port[0] = sp->key[PF_SK_STACK].port[0];
- sks->port[1] = sp->key[PF_SK_STACK].port[1];
- sks->proto = sp->proto;
- sks->af = sp->af;
- }
- /* copy to state */
- memcpy(&s->id, &sp->id, sizeof(sp->id));
- s->creatorid = sp->creatorid;
- pf_state_peer_from_pfsync(&sp->src, &s->src);
- pf_state_peer_from_pfsync(&sp->dst, &s->dst);
-
- s->direction = sp->direction;
- s->rule.ptr = &pf_default_rule;
- s->nat_rule.ptr = NULL;
- s->anchor.ptr = NULL;
- s->rt_kif = NULL;
- s->creation = time_second;
- s->expire = time_second;
- if (sp->expire > 0)
- s->expire -= pf_default_rule.timeout[sp->timeout] - sp->expire;
- s->pfsync_time = 0;
- s->packets[0] = s->packets[1] = 0;
- s->bytes[0] = s->bytes[1] = 0;
-}
-
int
pf_setup_pfsync_matching(struct pf_ruleset *rs)
{
@@ -1678,57 +1582,13 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
case DIOCADDSTATE: {
struct pfioc_state *ps = (struct pfioc_state *)addr;
struct pfsync_state *sp = &ps->state;
- struct pf_state *s;
- struct pf_state_key *skw, *sks;
- struct pfi_kif *kif;
if (sp->timeout >= PFTM_MAX &&
sp->timeout != PFTM_UNTIL_PACKET) {
error = EINVAL;
break;
}
- s = pool_get(&pf_state_pl, PR_WAITOK | PR_LIMITFAIL | PR_ZERO);
- if (s == NULL) {
- error = ENOMEM;
- break;
- }
- if ((skw = pf_alloc_state_key()) == NULL) {
- pool_put(&pf_state_pl, s);
- error = ENOMEM;
- break;
- }
- if ((PF_ANEQ(&sp->key[PF_SK_WIRE].addr[0],
- &sp->key[PF_SK_STACK].addr[0], sp->af) ||
- PF_ANEQ(&sp->key[PF_SK_WIRE].addr[1],
- &sp->key[PF_SK_STACK].addr[1], sp->af) ||
- sp->key[PF_SK_WIRE].port[0] !=
- sp->key[PF_SK_STACK].port[0] ||
- sp->key[PF_SK_WIRE].port[1] !=
- sp->key[PF_SK_STACK].port[1]) &&
- (sks = pf_alloc_state_key()) == NULL) {
- pool_put(&pf_state_pl, s);
- pool_put(&pf_state_key_pl, skw);
- error = ENOMEM;
- break;
- } else
- sks = skw;
- pf_state_import(sp, skw, sks, s);
- kif = pfi_kif_get(sp->ifname);
- if (kif == NULL) {
- pool_put(&pf_state_pl, s);
- pool_put(&pf_state_key_pl, skw);
- if (skw != sks)
- pool_put(&pf_state_key_pl, sks);
- error = ENOENT;
- break;
- }
- if (pf_state_insert(kif, skw, sks, s)) {
- pfi_kif_unref(kif, PFI_KIF_REF_NONE);
- pool_put(&pf_state_pl, s);
- error = EEXIST;
- break;
- }
- pf_default_rule.states_cur++;
+ error = pfsync_state_import(sp, PFSYNC_SI_IOCTL);
break;
}
@@ -1746,7 +1606,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
break;
}
- pf_state_export(&ps->state, s);
+ pfsync_state_export(&ps->state, s);
break;
}
@@ -1771,7 +1631,7 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p)
if (state->timeout != PFTM_UNLINKED) {
if ((nr+1) * sizeof(*p) > (unsigned)ps->ps_len)
break;
- pf_state_export(pstore, state);
+ pfsync_state_export(pstore, state);
error = copyout(pstore, p, sizeof(*p));
if (error) {
free(pstore, M_TEMP);