From e23680056e987eb5b4d4afdb5d4044d1973847e8 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Mon, 3 Apr 2017 14:56:08 +0200 Subject: Fix issue with udp port registration when running multithreaded Change-Id: I16606757176649e61f0a51895329586311144766 Signed-off-by: Damjan Marion --- src/vnet/udp/udp.h | 7 +++ src/vnet/udp/udp_local.c | 118 ++++++++++++++++++----------------------------- 2 files changed, 51 insertions(+), 74 deletions(-) diff --git a/src/vnet/udp/udp.h b/src/vnet/udp/udp.h index 7ab26ce96f0..bd163e273d2 100644 --- a/src/vnet/udp/udp.h +++ b/src/vnet/udp/udp.h @@ -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; diff --git a/src/vnet/udp/udp_local.c b/src/vnet/udp/udp_local.c index 3a60b29b990..8c0ac465e04 100644 --- a/src/vnet/udp/udp_local.c +++ b/src/vnet/udp/udp_local.c @@ -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 * -- cgit 1.2.3-korg