Fix issue with udp port registration when running multithreaded 08/6008/2
authorDamjan Marion <damarion@cisco.com>
Mon, 3 Apr 2017 12:56:08 +0000 (14:56 +0200)
committerDamjan Marion <damarion@cisco.com>
Tue, 4 Apr 2017 19:40:27 +0000 (21:40 +0200)
Change-Id: I16606757176649e61f0a51895329586311144766
Signed-off-by: Damjan Marion <damarion@cisco.com>
src/vnet/udp/udp.h
src/vnet/udp/udp_local.c

index 7ab26ce..bd163e2 100644 (file)
@@ -146,6 +146,13 @@ typedef struct
   uword *dst_port_info_by_name[N_UDP_AF];
   uword *dst_port_info_by_dst_port[N_UDP_AF];
 
+  /* Sparse vector mapping udp dst_port in network byte order
+     to next index. */
+  u16 *next_by_dst_port4;
+  u16 *next_by_dst_port6;
+  u8 punt_unknown4;
+  u8 punt_unknown6;
+
   /* convenience */
   vlib_main_t *vlib_main;
 } udp_main_t;
index 3a60b29..8c0ac46 100644 (file)
@@ -58,14 +58,6 @@ format_udp_rx_trace (u8 * s, va_list * args)
   return s;
 }
 
-typedef struct
-{
-  /* Sparse vector mapping udp dst_port in network byte order
-     to next index. */
-  u16 *next_by_dst_port;
-  u8 punt_unknown;
-} udp_input_runtime_t;
-
 vlib_node_registration_t udp4_input_node;
 vlib_node_registration_t udp6_input_node;
 
