summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorMike Frantzen <frantzen@cvs.openbsd.org>2002-03-25 22:03:02 +0000
committerMike Frantzen <frantzen@cvs.openbsd.org>2002-03-25 22:03:02 +0000
commit89db73fcfbfdf3a4b8dd0dc89403d028a8d26d6d (patch)
tree12500feb4890e55fe5c57e9df4745249d4c183b2 /sys/net
parent1004f5733a9c92f16ca07bfe7ba3b3fb5f6386f7 (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.c37
-rw-r--r--sys/net/pfvar.h11
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