X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip6_input.c;h=8d89890f99974d9c8514464d6dec3f0788155bf4;hb=4b4aded6afc8abce602cd826c52ec28beb3b7ec0;hp=bbc2cebaa3918b20d227cf5a8e2c9a8e66ef4bdd;hpb=7cd468a3d7dee7d6c92f69a0bb7061ae208ec727;p=vpp.git diff --git a/src/vnet/ip/ip6_input.c b/src/vnet/ip/ip6_input.c index bbc2cebaa39..8d89890f999 100644 --- a/src/vnet/ip/ip6_input.c +++ b/src/vnet/ip/ip6_input.c @@ -37,10 +37,11 @@ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -#include +#include #include #include #include +#include typedef struct { @@ -60,18 +61,10 @@ format_ip6_input_trace (u8 * s, va_list * va) return s; } -typedef enum -{ - IP6_INPUT_NEXT_DROP, - IP6_INPUT_NEXT_LOOKUP, - IP6_INPUT_NEXT_ICMP_ERROR, - IP6_INPUT_N_NEXT, -} ip6_input_next_t; - /* Validate IP v6 packets and pass them either to forwarding code or drop exception packets. */ -static uword -ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) +VLIB_NODE_FN (ip6_input_node) (vlib_main_t * vm, vlib_node_runtime_t * node, + vlib_frame_t * frame) { vnet_main_t *vnm = vnet_get_main (); ip6_main_t *im = &ip6_main; @@ -81,7 +74,7 @@ ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) vlib_node_runtime_t *error_node = vlib_node_get_runtime (vm, ip6_input_node.index); vlib_simple_counter_main_t *cm; - u32 cpu_index = os_get_cpu_number (); + u32 thread_index = vm->thread_index; from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -107,7 +100,7 @@ ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) ip6_header_t *ip0, *ip1; u32 pi0, sw_if_index0, next0 = 0; u32 pi1, sw_if_index1, next1 = 0; - u8 error0, error1, arc0, arc1; + u8 arc0, arc1; /* Prefetch next iteration. */ { @@ -142,12 +135,27 @@ ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX]; sw_if_index1 = vnet_buffer (p1)->sw_if_index[VLIB_RX]; - arc0 = - ip6_address_is_multicast (&ip0->dst_address) ? - lm->mcast_feature_arc_index : lm->ucast_feature_arc_index; - arc1 = - ip6_address_is_multicast (&ip1->dst_address) ? - lm->mcast_feature_arc_index : lm->ucast_feature_arc_index; + if (PREDICT_FALSE (ip6_address_is_multicast (&ip0->dst_address))) + { + arc0 = lm->mcast_feature_arc_index; + next0 = IP6_INPUT_NEXT_LOOKUP_MULTICAST; + } + else + { + arc0 = lm->ucast_feature_arc_index; + next0 = IP6_INPUT_NEXT_LOOKUP; + } + + if (PREDICT_FALSE (ip6_address_is_multicast (&ip1->dst_address))) + { + arc1 = lm->mcast_feature_arc_index; + next1 = IP6_INPUT_NEXT_LOOKUP_MULTICAST; + } + else + { + arc1 = lm->ucast_feature_arc_index; + next1 = IP6_INPUT_NEXT_LOOKUP; + } vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0; vnet_buffer (p1)->ip.adj_index[VLIB_RX] = ~0; @@ -155,67 +163,10 @@ ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) vnet_feature_arc_start (arc0, sw_if_index0, &next0, p0); vnet_feature_arc_start (arc1, sw_if_index1, &next1, p1); - vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1); - vlib_increment_simple_counter (cm, cpu_index, sw_if_index1, 1); - - error0 = error1 = IP6_ERROR_NONE; - - /* Version != 6? Drop it. */ - error0 = - (clib_net_to_host_u32 - (ip0->ip_version_traffic_class_and_flow_label) >> 28) != - 6 ? IP6_ERROR_VERSION : error0; - error1 = - (clib_net_to_host_u32 - (ip1->ip_version_traffic_class_and_flow_label) >> 28) != - 6 ? IP6_ERROR_VERSION : error1; - - /* hop limit < 1? Drop it. for link-local broadcast packets, - * like dhcpv6 packets from client has hop-limit 1, which should not - * be dropped. - */ - error0 = ip0->hop_limit < 1 ? IP6_ERROR_TIME_EXPIRED : error0; - error1 = ip1->hop_limit < 1 ? IP6_ERROR_TIME_EXPIRED : error1; - - /* L2 length must be at least minimal IP header. */ - error0 = - p0->current_length < - sizeof (ip0[0]) ? IP6_ERROR_TOO_SHORT : error0; - error1 = - p1->current_length < - sizeof (ip1[0]) ? IP6_ERROR_TOO_SHORT : error1; - - if (PREDICT_FALSE (error0 != IP6_ERROR_NONE)) - { - if (error0 == IP6_ERROR_TIME_EXPIRED) - { - icmp6_error_set_vnet_buffer (p0, ICMP6_time_exceeded, - ICMP6_time_exceeded_ttl_exceeded_in_transit, - 0); - next0 = IP6_INPUT_NEXT_ICMP_ERROR; - } - else - { - next0 = IP6_INPUT_NEXT_DROP; - } - } - if (PREDICT_FALSE (error1 != IP6_ERROR_NONE)) - { - if (error1 == IP6_ERROR_TIME_EXPIRED) - { - icmp6_error_set_vnet_buffer (p1, ICMP6_time_exceeded, - ICMP6_time_exceeded_ttl_exceeded_in_transit, - 0); - next1 = IP6_INPUT_NEXT_ICMP_ERROR; - } - else - { - next1 = IP6_INPUT_NEXT_DROP; - } - } - - p0->error = error_node->errors[error0]; - p1->error = error_node->errors[error1]; + vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1); + vlib_increment_simple_counter (cm, thread_index, sw_if_index1, 1); + ip6_input_check_x2 (vm, error_node, + p0, p1, ip0, ip1, &next0, &next1); vlib_validate_buffer_enqueue_x2 (vm, node, next_index, to_next, n_left_to_next, @@ -227,7 +178,7 @@ ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) vlib_buffer_t *p0; ip6_header_t *ip0; u32 pi0, sw_if_index0, next0 = 0; - u8 error0, arc0; + u8 arc0; pi0 = from[0]; to_next[0] = pi0; @@ -240,47 +191,22 @@ ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) ip0 = vlib_buffer_get_current (p0); sw_if_index0 = vnet_buffer (p0)->sw_if_index[VLIB_RX]; - arc0 = - ip6_address_is_multicast (&ip0->dst_address) ? - lm->mcast_feature_arc_index : lm->ucast_feature_arc_index; + if (PREDICT_FALSE (ip6_address_is_multicast (&ip0->dst_address))) + { + arc0 = lm->mcast_feature_arc_index; + next0 = IP6_INPUT_NEXT_LOOKUP_MULTICAST; + } + else + { + arc0 = lm->ucast_feature_arc_index; + next0 = IP6_INPUT_NEXT_LOOKUP; + } + vnet_buffer (p0)->ip.adj_index[VLIB_RX] = ~0; vnet_feature_arc_start (arc0, sw_if_index0, &next0, p0); - vlib_increment_simple_counter (cm, cpu_index, sw_if_index0, 1); - error0 = IP6_ERROR_NONE; - - /* Version != 6? Drop it. */ - error0 = - (clib_net_to_host_u32 - (ip0->ip_version_traffic_class_and_flow_label) >> 28) != - 6 ? IP6_ERROR_VERSION : error0; - - /* hop limit < 1? Drop it. for link-local broadcast packets, - * like dhcpv6 packets from client has hop-limit 1, which should not - * be dropped. - */ - error0 = ip0->hop_limit < 1 ? IP6_ERROR_TIME_EXPIRED : error0; - - /* L2 length must be at least minimal IP header. */ - error0 = - p0->current_length < - sizeof (ip0[0]) ? IP6_ERROR_TOO_SHORT : error0; - - if (PREDICT_FALSE (error0 != IP6_ERROR_NONE)) - { - if (error0 == IP6_ERROR_TIME_EXPIRED) - { - icmp6_error_set_vnet_buffer (p0, ICMP6_time_exceeded, - ICMP6_time_exceeded_ttl_exceeded_in_transit, - 0); - next0 = IP6_INPUT_NEXT_ICMP_ERROR; - } - else - { - next0 = IP6_INPUT_NEXT_DROP; - } - } - p0->error = error_node->errors[error0]; + vlib_increment_simple_counter (cm, thread_index, sw_if_index0, 1); + ip6_input_check_x1 (vm, error_node, p0, ip0, &next0); vlib_validate_buffer_enqueue_x1 (vm, node, next_index, to_next, n_left_to_next, @@ -293,26 +219,20 @@ ip6_input (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) return frame->n_vectors; } -static char *ip6_error_strings[] = { -#define _(sym,string) string, - foreach_ip6_error -#undef _ -}; - /* *INDENT-OFF* */ VLIB_REGISTER_NODE (ip6_input_node) = { - .function = ip6_input, .name = "ip6-input", .vector_size = sizeof (u32), .n_errors = IP6_N_ERROR, - .error_strings = ip6_error_strings, + .error_counters = ip6_error_counters, .n_next_nodes = IP6_INPUT_N_NEXT, .next_nodes = { [IP6_INPUT_NEXT_DROP] = "error-drop", [IP6_INPUT_NEXT_LOOKUP] = "ip6-lookup", [IP6_INPUT_NEXT_ICMP_ERROR] = "ip6-icmp-error", + [IP6_INPUT_NEXT_LOOKUP_MULTICAST] = "ip6-mfib-forward-lookup", }, .format_buffer = format_ip6_header, @@ -320,8 +240,8 @@ VLIB_REGISTER_NODE (ip6_input_node) = { }; /* *INDENT-ON* */ -VLIB_NODE_FUNCTION_MULTIARCH (ip6_input_node, ip6_input) - static clib_error_t *ip6_init (vlib_main_t * vm) +static clib_error_t * +ip6_init (vlib_main_t * vm) { ethernet_register_input_type (vm, ETHERNET_TYPE_IP6, ip6_input_node.index); ppp_register_input_protocol (vm, PPP_PROTOCOL_ip6, ip6_input_node.index); @@ -339,6 +259,15 @@ VLIB_NODE_FUNCTION_MULTIARCH (ip6_input_node, ip6_input) /* Default hop limit for packets we generate. */ ip6_main.host_config.ttl = 64; + + uword *u = hash_get (ip_main.protocol_info_by_name, "IPV6_FRAGMENTATION"); + if (u) + { + ip_protocol_info_t *info = + vec_elt_at_index (ip_main.protocol_infos, *u); + ASSERT (NULL == info->format_header); + info->format_header = format_ip6_frag_hdr; + } return /* no error */ 0; }