From f3ab4896ed13733a22e9637395973fc1808823e1 Mon Sep 17 00:00:00 2001 From: Marco Varlese Date: Mon, 19 Feb 2018 15:23:13 +0100 Subject: SCTP: congestion control This patch addresses the requirements depicted by section 7.1.1 and 7.1.2 of the RFC 4960. Specifically, it implements the Slow-start and Congestion-avoidance policies. The patch also took care of correctly implementing some 'formatting' functions required - for instance - in packet(s) tracing. Change-Id: I68eade1b30345de3acb3ac8a653a5ef76eb6d2ac Signed-off-by: Marco Varlese --- src/vnet/sctp/sctp_output.c | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) (limited to 'src/vnet/sctp/sctp_output.c') diff --git a/src/vnet/sctp/sctp_output.c b/src/vnet/sctp/sctp_output.c index 459b33d46bc..fba06d942e7 100644 --- a/src/vnet/sctp/sctp_output.c +++ b/src/vnet/sctp/sctp_output.c @@ -463,7 +463,7 @@ sctp_prepare_init_chunk (sctp_connection_t * sctp_conn, u8 idx, vnet_sctp_set_chunk_length (&init_chunk->chunk_hdr, chunk_len); vnet_sctp_common_hdr_params_host_to_net (&init_chunk->chunk_hdr); - init_chunk->a_rwnd = clib_host_to_net_u32 (DEFAULT_A_RWND); + init_chunk->a_rwnd = clib_host_to_net_u32 (sctp_conn->sub_conn[idx].cwnd); init_chunk->initiate_tag = clib_host_to_net_u32 (random_u32 (&random_seed)); init_chunk->inboud_streams_count = clib_host_to_net_u16 (INBOUND_STREAMS_COUNT); @@ -717,7 +717,8 @@ sctp_prepare_initack_chunk (sctp_connection_t * sctp_conn, u8 idx, init_ack_chunk->initiate_tag = clib_host_to_net_u32 (random_u32 (&random_seed)); - init_ack_chunk->a_rwnd = clib_host_to_net_u32 (DEFAULT_A_RWND); + init_ack_chunk->a_rwnd = + clib_host_to_net_u32 (sctp_conn->sub_conn[idx].cwnd); init_ack_chunk->inboud_streams_count = clib_host_to_net_u16 (INBOUND_STREAMS_COUNT); init_ack_chunk->outbound_streams_count = @@ -1030,8 +1031,6 @@ sctp_send_shutdown_complete (sctp_connection_t * sctp_conn, u8 idx, sctp_reuse_buffer (vm, b0); sctp_prepare_shutdown_complete_chunk (sctp_conn, idx, b0); - - sctp_conn->state = SCTP_STATE_CLOSED; } /* @@ -1072,7 +1071,7 @@ sctp_send_init (sctp_connection_t * sctp_conn) * Push SCTP header and update connection variables */ static void -sctp_push_hdr_i (sctp_connection_t * sctp_conn, u8 idx, vlib_buffer_t * b, +sctp_push_hdr_i (sctp_connection_t * sctp_conn, vlib_buffer_t * b, sctp_state_t next_state) { u16 data_len = @@ -1093,6 +1092,8 @@ sctp_push_hdr_i (sctp_connection_t * sctp_conn, u8 idx, vlib_buffer_t * b, sctp_payload_data_chunk_t *data_chunk = vlib_buffer_push_uninit (b, bytes_to_add); + u8 idx = sctp_data_subconn_select (sctp_conn); + data_chunk->sctp_hdr.checksum = 0; data_chunk->sctp_hdr.src_port = sctp_conn->sub_conn[idx].connection.lcl_port; @@ -1113,8 +1114,22 @@ sctp_push_hdr_i (sctp_connection_t * sctp_conn, u8 idx, vlib_buffer_t * b, SCTP_ADV_DBG_OUTPUT ("POINTER_WITH_DATA = %p, DATA_OFFSET = %u", b->data, b->current_data); + sctp_conn->last_unacked_tsn = sctp_conn->next_tsn; sctp_conn->next_tsn += data_len; + u32 inflight = sctp_conn->next_tsn - sctp_conn->last_unacked_tsn; + /* Section 7.2.2; point (3) */ + if (sctp_conn->sub_conn[idx].partially_acked_bytes >= + sctp_conn->sub_conn[idx].cwnd + && inflight >= sctp_conn->sub_conn[idx].cwnd) + { + sctp_conn->sub_conn[idx].cwnd += sctp_conn->sub_conn[idx].PMTU; + sctp_conn->sub_conn[idx].partially_acked_bytes -= + sctp_conn->sub_conn[idx].cwnd; + } + + sctp_conn->sub_conn[idx].last_data_ts = sctp_time_now (); + vnet_buffer (b)->sctp.connection_index = sctp_conn->sub_conn[idx].connection.c_index; @@ -1127,9 +1142,7 @@ sctp_push_header (transport_connection_t * trans_conn, vlib_buffer_t * b) sctp_connection_t *sctp_conn = sctp_get_connection_from_transport (trans_conn); - u8 idx = sctp_data_subconn_select (sctp_conn); - - sctp_push_hdr_i (sctp_conn, idx, b, SCTP_STATE_ESTABLISHED); + sctp_push_hdr_i (sctp_conn, b, SCTP_STATE_ESTABLISHED); sctp_trajectory_add_start (b0, 3); @@ -1333,8 +1346,9 @@ sctp46_output_inline (vlib_main_t * vm, } #endif SCTP_DBG_STATE_MACHINE - ("CONN_INDEX = %u, CURR_CONN_STATE = %u (%s), " + ("SESSION_INDEX = %u, CONN_INDEX = %u, CURR_CONN_STATE = %u (%s), " "CHUNK_TYPE = %s, " "SRC_PORT = %u, DST_PORT = %u", + sctp_conn->sub_conn[idx].connection.s_index, sctp_conn->sub_conn[idx].connection.c_index, sctp_conn->state, sctp_state_to_string (sctp_conn->state), sctp_chunk_to_string (chunk_type), full_hdr->hdr.src_port, @@ -1352,6 +1366,7 @@ sctp46_output_inline (vlib_main_t * vm, error0 = SCTP_ERROR_UNKOWN_CHUNK; next0 = SCTP_OUTPUT_NEXT_DROP; goto done; + } #endif @@ -1415,12 +1430,12 @@ sctp46_output_inline (vlib_main_t * vm, b0->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED; - SCTP_DBG_STATE_MACHINE ("CONNECTION_INDEX = %u, " - "NEW_STATE = %s, " - "CHUNK_SENT = %s", - sctp_conn->sub_conn[idx].connection.c_index, - sctp_state_to_string (sctp_conn->state), - sctp_chunk_to_string (chunk_type)); + SCTP_DBG_STATE_MACHINE + ("SESSION_INDEX = %u, CONNECTION_INDEX = %u, " "NEW_STATE = %s, " + "CHUNK_SENT = %s", sctp_conn->sub_conn[idx].connection.s_index, + sctp_conn->sub_conn[idx].connection.c_index, + sctp_state_to_string (sctp_conn->state), + sctp_chunk_to_string (chunk_type)); vnet_sctp_common_hdr_params_host_to_net (&full_hdr->common_hdr); -- cgit 1.2.3-korg