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
--- /dev/null
+# 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
+)
* 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;
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)
{
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;
}
.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* */
/*
#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
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;
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);
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;
{
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)
--- /dev/null
+/*
+ * 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>
/*
*------------------------------------------------------------------
- * 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");
*------------------------------------------------------------------
*/
-#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)
}
#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
*
* limitations under the License.
*/
-#include <vnet/sctp/sctp.h>
+#include <sctp/sctp.h>
/* Format SCTP header. */
u8 *
* 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
};
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);
* 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))
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))
{
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)
{
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))
{
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 */
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;
--- /dev/null
+/*
+ * 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 */
* 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>
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);
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);
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, "
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
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;
}
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;
}
/**
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;
}
/**
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;
}
/**
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;
}
/**
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;
}
/*
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;
}
/*
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;
}
/**
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;
}
/**
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
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
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
* 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>
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
};
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))
{
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);
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
##############################################################################
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
{
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. */
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;
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 */
/*
{
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: ");
(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;
}
{
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;
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)
{
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 */
#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>
* @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.
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)
{
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);
}
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);
#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>
#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>
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
@classmethod
def setUpClass(cls):
+ cls.extra_vpp_plugin_config.append("plugin sctp_plugin.so { enable }")
super(TestSCTP, cls).setUpClass()
@classmethod