diff options
author | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2011-04-24 19:36:55 +0000 |
---|---|---|
committer | Alexander Bluhm <bluhm@cvs.openbsd.org> | 2011-04-24 19:36:55 +0000 |
commit | ccf01298eb370933be2f6386e5502f7f812047bc (patch) | |
tree | 08626863187ebafa510ae55a9c551d731cd4bf76 /sys/netinet/in_pcb.c | |
parent | 7b1ea8a3a89e1966e6de0290fc2ecd008d8f4128 (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.c | 21 |
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); |