sctp: move to plugins, disabled by default

Removed sctp buffer metadata from vnet/buffer.h, added it to the
plugin. Add registration APIs for plugin-based vlib_buffer_opaque /
opaque2 decoders, used by "pcap dispatch trace ..." for display in the
wireshark dissector.

Type:refactor

Not actively maintained.

Change-Id: Ie4cb6ba66f68b3b3a7d7d2c63c917fdccf994371
Signed-off-by: Florin Coras <fcoras@cisco.com>
Signed-off-by: Dave Barach <dave@barachs.net>
This commit is contained in:
Florin Coras
2019-06-26 16:27:13 -07:00
committed by Dave Barach
parent 1cfcb78940
commit 3ffe6cadf0
27 changed files with 324 additions and 178 deletions

View File

@ -437,9 +437,9 @@ M: Ole Troan <ot@cisco.com>
M: Paul Vinciguerra <pvinci@vinciconsulting.com>
F: src/vpp-api/python
VNET SCTP
Plugin - SCTP
I: sctp
F: src/vnet/sctp
F: src/plugins/sctp/
THE REST
I: misc

View File

@ -0,0 +1,38 @@
# Copyright (c) 2019 Cisco and/or its affiliates.
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at:
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
add_vpp_plugin(sctp
SOURCES
sctp.c
sctp_api.c
sctp_pg.c
sctp_input.c
sctp_output.c
sctp_output_node.c
sctp_format.c
API_FILES
sctp.api
MULTIARCH_SOURCES
sctp_output_node.c
sctp_input.c
INSTALL_HEADERS
sctp_all_api_h.h
sctp_msg_enum.h
sctp_error.def
sctp_packet.h
sctp_timer.h
sctp.h
)

View File

