|
static u8 | tcp_segment_in_rcv_wnd (tcp_connection_t *tc, u32 seq, u32 end_seq) |
| Validate segment sequence number. More...
|
|
int | tcp_options_parse (tcp_header_t *th, tcp_options_t *to) |
| Parse TCP header options. More...
|
|
static int | tcp_segment_check_paws (tcp_connection_t *tc) |
| RFC1323: Check against wrapped sequence numbers (PAWS). More...
|
|
static void | tcp_update_timestamp (tcp_connection_t *tc, u32 seq, u32 seq_end) |
| Update tsval recent. More...
|
|
static int | tcp_segment_validate (vlib_main_t *vm, tcp_connection_t *tc0, vlib_buffer_t *b0, tcp_header_t *th0, u32 *next0) |
| Validate incoming segment as per RFC793 p. More...
|
|
static int | tcp_rcv_ack_is_acceptable (tcp_connection_t *tc0, vlib_buffer_t *tb0) |
|
static void | tcp_estimate_rtt (tcp_connection_t *tc, u32 mrtt) |
| Compute smoothed RTT as per VJ's '88 SIGCOMM and RFC6298. More...
|
|
void | tcp_update_rto (tcp_connection_t *tc) |
|
static int | tcp_update_rtt (tcp_connection_t *tc, u32 ack) |
| Update RTT estimate and RTO timer. More...
|
|
static void | tcp_dequeue_acked (tcp_connection_t *tc, u32 ack) |
| Dequeue bytes that have been acked and while at it update RTT estimates. More...
|
|
static u8 | tcp_ack_is_dupack (tcp_connection_t *tc, vlib_buffer_t *b, u32 prev_snd_wnd, u32 prev_snd_una) |
| Check if duplicate ack as per RFC5681 Sec. More...
|
|
static u8 | tcp_ack_is_cc_event (tcp_connection_t *tc, vlib_buffer_t *b, u32 prev_snd_wnd, u32 prev_snd_una, u8 *is_dack) |
| Checks if ack is a congestion control event. More...
|
|
void | scoreboard_remove_hole (sack_scoreboard_t *sb, sack_scoreboard_hole_t *hole) |
|
sack_scoreboard_hole_t * | scoreboard_insert_hole (sack_scoreboard_t *sb, u32 prev_index, u32 start, u32 end) |
|
void | scoreboard_update_bytes (tcp_connection_t *tc, sack_scoreboard_t *sb) |
|
sack_scoreboard_hole_t * | scoreboard_next_rxt_hole (sack_scoreboard_t *sb, sack_scoreboard_hole_t *start, u8 have_sent_1_smss, u8 *can_rescue, u8 *snd_limited) |
| Figure out the next hole to retransmit. More...
|
|
void | scoreboard_init_high_rxt (sack_scoreboard_t *sb) |
|
void | tcp_rcv_sacks (tcp_connection_t *tc, u32 ack) |
|
static void | tcp_update_snd_wnd (tcp_connection_t *tc, u32 seq, u32 ack, u32 snd_wnd) |
| Try to update snd_wnd based on feedback received from peer. More...
|
|
void | tcp_cc_init_congestion (tcp_connection_t *tc) |
|
static void | tcp_cc_recovery_exit (tcp_connection_t *tc) |
|
void | tcp_cc_fastrecovery_exit (tcp_connection_t *tc) |
|
static void | tcp_cc_congestion_undo (tcp_connection_t *tc) |
|
static u8 | tcp_cc_is_spurious_retransmit (tcp_connection_t *tc) |
|
int | tcp_cc_recover (tcp_connection_t *tc) |
|
static void | tcp_cc_update (tcp_connection_t *tc, vlib_buffer_t *b) |
|
static u8 | tcp_should_fastrecover_sack (tcp_connection_t *tc) |
|
static u8 | tcp_should_fastrecover (tcp_connection_t *tc) |
|
static void | tcp_cc_handle_event (tcp_connection_t *tc, u32 is_dack) |
| One function to rule them all ... More...
|
|
void | tcp_cc_init (tcp_connection_t *tc) |
|
static int | tcp_rcv_ack (tcp_connection_t *tc, vlib_buffer_t *b, tcp_header_t *th, u32 *next, u32 *error) |
| Process incoming ACK. More...
|
|
void | tcp_update_sack_list (tcp_connection_t *tc, u32 start, u32 end) |
| Build SACK list as per RFC2018. More...
|
|
static int | tcp_session_enqueue_data (tcp_connection_t *tc, vlib_buffer_t *b, u16 data_len) |
| Enqueue data for delivery to application. More...
|
|
static int | tcp_session_enqueue_ooo (tcp_connection_t *tc, vlib_buffer_t *b, u16 data_len) |
| Enqueue out-of-order data. More...
|
|
static int | tcp_can_delack (tcp_connection_t *tc) |
| Check if ACK could be delayed. More...
|
|
static int | tcp_segment_rcv (tcp_main_t *tm, tcp_connection_t *tc, vlib_buffer_t *b, u16 n_data_bytes, u32 *next0) |
|
u8 * | format_tcp_rx_trace (u8 *s, va_list *args) |
|
u8 * | format_tcp_rx_trace_short (u8 *s, va_list *args) |
|
void | tcp_set_rx_trace_data (tcp_rx_trace_t *t0, tcp_connection_t *tc0, tcp_header_t *th0, vlib_buffer_t *b0, u8 is_ip4) |
|
static void | tcp_established_inc_counter (vlib_main_t *vm, u8 is_ip4, u8 evt, u8 val) |
|
static uword | tcp46_established_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4) |
|
static uword | tcp4_established (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
static uword | tcp6_established (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp4_established_node, tcp4_established) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp6_established_node, tcp6_established) |
|
static uword | tcp46_syn_sent_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4) |
|
static uword | tcp4_syn_sent (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
static uword | tcp6_syn_sent_rcv (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp4_syn_sent_node, tcp4_syn_sent) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp6_syn_sent_node, tcp6_syn_sent_rcv) |
|
static uword | tcp46_rcv_process_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4) |
| Handles reception for all states except LISTEN, SYN-SENT and ESTABLISHED as per RFC793 p. More...
|
|
static uword | tcp4_rcv_process (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
static uword | tcp6_rcv_process (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp4_rcv_process_node, tcp4_rcv_process) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp6_rcv_process_node, tcp6_rcv_process) |
|
static uword | tcp46_listen_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4) |
| LISTEN state processing as per RFC 793 p. More...
|
|
static uword | tcp4_listen (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
static uword | tcp6_listen (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp4_listen_node, tcp4_listen) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp6_listen_node, tcp6_listen) |
|
static uword | tcp46_input_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame, int is_ip4) |
|
static uword | tcp4_input (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
static uword | tcp6_input (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp4_input_node, tcp4_input) |
|
| VLIB_NODE_FUNCTION_MULTIARCH (tcp6_input_node, tcp6_input) |
|
static void | tcp_dispatch_table_init (tcp_main_t *tm) |
|
clib_error_t * | tcp_input_init (vlib_main_t *vm) |
|
Validate segment sequence number.
As per RFC793:
Segment Receive Test Length Window
0 0 SEG.SEQ = RCV.NXT 0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND >0 0 not acceptable >0 >0 RCV.NXT =< SEG.SEQ < RCV.NXT+RCV.WND or RCV.NXT =< SEG.SEQ+SEG.LEN-1 < RCV.NXT+RCV.WND
This ultimately consists in checking if segment falls within the window. The one important difference compared to RFC793 is that we use rcv_las, or the rcv_nxt at last ack sent instead of rcv_nxt since that's the peer's reference when computing our receive window.
This: seq_leq (end_seq, tc->rcv_las + tc->rcv_wnd) && seq_geq (seq, tc->rcv_las) however, is too strict when we have retransmits. Instead we just check that the seq is not beyond the right edge and that the end of the segment is not less than the left edge.
N.B. rcv_nxt and rcv_wnd are both updated in this node if acks are sent, so use rcv_nxt in the right edge window test instead of rcv_las.
Definition at line 109 of file tcp_input.c.