Fix issue with udp port registration when running multithreaded

Change-Id: I16606757176649e61f0a51895329586311144766
Signed-off-by: Damjan Marion <damarion@cisco.com>
diff --git a/src/vnet/udp/udp.h b/src/vnet/udp/udp.h
index 7ab26ce..bd163e2 100644
--- a/src/vnet/udp/udp.h
+++ b/src/vnet/udp/udp.h
@@ -146,6 +146,13 @@
   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;
diff --git a/src/vnet/udp/udp_local.c b/src/vnet/udp/udp_local.c
index 3a60b29..8c0ac46 100644
--- a/src/vnet/udp/udp_local.c
+++ b/src/vnet/udp/udp_local.c
@@ -58,14 +58,6 @@
   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 @@
 		    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 @@
 	  /* 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 @@
 	  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 @@
   /* 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 @@
   /* 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_main_t *um = &udp_main;
   udp_dst_port_info_t *pi;
-  udp_input_runtime_t *rt;
   u16 *n;
 
   {
@@ -520,15 +512,14 @@
 				       : 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_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 @@
     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 @@
   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_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 @@
 
 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
  *