X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip4_forward.c;h=69a8dbad80507e8ca176b0faa03eb2a92e12492b;hb=75b9f45a15bfae423b114dfcaa6eb114c91527eb;hp=614b6e2cb4afbe35b7f850435e57ac92dc341688;hpb=ca3ff1a25f62af33d7966726811f714a0c30a431;p=vpp.git diff --git a/src/vnet/ip/ip4_forward.c b/src/vnet/ip/ip4_forward.c index 614b6e2cb4a..69a8dbad805 100644 --- a/src/vnet/ip/ip4_forward.c +++ b/src/vnet/ip/ip4_forward.c @@ -1481,20 +1481,51 @@ ip4_local_check_src_x2 (vlib_buffer_t ** b, ip4_header_t ** ip, } } +enum ip_local_packet_type_e +{ + IP_LOCAL_PACKET_TYPE_L4, + IP_LOCAL_PACKET_TYPE_NAT, + IP_LOCAL_PACKET_TYPE_FRAG, +}; + +/** + * Determine packet type and next node. + * + * The expectation is that all packets that are not L4 will skip + * checksums and source checks. + */ +always_inline u8 +ip4_local_classify (vlib_buffer_t * b, ip4_header_t * ip, u16 * next) +{ + ip_lookup_main_t *lm = &ip4_main.lookup_main; + + if (PREDICT_FALSE (ip4_is_fragment (ip))) + { + *next = IP_LOCAL_NEXT_REASSEMBLY; + return IP_LOCAL_PACKET_TYPE_FRAG; + } + if (PREDICT_FALSE (b->flags & VNET_BUFFER_F_IS_NATED)) + { + *next = lm->local_next_by_ip_protocol[ip->protocol]; + return IP_LOCAL_PACKET_TYPE_NAT; + } + + *next = lm->local_next_by_ip_protocol[ip->protocol]; + return IP_LOCAL_PACKET_TYPE_L4; +} + static inline uword ip4_local_inline (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame, int head_of_feature_arc) { - ip4_main_t *im = &ip4_main; - ip_lookup_main_t *lm = &im->lookup_main; u32 *from, n_left_from; vlib_node_runtime_t *error_node = vlib_node_get_runtime (vm, ip4_input_node.index); u16 nexts[VLIB_FRAME_SIZE], *next; vlib_buffer_t *bufs[VLIB_FRAME_SIZE], **b; ip4_header_t *ip[2]; - u8 error[2]; + u8 error[2], pt[2]; ip4_local_last_check_t last_check = { .src = {.as_u32 = 0}, @@ -1514,7 +1545,7 @@ ip4_local_inline (vlib_main_t * vm, while (n_left_from >= 6) { - u32 is_nat, not_batch = 0; + u8 not_batch = 0; /* Prefetch next iteration. */ { @@ -1533,10 +1564,12 @@ ip4_local_inline (vlib_main_t * vm, vnet_buffer (b[0])->l3_hdr_offset = b[0]->current_data; vnet_buffer (b[1])->l3_hdr_offset = b[1]->current_data; - is_nat = b[0]->flags & VNET_BUFFER_F_IS_NATED; - not_batch |= is_nat ^ (b[1]->flags & VNET_BUFFER_F_IS_NATED); + pt[0] = ip4_local_classify (b[0], ip[0], &next[0]); + pt[1] = ip4_local_classify (b[1], ip[1], &next[1]); - if (head_of_feature_arc == 0 || (is_nat && not_batch == 0)) + not_batch = pt[0] ^ pt[1]; + + if (head_of_feature_arc == 0 || (pt[0] && not_batch == 0)) goto skip_checks; if (PREDICT_TRUE (not_batch == 0)) @@ -1546,12 +1579,12 @@ ip4_local_inline (vlib_main_t * vm, } else { - if (!(b[0]->flags & VNET_BUFFER_F_IS_NATED)) + if (!pt[0]) { ip4_local_check_l4_csum (vm, b[0], ip[0], &error[0]); ip4_local_check_src (b[0], ip[0], &last_check, &error[0]); } - if (!(b[1]->flags & VNET_BUFFER_F_IS_NATED)) + if (!pt[1]) { ip4_local_check_l4_csum (vm, b[1], ip[1], &error[1]); ip4_local_check_src (b[1], ip[1], &last_check, &error[1]); @@ -1560,8 +1593,6 @@ ip4_local_inline (vlib_main_t * vm, skip_checks: - next[0] = lm->local_next_by_ip_protocol[ip[0]->protocol]; - next[1] = lm->local_next_by_ip_protocol[ip[1]->protocol]; ip4_local_set_next_and_error (error_node, b[0], &next[0], error[0], head_of_feature_arc); ip4_local_set_next_and_error (error_node, b[1], &next[1], error[1], @@ -1578,8 +1609,9 @@ ip4_local_inline (vlib_main_t * vm, ip[0] = vlib_buffer_get_current (b[0]); vnet_buffer (b[0])->l3_hdr_offset = b[0]->current_data; + pt[0] = ip4_local_classify (b[0], ip[0], &next[0]); - if (head_of_feature_arc == 0 || (b[0]->flags & VNET_BUFFER_F_IS_NATED)) + if (head_of_feature_arc == 0 || pt[0]) goto skip_check; ip4_local_check_l4_csum (vm, b[0], ip[0], &error[0]); @@ -1587,7 +1619,6 @@ ip4_local_inline (vlib_main_t * vm, skip_check: - next[0] = lm->local_next_by_ip_protocol[ip[0]->protocol]; ip4_local_set_next_and_error (error_node, b[0], &next[0], error[0], head_of_feature_arc); @@ -1619,6 +1650,7 @@ VLIB_REGISTER_NODE (ip4_local_node) = [IP_LOCAL_NEXT_PUNT] = "ip4-punt", [IP_LOCAL_NEXT_UDP_LOOKUP] = "ip4-udp-lookup", [IP_LOCAL_NEXT_ICMP] = "ip4-icmp-input", + [IP_LOCAL_NEXT_REASSEMBLY] = "ip4-reassembly", }, }; /* *INDENT-ON* */ @@ -1719,21 +1751,11 @@ ip4_arp_inline (vlib_main_t * vm, uword n_left_from, n_left_to_next_drop, next_index; u32 thread_index = vm->thread_index; u32 seed; - f64 time_now; if (node->flags & VLIB_NODE_FLAG_TRACE) ip4_forward_next_trace (vm, node, frame, VLIB_TX); - time_now = vlib_time_now (vm); - if (time_now - im->arp_throttle_last_seed_change_time[thread_index] > 1e-3) - { - (void) random_u32 (&im->arp_throttle_seeds[thread_index]); - memset (im->arp_throttle_bitmaps[thread_index], 0, - ARP_THROTTLE_BITS / BITS (u8)); - - im->arp_throttle_last_seed_change_time[thread_index] = time_now; - } - seed = im->arp_throttle_seeds[thread_index]; + seed = throttle_seed (&im->arp_throttle, thread_index, vlib_time_now (vm)); from = vlib_frame_vector_args (frame); n_left_from = frame->n_vectors; @@ -1748,8 +1770,7 @@ ip4_arp_inline (vlib_main_t * vm, while (n_left_from > 0 && n_left_to_next_drop > 0) { - u32 pi0, adj_index0, r0, w0, sw_if_index0, drop0; - uword m0; + u32 pi0, adj_index0, r0, sw_if_index0, drop0; ip_adjacency_t *adj0; vlib_buffer_t *p0; ip4_header_t *ip0; @@ -1778,14 +1799,7 @@ ip4_arp_inline (vlib_main_t * vm, r0 = adj0->sub_type.nbr.next_hop.ip4.data_u32; } - r0 ^= seed; - /* Select bit number */ - r0 &= ARP_THROTTLE_BITS - 1; - w0 = r0 / BITS (uword); - m0 = (uword) 1 << (r0 % BITS (uword)); - - drop0 = (im->arp_throttle_bitmaps[thread_index][w0] & m0) != 0; - im->arp_throttle_bitmaps[thread_index][w0] |= m0; + drop0 = throttle_check (&im->arp_throttle, thread_index, r0, seed); from += 1; n_left_from -= 1; @@ -2115,7 +2129,7 @@ ip4_mtu_check (vlib_buffer_t * b, u16 packet_len, else { /* IP fragmentation */ - ip_frag_set_vnet_buffer (b, 0, adj_packet_bytes, + ip_frag_set_vnet_buffer (b, adj_packet_bytes, IP4_FRAG_NEXT_IP4_REWRITE, 0); *next = IP4_REWRITE_NEXT_FRAGMENT; }