Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/net/npf - Add npf_tcpfl2case() and make TCP state table ...
details: https://anonhg.NetBSD.org/src/rev/be38087a1ac1
branches: trunk
changeset: 771874:be38087a1ac1
user: rmind <rmind%NetBSD.org@localhost>
date: Mon Dec 05 00:34:25 2011 +0000
description:
- Add npf_tcpfl2case() and make TCP state table more compact.
- Adjust the state for FIN case on sim-SYN and SYN-RECEIVED.
diffstat:
sys/net/npf/npf_state_tcp.c | 130 ++++++++++++++++++++++++-------------------
1 files changed, 72 insertions(+), 58 deletions(-)
diffs (266 lines):
diff -r d51e4e7dc6ad -r be38087a1ac1 sys/net/npf/npf_state_tcp.c
--- a/sys/net/npf/npf_state_tcp.c Mon Dec 05 00:13:30 2011 +0000
+++ b/sys/net/npf/npf_state_tcp.c Mon Dec 05 00:34:25 2011 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: npf_state_tcp.c,v 1.1 2011/11/29 20:05:30 rmind Exp $ */
+/* $NetBSD: npf_state_tcp.c,v 1.2 2011/12/05 00:34:25 rmind Exp $ */
/*-
* Copyright (c) 2010-2011 The NetBSD Foundation, Inc.
@@ -34,7 +34,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.1 2011/11/29 20:05:30 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: npf_state_tcp.c,v 1.2 2011/12/05 00:34:25 rmind Exp $");
#include <sys/param.h>
#include <sys/types.h>
@@ -79,7 +79,7 @@
/*
* TCP connection timeout table (in seconds).
*/
-static const u_int npf_tcp_timeouts[] __read_mostly = {
+static u_int npf_tcp_timeouts[] __read_mostly = {
/* Closed, timeout nearly immediately. */
[NPF_TCPS_CLOSED] = 10,
/* Unsynchronised states. */
@@ -99,71 +99,92 @@
#define NPF_TCP_MAXACKWIN 66000
-#define TH_STATE_MASK (TH_SYN | TH_ACK | TH_FIN)
-#define TH_SYNACK (TH_SYN | TH_ACK)
-#define TH_FINACK (TH_FIN | TH_ACK)
+/*
+ * List of TCP flag cases and conversion of flags to a case (index).
+ */
+
+#define TCPFC_INVALID 0
+#define TCPFC_SYN 1
+#define TCPFC_SYNACK 2
+#define TCPFC_ACK 3
+#define TCPFC_FIN 4
+#define TCPFC_COUNT 5
+
+static inline u_int
+npf_tcpfl2case(const int tcpfl)
+{
+ u_int i, c;
+
+ /*
+ * Magic value maps flag combinations to TCPFC case numbers.
+ * Other cases are zero. Note: FIN-ACK is mapped to FIN.
+ */
+ i = (tcpfl & (TH_SYN | TH_FIN)) | ((tcpfl & TH_ACK) >> 2);
+ c = (0x2430140 >> (i << 2)) & 7;
+
+ KASSERT(c < TCPFC_COUNT);
+ return c;
+}
/*
* NPF transition table of a tracked TCP connection.
*
* There is a single state, which is changed in the following way:
*
- * new_state = npf_tcp_fsm[old_state][direction][tcp_flags & TH_STATE_MASK];
+ * new_state = npf_tcp_fsm[old_state][direction][npf_tcpfl2case(tcp_flags)];
*
* Note that this state is different from the state in each end (host).
*/
-static const int npf_tcp_fsm[NPF_TCP_NSTATES][2][TH_STATE_MASK + 1]
- __read_mostly = {
+static const int npf_tcp_fsm[NPF_TCP_NSTATES][2][TCPFC_COUNT] = {
[NPF_TCPS_CLOSED] = {
[NPF_FLOW_FORW] = {
/* Handshake (1): initial SYN. */
- [TH_SYN] = NPF_TCPS_SYN_SENT,
+ [TCPFC_SYN] = NPF_TCPS_SYN_SENT,
},
},
[NPF_TCPS_SYN_SENT] = {
[NPF_FLOW_FORW] = {
/* SYN may be retransmitted. */
- [TH_SYN] = NPF_TCPS_OK,
+ [TCPFC_SYN] = NPF_TCPS_OK,
},
[NPF_FLOW_BACK] = {
/* Handshake (2): SYN-ACK is expected. */
- [TH_SYNACK] = NPF_TCPS_SYN_RECEIVED,
+ [TCPFC_SYNACK] = NPF_TCPS_SYN_RECEIVED,
/* Simultaneous initiation - SYN. */
- [TH_SYN] = NPF_TCPS_SIMSYN_SENT,
+ [TCPFC_SYN] = NPF_TCPS_SIMSYN_SENT,
},
},
[NPF_TCPS_SIMSYN_SENT] = {
[NPF_FLOW_FORW] = {
/* Original SYN re-transmission. */
- [TH_SYN] = NPF_TCPS_OK,
+ [TCPFC_SYN] = NPF_TCPS_OK,
/* SYN-ACK response to simultaneous SYN. */
- [TH_SYNACK] = NPF_TCPS_SYN_RECEIVED,
+ [TCPFC_SYNACK] = NPF_TCPS_SYN_RECEIVED,
},
[NPF_FLOW_BACK] = {
/* Simultaneous SYN re-transmission.*/
- [TH_SYN] = NPF_TCPS_OK,
+ [TCPFC_SYN] = NPF_TCPS_OK,
/* SYN-ACK response to original SYN. */
- [TH_SYNACK] = NPF_TCPS_SYN_RECEIVED,
- /* FIN may be sent at this point. */
- [TH_FIN] = NPF_TCPS_FIN_SEEN,
- [TH_FINACK] = NPF_TCPS_FIN_SEEN,
+ [TCPFC_SYNACK] = NPF_TCPS_SYN_RECEIVED,
+ /* FIN may be sent early. */
+ [TCPFC_FIN] = NPF_TCPS_FIN_SEEN,
},
},
[NPF_TCPS_SYN_RECEIVED] = {
[NPF_FLOW_FORW] = {
/* Handshake (3): ACK is expected. */
- [TH_ACK] = NPF_TCPS_ESTABLISHED,
- [TH_FIN] = NPF_TCPS_CLOSING,
- [TH_FINACK] = NPF_TCPS_CLOSING,
+ [TCPFC_ACK] = NPF_TCPS_ESTABLISHED,
+ /* FIN may be sent early. */
+ [TCPFC_FIN] = NPF_TCPS_FIN_SEEN,
},
[NPF_FLOW_BACK] = {
/* SYN-ACK may be retransmitted. */
- [TH_SYNACK] = NPF_TCPS_OK,
+ [TCPFC_SYNACK] = NPF_TCPS_OK,
/* XXX: ACK of late SYN in simultaneous case? */
- [TH_ACK] = NPF_TCPS_OK,
- /* XXX: Can this happen?
- [TH_FIN] = NPF_TCPS_CLOSING, */
+ [TCPFC_ACK] = NPF_TCPS_OK,
+ /* FIN may be sent early. */
+ [TCPFC_FIN] = NPF_TCPS_FIN_SEEN,
},
},
[NPF_TCPS_ESTABLISHED] = {
@@ -172,16 +193,14 @@
* FIN packets may have ACK set.
*/
[NPF_FLOW_FORW] = {
- [TH_ACK] = NPF_TCPS_OK,
+ [TCPFC_ACK] = NPF_TCPS_OK,
/* FIN by the sender. */
- [TH_FIN] = NPF_TCPS_FIN_SEEN,
- [TH_FINACK] = NPF_TCPS_FIN_SEEN,
+ [TCPFC_FIN] = NPF_TCPS_FIN_SEEN,
},
[NPF_FLOW_BACK] = {
- [TH_ACK] = NPF_TCPS_OK,
+ [TCPFC_ACK] = NPF_TCPS_OK,
/* FIN by the receiver. */
- [TH_FIN] = NPF_TCPS_FIN_SEEN,
- [TH_FINACK] = NPF_TCPS_FIN_SEEN,
+ [TCPFC_FIN] = NPF_TCPS_FIN_SEEN,
},
},
[NPF_TCPS_FIN_SEEN] = {
@@ -192,64 +211,58 @@
* case we are closing immediately.
*/
[NPF_FLOW_FORW] = {
- [TH_ACK] = NPF_TCPS_CLOSE_WAIT,
- [TH_FIN] = NPF_TCPS_CLOSING,
- [TH_FINACK] = NPF_TCPS_CLOSING,
+ [TCPFC_ACK] = NPF_TCPS_CLOSE_WAIT,
+ [TCPFC_FIN] = NPF_TCPS_CLOSING,
},
[NPF_FLOW_BACK] = {
- [TH_ACK] = NPF_TCPS_FIN_WAIT,
- [TH_FIN] = NPF_TCPS_CLOSING,
- [TH_FINACK] = NPF_TCPS_CLOSING,
+ [TCPFC_ACK] = NPF_TCPS_FIN_WAIT,
+ [TCPFC_FIN] = NPF_TCPS_CLOSING,
},
},
[NPF_TCPS_CLOSE_WAIT] = {
/* Sender has sent the FIN and closed its end. */
[NPF_FLOW_FORW] = {
- [TH_ACK] = NPF_TCPS_OK,
- [TH_FIN] = NPF_TCPS_LAST_ACK,
- [TH_FINACK] = NPF_TCPS_LAST_ACK,
+ [TCPFC_ACK] = NPF_TCPS_OK,
+ [TCPFC_FIN] = NPF_TCPS_LAST_ACK,
},
[NPF_FLOW_BACK] = {
- [TH_ACK] = NPF_TCPS_OK,
- [TH_FIN] = NPF_TCPS_LAST_ACK,
- [TH_FINACK] = NPF_TCPS_LAST_ACK,
+ [TCPFC_ACK] = NPF_TCPS_OK,
+ [TCPFC_FIN] = NPF_TCPS_LAST_ACK,
},
},
[NPF_TCPS_FIN_WAIT] = {
/* Receiver has closed its end. */
[NPF_FLOW_FORW] = {
- [TH_ACK] = NPF_TCPS_OK,
- [TH_FIN] = NPF_TCPS_LAST_ACK,
- [TH_FINACK] = NPF_TCPS_LAST_ACK,
+ [TCPFC_ACK] = NPF_TCPS_OK,
+ [TCPFC_FIN] = NPF_TCPS_LAST_ACK,
},
[NPF_FLOW_BACK] = {
- [TH_ACK] = NPF_TCPS_OK,
- [TH_FIN] = NPF_TCPS_LAST_ACK,
- [TH_FINACK] = NPF_TCPS_LAST_ACK,
+ [TCPFC_ACK] = NPF_TCPS_OK,
+ [TCPFC_FIN] = NPF_TCPS_LAST_ACK,
},
},
[NPF_TCPS_CLOSING] = {
/* Race of FINs - expecting ACK. */
[NPF_FLOW_FORW] = {
- [TH_ACK] = NPF_TCPS_LAST_ACK,
+ [TCPFC_ACK] = NPF_TCPS_LAST_ACK,
},
[NPF_FLOW_BACK] = {
- [TH_ACK] = NPF_TCPS_LAST_ACK,
+ [TCPFC_ACK] = NPF_TCPS_LAST_ACK,
},
},
[NPF_TCPS_LAST_ACK] = {
/* FINs exchanged - expecting last ACK. */
[NPF_FLOW_FORW] = {
- [TH_ACK] = NPF_TCPS_TIME_WAIT,
+ [TCPFC_ACK] = NPF_TCPS_TIME_WAIT,
},
[NPF_FLOW_BACK] = {
- [TH_ACK] = NPF_TCPS_TIME_WAIT,
+ [TCPFC_ACK] = NPF_TCPS_TIME_WAIT,
},
},
[NPF_TCPS_TIME_WAIT] = {
/* May re-open the connection as per RFC 1122. */
[NPF_FLOW_FORW] = {
- [TH_SYN] = NPF_TCPS_SYN_SENT,
+ [TCPFC_SYN] = NPF_TCPS_SYN_SENT,
},
},
};
@@ -280,7 +293,7 @@
*
* There four boundaries are defined as following:
* I) SEQ + LEN <= MAX { SND.ACK + MAX(SND.WIN, 1) }
- * II) SEQ >= MAX { SND.SEQ + SND.LEN }
+ * II) SEQ >= MAX { SND.SEQ + SND.LEN - MAX(RCV.WIN, 1) }
* III) ACK <= MAX { RCV.SEQ + RCV.LEN }
* IV) ACK >= MAX { RCV.SEQ + RCV.LEN } - MAXACKWIN
*
@@ -427,7 +440,8 @@
/* Look for a transition to a new state. */
if (__predict_true((tcpfl & TH_RST) == 0)) {
- nstate = npf_tcp_fsm[state][di][tcpfl & TH_STATE_MASK];
+ const int flagcase = npf_tcpfl2case(tcpfl);
+ nstate = npf_tcp_fsm[state][di][flagcase];
} else if (state == NPF_TCPS_TIME_WAIT) {
/* Prevent TIME-WAIT assassination (RFC 1337). */
nstate = NPF_TCPS_OK;
Home |
Main Index |
Thread Index |
Old Index