@ -12,8 +12,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vnet/sctp/sctp.h>
#include <vnet/sctp/sctp_debug.h>
#include <vnet/plugin/plugin.h>
#include <vpp/app/version.h>
#include <sctp/sctp.h>
#include <sctp/sctp_debug.h>
sctp_main_t sctp_main;
@ -1001,6 +1005,30 @@ sctp_enable_disable (vlib_main_t * vm, u8 is_en)
return 0;
}
static u8 *
sctp_format_buffer_opaque_helper (const vlib_buffer_t * b, u8 * s)
{
sctp_buffer_opaque_t *o = sctp_buffer_opaque (b);
s = format (s,
"sctp.connection_index: %d, sctp.sid: %d, sctp.ssn: %d, "
"sctp.tsn: %d, sctp.hdr_offset: %d",
o->sctp.connection_index,
(u32) (o->sctp.sid),
(u32) (o->sctp.ssn),
(u32) (o->sctp.tsn), (u32) (o->sctp.hdr_offset));
vec_add1 (s, '\n');
s = format
(s, "sctp.data_offset: %d, sctp.data_len: %d, sctp.subconn_idx: %d, "
"sctp.flags: 0x%x",
(u32) (o->sctp.data_offset),
(u32) (o->sctp.data_len),
(u32) (o->sctp.subconn_idx), (u32) (o->sctp.flags));
vec_add1 (s, '\n');
return s;
}
clib_error_t *
sctp_init (vlib_main_t * vm)
{
@ -1010,8 +1038,11 @@ sctp_init (vlib_main_t * vm)
sm->is_enabled = 0;
sm->is_init = 0;
sctp_api_reference ();
/* initialize binary API */
sctp_plugin_api_hookup (vm);
vnet_register_format_buffer_opaque_helper
(sctp_format_buffer_opaque_helper);
return 0;
}
@ -1078,6 +1109,14 @@ VLIB_CLI_COMMAND (show_sctp_command, static) =
.short_help = "sctp [enable | disable]",
.function = sctp_fn,
};
/* *INDENT-OFF* */
VLIB_PLUGIN_REGISTER () =
{
.version = VPP_BUILD_VER,
.description = "Stream Control Transmission Protocol (SCTP)",
.default_disabled = 1,
};
/* *INDENT-ON* */
/*

View File

@ -17,18 +17,44 @@
#include <vnet/vnet.h>
#include <vnet/ip/ip.h>
#include <vnet/sctp/sctp_timer.h>
#include <vnet/sctp/sctp_packet.h>
#include <sctp/sctp_timer.h>
#include <sctp/sctp_packet.h>
#include <vnet/session/transport.h>
#include <vnet/session/session.h>
/* SCTP buffer opaque definition */
typedef struct
{
struct
{
u32 connection_index;
u16 sid; /**< Stream ID */
u16 ssn; /**< Stream Sequence Number */
u32 tsn; /**< Transmission Sequence Number */
u16 hdr_offset; /**< offset relative to ip hdr */
u16 data_offset; /**< offset relative to ip hdr */
u16 data_len; /**< data len */
u8 subconn_idx; /**< index of the sub_connection being used */
u8 flags;
} sctp;
} sctp_buffer_opaque_t;
STATIC_ASSERT (sizeof (sctp_buffer_opaque_t) <=
STRUCT_SIZE_OF (vnet_buffer_opaque_t, unused),
"sctp_buffer_opaque_t too large for vnet_buffer_opaque_t");
#define sctp_buffer_opaque(b) \
((sctp_buffer_opaque_t *)((u8 *)((b)->opaque) + \
STRUCT_OFFSET_OF (vnet_buffer_opaque_t, unused)))
/* SCTP timers */
#define foreach_sctp_timer \
_(T1_INIT, "T1_INIT") \
_(T1_COOKIE, "T1_COOKIE") \
_(T1_INIT, "T1_INIT") \
_(T1_COOKIE, "T1_COOKIE") \
_(T2_SHUTDOWN, "T2_SHUTDOWN") \
_(T3_RXTX, "T3_RXTX") \
_(T4_HEARTBEAT, "T4_HB") \
_(T3_RXTX, "T3_RXTX") \
_(T4_HEARTBEAT, "T4_HB") \
_(T5_SHUTDOWN_GUARD, "T5_SHUTDOWN_GUARD")
typedef enum _sctp_timers
@ -65,7 +91,7 @@ sctp_timer_to_string (u8 timer_id)
typedef enum _sctp_error
{
#define sctp_error(n,s) SCTP_ERROR_##n,
#include <vnet/sctp/sctp_error.def>
#include <sctp/sctp_error.def>
#undef sctp_error
SCTP_N_ERROR,
} sctp_error_t;
@ -306,6 +332,7 @@ u8 *format_sctp_connection (u8 * s, va_list * args);
u8 *format_sctp_scoreboard (u8 * s, va_list * args);
u8 *format_sctp_header (u8 * s, va_list * args);
u8 *format_sctp_tx_trace (u8 * s, va_list * args);
unformat_function_t unformat_pg_sctp_header;
clib_error_t *sctp_init (vlib_main_t * vm);
void sctp_connection_timers_init (sctp_connection_t * sctp_conn);
@ -533,6 +560,8 @@ typedef struct _sctp_main
u32 sctp4_established_phase_node_index;
u32 sctp6_established_phase_node_index;
u16 msg_id_base;
} sctp_main_t;
extern sctp_main_t sctp_main;
@ -552,10 +581,11 @@ sctp_buffer_hdr (vlib_buffer_t * b)
{
ASSERT ((signed) b->current_data >= (signed) -VLIB_BUFFER_PRE_DATA_SIZE);
return (sctp_header_t *) (b->data + b->current_data
+ vnet_buffer (b)->sctp.hdr_offset);
+ sctp_buffer_opaque (b)->sctp.hdr_offset);
}
clib_error_t *vnet_sctp_enable_disable (vlib_main_t * vm, u8 is_en);
clib_error_t *sctp_plugin_api_hookup (vlib_main_t * vm);
always_inline sctp_connection_t *
sctp_half_open_connection_get (u32 conn_index)

View File

@ -0,0 +1,16 @@
/*
* Copyright (c) 2019 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/* Include the generated file, see BUILT_SOURCES in Makefile.am */
#include <sctp/sctp.api.h>

View File

