sctp: move to plugins, disabled by default 74/20374/15
authorFlorin Coras <fcoras@cisco.com>
Wed, 26 Jun 2019 23:27:13 +0000 (16:27 -0700)
committerDave Barach <openvpp@barachs.net>
Fri, 5 Jul 2019 17:49:39 +0000 (17:49 +0000)
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>
27 files changed:
MAINTAINERS
src/plugins/sctp/CMakeLists.txt [new file with mode: 0644]
src/plugins/sctp/sctp.api [moved from src/vnet/sctp/sctp.api with 100% similarity]
src/plugins/sctp/sctp.c [moved from src/vnet/sctp/sctp.c with 96% similarity]
src/plugins/sctp/sctp.h [moved from src/vnet/sctp/sctp.h with 95% similarity]
src/plugins/sctp/sctp_all_api_h.h [new file with mode: 0644]
src/plugins/sctp/sctp_api.c [moved from src/vnet/sctp/sctp_api.c with 74% similarity]
src/plugins/sctp/sctp_debug.h [moved from src/vnet/sctp/sctp_debug.h with 100% similarity]
src/plugins/sctp/sctp_error.def [moved from src/vnet/sctp/sctp_error.def with 100% similarity]
src/plugins/sctp/sctp_format.c [moved from src/vnet/sctp/sctp_format.c with 97% similarity]
src/plugins/sctp/sctp_input.c [moved from src/vnet/sctp/sctp_input.c with 98% similarity]
src/plugins/sctp/sctp_msg_enum.h [new file with mode: 0644]
src/plugins/sctp/sctp_output.c [moved from src/vnet/sctp/sctp_output.c with 96% similarity]
src/plugins/sctp/sctp_output_node.c [moved from src/vnet/sctp/sctp_output_node.c with 97% similarity]
src/plugins/sctp/sctp_packet.h [moved from src/vnet/sctp/sctp_packet.h with 100% similarity]
src/plugins/sctp/sctp_pg.c [moved from src/vnet/sctp/sctp_pg.c with 100% similarity]
src/plugins/sctp/sctp_timer.h [moved from src/vnet/sctp/sctp_timer.h with 100% similarity]
src/vnet/CMakeLists.txt
src/vnet/buffer.h
src/vnet/interface.h
src/vnet/interface_format.c
src/vnet/ip/format.h
src/vnet/ip/punt.c
src/vnet/ip/punt_node.c
src/vnet/vnet_all_api_h.h
src/vpp-api/client/stat_client.c
test/test_sctp.py

index b93d719..c57b6d7 100644 (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
diff --git a/src/plugins/sctp/CMakeLists.txt b/src/plugins/sctp/CMakeLists.txt
new file mode 100644 (file)
index 0000000..0c28fe7
--- /dev/null
@@ -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
+)
similarity index 96%
rename from src/vnet/sctp/sctp.c
rename to src/plugins/sctp/sctp.c
index e27ddb6..14958e5 100644 (file)
  * 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* */
 
 /*
similarity index 95%
rename from src/vnet/sctp/sctp.h
rename to src/plugins/sctp/sctp.h
index 5cbe8d6..a99b01c 100644 (file)
 
 #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)
diff --git a/src/plugins/sctp/sctp_all_api_h.h b/src/plugins/sctp/sctp_all_api_h.h
new file mode 100644 (file)
index 0000000..16bba76
--- /dev/null
@@ -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>
similarity index 74%
rename from src/vnet/sctp/sctp_api.c
rename to src/plugins/sctp/sctp_api.c
index 5f93040..7702d34 100644 (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");
  *------------------------------------------------------------------
  */
 
-#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
  *
similarity index 97%
rename from src/vnet/sctp/sctp_format.c
rename to src/plugins/sctp/sctp_format.c
index 49ee04d..99430c7 100644 (file)
@@ -13,7 +13,7 @@
  * limitations under the License.
  */
 
-#include <vnet/sctp/sctp.h>
+#include <sctp/sctp.h>
 
 /* Format SCTP header. */
 u8 *
similarity index 98%
rename from src/vnet/sctp/sctp_input.c
rename to src/plugins/sctp/sctp_input.c
index b102d51..7f52a2f 100644 (file)
  * 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;
diff --git a/src/plugins/sctp/sctp_msg_enum.h b/src/plugins/sctp/sctp_msg_enum.h
new file mode 100644 (file)
index 0000000..cbf84c6
--- /dev/null
@@ -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 */
similarity index 96%
rename from src/vnet/sctp/sctp_output.c
rename to src/plugins/sctp/sctp_output.c
index 3c2099a..955010a 100644 (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
similarity index 97%
rename from src/vnet/sctp/sctp_output_node.c
rename to src/plugins/sctp/sctp_output_node.c
index b36c49d..7bf2e89 100644 (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);
 
index 83183af..7af1703 100644 (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
 ##############################################################################
index 324c903..97dd31c 100644 (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
     {
index d5497f5..c6400ce 100644 (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 */
 
 /*
index e25a05a..1a3ef02 100644 (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));
+  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)
 {
index 4d63ba4..7b1740d 100644 (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 */
 
index b057a53..a979803 100644 (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);
 
index 67f9743..32a0884 100644 (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>
 
index 5dcdad4..dc0ab5f 100644 (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>
index cfe213d..0eaec15 100644 (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
index 59dcfd3..75bbb23 100644 (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