diff options
author | Marco Varlese <marco.varlese@suse.com> | 2018-02-15 17:01:56 +0100 |
---|---|---|
committer | Damjan Marion <dmarion.lists@gmail.com> | 2018-02-17 09:45:28 +0000 |
commit | 54432f8c0ac1f680198afa6047ce74bc4a126f21 (patch) | |
tree | 472bcb2609160a17e285d97d0d1b484baa332af8 /src/vnet/sctp/sctp.c | |
parent | a250882b8fbc3f75d919bffaea10809a37205204 (diff) |
SCTP: 'multi-home' support
This patch addresses the SCTP requirement for multiple sub-connections
to implement the so called 'multi-homed' scenario.
Change-Id: Ibce18f216e9d2bebe318992c441bf278e16aad17
Signed-off-by: Marco Varlese <marco.varlese@suse.com>
Diffstat (limited to 'src/vnet/sctp/sctp.c')
-rw-r--r-- | src/vnet/sctp/sctp.c | 49 |
1 files changed, 39 insertions, 10 deletions
diff --git a/src/vnet/sctp/sctp.c b/src/vnet/sctp/sctp.c index 529e4089644..224c97d419e 100644 --- a/src/vnet/sctp/sctp.c +++ b/src/vnet/sctp/sctp.c @@ -360,7 +360,7 @@ sctp_connection_open (transport_endpoint_t * rmt) uword thread_id; int rv; - u8 idx = sctp_pick_conn_idx_on_state (SCTP_STATE_CLOSED); + u8 idx = MAIN_SCTP_SUB_CONN_IDX; /* * Allocate local endpoint @@ -452,6 +452,21 @@ sctp_session_open (transport_endpoint_t * tep) u16 sctp_check_outstanding_data_chunks (sctp_connection_t * sctp_conn) { + u8 i; + for (i = 0; i < MAX_SCTP_CONNECTIONS; i++) + { + if (sctp_conn->sub_conn[i].state == SCTP_SUBCONN_STATE_DOWN) + continue; + + if (sctp_conn->sub_conn[i].is_retransmitting == 1 || + sctp_conn->sub_conn[i].enqueue_state != SCTP_ERROR_ENQUEUED) + { + SCTP_DBG_OUTPUT + ("Connection %u has still DATA to be enqueued inboud / outboud"); + return 1; + } + + } return 0; /* Indicates no more data to be read/sent */ } @@ -622,8 +637,6 @@ sctp_expired_timers_cb (u32 conn_index, u32 timer_id) case SCTP_TIMER_T1_COOKIE: case SCTP_TIMER_T2_SHUTDOWN: case SCTP_TIMER_T3_RXTX: - clib_smp_atomic_add (&sctp_conn->sub_conn[conn_index].unacknowledged_hb, - 1); sctp_timer_reset (sctp_conn, conn_index, timer_id); break; case SCTP_TIMER_T4_HEARTBEAT: @@ -632,18 +645,34 @@ sctp_expired_timers_cb (u32 conn_index, u32 timer_id) } if (sctp_conn->sub_conn[conn_index].unacknowledged_hb > - SCTP_ASSOCIATION_MAX_RETRANS) + SCTP_PATH_MAX_RETRANS) { // The remote-peer is considered to be unreachable hence shutting down + u8 i, total_subs_down = 1; + for (i = 0; i < MAX_SCTP_CONNECTIONS; i++) + { + if (sctp_conn->sub_conn[i].state == SCTP_SUBCONN_STATE_DOWN) + continue; + + u32 now = sctp_time_now (); + if (now > (sctp_conn->sub_conn[i].last_seen + SCTP_HB_INTERVAL)) + { + total_subs_down += 1; + sctp_conn->sub_conn[i].state = SCTP_SUBCONN_STATE_DOWN; + } + } - /* Start cleanup. App wasn't notified yet so use delete notify as - * opposed to delete to cleanup session layer state. */ - stream_session_delete_notify (&sctp_conn->sub_conn - [MAIN_SCTP_SUB_CONN_IDX].connection); + if (total_subs_down == MAX_SCTP_CONNECTIONS) + { + /* Start cleanup. App wasn't notified yet so use delete notify as + * opposed to delete to cleanup session layer state. */ + stream_session_delete_notify (&sctp_conn->sub_conn + [MAIN_SCTP_SUB_CONN_IDX].connection); - sctp_connection_timers_reset (sctp_conn); + sctp_connection_timers_reset (sctp_conn); - sctp_connection_cleanup (sctp_conn); + sctp_connection_cleanup (sctp_conn); + } } return; |