X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fudp%2Fudp_local.c;h=6531b73cd1181d28389d6b76811614164f205ff6;hb=HEAD;hp=3a60b29b99059d1022de1ab2a5aac3de9580022e;hpb=e9f929b52ddb741ec1e4cb2d92c6be1e798933a0;p=vpp.git diff --git a/src/vnet/udp/udp_local.c b/src/vnet/udp/udp_local.c index 3a60b29b990..6531b73cd11 100644 --- a/src/vnet/udp/udp_local.c +++ b/src/vnet/udp/udp_local.c @@ -1,7 +1,7 @@ /* * node.c: udp packet processing * - * Copyright (c) 2013 Cisco and/or its affiliates. + * Copyright (c) 2013-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: @@ -21,35 +21,34 @@ #include #include -udp_main_t udp_main; - -#define foreach_udp_input_next \ - _ (PUNT, "error-punt") \ - _ (DROP, "error-drop") \ - _ (ICMP4_ERROR, "ip4-icmp-error") \ - _ (ICMP6_ERROR, "ip6-icmp-error") - typedef enum { -#define _(s,n) UDP_INPUT_NEXT_##s, - foreach_udp_input_next -#undef _ - UDP_INPUT_N_NEXT, -} udp_input_next_t; + UDP_LOCAL_NEXT_PUNT, + UDP_LOCAL_NEXT_DROP, + UDP_LOCAL_NEXT_ICMP, + UDP_LOCAL_N_NEXT +} udp_local_next_t; typedef struct { u16 src_port; u16 dst_port; u8 bound; -} udp_rx_trace_t; +} udp_local_rx_trace_t; + +static vlib_error_desc_t udp_error_counters[] = { +#define udp_error(f, n, s, d) { #n, d, VL_COUNTER_SEVERITY_##s }, +#include "udp_error.def" +#undef udp_error +}; +#ifndef CLIB_MARCH_VARIANT u8 * format_udp_rx_trace (u8 * s, va_list * args) { CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *); CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *); - udp_rx_trace_t *t = va_arg (*args, udp_rx_trace_t *); + udp_local_rx_trace_t *t = va_arg (*args, udp_local_rx_trace_t *); s = format (s, "UDP: src-port %d dst-port %d%s", clib_net_to_host_u16 (t->src_port), @@ -57,30 +56,59 @@ format_udp_rx_trace (u8 * s, va_list * args) t->bound ? "" : " (no listener)"); return s; } +#endif /* CLIB_MARCH_VARIANT */ -typedef struct +always_inline void +udp_dispatch_error (vlib_node_runtime_t *node, vlib_buffer_t *b, u32 advance, + u8 is_ip4, u32 *next) { - /* 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; + udp_main_t *um = &udp_main; + u8 punt_unknown = is_ip4 ? um->punt_unknown4 : um->punt_unknown6; -vlib_node_registration_t udp4_input_node; -vlib_node_registration_t udp6_input_node; + if (PREDICT_FALSE (punt_unknown)) + { + vlib_buffer_advance (b, -(word) advance); + b->error = node->errors[UDP_ERROR_PUNT]; + *next = UDP_LOCAL_NEXT_PUNT; + } + else if (um->icmp_send_unreachable_disabled) + { + *next = UDP_LOCAL_NEXT_DROP; + b->error = node->errors[UDP_ERROR_NO_LISTENER]; + } + else + { + /* move the pointer back so icmp-error can find the ip packet header */ + vlib_buffer_advance (b, -(word) advance); + + if (is_ip4) + { + icmp4_error_set_vnet_buffer ( + b, ICMP4_destination_unreachable, + ICMP4_destination_unreachable_port_unreachable, 0); + b->error = node->errors[UDP_ERROR_NO_LISTENER]; + *next = UDP_LOCAL_NEXT_ICMP; + } + else + { + icmp6_error_set_vnet_buffer ( + b, ICMP6_destination_unreachable, + ICMP6_destination_unreachable_port_unreachable, 0); + b->error = node->errors[UDP_ERROR_NO_LISTENER]; + *next = UDP_LOCAL_NEXT_ICMP; + } + } +} always_inline uword -udp46_input_inline (vlib_main_t * vm, +udp46_local_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; - + u16 *next_by_dst_port = (is_ip4 ? + um->next_by_dst_port4 : um->next_by_dst_port6); from = vlib_frame_vector_args (from_frame); n_left_from = from_frame->n_vectors; @@ -97,9 +125,8 @@ udp46_input_inline (vlib_main_t * vm, u32 bi0, bi1; vlib_buffer_t *b0, *b1; udp_header_t *h0 = 0, *h1 = 0; - u32 i0, i1, dst_port0, dst_port1; + u32 i0, i1, next0, next1; u32 advance0, advance1; - u32 error0, next0, error1, next1; /* Prefetch next iteration. */ { @@ -130,8 +157,8 @@ udp46_input_inline (vlib_main_t * vm, /* ip4/6_local hands us the ip header, not the udp header */ if (is_ip4) { - advance0 = sizeof (ip4_header_t); - advance1 = sizeof (ip4_header_t); + advance0 = ip4_header_bytes (vlib_buffer_get_current (b0)); + advance1 = ip4_header_bytes (vlib_buffer_get_current (b1)); } else { @@ -141,144 +168,128 @@ udp46_input_inline (vlib_main_t * vm, if (PREDICT_FALSE (b0->current_length < advance0 + sizeof (*h0))) { - error0 = UDP_ERROR_LENGTH_ERROR; - next0 = UDP_INPUT_NEXT_DROP; + b0->error = node->errors[UDP_ERROR_LENGTH_ERROR]; + next0 = UDP_LOCAL_NEXT_DROP; } else { vlib_buffer_advance (b0, advance0); h0 = vlib_buffer_get_current (b0); - error0 = next0 = 0; + next0 = UDP_LOCAL_NEXT_PUNT; if (PREDICT_FALSE (clib_net_to_host_u16 (h0->length) > vlib_buffer_length_in_chain (vm, b0))) { - error0 = UDP_ERROR_LENGTH_ERROR; - next0 = UDP_INPUT_NEXT_DROP; + b0->error = node->errors[UDP_ERROR_LENGTH_ERROR]; + next0 = UDP_LOCAL_NEXT_DROP; } } if (PREDICT_FALSE (b1->current_length < advance1 + sizeof (*h1))) { - error1 = UDP_ERROR_LENGTH_ERROR; - next1 = UDP_INPUT_NEXT_DROP; + b1->error = node->errors[UDP_ERROR_LENGTH_ERROR]; + next1 = UDP_LOCAL_NEXT_DROP; } else { vlib_buffer_advance (b1, advance1); h1 = vlib_buffer_get_current (b1); - error1 = next1 = 0; + next1 = UDP_LOCAL_NEXT_PUNT; if (PREDICT_FALSE (clib_net_to_host_u16 (h1->length) > vlib_buffer_length_in_chain (vm, b1))) { - error1 = UDP_ERROR_LENGTH_ERROR; - next1 = UDP_INPUT_NEXT_DROP; + b1->error = node->errors[UDP_ERROR_LENGTH_ERROR]; + next1 = UDP_LOCAL_NEXT_DROP; } } /* 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; - - if (PREDICT_FALSE (i0 == SPARSE_VEC_INVALID_INDEX)) + if (PREDICT_TRUE (next0 == UDP_LOCAL_NEXT_PUNT && + next1 == UDP_LOCAL_NEXT_PUNT)) { - // move the pointer back so icmp-error can find the - // ip packet header - vlib_buffer_advance (b0, -(word) advance0); + sparse_vec_index2 (next_by_dst_port, h0->dst_port, h1->dst_port, + &i0, &i1); + next0 = vec_elt (next_by_dst_port, i0); + next1 = vec_elt (next_by_dst_port, i1); - if (PREDICT_FALSE (punt_unknown)) + if (PREDICT_FALSE (i0 == SPARSE_VEC_INVALID_INDEX || + next0 == UDP_NO_NODE_SET)) + { + udp_dispatch_error (node, b0, advance0, is_ip4, &next0); + } + else { - b0->error = node->errors[UDP_ERROR_PUNT]; - next0 = UDP_INPUT_NEXT_PUNT; + b0->error = node->errors[UDP_ERROR_NONE]; + // advance to the payload + vlib_buffer_advance (b0, sizeof (*h0)); } - else if (is_ip4) + + if (PREDICT_FALSE (i1 == SPARSE_VEC_INVALID_INDEX || + next1 == UDP_NO_NODE_SET)) { - icmp4_error_set_vnet_buffer (b0, - ICMP4_destination_unreachable, - ICMP4_destination_unreachable_port_unreachable, - 0); - next0 = UDP_INPUT_NEXT_ICMP4_ERROR; - n_no_listener++; + udp_dispatch_error (node, b1, advance1, is_ip4, &next1); } else { - icmp6_error_set_vnet_buffer (b0, - ICMP6_destination_unreachable, - ICMP6_destination_unreachable_port_unreachable, - 0); - next0 = UDP_INPUT_NEXT_ICMP6_ERROR; - n_no_listener++; + b1->error = node->errors[UDP_ERROR_NONE]; + // advance to the payload + vlib_buffer_advance (b1, sizeof (*h1)); } } - else + else if (next0 == UDP_LOCAL_NEXT_PUNT) { - b0->error = node->errors[UDP_ERROR_NONE]; - // advance to the payload - vlib_buffer_advance (b0, sizeof (*h0)); - } + i0 = sparse_vec_index (next_by_dst_port, h0->dst_port); + next0 = vec_elt (next_by_dst_port, i0); - if (PREDICT_FALSE (i1 == SPARSE_VEC_INVALID_INDEX)) - { - // move the pointer back so icmp-error can find the - // ip packet header - vlib_buffer_advance (b1, -(word) advance1); - - if (PREDICT_FALSE (punt_unknown)) - { - b1->error = node->errors[UDP_ERROR_PUNT]; - next1 = UDP_INPUT_NEXT_PUNT; - } - else if (is_ip4) + if (PREDICT_FALSE (i0 == SPARSE_VEC_INVALID_INDEX || + next0 == UDP_NO_NODE_SET)) { - icmp4_error_set_vnet_buffer (b1, - ICMP4_destination_unreachable, - ICMP4_destination_unreachable_port_unreachable, - 0); - next1 = UDP_INPUT_NEXT_ICMP4_ERROR; - n_no_listener++; + udp_dispatch_error (node, b0, advance0, is_ip4, &next0); } else { - icmp6_error_set_vnet_buffer (b1, - ICMP6_destination_unreachable, - ICMP6_destination_unreachable_port_unreachable, - 0); - next1 = UDP_INPUT_NEXT_ICMP6_ERROR; - n_no_listener++; + b0->error = node->errors[UDP_ERROR_NONE]; + // advance to the payload + vlib_buffer_advance (b0, sizeof (*h0)); } } - else + else if (next1 == UDP_LOCAL_NEXT_PUNT) { - b1->error = node->errors[UDP_ERROR_NONE]; - // advance to the payload - vlib_buffer_advance (b1, sizeof (*h1)); + i1 = sparse_vec_index (next_by_dst_port, h1->dst_port); + next1 = vec_elt (next_by_dst_port, i1); + + if (PREDICT_FALSE (i1 == SPARSE_VEC_INVALID_INDEX || + next1 == UDP_NO_NODE_SET)) + { + udp_dispatch_error (node, b1, advance1, is_ip4, &next1); + } + else + { + b1->error = node->errors[UDP_ERROR_NONE]; + // advance to the payload + vlib_buffer_advance (b1, sizeof (*h1)); + } } if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) { - udp_rx_trace_t *tr = vlib_add_trace (vm, node, - b0, sizeof (*tr)); + udp_local_rx_trace_t *tr = vlib_add_trace (vm, node, + b0, sizeof (*tr)); if (b0->error != node->errors[UDP_ERROR_LENGTH_ERROR]) { tr->src_port = h0 ? h0->src_port : 0; tr->dst_port = h0 ? h0->dst_port : 0; - tr->bound = (next0 != UDP_INPUT_NEXT_ICMP4_ERROR && - next0 != UDP_INPUT_NEXT_ICMP6_ERROR); + tr->bound = (next0 != UDP_LOCAL_NEXT_ICMP); } } if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED)) { - udp_rx_trace_t *tr = vlib_add_trace (vm, node, - b1, sizeof (*tr)); + udp_local_rx_trace_t *tr = vlib_add_trace (vm, node, + b1, sizeof (*tr)); if (b1->error != node->errors[UDP_ERROR_LENGTH_ERROR]) { tr->src_port = h1 ? h1->src_port : 0; tr->dst_port = h1 ? h1->dst_port : 0; - tr->bound = (next1 != UDP_INPUT_NEXT_ICMP4_ERROR && - next1 != UDP_INPUT_NEXT_ICMP6_ERROR); + tr->bound = (next1 != UDP_LOCAL_NEXT_ICMP); } } @@ -306,14 +317,14 @@ udp46_input_inline (vlib_main_t * vm, /* ip4/6_local hands us the ip header, not the udp header */ if (is_ip4) - advance0 = sizeof (ip4_header_t); + advance0 = ip4_header_bytes (vlib_buffer_get_current (b0)); else advance0 = sizeof (ip6_header_t); if (PREDICT_FALSE (b0->current_length < advance0 + sizeof (*h0))) { b0->error = node->errors[UDP_ERROR_LENGTH_ERROR]; - next0 = UDP_INPUT_NEXT_DROP; + next0 = UDP_LOCAL_NEXT_DROP; goto trace_x1; } @@ -324,38 +335,13 @@ 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 (next_by_dst_port, h0->dst_port); + next0 = vec_elt (next_by_dst_port, i0); - if (PREDICT_FALSE (i0 == SPARSE_VEC_INVALID_INDEX)) + if (PREDICT_FALSE ((i0 == SPARSE_VEC_INVALID_INDEX) || + next0 == UDP_NO_NODE_SET)) { - // move the pointer back so icmp-error can find the - // ip packet header - vlib_buffer_advance (b0, -(word) advance0); - - if (PREDICT_FALSE (punt_unknown)) - { - b0->error = node->errors[UDP_ERROR_PUNT]; - next0 = UDP_INPUT_NEXT_PUNT; - } - else if (is_ip4) - { - icmp4_error_set_vnet_buffer (b0, - ICMP4_destination_unreachable, - ICMP4_destination_unreachable_port_unreachable, - 0); - next0 = UDP_INPUT_NEXT_ICMP4_ERROR; - n_no_listener++; - } - else - { - icmp6_error_set_vnet_buffer (b0, - ICMP6_destination_unreachable, - ICMP6_destination_unreachable_port_unreachable, - 0); - next0 = UDP_INPUT_NEXT_ICMP6_ERROR; - n_no_listener++; - } + udp_dispatch_error (node, b0, advance0, is_ip4, &next0); } else { @@ -367,20 +353,19 @@ udp46_input_inline (vlib_main_t * vm, else { b0->error = node->errors[UDP_ERROR_LENGTH_ERROR]; - next0 = UDP_INPUT_NEXT_DROP; + next0 = UDP_LOCAL_NEXT_DROP; } trace_x1: if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED)) { - udp_rx_trace_t *tr = vlib_add_trace (vm, node, - b0, sizeof (*tr)); + udp_local_rx_trace_t *tr = vlib_add_trace (vm, node, + b0, sizeof (*tr)); if (b0->error != node->errors[UDP_ERROR_LENGTH_ERROR]) { tr->src_port = h0->src_port; tr->dst_port = h0->dst_port; - tr->bound = (next0 != UDP_INPUT_NEXT_ICMP4_ERROR && - next0 != UDP_INPUT_NEXT_ICMP6_ERROR); + tr->bound = (next0 != UDP_LOCAL_NEXT_ICMP); } } @@ -391,89 +376,67 @@ udp46_input_inline (vlib_main_t * vm, vlib_put_next_frame (vm, node, next_index, n_left_to_next); } - vlib_error_count (vm, node->node_index, UDP_ERROR_NO_LISTENER, - n_no_listener); return from_frame->n_vectors; } -static char *udp_error_strings[] = { -#define udp_error(n,s) s, -#include "udp_error.def" -#undef udp_error -}; - -static uword -udp4_input (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * from_frame) +VLIB_NODE_FN (udp4_local_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * from_frame) { - return udp46_input_inline (vm, node, from_frame, 1 /* is_ip4 */ ); + return udp46_local_inline (vm, node, from_frame, 1 /* is_ip4 */ ); } -static uword -udp6_input (vlib_main_t * vm, - vlib_node_runtime_t * node, vlib_frame_t * from_frame) +VLIB_NODE_FN (udp6_local_node) (vlib_main_t * vm, + vlib_node_runtime_t * node, + vlib_frame_t * from_frame) { - return udp46_input_inline (vm, node, from_frame, 0 /* is_ip4 */ ); + return udp46_local_inline (vm, node, from_frame, 0 /* is_ip4 */ ); } - -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (udp4_input_node) = { - .function = udp4_input, +VLIB_REGISTER_NODE (udp4_local_node) = { .name = "ip4-udp-lookup", /* 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, + .error_counters = udp_error_counters, - .n_next_nodes = UDP_INPUT_N_NEXT, + .n_next_nodes = UDP_LOCAL_N_NEXT, .next_nodes = { -#define _(s,n) [UDP_INPUT_NEXT_##s] = n, - foreach_udp_input_next -#undef _ + [UDP_LOCAL_NEXT_PUNT]= "ip4-punt", + [UDP_LOCAL_NEXT_DROP]= "ip4-drop", + [UDP_LOCAL_NEXT_ICMP]= "ip4-icmp-error", }, .format_buffer = format_udp_header, .format_trace = format_udp_rx_trace, .unformat_buffer = unformat_udp_header, }; -/* *INDENT-ON* */ - -VLIB_NODE_FUNCTION_MULTIARCH (udp4_input_node, udp4_input); -/* *INDENT-OFF* */ -VLIB_REGISTER_NODE (udp6_input_node) = { - .function = udp6_input, +VLIB_REGISTER_NODE (udp6_local_node) = { .name = "ip6-udp-lookup", /* 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, + .error_counters = udp_error_counters, - .n_next_nodes = UDP_INPUT_N_NEXT, + .n_next_nodes = UDP_LOCAL_N_NEXT, .next_nodes = { -#define _(s,n) [UDP_INPUT_NEXT_##s] = n, - foreach_udp_input_next -#undef _ + [UDP_LOCAL_NEXT_PUNT]= "ip6-punt", + [UDP_LOCAL_NEXT_DROP]= "ip6-drop", + [UDP_LOCAL_NEXT_ICMP]= "ip6-icmp-error", }, .format_buffer = format_udp_header, .format_trace = format_udp_rx_trace, .unformat_buffer = unformat_udp_header, }; -/* *INDENT-ON* */ - -VLIB_NODE_FUNCTION_MULTIARCH (udp6_input_node, udp6_input); -static void -add_dst_port (udp_main_t * um, - udp_dst_port_t dst_port, char *dst_port_name, u8 is_ip4) +#ifndef CLIB_MARCH_VARIANT +void +udp_add_dst_port (udp_main_t * um, udp_dst_port_t dst_port, + char *dst_port_name, u8 is_ip4) { udp_dst_port_info_t *pi; u32 i; @@ -497,7 +460,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; { @@ -509,26 +471,25 @@ udp_register_dst_port (vlib_main_t * vm, pi = udp_get_dst_port_info (um, dst_port, is_ip4); if (!pi) { - add_dst_port (um, dst_port, 0, is_ip4); + udp_add_dst_port (um, dst_port, 0, is_ip4); pi = udp_get_dst_port_info (um, dst_port, is_ip4); ASSERT (pi); } pi->node_index = node_index; pi->next_index = vlib_node_add_next (vm, - is_ip4 ? udp4_input_node.index - : udp6_input_node.index, node_index); + is_ip4 ? udp4_local_node.index + : udp6_local_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)); + else + n = sparse_vec_validate (um->next_by_dst_port6, clib_host_to_net_u16 (dst_port)); - n[0] = pi->next_index; - }); - /* *INDENT-ON* */ + + n[0] = pi->next_index; } void @@ -536,7 +497,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 +505,42 @@ 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] = UDP_NO_NODE_SET; +} + +u8 +udp_is_valid_dst_port (udp_dst_port_t dst_port, u8 is_ip4) +{ + udp_main_t *um = &udp_main; + u16 *next_by_dst_port = + is_ip4 ? um->next_by_dst_port4 : um->next_by_dst_port6; + uword index = + sparse_vec_index (next_by_dst_port, clib_host_to_net_u16 (dst_port)); + return (index != SPARSE_VEC_INVALID_INDEX && + vec_elt (next_by_dst_port, index) != UDP_NO_NODE_SET); } 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. */ @@ -591,7 +561,7 @@ unformat_udp_header (unformat_input_t * input, va_list * args) udp = p; } - memset (udp, 0, sizeof (udp[0])); + clib_memset (udp, 0, sizeof (udp[0])); if (unformat (input, "src-port %d dst-port %d", &src_port, &dst_port)) { udp->src_port = clib_host_to_net_u16 (src_port); @@ -612,24 +582,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) { @@ -650,32 +602,33 @@ udp_local_init (vlib_main_t * vm) um->dst_port_info_by_dst_port[i] = hash_create (0, sizeof (uword)); } - udp_setup_node (vm, udp4_input_node.index); - udp_setup_node (vm, udp6_input_node.index); + udp_setup_node (vm, udp4_local_node.index); + udp_setup_node (vm, udp6_local_node.index); + + 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)); - udp_local_node_runtime_init (vm); + 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 */); +#define _(n,s) udp_add_dst_port (um, UDP_DST_PORT_##s, #s, 1 /* is_ip4 */); foreach_udp4_dst_port #undef _ -#define _(n,s) add_dst_port (um, UDP_DST_PORT_##s, #s, 0 /* is_ip4 */); +#define _(n,s) udp_add_dst_port (um, UDP_DST_PORT_##s, #s, 0 /* is_ip4 */); foreach_udp6_dst_port #undef _ - ip4_register_protocol (IP_PROTOCOL_UDP, udp4_input_node.index); + ip4_register_protocol (IP_PROTOCOL_UDP, udp4_local_node.index); /* Note: ip6 differs from ip4, UDP is hotwired to ip6-udp-lookup */ return 0; } 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); +#endif /* CLIB_MARCH_VARIANT */ /* * fd.io coding-style-patch-verification: ON