@@ -74,12 +66,10 @@ udp46_input_inline (vlib_main_t * vm,
                    vlib_node_runtime_t * node,
                    vlib_frame_t * from_frame, int is_ip4)
 {
-  udp_input_runtime_t *rt = is_ip4 ?
-    (void *) vlib_node_get_runtime_data (vm, udp4_input_node.index)
-    : (void *) vlib_node_get_runtime_data (vm, udp6_input_node.index);
+  udp_main_t *um = &udp_main;
   __attribute__ ((unused)) u32 n_left_from, next_index, *from, *to_next;
   word n_no_listener = 0;
-  u8 punt_unknown = rt->punt_unknown;
+  u8 punt_unknown = is_ip4 ? um->punt_unknown4 : um->punt_unknown6;
 
   from = vlib_frame_vector_args (from_frame);
   n_left_from = from_frame->n_vectors;
@@ -178,10 +168,15 @@ udp46_input_inline (vlib_main_t * vm,
          /* Index sparse array with network byte order. */
          dst_port0 = (error0 == 0) ? h0->dst_port : 0;
          dst_port1 = (error1 == 0) ? h1->dst_port : 0;
-         sparse_vec_index2 (rt->next_by_dst_port, dst_port0, dst_port1,
-                            &i0, &i1);
-         next0 = (error0 == 0) ? vec_elt (rt->next_by_dst_port, i0) : next0;
-         next1 = (error1 == 0) ? vec_elt (rt->next_by_dst_port, i1) : next1;
+         sparse_vec_index2 (is_ip4 ? um->next_by_dst_port4 :
+                            um->next_by_dst_port6,
+                            dst_port0, dst_port1, &i0, &i1);
+         next0 = (error0 == 0) ?
+           vec_elt (is_ip4 ? um->next_by_dst_port4 : um->next_by_dst_port6,
+                    i0) : next0;
+         next1 = (error1 == 0) ?
+           vec_elt (is_ip4 ? um->next_by_dst_port4 : um->next_by_dst_port6,
+                    i1) : next1;
 
          if (PREDICT_FALSE (i0 == SPARSE_VEC_INVALID_INDEX))
            {
@@ -324,8 +319,10 @@ udp46_input_inline (vlib_main_t * vm,
          if (PREDICT_TRUE (clib_net_to_host_u16 (h0->length) <=
                            vlib_buffer_length_in_chain (vm, b0)))
            {
-             i0 = sparse_vec_index (rt->next_by_dst_port, h0->dst_port);
-             next0 = vec_elt (rt->next_by_dst_port, i0);
+             i0 = sparse_vec_index (is_ip4 ? um->next_by_dst_port4 :
+                                    um->next_by_dst_port6, h0->dst_port);
+             next0 = vec_elt (is_ip4 ? um->next_by_dst_port4 :
+                              um->next_by_dst_port6, i0);
 
              if (PREDICT_FALSE (i0 == SPARSE_VEC_INVALID_INDEX))
                {
@@ -424,8 +421,6 @@ VLIB_REGISTER_NODE (udp4_input_node) = {
   /* Takes a vector of packets. */
   .vector_size = sizeof (u32),
 
-  .runtime_data_bytes = sizeof (udp_input_runtime_t),
-
   .n_errors = UDP_N_ERROR,
   .error_strings = udp_error_strings,
 
@@ -451,8 +446,6 @@ VLIB_REGISTER_NODE (udp6_input_node) = {
   /* Takes a vector of packets. */
   .vector_size = sizeof (u32),
 
-  .runtime_data_bytes = sizeof (udp_input_runtime_t),
-
   .n_errors = UDP_N_ERROR,
   .error_strings = udp_error_strings,
 
@@ -497,7 +490,6 @@ udp_register_dst_port (vlib_main_t * vm,
 {
   udp_main_t *um = &udp_main;
   udp_dst_port_info_t *pi;
-  udp_input_runtime_t *rt;
   u16 *n;
 
   {
@@ -520,15 +512,14 @@ udp_register_dst_port (vlib_main_t * vm,
                                       : udp6_input_node.index, node_index);
 
   /* Setup udp protocol -> next index sparse vector mapping. */
-  /* *INDENT-OFF* */
-  foreach_vlib_main({
-    rt = vlib_node_get_runtime_data
-      (this_vlib_main, is_ip4 ? udp4_input_node.index : udp6_input_node.index);
-    n = sparse_vec_validate (rt->next_by_dst_port,
+  if (is_ip4)
+    n = sparse_vec_validate (um->next_by_dst_port4,
                             clib_host_to_net_u16 (dst_port));
-    n[0] = pi->next_index;
-  });
-  /* *INDENT-ON* */
+  else
+    n = sparse_vec_validate (um->next_by_dst_port6,
+                            clib_host_to_net_u16 (dst_port));
+
+  n[0] = pi->next_index;
 }
 
 void
@@ -536,7 +527,6 @@ udp_unregister_dst_port (vlib_main_t * vm, udp_dst_port_t dst_port, u8 is_ip4)
 {
   udp_main_t *um = &udp_main;
   udp_dst_port_info_t *pi;
-  udp_input_runtime_t *rt;
   u16 *n;
 
   pi = udp_get_dst_port_info (um, dst_port, is_ip4);
@@ -545,32 +535,30 @@ udp_unregister_dst_port (vlib_main_t * vm, udp_dst_port_t dst_port, u8 is_ip4)
     return;
 
   /* Kill the mapping. Don't bother killing the pi, it may be back. */
-  /* *INDENT-OFF* */
-  foreach_vlib_main({
-    rt = vlib_node_get_runtime_data
-      (this_vlib_main, is_ip4 ? udp4_input_node.index : udp6_input_node.index);
-    n = sparse_vec_validate (rt->next_by_dst_port,
+  if (is_ip4)
+    n = sparse_vec_validate (um->next_by_dst_port4,
                             clib_host_to_net_u16 (dst_port));
-    n[0] = SPARSE_VEC_INVALID_INDEX;
-  });
-  /* *INDENT-ON* */
+  else
+    n = sparse_vec_validate (um->next_by_dst_port6,
+                            clib_host_to_net_u16 (dst_port));
+
+  n[0] = SPARSE_VEC_INVALID_INDEX;
 }
 
 void
 udp_punt_unknown (vlib_main_t * vm, u8 is_ip4, u8 is_add)
 {
-  udp_input_runtime_t *rt;
-
+  udp_main_t *um = &udp_main;
   {
     clib_error_t *error = vlib_call_init_function (vm, udp_local_init);
     if (error)
       clib_error_report (error);
   }
 
-  rt = vlib_node_get_runtime_data
-    (vm, is_ip4 ? udp4_input_node.index : udp6_input_node.index);
-
-  rt->punt_unknown = is_add;
+  if (is_ip4)
+    um->punt_unknown4 = is_add;
+  else
+    um->punt_unknown6 = is_add;
 }
 
 /* Parse a UDP header. */
@@ -612,24 +600,6 @@ udp_setup_node (vlib_main_t * vm, u32 node_index)
   pn->unformat_edit = unformat_pg_udp_header;
 }
 
-static void
-udp_local_node_runtime_init (vlib_main_t * vm)
-{
-  udp_input_runtime_t *rt;
-
-  rt = vlib_node_get_runtime_data (vm, udp4_input_node.index);
-  rt->next_by_dst_port = sparse_vec_new
-    ( /* elt bytes */ sizeof (rt->next_by_dst_port[0]),
-     /* bits in index */ BITS (((udp_header_t *) 0)->dst_port));
-  rt->punt_unknown = 0;
-
-  rt = vlib_node_get_runtime_data (vm, udp6_input_node.index);
-  rt->next_by_dst_port = sparse_vec_new
-    ( /* elt bytes */ sizeof (rt->next_by_dst_port[0]),
-     /* bits in index */ BITS (((udp_header_t *) 0)->dst_port));
-  rt->punt_unknown = 0;
-}
-
 clib_error_t *
 udp_local_init (vlib_main_t * vm)
 {
@@ -653,7 +623,16 @@ udp_local_init (vlib_main_t * vm)
   udp_setup_node (vm, udp4_input_node.index);
   udp_setup_node (vm, udp6_input_node.index);
 
-  udp_local_node_runtime_init (vm);
+  um->punt_unknown4 = 0;
+  um->punt_unknown6 = 0;
+
+  um->next_by_dst_port4 = sparse_vec_new
+    ( /* elt bytes */ sizeof (um->next_by_dst_port4[0]),
+     /* bits in index */ BITS (((udp_header_t *) 0)->dst_port));
+
+  um->next_by_dst_port6 = sparse_vec_new
+    ( /* elt bytes */ sizeof (um->next_by_dst_port6[0]),
+     /* bits in index */ BITS (((udp_header_t *) 0)->dst_port));
 
 #define _(n,s) add_dst_port (um, UDP_DST_PORT_##s, #s, 1 /* is_ip4 */);
   foreach_udp4_dst_port
@@ -668,15 +647,6 @@ udp_local_init (vlib_main_t * vm)
 
 VLIB_INIT_FUNCTION (udp_local_init);
 
-clib_error_t *
-udp_local_worker_init (vlib_main_t * vm)
-{
-  udp_local_node_runtime_init (vm);
-  return 0;
-}
-
-VLIB_WORKER_INIT_FUNCTION (udp_local_worker_init);
-
 /*
  * fd.io coding-style-patch-verification: ON
  *