@ -1,6 +1,6 @@
/*
*------------------------------------------------------------------
* sctp_api.c - vnet sctp-layer API
* sctp_api.c - sctp-layer API
*
* Copyright (c) 2018 SUSE LLC.
* Licensed under the Apache License, Version 2.0 (the "License");
@ -17,30 +17,36 @@
*------------------------------------------------------------------
*/
#include <vnet/vnet.h>
#include <vlib/vlib.h>
#include <vlibapi/api.h>
#include <vlibmemory/api.h>
#include <vnet/sctp/sctp.h>
#include <sctp/sctp.h>
#include <vnet/vnet_msg_enum.h>
#include <sctp/sctp_msg_enum.h>
#define vl_typedefs /* define message structures */
#include <vnet/vnet_all_api_h.h>
#include <sctp/sctp_all_api_h.h>
#undef vl_typedefs
#define vl_endianfun /* define message structures */
#include <vnet/vnet_all_api_h.h>
#include <sctp/sctp_all_api_h.h>
#undef vl_endianfun
/* instantiate all the print functions we know about */
#define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
#define vl_printfun
#include <vnet/vnet_all_api_h.h>
#include <sctp/sctp_all_api_h.h>
#undef vl_printfun
#define vl_api_version(n,v) static u32 api_version=(v);
#include <sctp/sctp_all_api_h.h>
#undef vl_api_version
#define REPLY_MSG_ID_BASE sctp_main.msg_id_base
#include <vlibapi/api_helper_macros.h>
#define foreach_sctp_api_msg \
#define foreach_sctp_plugin_api_msg \
_(SCTP_ADD_SRC_DST_CONNECTION, sctp_add_src_dst_connection) \
_(SCTP_DEL_SRC_DST_CONNECTION, sctp_del_src_dst_connection) \
_(SCTP_CONFIG, sctp_config)
@ -97,47 +103,52 @@ vl_api_sctp_config_t_handler (vl_api_sctp_config_t * mp)
}
#define vl_msg_name_crc_list
#include <vnet/sctp/sctp.api.h>
#include <sctp/sctp_all_api_h.h>
#undef vl_msg_name_crc_list
static void
setup_message_id_table (api_main_t * am)
setup_message_id_table (sctp_main_t * sm, api_main_t * am)
{
#define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
#define _(id,n,crc) \
vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + sm->msg_id_base);
foreach_vl_msg_name_crc_sctp;
#undef _
}
static clib_error_t *
sctp_api_hookup (vlib_main_t * vm)
clib_error_t *
sctp_plugin_api_hookup (vlib_main_t * vm)
{
sctp_main_t *sm = &sctp_main;
api_main_t *am = &api_main;
u8 *name;
/* Construct the API name */
name = format (0, "sctp_%08x%c", api_version, 0);
/* Ask for a correctly-sized block of API message decode slots */
sctp_main.msg_id_base = vl_msg_api_get_msg_ids
((char *) name, VL_MSG_FIRST_AVAILABLE);
#define _(N,n) \
vl_msg_api_set_handlers(VL_API_##N, #n, \
vl_msg_api_set_handlers((VL_API_##N + sm->msg_id_base), \
#n, \
vl_api_##n##_t_handler, \
vl_noop_handler, \
vl_api_##n##_t_endian, \
vl_api_##n##_t_print, \
sizeof(vl_api_##n##_t), 1);
foreach_sctp_api_msg;
foreach_sctp_plugin_api_msg;
#undef _
/*
* Set up the (msg_name, crc, message-id) table
*/
setup_message_id_table (am);
setup_message_id_table (sm, am);
vec_free (name);
return 0;
}
VLIB_API_INIT_FUNCTION (sctp_api_hookup);
void
sctp_api_reference (void)
{
}
/*
* fd.io coding-style-patch-verification: ON
*

View File

@ -13,7 +13,7 @@
* limitations under the License.
*/
#include <vnet/sctp/sctp.h>
#include <sctp/sctp.h>
/* Format SCTP header. */
u8 *

View File

@ -13,15 +13,15 @@
* limitations under the License.
*/
#include <vppinfra/sparse_vec.h>
#include <vnet/sctp/sctp.h>
#include <vnet/sctp/sctp_packet.h>
#include <vnet/sctp/sctp_debug.h>
#include <sctp/sctp.h>
#include <sctp/sctp_packet.h>
#include <sctp/sctp_debug.h>
#include <vnet/session/session.h>
#include <math.h>
static char *sctp_error_strings[] = {
#define sctp_error(n,s) s,
#include <vnet/sctp/sctp_error.def>
#include <sctp/sctp_error.def>
#undef sctp_error
};
@ -785,33 +785,33 @@ sctp_handle_data (sctp_payload_data_chunk_t * sctp_data_chunk,
return sctp_conn->sub_conn[idx].enqueue_state;
}
vnet_buffer (b)->sctp.sid = sctp_data_chunk->stream_id;
vnet_buffer (b)->sctp.ssn = sctp_data_chunk->stream_seq;
sctp_buffer_opaque (b)->sctp.sid = sctp_data_chunk->stream_id;
sctp_buffer_opaque (b)->sctp.ssn = sctp_data_chunk->stream_seq;
u32 tsn = clib_net_to_host_u32 (sctp_data_chunk->tsn);
vlib_buffer_advance (b, vnet_buffer (b)->sctp.data_offset);
vlib_buffer_advance (b, sctp_buffer_opaque (b)->sctp.data_offset);
u32 chunk_len = vnet_sctp_get_chunk_length (&sctp_data_chunk->chunk_hdr) -
(sizeof (sctp_payload_data_chunk_t) - sizeof (sctp_header_t));
ASSERT (vnet_buffer (b)->sctp.data_len);
ASSERT (sctp_buffer_opaque (b)->sctp.data_len);
ASSERT (chunk_len);
/* Padding was added: see RFC 4096 section 3.3.1 */
if (vnet_buffer (b)->sctp.data_len > chunk_len)
if (sctp_buffer_opaque (b)->sctp.data_len > chunk_len)
{
/* Let's change the data_len to the right amount calculated here now.
* We cannot do that in the generic sctp46_input_dispatcher node since
* that is common to all CHUNKS handling.
*/
vnet_buffer (b)->sctp.data_len = chunk_len;
sctp_buffer_opaque (b)->sctp.data_len = chunk_len;
/* We need to change b->current_length so that downstream calls to
* session_enqueue_stream_connection (called by sctp_session_enqueue_data)
* push the correct amount of data to be enqueued.
*/
b->current_length = chunk_len;
}
n_data_bytes = vnet_buffer (b)->sctp.data_len;
n_data_bytes = sctp_buffer_opaque (b)->sctp.data_len;
sctp_is_connection_gapping (sctp_conn, tsn, &is_gapping);
@ -994,7 +994,7 @@ sctp46_rcv_phase_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
* will come from the half-open connections pool.
*/
sctp_conn =
sctp_half_open_connection_get (vnet_buffer (b0)->
sctp_half_open_connection_get (sctp_buffer_opaque (b0)->
sctp.connection_index);
if (PREDICT_FALSE (sctp_conn == 0))
@ -1339,8 +1339,8 @@ sctp46_shutdown_phase_inline (vlib_main_t * vm,
b0 = vlib_get_buffer (vm, bi0);
sctp_conn =
sctp_connection_get (vnet_buffer (b0)->sctp.connection_index,
my_thread_index);
sctp_connection_get (sctp_buffer_opaque (b0)->
sctp.connection_index, my_thread_index);
if (PREDICT_FALSE (sctp_conn == 0))
{
@ -1642,7 +1642,8 @@ sctp46_listen_process_inline (vlib_main_t * vm,
b0 = vlib_get_buffer (vm, bi0);
sctp_listener =
sctp_listener_get (vnet_buffer (b0)->sctp.connection_index);
sctp_listener_get (sctp_buffer_opaque (b0)->
sctp.connection_index);
if (is_ip4)
{
@ -1851,8 +1852,8 @@ sctp46_established_phase_inline (vlib_main_t * vm, vlib_node_runtime_t * node,
b0 = vlib_get_buffer (vm, bi0);
sctp_conn =
sctp_connection_get (vnet_buffer (b0)->sctp.connection_index,
my_thread_index);
sctp_connection_get (sctp_buffer_opaque (b0)->
sctp.connection_index, my_thread_index);
if (PREDICT_FALSE (sctp_conn == 0))
{
@ -2117,7 +2118,7 @@ sctp46_input_dispatcher (vlib_main_t * vm, vlib_node_runtime_t * node,
n_left_to_next -= 1;
b0 = vlib_get_buffer (vm, bi0);
vnet_buffer (b0)->sctp.flags = 0;
sctp_buffer_opaque (b0)->sctp.flags = 0;
fib_index0 = vnet_buffer (b0)->ip.fib_index;
/* Checksum computed by ipx_local no need to compute again */
@ -2193,16 +2194,17 @@ sctp46_input_dispatcher (vlib_main_t * vm, vlib_node_runtime_t * node,
goto done;
}
vnet_buffer (b0)->sctp.hdr_offset =
sctp_buffer_opaque (b0)->sctp.hdr_offset =
(u8 *) sctp_hdr - (u8 *) vlib_buffer_get_current (b0);
/* Session exists */
if (PREDICT_TRUE (0 != sctp_conn))
{
/* Save connection index */
vnet_buffer (b0)->sctp.connection_index = trans_conn->c_index;
vnet_buffer (b0)->sctp.data_offset = n_advance_bytes0;
vnet_buffer (b0)->sctp.data_len = n_data_bytes0;
sctp_buffer_opaque (b0)->sctp.connection_index
= trans_conn->c_index;
sctp_buffer_opaque (b0)->sctp.data_offset = n_advance_bytes0;
sctp_buffer_opaque (b0)->sctp.data_len = n_data_bytes0;
next0 = tm->dispatch_table[sctp_conn->state][chunk_type].next;
error0 = tm->dispatch_table[sctp_conn->state][chunk_type].error;

View File

@ -0,0 +1,28 @@
/*
* Copyright (c) 2019 Cisco and/or its affiliates.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at:
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef included_sctp_msg_enum_h
#define included_sctp_msg_enum_h
#include <vppinfra/byte_order.h>
#define vl_msg_id(n,h) n,
typedef enum {
#include <sctp/sctp_all_api_h.h>
/* We'll want to know how many messages IDs we need... */
VL_MSG_FIRST_AVAILABLE,
} vl_msg_id_t;
#undef vl_msg_id
#endif /* included_http_static_msg_enum_h */

View File

@ -12,8 +12,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vnet/sctp/sctp.h>
#include <vnet/sctp/sctp_debug.h>
#include <sctp/sctp.h>
#include <sctp/sctp_debug.h>
#include <vppinfra/random.h>
#include <openssl/hmac.h>
@ -230,8 +230,8 @@ sctp_reuse_buffer (vlib_main_t * vm, vlib_buffer_t * b)
b->current_data = 0;
b->current_length = 0;
b->total_length_not_including_first_buffer = 0;
vnet_buffer (b)->sctp.flags = 0;
vnet_buffer (b)->sctp.subconn_idx = MAX_SCTP_CONNECTIONS;
sctp_buffer_opaque (b)->sctp.flags = 0;
sctp_buffer_opaque (b)->sctp.subconn_idx = MAX_SCTP_CONNECTIONS;
/* Leave enough space for headers */
return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
@ -243,8 +243,8 @@ sctp_init_buffer (vlib_main_t * vm, vlib_buffer_t * b)
ASSERT ((b->flags & VLIB_BUFFER_NEXT_PRESENT) == 0);
b->flags |= VNET_BUFFER_F_LOCALLY_ORIGINATED;
b->total_length_not_including_first_buffer = 0;
vnet_buffer (b)->sctp.flags = 0;
vnet_buffer (b)->sctp.subconn_idx = MAX_SCTP_CONNECTIONS;
sctp_buffer_opaque (b)->sctp.flags = 0;
sctp_buffer_opaque (b)->sctp.subconn_idx = MAX_SCTP_CONNECTIONS;
VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
/* Leave enough space for headers */
return vlib_buffer_make_headroom (b, TRANSPORT_MAX_HDRS_LEN);
@ -450,8 +450,8 @@ sctp_prepare_init_chunk (sctp_connection_t * sctp_conn, u8 idx,
sctp_conn->local_tag = init_chunk->initiate_tag;
vnet_buffer (b)->sctp.connection_index = sub_conn->c_c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.connection_index = sub_conn->c_c_index;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
SCTP_DBG_STATE_MACHINE ("CONN_INDEX = %u, CURR_CONN_STATE = %u (%s), "
"CHUNK_TYPE = %s, "
@ -522,9 +522,9 @@ sctp_prepare_cookie_ack_chunk (sctp_connection_t * sctp_conn, u8 idx,
vnet_sctp_set_chunk_type (&cookie_ack_chunk->chunk_hdr, COOKIE_ACK);
vnet_sctp_set_chunk_length (&cookie_ack_chunk->chunk_hdr, chunk_len);
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
void
@ -556,9 +556,9 @@ sctp_prepare_cookie_echo_chunk (sctp_connection_t * sctp_conn, u8 idx,
clib_memcpy_fast (&(cookie_echo_chunk->cookie), &sctp_conn->cookie_param,
sizeof (sctp_state_cookie_param_t));
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
@ -647,9 +647,9 @@ sctp_prepare_operation_error (sctp_connection_t * sctp_conn, u8 idx,
vnet_sctp_set_chunk_type (&err_chunk->chunk_hdr, OPERATION_ERROR);
vnet_sctp_set_chunk_length (&err_chunk->chunk_hdr, chunk_len);
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
/**
@ -688,9 +688,9 @@ sctp_prepare_abort_for_collision (sctp_connection_t * sctp_conn, u8 idx,
vnet_sctp_set_chunk_type (&abort_chunk->chunk_hdr, ABORT);
vnet_sctp_set_chunk_length (&abort_chunk->chunk_hdr, chunk_len);
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
/**
@ -828,9 +828,9 @@ sctp_prepare_initack_chunk_for_collision (sctp_connection_t * sctp_conn,
init_ack_chunk->outbound_streams_count =
clib_host_to_net_u16 (OUTBOUND_STREAMS_COUNT);
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
/**
@ -971,9 +971,9 @@ sctp_prepare_initack_chunk (sctp_connection_t * sctp_conn, u8 idx,
sctp_conn->local_tag = init_ack_chunk->initiate_tag;
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
/**
@ -1007,9 +1007,9 @@ sctp_prepare_shutdown_chunk (sctp_connection_t * sctp_conn, u8 idx,
shutdown_chunk->cumulative_tsn_ack = sctp_conn->last_rcvd_tsn;
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
/*
@ -1065,9 +1065,9 @@ sctp_prepare_shutdown_ack_chunk (sctp_connection_t * sctp_conn, u8 idx,
vnet_sctp_set_chunk_type (&shutdown_ack_chunk->chunk_hdr, SHUTDOWN_ACK);
vnet_sctp_set_chunk_length (&shutdown_ack_chunk->chunk_hdr, chunk_len);
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
/*
@ -1120,9 +1120,9 @@ sctp_prepare_sack_chunk (sctp_connection_t * sctp_conn, u8 idx,
sctp_conn->ack_state = 0;
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
/**
@ -1159,9 +1159,9 @@ sctp_prepare_heartbeat_ack_chunk (sctp_connection_t * sctp_conn, u8 idx,
vnet_sctp_set_chunk_type (&hb_ack->chunk_hdr, HEARTBEAT_ACK);
vnet_sctp_set_chunk_length (&hb_ack->chunk_hdr, chunk_len);
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
/**
@ -1194,9 +1194,9 @@ sctp_prepare_heartbeat_chunk (sctp_connection_t * sctp_conn, u8 idx,
vnet_sctp_set_chunk_type (&hb_req->chunk_hdr, HEARTBEAT);
vnet_sctp_set_chunk_length (&hb_req->chunk_hdr, chunk_len);
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
void
@ -1259,9 +1259,9 @@ sctp_prepare_shutdown_complete_chunk (sctp_connection_t * sctp_conn, u8 idx,
vnet_sctp_set_chunk_type (&shutdown_complete->chunk_hdr, SHUTDOWN_COMPLETE);
vnet_sctp_set_chunk_length (&shutdown_complete->chunk_hdr, chunk_len);
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
void
@ -1409,10 +1409,10 @@ sctp_push_hdr_i (sctp_connection_t * sctp_conn, vlib_buffer_t * b,
sctp_conn->sub_conn[idx].last_data_ts = sctp_time_now ();
vnet_buffer (b)->sctp.connection_index =
sctp_buffer_opaque (b)->sctp.connection_index =
sctp_conn->sub_conn[idx].connection.c_index;
vnet_buffer (b)->sctp.subconn_idx = idx;
sctp_buffer_opaque (b)->sctp.subconn_idx = idx;
}
u32

View File

@ -12,8 +12,8 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <vnet/sctp/sctp.h>
#include <vnet/sctp/sctp_debug.h>
#include <sctp/sctp.h>
#include <sctp/sctp_debug.h>
#include <vppinfra/random.h>
#include <openssl/hmac.h>
@ -35,7 +35,7 @@ ip4_sctp_compute_checksum (vlib_main_t * vm, vlib_buffer_t * p0,
static char *sctp_error_strings[] = {
#define sctp_error(n,s) s,
#include <vnet/sctp/sctp_error.def>
#include <sctp/sctp_error.def>
#undef sctp_error
};
@ -102,8 +102,8 @@ sctp46_output_inline (vlib_main_t * vm,
b0 = vlib_get_buffer (vm, bi0);
sctp_conn =
sctp_connection_get (vnet_buffer (b0)->sctp.connection_index,
my_thread_index);
sctp_connection_get (sctp_buffer_opaque (b0)->
sctp.connection_index, my_thread_index);
if (PREDICT_FALSE (sctp_conn == 0))
{
@ -112,7 +112,7 @@ sctp46_output_inline (vlib_main_t * vm,
goto done;
}
u8 idx = vnet_buffer (b0)->sctp.subconn_idx;
u8 idx = sctp_buffer_opaque (b0)->sctp.subconn_idx;
th0 = vlib_buffer_get_current (b0);

View File

@ -676,33 +676,6 @@ list(APPEND VNET_HEADERS
list(APPEND VNET_API_FILES udp/udp.api)
##############################################################################
# Layer 4 protocol: sctp
##############################################################################
list(APPEND VNET_SOURCES
sctp/sctp_api.c
sctp/sctp.c
sctp/sctp_pg.c
sctp/sctp_input.c
sctp/sctp_output.c
sctp/sctp_output_node.c
sctp/sctp_format.c
)
list(APPEND VNET_MULTIARCH_SOURCES
sctp/sctp_output_node.c
sctp/sctp_input.c
)
list(APPEND VNET_HEADERS
sctp/sctp_error.def
sctp/sctp_packet.h
sctp/sctp_timer.h
sctp/sctp.h
)
list(APPEND VNET_API_FILES sctp/sctp.api)
##############################################################################
# Tunnel protocol: gre
##############################################################################

View File

@ -340,20 +340,6 @@ typedef struct
u8 flags;
} tcp;
/* SCTP */
struct
{
u32 connection_index;
u16 sid; /**< Stream ID */
u16 ssn; /**< Stream Sequence Number */
u32 tsn; /**< Transmission Sequence Number */
u16 hdr_offset; /**< offset relative to ip hdr */
u16 data_offset; /**< offset relative to ip hdr */
u16 data_len; /**< data len */
u8 subconn_idx; /**< index of the sub_connection being used */
u8 flags;
} sctp;
/* SNAT */
struct
{

View File

@ -809,6 +809,9 @@ typedef struct
u32 *split_buffers;
} vnet_interface_per_thread_data_t;
typedef u8 *(*vnet_buffer_opquae_formatter_t) (const vlib_buffer_t * b,
u8 * s);
typedef struct
{
/* Hardware interfaces. */
@ -847,6 +850,10 @@ typedef struct
u32 pcap_pkts_to_capture;
uword *pcap_drop_filter_hash;
/* Buffer metadata format helper functions */
vnet_buffer_opquae_formatter_t *buffer_opaque_format_helpers;
vnet_buffer_opquae_formatter_t *buffer_opaque2_format_helpers;
/* per-thread data */
vnet_interface_per_thread_data_t *per_thread_data;
@ -880,6 +887,12 @@ uword vnet_interface_output_node (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame);
void vnet_register_format_buffer_opaque_helper
(vnet_buffer_opquae_formatter_t fn);
void vnet_register_format_buffer_opaque2_helper
(vnet_buffer_opquae_formatter_t fn);
#endif /* included_vnet_interface_h */
/*

View File

@ -361,6 +361,8 @@ format_vnet_buffer_opaque (u8 * s, va_list * args)
{
vlib_buffer_t *b = va_arg (*args, vlib_buffer_t *);
vnet_buffer_opaque_t *o = (vnet_buffer_opaque_t *) b->opaque;
vnet_interface_main_t *im = &vnet_get_main ()->interface_main;
vnet_buffer_opquae_formatter_t helper_fp;
int i;
s = format (s, "raw: ");
@ -510,25 +512,15 @@ format_vnet_buffer_opaque (u8 * s, va_list * args)
(u32) (o->tcp.data_len), (u32) (o->tcp.flags));
vec_add1 (s, '\n');
s = format (s,
"sctp.connection_index: %d, sctp.sid: %d, sctp.ssn: %d, "
"sctp.tsn: %d, sctp.hdr_offset: %d",
o->sctp.connection_index,
(u32) (o->sctp.sid),
(u32) (o->sctp.ssn),
(u32) (o->sctp.tsn), (u32) (o->sctp.hdr_offset));
vec_add1 (s, '\n');
s = format
(s, "sctp.data_offset: %d, sctp.data_len: %d, sctp.subconn_idx: %d, "
"sctp.flags: 0x%x",
(u32) (o->sctp.data_offset),
(u32) (o->sctp.data_len),
(u32) (o->sctp.subconn_idx), (u32) (o->sctp.flags));
vec_add1 (s, '\n');
s = format (s, "snat.flags: 0x%x", o->snat.flags);
vec_add1 (s, '\n');
for (i = 0; i < vec_len (im->buffer_opaque_format_helpers); i++)
{
helper_fp = im->buffer_opaque_format_helpers[i];
s = (*helper_fp) (b, s);
}
return s;
}
@ -537,6 +529,8 @@ format_vnet_buffer_opaque2 (u8 * s, va_list * args)
{
vlib_buffer_t *b = va_arg (*args, vlib_buffer_t *);
vnet_buffer_opaque2_t *o = (vnet_buffer_opaque2_t *) b->opaque2;
vnet_interface_main_t *im = &vnet_get_main ()->interface_main;
vnet_buffer_opquae_formatter_t helper_fp;
int i;
@ -558,9 +552,31 @@ format_vnet_buffer_opaque2 (u8 * s, va_list * args)
s = format (s, "pg_replay_timestamp: %llu", (u32) (o->pg_replay_timestamp));
vec_add1 (s, '\n');
for (i = 0; i < vec_len (im->buffer_opaque2_format_helpers); i++)
{
helper_fp = im->buffer_opaque2_format_helpers[i];
s = (*helper_fp) (b, s);
}
return s;
}
void
vnet_register_format_buffer_opaque_helper (vnet_buffer_opquae_formatter_t fp)
{
vnet_interface_main_t *im = &vnet_get_main ()->interface_main;
vec_add1 (im->buffer_opaque_format_helpers, fp);
}
void
vnet_register_format_buffer_opaque2_helper (vnet_buffer_opquae_formatter_t fp)
{
vnet_interface_main_t *im = &vnet_get_main ()->interface_main;
vec_add1 (im->buffer_opaque2_format_helpers, fp);
}
uword
unformat_vnet_hw_interface (unformat_input_t * input, va_list * args)
{

View File

@ -98,10 +98,9 @@ format_function_t format_ip6_header;
unformat_function_t unformat_pg_ip6_header;
/* Format a TCP/UDP headers. */
format_function_t format_tcp_header, format_udp_header, format_sctp_header;
format_function_t format_tcp_header, format_udp_header;
unformat_function_t unformat_pg_tcp_header, unformat_pg_udp_header,
unformat_pg_sctp_header;
unformat_function_t unformat_pg_tcp_header, unformat_pg_udp_header;
#endif /* included_ip_format_h */

View File

@ -27,7 +27,6 @@
#include <vnet/pg/pg.h>
#include <vnet/udp/udp.h>
#include <vnet/tcp/tcp.h>
#include <vnet/sctp/sctp.h>
#include <vnet/ip/punt.h>
#include <vlib/unix/unix.h>
@ -355,7 +354,7 @@ vnet_punt_socket_del (vlib_main_t * vm, const punt_reg_t * pr)
* @brief Request IP traffic punt to the local TCP/IP stack.
*
* @em Note
* - UDP, TCP and SCTP are the only protocols supported in the current implementation
* - UDP and TCP are the only protocols supported in the current implementation
*
* @param vm vlib_main_t corresponding to the current thread
* @param af IP address family.
@ -371,13 +370,11 @@ punt_l4_add_del (vlib_main_t * vm,
ip_address_family_t af,
ip_protocol_t protocol, u16 port, bool is_add)
{
/* For now we only support TCP, UDP and SCTP punt */
if (protocol != IP_PROTOCOL_UDP &&
protocol != IP_PROTOCOL_TCP && protocol != IP_PROTOCOL_SCTP)
/* For now we only support TCP and UDP punt */
if (protocol != IP_PROTOCOL_UDP && protocol != IP_PROTOCOL_TCP)
return clib_error_return (0,
"only UDP (%d), TCP (%d) and SCTP (%d) protocols are supported, got %d",
IP_PROTOCOL_UDP, IP_PROTOCOL_TCP,
IP_PROTOCOL_SCTP, protocol);
"only UDP (%d) and TCP (%d) protocols are supported, got %d",
IP_PROTOCOL_UDP, IP_PROTOCOL_TCP, protocol);
if (port == (u16) ~ 0)
{
@ -385,17 +382,14 @@ punt_l4_add_del (vlib_main_t * vm,
udp_punt_unknown (vm, af == AF_IP4, is_add);
else if (protocol == IP_PROTOCOL_TCP)
tcp_punt_unknown (vm, af == AF_IP4, is_add);
else if (protocol == IP_PROTOCOL_SCTP)
sctp_punt_unknown (vm, af == AF_IP4, is_add);
return 0;
}
else if (is_add)
{
if (protocol == IP_PROTOCOL_TCP || protocol == IP_PROTOCOL_SCTP)
return clib_error_return (0,
"punt TCP/SCTP ports is not supported yet");
if (protocol == IP_PROTOCOL_TCP)
return clib_error_return (0, "punt TCP ports is not supported yet");
udp_register_dst_port (vm, port, udp4_punt_node.index, af == AF_IP4);
@ -403,9 +397,8 @@ punt_l4_add_del (vlib_main_t * vm,
}
else
{
if (protocol == IP_PROTOCOL_TCP || protocol == IP_PROTOCOL_SCTP)
return clib_error_return (0,
"punt TCP/SCTP ports is not supported yet");
if (protocol == IP_PROTOCOL_TCP)
return clib_error_return (0, "punt TCP ports is not supported yet");
udp_unregister_dst_port (vm, port, af == AF_IP4);

View File

@ -27,7 +27,6 @@
#include <vnet/pg/pg.h>
#include <vnet/udp/udp.h>
#include <vnet/tcp/tcp.h>
#include <vnet/sctp/sctp.h>
#include <vnet/ip/punt.h>
#include <vlib/unix/unix.h>

View File

@ -68,7 +68,6 @@
#include <vnet/ip/punt.api.h>
#include <vnet/pg/pg.api.h>
#include <vnet/feature/feature.api.h>
#include <vnet/sctp/sctp.api.h>
#include <vnet/qos/qos.api.h>
#include <vnet/dhcp/dhcp6_pd_client_cp.api.h>
#include <vnet/dhcp/dhcp6_ia_na_client_cp.api.h>

View File

@ -182,6 +182,9 @@ stat_segment_access_start (stat_segment_access_t * sa,
sa->epoch = shared_header->epoch;
while (shared_header->in_progress != 0)
;
sm->directory_vector = stat_segment_pointer (sm->shared_header,
sm->
shared_header->directory_offset);
}
static bool

View File

@ -11,6 +11,7 @@ class TestSCTP(VppTestCase):
@classmethod
def setUpClass(cls):
cls.extra_vpp_plugin_config.append("plugin sctp_plugin.so { enable }")
super(TestSCTP, cls).setUpClass()
@classmethod