summaryrefslogtreecommitdiff
path: root/sys/netinet/in_pcb.c
diff options
context:
space:
mode:
authorAlexander Bluhm <bluhm@cvs.openbsd.org>2011-04-24 19:36:55 +0000
committerAlexander Bluhm <bluhm@cvs.openbsd.org>2011-04-24 19:36:55 +0000
commitccf01298eb370933be2f6386e5502f7f812047bc (patch)
tree08626863187ebafa510ae55a9c551d731cd4bf76 /sys/netinet/in_pcb.c
parent7b1ea8a3a89e1966e6de0290fc2ecd008d8f4128 (diff)
Double link between pf states and sockets. Henning has already
implemented half of it. The additional part is: - The pf state lookup for outgoing packets is optimized by using mbuf->inp->state. - For incomming tcp, udp, raw, raw6 packets the socket lookup always is optimized by using mbuf->state->inp. - All protocols establish the link for incomming packets. - All protocols set the inp in the mbuf for outgoing packets. This allows the linkage beginning with the first packet for outgoing connections. - In case of divert states, delete the state when the socket closes. Otherwise new connections could match on old states instead of being diverted to the listen socket. ok henning@
Diffstat (limited to 'sys/netinet/in_pcb.c')
-rw-r--r--sys/netinet/in_pcb.c21
1 files changed, 18 insertions, 3 deletions
diff --git a/sys/netinet/in_pcb.c b/sys/netinet/in_pcb.c
index c9981fcc442..b372fdcecc9 100644
--- a/sys/netinet/in_pcb.c
+++ b/sys/netinet/in_pcb.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: in_pcb.c,v 1.116 2011/04/19 03:47:29 dlg Exp $ */
+/* $OpenBSD: in_pcb.c,v 1.117 2011/04/24 19:36:54 bluhm Exp $ */
/* $NetBSD: in_pcb.c,v 1.25 1996/02/13 23:41:53 christos Exp $ */
/*
@@ -509,8 +509,23 @@ in_pcbdetach(v)
splx(s);
#endif
#if NPF > 0
- if (inp->inp_pf_sk)
- ((struct pf_state_key *)inp->inp_pf_sk)->inp = NULL;
+ if (inp->inp_pf_sk) {
+ struct pf_state_key *sk;
+ struct pf_state_item *si;
+
+ s = splsoftnet();
+ sk = (struct pf_state_key *)inp->inp_pf_sk;
+ TAILQ_FOREACH(si, &sk->states, entry)
+ if (sk == si->s->key[PF_SK_STACK] && si->s->rule.ptr &&
+ si->s->rule.ptr->divert.port) {
+ pf_unlink_state(si->s);
+ break;
+ }
+ /* pf_unlink_state() may have detached the state */
+ if (inp->inp_pf_sk)
+ ((struct pf_state_key *)inp->inp_pf_sk)->inp = NULL;
+ splx(s);
+ }
#endif
s = splnet();
LIST_REMOVE(inp, inp_lhash);