diff options
author | Klement Sekera <ksekera@cisco.com> | 2022-01-10 21:57:27 +0000 |
---|---|---|
committer | Ole Tr�an <otroan@employees.org> | 2022-01-24 12:59:46 +0000 |
commit | 56c492aa0502751de2dd9d890096a82c5f04776d (patch) | |
tree | a2b8a1c300853070b26f9953a10bd1a4e41f3bdd /src/plugins/nat/nat44-ed/nat44_ed.h | |
parent | 4634d02501235d3803a17839eeaf076110abcb18 (diff) |
nat: TCP state tracking based on RFC 7857/RFC 6146
Implement proper state machine based on above RFCs. ACKs to SYNs/FINs
are no longer required/tracked. This is more friendly to peers and
accounts for lost packets and retransmits.
This change also means that all traffic is translated and forwarded
while in transitory timeout, which helps delivering e.g. retransmitted
FINs, FINACKs and other messages.
Also support reopening a session in transitory timeout after seeing both
FINs by seeing both SYNs again. This helps quick connection
reestablishment if the peers want to.
Type: improvement
Signed-off-by: Klement Sekera <ksekera@cisco.com>
Signed-off-by: Miklos Tirpak <miklos.tirpak@gmail.com>
Change-Id: Ibf521c79463472db97e593bfa02b32b4a06dfd2a
Diffstat (limited to 'src/plugins/nat/nat44-ed/nat44_ed.h')
-rw-r--r-- | src/plugins/nat/nat44-ed/nat44_ed.h | 88 |
1 files changed, 46 insertions, 42 deletions
diff --git a/src/plugins/nat/nat44-ed/nat44_ed.h b/src/plugins/nat/nat44-ed/nat44_ed.h index 9772f1ec79a..0706785514b 100644 --- a/src/plugins/nat/nat44-ed/nat44_ed.h +++ b/src/plugins/nat/nat44-ed/nat44_ed.h @@ -105,33 +105,12 @@ typedef enum #undef _ } nat_addr_and_port_alloc_alg_t; -/* Session state */ -#define foreach_snat_session_state \ - _(0, UNKNOWN, "unknown") \ - _(1, UDP_ACTIVE, "udp-active") \ - _(2, TCP_SYN_SENT, "tcp-syn-sent") \ - _(3, TCP_ESTABLISHED, "tcp-established") \ - _(4, TCP_FIN_WAIT, "tcp-fin-wait") \ - _(5, TCP_CLOSE_WAIT, "tcp-close-wait") \ - _(6, TCP_CLOSING, "tcp-closing") \ - _(7, TCP_LAST_ACK, "tcp-last-ack") \ - _(8, TCP_CLOSED, "tcp-closed") \ - _(9, ICMP_ACTIVE, "icmp-active") - -typedef enum -{ -#define _(v, N, s) SNAT_SESSION_##N = v, - foreach_snat_session_state -#undef _ -} snat_session_state_t; - #define foreach_nat_in2out_ed_error \ _ (UNSUPPORTED_PROTOCOL, "unsupported protocol") \ _ (OUT_OF_PORTS, "out of ports") \ _ (BAD_ICMP_TYPE, "unsupported ICMP type") \ _ (MAX_SESSIONS_EXCEEDED, "maximum sessions exceeded") \ _ (NON_SYN, "non-SYN packet try to create session") \ - _ (TCP_CLOSED, "drops due to TCP in transitory timeout") \ _ (TRNSL_FAILED, "couldn't translate packet") typedef enum @@ -161,15 +140,43 @@ typedef enum NAT_OUT2IN_ED_N_ERROR, } nat_out2in_ed_error_t; +typedef enum +{ + NAT44_ED_TCP_FLAG_NONE = 0, + NAT44_ED_TCP_FLAG_FIN, + NAT44_ED_TCP_FLAG_SYN, + NAT44_ED_TCP_FLAG_SYNFIN, + NAT44_ED_TCP_FLAG_RST, + NAT44_ED_TCP_FLAG_FINRST, + NAT44_ED_TCP_FLAG_SYNRST, + NAT44_ED_TCP_FLAG_SYNFINRST, + NAT44_ED_TCP_N_FLAG, +} nat44_ed_tcp_flag_e; + +typedef enum +{ + NAT44_ED_DIR_I2O = 0, + NAT44_ED_DIR_O2I, + NAT44_ED_N_DIR, +} nat44_ed_dir_e; /* Endpoint dependent TCP session state */ -#define NAT44_SES_I2O_FIN 1 -#define NAT44_SES_O2I_FIN 2 -#define NAT44_SES_I2O_FIN_ACK 4 -#define NAT44_SES_O2I_FIN_ACK 8 -#define NAT44_SES_I2O_SYN 16 -#define NAT44_SES_O2I_SYN 32 -#define NAT44_SES_RST 64 +typedef enum +{ + NAT44_ED_TCP_STATE_CLOSED = 0, + NAT44_ED_TCP_STATE_SYN_I2O, + NAT44_ED_TCP_STATE_SYN_O2I, + NAT44_ED_TCP_STATE_ESTABLISHED, + NAT44_ED_TCP_STATE_FIN_I2O, + NAT44_ED_TCP_STATE_FIN_O2I, + NAT44_ED_TCP_STATE_RST_TRANS, + NAT44_ED_TCP_STATE_FIN_TRANS, + NAT44_ED_TCP_STATE_FIN_REOPEN_SYN_I2O, + NAT44_ED_TCP_STATE_FIN_REOPEN_SYN_O2I, + NAT44_ED_TCP_N_STATE, +} nat44_ed_tcp_state_e; + +format_function_t format_nat44_ed_tcp_state; /* Session flags */ #define SNAT_SESSION_FLAG_STATIC_MAPPING (1 << 0) @@ -341,10 +348,7 @@ typedef CLIB_PACKED(struct u16 ext_host_nat_port; /* TCP session state */ - u8 state; - u32 i2o_fin_seq; - u32 o2i_fin_seq; - u64 tcp_closed_timestamp; + nat44_ed_tcp_state_e tcp_state; /* per vrf sessions index */ u32 per_vrf_sessions_index; @@ -668,6 +672,16 @@ typedef struct snat_main_s vnet_main_t *vnet_main; + /* TCP session state machine table: + * first dimension is possible states + * second dimension is direction (in2out/out2in) + * third dimension is TCP flag (SYN, RST, FIN) + * + * value is next state to change to + */ + nat44_ed_tcp_state_e tcp_state_change_table[NAT44_ED_TCP_N_STATE] + [NAT44_ED_N_DIR] + [NAT44_ED_TCP_N_FLAG]; } snat_main_t; typedef struct @@ -789,16 +803,6 @@ nat44_ed_is_interface_outside (snat_interface_t *i) return i->flags & NAT_INTERFACE_FLAG_IS_OUTSIDE; } -/** \brief Check if NAT44 endpoint-dependent TCP session is closed. - @param s NAT session - @return true if session is closed -*/ -always_inline bool -nat44_is_ses_closed (snat_session_t *s) -{ - return s->state == 0xf; -} - /** \brief Check if client initiating TCP connection (received SYN from client) @param t TCP header @return true if client initiating TCP connection |