- if (ptr != 0)
- {
- if (!vlib_buffer_alloc (vm, &bi, 1))
- {
- *error = IP_FRAG_ERROR_MEMORY;
- return;
- }
- b = vlib_get_buffer (vm, bi);
- vnet_buffer (b)->sw_if_index[VLIB_RX] =
- 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,
- payload + ptr, len);
- frag_hdr =
- vlib_buffer_get_current (b) + headers_len - sizeof (*frag_hdr);
- }
- else
- {
- bi = pi;
- b = vlib_get_buffer (vm, bi);
- //frag_hdr already set here
- }
-
- ip6_hdr =
- vlib_buffer_get_current (b) + vnet_buffer (p)->ip_frag.header_offset;
- frag_hdr->fragment_offset_and_more =
- ip6_frag_hdr_offset_and_more (initial_offset + (ptr >> 3),
- (rem || has_more));
- b->current_length = headers_len + len;
- ip6_hdr->payload_length =
- clib_host_to_net_u16 (b->current_length -
- vnet_buffer (p)->ip_frag.header_offset -
- sizeof (*ip6_hdr));
-
- if (vnet_buffer (p)->ip_frag.flags & IP_FRAG_FLAG_IP4_HEADER)
- {
- //Encapsulating ipv4 header
- ip4_header_t *encap_header4 =
- (ip4_header_t *) vlib_buffer_get_current (b);
- encap_header4->length = clib_host_to_net_u16 (b->current_length);
- encap_header4->checksum = ip4_header_checksum (encap_header4);
- }
- else if (vnet_buffer (p)->ip_frag.flags & IP_FRAG_FLAG_IP6_HEADER)