From 3ffe6cadf083d1a0bc32e4a37d56b42a1153ff7b Mon Sep 17 00:00:00 2001 From: Florin Coras Date: Wed, 26 Jun 2019 16:27:13 -0700 Subject: [PATCH] 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 Signed-off-by: Dave Barach --- MAINTAINERS | 4 +- src/plugins/sctp/CMakeLists.txt | 38 +++++++++++++++ src/{vnet => plugins}/sctp/sctp.api | 0 src/{vnet => plugins}/sctp/sctp.c | 45 ++++++++++++++++-- src/{vnet => plugins}/sctp/sctp.h | 46 ++++++++++++++---- src/plugins/sctp/sctp_all_api_h.h | 16 +++++++ src/{vnet => plugins}/sctp/sctp_api.c | 57 +++++++++++++--------- src/{vnet => plugins}/sctp/sctp_debug.h | 0 src/{vnet => plugins}/sctp/sctp_error.def | 0 src/{vnet => plugins}/sctp/sctp_format.c | 2 +- src/{vnet => plugins}/sctp/sctp_input.c | 46 +++++++++--------- src/plugins/sctp/sctp_msg_enum.h | 28 +++++++++++ src/{vnet => plugins}/sctp/sctp_output.c | 68 +++++++++++++-------------- src/{vnet => plugins}/sctp/sctp_output_node.c | 12 ++--- src/{vnet => plugins}/sctp/sctp_packet.h | 0 src/{vnet => plugins}/sctp/sctp_pg.c | 0 src/{vnet => plugins}/sctp/sctp_timer.h | 0 src/vnet/CMakeLists.txt | 27 ----------- src/vnet/buffer.h | 14 ------ src/vnet/interface.h | 13 +++++ src/vnet/interface_format.c | 48 ++++++++++++------- src/vnet/ip/format.h | 5 +- src/vnet/ip/punt.c | 25 ++++------ src/vnet/ip/punt_node.c | 1 - src/vnet/vnet_all_api_h.h | 1 - src/vpp-api/client/stat_client.c | 3 ++ test/test_sctp.py | 1 + 27 files changed, 323 insertions(+), 177 deletions(-) create mode 100644 src/plugins/sctp/CMakeLists.txt rename src/{vnet => plugins}/sctp/sctp.api (100%) rename src/{vnet => plugins}/sctp/sctp.c (96%) rename src/{vnet => plugins}/sctp/sctp.h (95%) create mode 100644 src/plugins/sctp/sctp_all_api_h.h rename src/{vnet => plugins}/sctp/sctp_api.c (74%) rename src/{vnet => plugins}/sctp/sctp_debug.h (100%) rename src/{vnet => plugins}/sctp/sctp_error.def (100%) rename src/{vnet => plugins}/sctp/sctp_format.c (97%) rename src/{vnet => plugins}/sctp/sctp_input.c (98%) create mode 100644 src/plugins/sctp/sctp_msg_enum.h rename src/{vnet => plugins}/sctp/sctp_output.c (96%) rename src/{vnet => plugins}/sctp/sctp_output_node.c (97%) rename src/{vnet => plugins}/sctp/sctp_packet.h (100%) rename src/{vnet => plugins}/sctp/sctp_pg.c (100%) rename src/{vnet => plugins}/sctp/sctp_timer.h (100%) diff --git a/MAINTAINERS b/MAINTAINERS index b93d719f524..c57b6d71518 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -437,9 +437,9 @@ M: Ole Troan M: Paul Vinciguerra F: src/vpp-api/python -VNET SCTP +Plugin - SCTP I: sctp -F: src/vnet/sctp +F: src/plugins/sctp/ THE REST I: misc diff --git a/src/plugins/sctp/CMakeLists.txt b/src/plugins/sctp/CMakeLists.txt new file mode 100644 index 00000000000..0c28fe70524 --- /dev/null +++ b/src/plugins/sctp/CMakeLists.txt @@ -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 +) diff --git a/src/vnet/sctp/sctp.api b/src/plugins/sctp/sctp.api similarity index 100% rename from src/vnet/sctp/sctp.api rename to src/plugins/sctp/sctp.api diff --git a/src/vnet/sctp/sctp.c b/src/plugins/sctp/sctp.c similarity index 96% rename from src/vnet/sctp/sctp.c rename to src/plugins/sctp/sctp.c index e27ddb6e11b..14958e55d60 100644 --- a/src/vnet/sctp/sctp.c +++ b/src/plugins/sctp/sctp.c @@ -12,8 +12,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include + +#include +#include + +#include +#include 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* */ /* diff --git a/src/vnet/sctp/sctp.h b/src/plugins/sctp/sctp.h similarity index 95% rename from src/vnet/sctp/sctp.h rename to src/plugins/sctp/sctp.h index 5cbe8d63fc9..a99b01c1c0a 100644 --- a/src/vnet/sctp/sctp.h +++ b/src/plugins/sctp/sctp.h @@ -17,18 +17,44 @@ #include #include -#include -#include +#include +#include #include #include +/* 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 +#include #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) diff --git a/src/plugins/sctp/sctp_all_api_h.h b/src/plugins/sctp/sctp_all_api_h.h new file mode 100644 index 00000000000..16bba76239e --- /dev/null +++ b/src/plugins/sctp/sctp_all_api_h.h @@ -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 diff --git a/src/vnet/sctp/sctp_api.c b/src/plugins/sctp/sctp_api.c similarity index 74% rename from src/vnet/sctp/sctp_api.c rename to src/plugins/sctp/sctp_api.c index 5f93040effc..7702d340aae 100644 --- a/src/vnet/sctp/sctp_api.c +++ b/src/plugins/sctp/sctp_api.c @@ -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 +#include +#include #include -#include +#include -#include +#include #define vl_typedefs /* define message structures */ -#include +#include #undef vl_typedefs #define vl_endianfun /* define message structures */ -#include +#include #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 +#include #undef vl_printfun +#define vl_api_version(n,v) static u32 api_version=(v); +#include +#undef vl_api_version + +#define REPLY_MSG_ID_BASE sctp_main.msg_id_base #include -#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 +#include #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 * diff --git a/src/vnet/sctp/sctp_debug.h b/src/plugins/sctp/sctp_debug.h similarity index 100% rename from src/vnet/sctp/sctp_debug.h rename to src/plugins/sctp/sctp_debug.h diff --git a/src/vnet/sctp/sctp_error.def b/src/plugins/sctp/sctp_error.def similarity index 100% rename from src/vnet/sctp/sctp_error.def rename to src/plugins/sctp/sctp_error.def diff --git a/src/vnet/sctp/sctp_format.c b/src/plugins/sctp/sctp_format.c similarity index 97% rename from src/vnet/sctp/sctp_format.c rename to src/plugins/sctp/sctp_format.c index 49ee04def65..99430c70c2c 100644 --- a/src/vnet/sctp/sctp_format.c +++ b/src/plugins/sctp/sctp_format.c @@ -13,7 +13,7 @@ * limitations under the License. */ -#include +#include /* Format SCTP header. */ u8 * diff --git a/src/vnet/sctp/sctp_input.c b/src/plugins/sctp/sctp_input.c similarity index 98% rename from src/vnet/sctp/sctp_input.c rename to src/plugins/sctp/sctp_input.c index b102d51083a..7f52a2f9c32 100644 --- a/src/vnet/sctp/sctp_input.c +++ b/src/plugins/sctp/sctp_input.c @@ -13,15 +13,15 @@ * limitations under the License. */ #include -#include -#include -#include +#include +#include +#include #include #include static char *sctp_error_strings[] = { #define sctp_error(n,s) s, -#include +#include #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; diff --git a/src/plugins/sctp/sctp_msg_enum.h b/src/plugins/sctp/sctp_msg_enum.h new file mode 100644 index 00000000000..cbf84c659f6 --- /dev/null +++ b/src/plugins/sctp/sctp_msg_enum.h @@ -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 + +#define vl_msg_id(n,h) n, +typedef enum { +#include + /* 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 */ diff --git a/src/vnet/sctp/sctp_output.c b/src/plugins/sctp/sctp_output.c similarity index 96% rename from src/vnet/sctp/sctp_output.c rename to src/plugins/sctp/sctp_output.c index 3c2099a08fd..955010a34b3 100644 --- a/src/vnet/sctp/sctp_output.c +++ b/src/plugins/sctp/sctp_output.c @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include +#include #include #include @@ -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 diff --git a/src/vnet/sctp/sctp_output_node.c b/src/plugins/sctp/sctp_output_node.c similarity index 97% rename from src/vnet/sctp/sctp_output_node.c rename to src/plugins/sctp/sctp_output_node.c index b36c49d3d24..7bf2e896acc 100644 --- a/src/vnet/sctp/sctp_output_node.c +++ b/src/plugins/sctp/sctp_output_node.c @@ -12,8 +12,8 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -#include -#include +#include +#include #include #include @@ -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 +#include #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); diff --git a/src/vnet/sctp/sctp_packet.h b/src/plugins/sctp/sctp_packet.h similarity index 100% rename from src/vnet/sctp/sctp_packet.h rename to src/plugins/sctp/sctp_packet.h diff --git a/src/vnet/sctp/sctp_pg.c b/src/plugins/sctp/sctp_pg.c similarity index 100% rename from src/vnet/sctp/sctp_pg.c rename to src/plugins/sctp/sctp_pg.c diff --git a/src/vnet/sctp/sctp_timer.h b/src/plugins/sctp/sctp_timer.h similarity index 100% rename from src/vnet/sctp/sctp_timer.h rename to src/plugins/sctp/sctp_timer.h diff --git a/src/vnet/CMakeLists.txt b/src/vnet/CMakeLists.txt index 83183af660e..7af1703fa46 100644 --- a/src/vnet/CMakeLists.txt +++ b/src/vnet/CMakeLists.txt @@ -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 ############################################################################## diff --git a/src/vnet/buffer.h b/src/vnet/buffer.h index 324c903db73..97dd31c1979 100644 --- a/src/vnet/buffer.h +++ b/src/vnet/buffer.h @@ -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 { diff --git a/src/vnet/interface.h b/src/vnet/interface.h index d5497f5cc91..c6400ce6978 100644 --- a/src/vnet/interface.h +++ b/src/vnet/interface.h @@ -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 */ /* diff --git a/src/vnet/interface_format.c b/src/vnet/interface_format.c index e25a05aa9f1..1a3ef026081 100644 --- a/src/vnet/interface_format.c +++ b/src/vnet/interface_format.c @@ -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)); + s = format (s, "snat.flags: 0x%x", o->snat.flags); 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'); + 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); + } - s = format (s, "snat.flags: 0x%x", o->snat.flags); - vec_add1 (s, '\n'); 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) { diff --git a/src/vnet/ip/format.h b/src/vnet/ip/format.h index 4d63ba43653..7b1740dad04 100644 --- a/src/vnet/ip/format.h +++ b/src/vnet/ip/format.h @@ -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 */ diff --git a/src/vnet/ip/punt.c b/src/vnet/ip/punt.c index b057a53306e..a979803bc1c 100644 --- a/src/vnet/ip/punt.c +++ b/src/vnet/ip/punt.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include @@ -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); diff --git a/src/vnet/ip/punt_node.c b/src/vnet/ip/punt_node.c index 67f97431c19..32a0884d86b 100644 --- a/src/vnet/ip/punt_node.c +++ b/src/vnet/ip/punt_node.c @@ -27,7 +27,6 @@ #include #include #include -#include #include #include diff --git a/src/vnet/vnet_all_api_h.h b/src/vnet/vnet_all_api_h.h index 5dcdad4f987..dc0ab5fcf9b 100644 --- a/src/vnet/vnet_all_api_h.h +++ b/src/vnet/vnet_all_api_h.h @@ -68,7 +68,6 @@ #include #include #include -#include #include #include #include diff --git a/src/vpp-api/client/stat_client.c b/src/vpp-api/client/stat_client.c index cfe213d938a..0eaec15ffb6 100644 --- a/src/vpp-api/client/stat_client.c +++ b/src/vpp-api/client/stat_client.c @@ -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 diff --git a/test/test_sctp.py b/test/test_sctp.py index 59dcfd35ded..75bbb23f31f 100644 --- a/test/test_sctp.py +++ b/test/test_sctp.py @@ -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 -- 2.16.6