From 465c087c58e356426588e5387fff133715a8762d Mon Sep 17 00:00:00 2001 From: Marco Varlese Date: Thu, 1 Mar 2018 14:01:46 +0100 Subject: [PATCH] SCTP: API to delete a sub-connection This patch adds an API to delete a sub-connection following a SRC/DST IP mapping as required by the RFC4960. Change-Id: I7673dd07352557442ffeed6c6c00da274b24953d Signed-off-by: Marco Varlese --- src/vnet/sctp/sctp.api | 8 ++++++ src/vnet/sctp/sctp.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++++ src/vnet/sctp/sctp.h | 8 ++++++ src/vnet/sctp/sctp_api.c | 22 +++++++++++++-- 4 files changed, 106 insertions(+), 2 deletions(-) diff --git a/src/vnet/sctp/sctp.api b/src/vnet/sctp/sctp.api index f2c48d664f8..6253c954d1c 100644 --- a/src/vnet/sctp/sctp.api +++ b/src/vnet/sctp/sctp.api @@ -34,3 +34,11 @@ autoreply define sctp_add_src_dst_connection { u8 dst_address[16]; }; +autoreply define sctp_del_src_dst_connection { + u32 client_index; + u32 context; + u8 is_ipv6; + u32 vrf_id; + u8 src_address[16]; + u8 dst_address[16]; + }; \ No newline at end of file diff --git a/src/vnet/sctp/sctp.c b/src/vnet/sctp/sctp.c index b1186a62052..cc70f7ccd8d 100644 --- a/src/vnet/sctp/sctp.c +++ b/src/vnet/sctp/sctp.c @@ -305,6 +305,40 @@ sctp_sub_connection_add_ip4 (vlib_main_t * vm, return SCTP_ERROR_NONE; } +u8 +sctp_sub_connection_del_ip4 (ip4_address_t * lcl_addr, + ip4_address_t * rmt_addr) +{ + sctp_main_t *sctp_main = vnet_get_sctp_main (); + + u32 thread_idx = vlib_get_thread_index (); + u8 i; + + ASSERT (thread_idx == 0); + + for (i = 0; i < MAX_SCTP_CONNECTIONS; i++) + { + sctp_connection_t *sctp_conn = sctp_main->connections[thread_idx]; + sctp_sub_connection_t *sub_conn = + &sctp_main->connections[thread_idx]->sub_conn[i]; + ip46_address_t *lcl_ip = + &sctp_main->connections[thread_idx]->sub_conn[i].connection.lcl_ip; + ip46_address_t *rmt_ip = + &sctp_main->connections[thread_idx]->sub_conn[i].connection.rmt_ip; + + if (!sub_conn->connection.is_ip4) + continue; + if (lcl_ip->ip4.as_u32 == lcl_addr->as_u32 && + rmt_ip->ip4.as_u32 == rmt_addr->as_u32) + { + sub_conn->state = SCTP_SUBCONN_STATE_DOWN; + sctp_conn->forming_association_changed = 1; + break; + } + } + return SCTP_ERROR_NONE; +} + u8 sctp_sub_connection_add_ip6 (vlib_main_t * vm, ip6_address_t * lcl_addr, @@ -328,6 +362,42 @@ sctp_sub_connection_add_ip6 (vlib_main_t * vm, return SCTP_ERROR_NONE; } +u8 +sctp_sub_connection_del_ip6 (ip6_address_t * lcl_addr, + ip6_address_t * rmt_addr) +{ + sctp_main_t *sctp_main = vnet_get_sctp_main (); + + u32 thread_idx = vlib_get_thread_index (); + u8 i; + + ASSERT (thread_idx == 0); + + for (i = 0; i < MAX_SCTP_CONNECTIONS; i++) + { + sctp_connection_t *sctp_conn = sctp_main->connections[thread_idx]; + sctp_sub_connection_t *sub_conn = + &sctp_main->connections[thread_idx]->sub_conn[i]; + ip46_address_t *lcl_ip = + &sctp_main->connections[thread_idx]->sub_conn[i].connection.lcl_ip; + ip46_address_t *rmt_ip = + &sctp_main->connections[thread_idx]->sub_conn[i].connection.rmt_ip; + + if (!sub_conn->connection.is_ip4) + continue; + if ((lcl_ip->ip6.as_u64[0] == lcl_addr->as_u64[0] + && lcl_ip->ip6.as_u64[1] == lcl_addr->as_u64[1]) + && (rmt_ip->ip6.as_u64[0] == rmt_addr->as_u64[0] + && rmt_ip->ip6.as_u64[1] == rmt_addr->as_u64[1])) + { + sub_conn->state = SCTP_SUBCONN_STATE_DOWN; + sctp_conn->forming_association_changed = 1; + break; + } + } + return SCTP_ERROR_NONE; +} + sctp_connection_t * sctp_connection_new (u8 thread_index) { diff --git a/src/vnet/sctp/sctp.h b/src/vnet/sctp/sctp.h index 487ff9e4824..9f17e5337ba 100644 --- a/src/vnet/sctp/sctp.h +++ b/src/vnet/sctp/sctp.h @@ -254,6 +254,14 @@ sctp_sub_connection_add_ip6 (vlib_main_t * vm, ip6_address_t * lcl_addr, ip6_address_t * rmt_addr); +u8 +sctp_sub_connection_del_ip4 (ip4_address_t * lcl_addr, + ip4_address_t * rmt_addr); + +u8 +sctp_sub_connection_del_ip6 (ip6_address_t * lcl_addr, + ip6_address_t * rmt_addr); + void sctp_connection_close (sctp_connection_t * sctp_conn); void sctp_connection_cleanup (sctp_connection_t * sctp_conn); void sctp_connection_del (sctp_connection_t * sctp_conn); diff --git a/src/vnet/sctp/sctp_api.c b/src/vnet/sctp/sctp_api.c index 2c1b072228f..6aac77d2826 100644 --- a/src/vnet/sctp/sctp_api.c +++ b/src/vnet/sctp/sctp_api.c @@ -40,8 +40,9 @@ #include -#define foreach_sctp_api_msg \ -_(SCTP_ADD_SRC_DST_CONNECTION, sctp_add_src_dst_connection) +#define foreach_sctp_api_msg \ +_(SCTP_ADD_SRC_DST_CONNECTION, sctp_add_src_dst_connection) \ +_(SCTP_DEL_SRC_DST_CONNECTION, sctp_del_src_dst_connection) static void vl_api_sctp_add_src_dst_connection_t_handler @@ -63,6 +64,23 @@ static void REPLY_MACRO (VL_API_SCTP_ADD_SRC_DST_CONNECTION_REPLY); } +static void + vl_api_sctp_del_src_dst_connection_t_handler + (vl_api_sctp_del_src_dst_connection_t * mp) +{ + vl_api_sctp_del_src_dst_connection_reply_t *rmp; + int rv; + + if (mp->is_ipv6) + rv = sctp_sub_connection_del_ip6 + ((ip6_address_t *) mp->src_address, (ip6_address_t *) mp->dst_address); + else + rv = sctp_sub_connection_del_ip4 + ((ip4_address_t *) mp->src_address, (ip4_address_t *) mp->dst_address); + + REPLY_MACRO (VL_API_SCTP_ADD_SRC_DST_CONNECTION_REPLY); +} + #define vl_msg_name_crc_list #include #undef vl_msg_name_crc_list -- 2.16.6