SCTP: API to configure some tunables
This patch adds the possibility to configure some behaviors of the SCTP
stack based on some tunable parameters (mainly ON/OFF). For the time
being, that is limited to the bundling option (multiplexing messages)
and to delaying the SACK message.
Change-Id: I696493e0309e47163c1e119c7d9f82f7d8ee6b87
Signed-off-by: Marco Varlese <marco.varlese@suse.com>
diff --git a/src/vnet/sctp/sctp_input.c b/src/vnet/sctp/sctp_input.c
index 70adc7c..962534c 100644
--- a/src/vnet/sctp/sctp_input.c
+++ b/src/vnet/sctp/sctp_input.c
@@ -337,7 +337,7 @@
case SCTP_STATE_COOKIE_WAIT:
SCTP_ADV_DBG ("Received INIT chunk while in COOKIE_WAIT state");
sctp_prepare_initack_chunk_for_collision (sctp_conn,
- MAIN_SCTP_SUB_CONN_IDX,
+ SCTP_PRIMARY_PATH_IDX,
b0, ip4_addr, ip6_addr);
return SCTP_ERROR_NONE;
case SCTP_STATE_COOKIE_ECHOED:
@@ -345,11 +345,11 @@
SCTP_ADV_DBG ("Received INIT chunk while in COOKIE_ECHOED state");
if (sctp_conn->forming_association_changed == 0)
sctp_prepare_initack_chunk_for_collision (sctp_conn,
- MAIN_SCTP_SUB_CONN_IDX,
+ SCTP_PRIMARY_PATH_IDX,
b0, ip4_addr, ip6_addr);
else
sctp_prepare_abort_for_collision (sctp_conn,
- MAIN_SCTP_SUB_CONN_IDX, b0,
+ SCTP_PRIMARY_PATH_IDX, b0,
ip4_addr, ip6_addr);
return SCTP_ERROR_NONE;
}
@@ -401,7 +401,7 @@
sctp_sub_connection_add_ip4 (vlib_get_main (),
&sctp_conn->sub_conn
- [MAIN_SCTP_SUB_CONN_IDX].connection.
+ [SCTP_PRIMARY_PATH_IDX].connection.
lcl_ip.ip4, &ipv4->address);
break;
@@ -415,7 +415,7 @@
sctp_sub_connection_add_ip6 (vlib_get_main (),
&sctp_conn->sub_conn
- [MAIN_SCTP_SUB_CONN_IDX].connection.
+ [SCTP_PRIMARY_PATH_IDX].connection.
lcl_ip.ip6, &ipv6->address);
break;
@@ -447,7 +447,7 @@
}
/* Reuse buffer to make init-ack and send */
- sctp_prepare_initack_chunk (sctp_conn, MAIN_SCTP_SUB_CONN_IDX, b0, ip4_addr,
+ sctp_prepare_initack_chunk (sctp_conn, SCTP_PRIMARY_PATH_IDX, b0, ip4_addr,
ip6_addr);
return SCTP_ERROR_NONE;
}
@@ -539,7 +539,7 @@
sctp_sub_connection_add_ip4 (vlib_get_main (),
&sctp_conn->sub_conn
- [MAIN_SCTP_SUB_CONN_IDX].connection.
+ [SCTP_PRIMARY_PATH_IDX].connection.
lcl_ip.ip4, &ipv4->address);
break;
@@ -551,7 +551,7 @@
sctp_sub_connection_add_ip6 (vlib_get_main (),
&sctp_conn->sub_conn
- [MAIN_SCTP_SUB_CONN_IDX].connection.
+ [SCTP_PRIMARY_PATH_IDX].connection.
lcl_ip.ip6, &ipv6->address);
break;
@@ -711,6 +711,12 @@
always_inline u8
sctp_is_sack_delayable (sctp_connection_t * sctp_conn, u8 idx, u8 is_gapping)
{
+ if (sctp_conn->conn_config.never_delay_sack)
+ {
+ SCTP_CONN_TRACKING_DBG ("sctp_conn->conn_config.never_delay_sack = ON");
+ return 0;
+ }
+
/* Section 4.4 of the RFC4960 */
if (sctp_conn->state == SCTP_STATE_SHUTDOWN_SENT)
{
@@ -748,7 +754,7 @@
{
SCTP_CONN_TRACKING_DBG
("GAPPING: CONN_INDEX = %u, sctp_conn->next_tsn_expected = %u, tsn = %u, diff = %u",
- sctp_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].connection.c_index,
+ sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.c_index,
sctp_conn->next_tsn_expected, tsn,
sctp_conn->next_tsn_expected - tsn);
@@ -1221,8 +1227,7 @@
* - STOP T2_SHUTDOWN timer
* - SEND SHUTDOWN_COMPLETE chunk
*/
- sctp_timer_reset (sctp_conn, MAIN_SCTP_SUB_CONN_IDX,
- SCTP_TIMER_T2_SHUTDOWN);
+ sctp_timer_reset (sctp_conn, SCTP_PRIMARY_PATH_IDX, SCTP_TIMER_T2_SHUTDOWN);
sctp_send_shutdown_complete (sctp_conn, idx, b0);
@@ -1633,14 +1638,14 @@
child_conn =
sctp_lookup_connection (sctp_listener->sub_conn
- [MAIN_SCTP_SUB_CONN_IDX].c_fib_index, b0,
+ [SCTP_PRIMARY_PATH_IDX].c_fib_index, b0,
my_thread_index, is_ip4);
if (PREDICT_FALSE (child_conn->state != SCTP_STATE_CLOSED))
{
SCTP_DBG
("conn_index = %u: child_conn->state != SCTP_STATE_CLOSED.... STATE=%s",
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
connection.c_index,
sctp_state_to_string (child_conn->state));
error0 = SCTP_ERROR_CREATE_EXISTS;
@@ -1649,33 +1654,33 @@
/* Create child session and send SYN-ACK */
child_conn = sctp_connection_new (my_thread_index);
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].subconn_idx =
- MAIN_SCTP_SUB_CONN_IDX;
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_lcl_port =
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].subconn_idx =
+ SCTP_PRIMARY_PATH_IDX;
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_lcl_port =
sctp_hdr->dst_port;
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_rmt_port =
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_rmt_port =
sctp_hdr->src_port;
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_is_ip4 = is_ip4;
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].connection.proto =
- sctp_listener->sub_conn[MAIN_SCTP_SUB_CONN_IDX].connection.proto;
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].PMTU =
- sctp_listener->sub_conn[MAIN_SCTP_SUB_CONN_IDX].PMTU;
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_is_ip4 = is_ip4;
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.proto =
+ sctp_listener->sub_conn[SCTP_PRIMARY_PATH_IDX].connection.proto;
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].PMTU =
+ sctp_listener->sub_conn[SCTP_PRIMARY_PATH_IDX].PMTU;
child_conn->state = SCTP_STATE_CLOSED;
if (is_ip4)
{
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_lcl_ip4.as_u32 =
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_lcl_ip4.as_u32 =
ip4_hdr->dst_address.as_u32;
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_rmt_ip4.as_u32 =
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].c_rmt_ip4.as_u32 =
ip4_hdr->src_address.as_u32;
}
else
{
clib_memcpy (&child_conn->
- sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_lcl_ip6,
+ sub_conn[SCTP_PRIMARY_PATH_IDX].c_lcl_ip6,
&ip6_hdr->dst_address, sizeof (ip6_address_t));
clib_memcpy (&child_conn->
- sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_rmt_ip6,
+ sub_conn[SCTP_PRIMARY_PATH_IDX].c_rmt_ip6,
&ip6_hdr->src_address, sizeof (ip6_address_t));
}
@@ -1687,7 +1692,7 @@
{
SCTP_DBG
("conn_index = %u: chunk_type != INIT... chunk_type=%s",
- child_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].
+ child_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
connection.c_index, sctp_chunk_to_string (chunk_type));
error0 = SCTP_ERROR_UNKOWN_CHUNK;
@@ -1715,9 +1720,9 @@
{
if (stream_session_accept
(&child_conn->
- sub_conn[MAIN_SCTP_SUB_CONN_IDX].connection,
+ sub_conn[SCTP_PRIMARY_PATH_IDX].connection,
sctp_listener->
- sub_conn[MAIN_SCTP_SUB_CONN_IDX].c_s_index, 0))
+ sub_conn[SCTP_PRIMARY_PATH_IDX].c_s_index, 0))
{
clib_warning ("session accept fail");
sctp_connection_cleanup (child_conn);
@@ -1738,8 +1743,7 @@
case OPERATION_ERROR:
error0 =
sctp_handle_operation_err (sctp_hdr, child_conn,
- MAIN_SCTP_SUB_CONN_IDX, b0,
- &next0);
+ SCTP_PRIMARY_PATH_IDX, b0, &next0);
break;
}
@@ -2167,7 +2171,7 @@
clib_warning
("Received an unrecognized chunk; sending back OPERATION_ERROR chunk");
- sctp_prepare_operation_error (sctp_conn, MAIN_SCTP_SUB_CONN_IDX,
+ sctp_prepare_operation_error (sctp_conn, SCTP_PRIMARY_PATH_IDX,
b0, UNRECOGNIZED_CHUNK_TYPE);
error0 = SCTP_ERROR_UNKOWN_CHUNK;
@@ -2192,9 +2196,9 @@
SCTP_DBG_STATE_MACHINE
("S_INDEX = %u, C_INDEX = %u, TRANS_CONN = %p, SCTP_CONN = %p, CURRENT_CONNECTION_STATE = %s,"
"CHUNK_TYPE_RECEIVED = %s " "NEXT_PHASE = %s",
- sctp_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].
+ sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
connection.s_index,
- sctp_conn->sub_conn[MAIN_SCTP_SUB_CONN_IDX].
+ sctp_conn->sub_conn[SCTP_PRIMARY_PATH_IDX].
connection.c_index, trans_conn, sctp_conn,
sctp_state_to_string (sctp_conn->state),
sctp_chunk_to_string (chunk_type), phase_to_string (next0));