|
static u8 | tcp_segment_in_rcv_wnd (tcp_connection_t *tc, u32 seq, u32 end_seq) |
| Validate segment sequence number. More...
|
|
static 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, u32 *error0) |
| 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...
|
|
static u32 | scoreboard_hole_index (sack_scoreboard_t *sb, sack_scoreboard_hole_t *hole) |
|
static u32 | scoreboard_hole_bytes (sack_scoreboard_hole_t *hole) |
|
sack_scoreboard_hole_t * | scoreboard_get_hole (sack_scoreboard_t *sb, u32 index) |
|
sack_scoreboard_hole_t * | scoreboard_next_hole (sack_scoreboard_t *sb, sack_scoreboard_hole_t *hole) |
|
sack_scoreboard_hole_t * | scoreboard_prev_hole (sack_scoreboard_t *sb, sack_scoreboard_hole_t *hole) |
|
sack_scoreboard_hole_t * | scoreboard_first_hole (sack_scoreboard_t *sb) |
|
sack_scoreboard_hole_t * | scoreboard_last_hole (sack_scoreboard_t *sb) |
|
static void | scoreboard_remove_hole (sack_scoreboard_t *sb, sack_scoreboard_hole_t *hole) |
|
static sack_scoreboard_hole_t * | scoreboard_insert_hole (sack_scoreboard_t *sb, u32 prev_index, u32 start, u32 end) |
|
static 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...
|
|
static void | scoreboard_init_high_rxt (sack_scoreboard_t *sb, u32 seq) |
|
void | scoreboard_init (sack_scoreboard_t *sb) |
|
void | scoreboard_clear (sack_scoreboard_t *sb) |
|
static u8 | tcp_scoreboard_is_sane_post_recovery (tcp_connection_t *tc) |
| Test that scoreboard is sane after recovery. More...
|
|
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) |
| Init loss recovery/fast recovery. More...
|
|
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) |
|
static 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...
|
|
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...
|
|
static u8 | tcp_sack_vector_is_sane (sack_block_t *sacks) |
|
void | tcp_update_sack_list (tcp_connection_t *tc, u32 start, u32 end) |
| Build SACK list as per RFC2018. More...
|
|
u32 | tcp_sack_list_bytes (tcp_connection_t *tc) |
|
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_buffer_discard_bytes (vlib_buffer_t *b, u32 n_bytes_to_drop) |
|
static int | tcp_segment_rcv (tcp_connection_t *tc, vlib_buffer_t *b, u32 *next0) |
| Receive buffer for connection and handle acks. More...
|
|
static u8 * | format_tcp_rx_trace (u8 *s, va_list *args) |
|
static u8 * | format_tcp_rx_trace_short (u8 *s, va_list *args) |
|
static 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_trace_frame (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame, u8 is_ip4) |
|
static void | tcp_node_inc_counter_i (vlib_main_t *vm, u32 tcp4_node, u32 tcp6_node, u8 is_ip4, u32 evt, u32 val) |
|
static uword | tcp46_established_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *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 u8 | tcp_lookup_is_valid (tcp_connection_t *tc, tcp_header_t *hdr) |
|
static tcp_connection_t * | tcp_lookup_connection (u32 fib_index, vlib_buffer_t *b, u8 thread_index, u8 is_ip4) |
| Lookup transport connection. More...
|
|
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 void | tcp_input_trace_frame (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_buffer_t **bs, u32 n_bufs, u8 is_ip4) |
|
static void | tcp_input_set_error_next (tcp_main_t *tm, u16 *next, u32 *error, u8 is_ip4) |
|
static tcp_connection_t * | tcp_input_lookup_buffer (vlib_buffer_t *b, u8 thread_index, u32 *error, u8 is_ip4) |
|
static void | tcp_input_dispatch_buffer (tcp_main_t *tm, tcp_connection_t *tc, vlib_buffer_t *b, u16 *next, u32 *error) |
|
static uword | tcp46_input_inline (vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *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) |
|
static 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 113 of file tcp_input.c.