X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=src%2Fvnet%2Fip%2Fip_frag.c;h=1207ec54b492db069a44b0baa058489970eed525;hb=313f7e2feac232ac841ad8a9d5e21e8387514803;hp=ca062bfd5e87fda2622b87086d24540fed410e19;hpb=7cd468a3d7dee7d6c92f69a0bb7061ae208ec727;p=vpp.git diff --git a/src/vnet/ip/ip_frag.c b/src/vnet/ip/ip_frag.c index ca062bfd5e8..1207ec54b49 100644 --- a/src/vnet/ip/ip_frag.c +++ b/src/vnet/ip/ip_frag.c @@ -85,13 +85,19 @@ ip4_frag_do_fragment (vlib_main_t * vm, u32 pi, u32 ** buffer, return; } + if (p->flags & VLIB_BUFFER_NEXT_PRESENT) + { + *error = IP_FRAG_ERROR_MALFORMED; + return; + } + if (ip4_is_fragment (ip4)) { ip_frag_id = ip4->fragment_id; ip_frag_offset = ip4_get_fragment_offset (ip4); more = - ! !(ip4->flags_and_fragment_offset & - clib_host_to_net_u16 (IP4_HEADER_FLAG_MORE_FRAGMENTS)); + !(!(ip4->flags_and_fragment_offset & + clib_host_to_net_u16 (IP4_HEADER_FLAG_MORE_FRAGMENTS))); } else { @@ -131,6 +137,12 @@ ip4_frag_do_fragment (vlib_main_t * vm, u32 pi, u32 ** buffer, vnet_buffer (p)->sw_if_index[VLIB_RX]; vnet_buffer (b)->sw_if_index[VLIB_TX] = vnet_buffer (p)->sw_if_index[VLIB_TX]; + /* Copy Adj_index in case DPO based node is sending for the fragmentation, + the packet would be sent back to the proper DPO next node and Index */ + vnet_buffer (b)->ip.adj_index[VLIB_RX] = + vnet_buffer (p)->ip.adj_index[VLIB_RX]; + vnet_buffer (b)->ip.adj_index[VLIB_TX] = + vnet_buffer (p)->ip.adj_index[VLIB_TX]; fip4 = (ip4_header_t *) (vlib_buffer_get_current (b) + offset); //Copy offset and ip4 header @@ -239,10 +251,12 @@ ip4_frag (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) next0 = IP4_FRAG_NEXT_ICMP_ERROR; } else - next0 = - (error0 == - IP_FRAG_ERROR_NONE) ? vnet_buffer (p0)-> - ip_frag.next_index : IP4_FRAG_NEXT_DROP; + { + /* *INDENT-OFF* */ + next0 = (error0 == IP_FRAG_ERROR_NONE) ? vnet_buffer (p0)-> + ip_frag.next_index : IP4_FRAG_NEXT_DROP; + /* *INDENT-ON* */ + } if (error0 == IP_FRAG_ERROR_NONE) { @@ -334,6 +348,12 @@ ip6_frag_do_fragment (vlib_main_t * vm, u32 pi, u32 ** buffer, return; } + if (p->flags & VLIB_BUFFER_NEXT_PRESENT) + { + *error = IP_FRAG_ERROR_MALFORMED; + return; + } + u8 has_more; u16 initial_offset; if (*next_header == IP_PROTOCOL_IPV6_FRAGMENTATION) @@ -391,6 +411,14 @@ ip6_frag_do_fragment (vlib_main_t * vm, u32 pi, u32 ** buffer, vnet_buffer (p)->sw_if_index[VLIB_RX]; vnet_buffer (b)->sw_if_index[VLIB_TX] = vnet_buffer (p)->sw_if_index[VLIB_TX]; + + /* Copy Adj_index in case DPO based node is sending for the fragmentation, + the packet would be sent back to the proper DPO next node and Index */ + vnet_buffer (b)->ip.adj_index[VLIB_RX] = + vnet_buffer (p)->ip.adj_index[VLIB_RX]; + vnet_buffer (b)->ip.adj_index[VLIB_TX] = + vnet_buffer (p)->ip.adj_index[VLIB_TX]; + clib_memcpy (vlib_buffer_get_current (b), vlib_buffer_get_current (p), headers_len); clib_memcpy (vlib_buffer_get_current (b) + headers_len, @@ -482,10 +510,11 @@ ip6_frag (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame) tr->next = vnet_buffer (p0)->ip_frag.next_index; } - next0 = - (error0 == - IP_FRAG_ERROR_NONE) ? vnet_buffer (p0)-> + /* *INDENT-OFF* */ + next0 = (error0 == IP_FRAG_ERROR_NONE) ? vnet_buffer (p0)-> ip_frag.next_index : IP6_FRAG_NEXT_DROP; + /* *INDENT-ON* */ + frag_sent += vec_len (buffer); small_packets += (vec_len (buffer) == 1); @@ -547,7 +576,7 @@ VLIB_REGISTER_NODE (ip4_frag_node) = { [IP4_FRAG_NEXT_IP4_LOOKUP] = "ip4-lookup", [IP4_FRAG_NEXT_IP6_LOOKUP] = "ip6-lookup", [IP4_FRAG_NEXT_ICMP_ERROR] = "ip4-icmp-error", - [IP4_FRAG_NEXT_DROP] = "error-drop" + [IP4_FRAG_NEXT_DROP] = "ip4-drop" }, }; /* *INDENT-ON* */ @@ -567,7 +596,7 @@ VLIB_REGISTER_NODE (ip6_frag_node) = { .next_nodes = { [IP6_FRAG_NEXT_IP4_LOOKUP] = "ip4-lookup", [IP6_FRAG_NEXT_IP6_LOOKUP] = "ip6-lookup", - [IP6_FRAG_NEXT_DROP] = "error-drop" + [IP6_FRAG_NEXT_DROP] = "ip6-drop" }, }; /* *INDENT-ON* */