diff options
author | Mike Frantzen <frantzen@cvs.openbsd.org> | 2002-03-25 22:03:02 +0000 |
---|---|---|
committer | Mike Frantzen <frantzen@cvs.openbsd.org> | 2002-03-25 22:03:02 +0000 |
commit | 89db73fcfbfdf3a4b8dd0dc89403d028a8d26d6d (patch) | |
tree | 12500feb4890e55fe5c57e9df4745249d4c183b2 /sys/net | |
parent | 1004f5733a9c92f16ca07bfe7ba3b3fb5f6386f7 (diff) |
add ioctl DIOCKILLSTATES to shootdown a subset of the state table. allows
discrimination on src/dst ips and netmask, src/dst port range and protocol.
ok dhartmei@
Diffstat (limited to 'sys/net')
-rw-r--r-- | sys/net/pf.c | 37 | ||||
-rw-r--r-- | sys/net/pfvar.h | 11 |
2 files changed, 46 insertions, 2 deletions
diff --git a/sys/net/pf.c b/sys/net/pf.c index 244ce50686d..bfaad4e126c 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.194 2002/03/08 11:32:52 mpech Exp $ */ +/* $OpenBSD: pf.c,v 1.195 2002/03/25 22:03:01 frantzen Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -1968,6 +1968,41 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) break; } + case DIOCKILLSTATES: { + struct pf_tree_node *n; + struct pf_state *st; + struct pfioc_state_kill *psk = + (struct pfioc_state_kill *)addr; + int killed = 0; + + s = splsoftnet(); + for (n = pf_tree_first(tree_ext_gwy); n != NULL; + n = pf_tree_next(n)) { + st = n->state; + if ((!psk->psk_af || st->af == psk->psk_af) && + (!psk->psk_proto || psk->psk_proto == st->proto) && + PF_MATCHA(psk->psk_src.not, &psk->psk_src.addr, + &psk->psk_src.mask, &st->lan.addr, st->af) && + PF_MATCHA(psk->psk_dst.not, &psk->psk_dst.addr, + &psk->psk_dst.mask, &st->ext.addr, st->af) && + (psk->psk_src.port_op == 0 || + pf_match_port(psk->psk_src.port_op, + psk->psk_src.port[0], psk->psk_src.port[1], + st->lan.port)) && + (psk->psk_dst.port_op == 0 || + pf_match_port(psk->psk_dst.port_op, + psk->psk_dst.port[0], psk->psk_dst.port[1], + st->ext.port))) { + st->expire = 0; + killed++; + } + } + pf_purge_expired_states(); + splx(s); + psk->psk_af = killed; + break; + } + case DIOCADDSTATE: { struct pfioc_state *ps = (struct pfioc_state *)addr; struct pf_state *state; diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index 9cb88d8538a..051c40d2155 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.64 2002/02/26 07:25:33 dhartmei Exp $ */ +/* $OpenBSD: pfvar.h,v 1.65 2002/03/25 22:03:01 frantzen Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -495,6 +495,14 @@ struct pfioc_state { struct pf_state state; }; +struct pfioc_state_kill { + /* XXX returns the number of states killed in psk_af */ + int psk_af; + int psk_proto; + struct pf_rule_addr psk_src; + struct pf_rule_addr psk_dst; +}; + struct pfioc_states { int ps_len; union { @@ -563,6 +571,7 @@ struct pfioc_limit { #define DIOCCLRRULECTRS _IO ('D', 38) #define DIOCGETLIMIT _IOWR('D', 39, struct pfioc_limit) #define DIOCSETLIMIT _IOWR('D', 40, struct pfioc_limit) +#define DIOCKILLSTATES _IOWR('D', 41, struct pfioc_state_kill) #ifdef _KERNEL |