#include <vnet/ip/ip.h>
+/*
+ * Copy the mpls header if present.
+ * The current is pointing to the ip header.
+ * Adjust the buffer and point to the mpls headers on these fragments
+ * before sending the packet back to mpls-output node.
+ */
+static inline void
+copy_mpls_hdr (vlib_buffer_t * to_b, vlib_buffer_t * from_b)
+{
+ if ((vnet_buffer (from_b)->ip_frag.flags) & IP_FRAG_FLAG_MPLS_HEADER)
+ {
+ u8 mpls_hdr_length = vnet_buffer (from_b)->mpls.mpls_hdr_length;
+ u8 *org_from_mpls_packet =
+ from_b->data + (from_b->current_data - mpls_hdr_length);
+ clib_memcpy_fast ((to_b->data - mpls_hdr_length), org_from_mpls_packet,
+ mpls_hdr_length);
+ vlib_buffer_advance (to_b, -vnet_buffer (to_b)->mpls.mpls_hdr_length);
+ }
+}
typedef struct
{
CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
ip_frag_trace_t *t = va_arg (*args, ip_frag_trace_t *);
- s = format (s, "IPv%s mtu: %u fragments: %u",
- t->ipv6 ? "6" : "4", t->mtu, t->n_fragments);
+ s = format (s, "IPv%s mtu: %u fragments: %u next: %d",
+ t->ipv6 ? "6" : "4", t->mtu, t->n_fragments, t->next);
return s;
}
vnet_buffer (from)->ip.adj_index[VLIB_RX];
vnet_buffer (to)->ip.adj_index[VLIB_TX] =
vnet_buffer (from)->ip.adj_index[VLIB_TX];
+
+ /* Copy QoS Bits */
+ if (PREDICT_TRUE (from->flags & VNET_BUFFER_F_QOS_DATA_VALID))
+ {
+ vnet_buffer2 (to)->qos = vnet_buffer2 (from)->qos;
+ to->flags |= VNET_BUFFER_F_QOS_DATA_VALID;
+ }
+
+ /* Copy mpls opaque data */
+ if ((vnet_buffer (from)->ip_frag.flags) & IP_FRAG_FLAG_MPLS_HEADER)
+ {
+ vnet_buffer (to)->mpls.pyld_proto = vnet_buffer (from)->mpls.pyld_proto;
+ vnet_buffer (to)->mpls.mpls_hdr_length =
+ vnet_buffer (from)->mpls.mpls_hdr_length;
+ }
}
static vlib_buffer_t *
return 0;
vlib_buffer_t *b = vlib_get_buffer (vm, *bi);
- vlib_buffer_free_list_t *fl =
- vlib_buffer_get_free_list (vm, VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
- vlib_buffer_init_for_free_list (b, fl);
VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b);
vlib_buffer_copy_trace_flag (vm, org_b, *bi);
rem = clib_net_to_host_u16 (ip4->length) - sizeof (ip4_header_t);
max =
- (clib_min (mtu, VLIB_BUFFER_DATA_SIZE) - sizeof (ip4_header_t)) & ~0x7;
+ (clib_min (mtu, vlib_buffer_get_default_data_size (vm)) -
+ sizeof (ip4_header_t)) & ~0x7;
if (rem >
(vlib_buffer_length_in_chain (vm, from_b) - sizeof (ip4_header_t)))
frag_set_sw_if_index (to_b, org_from_b);
/* Copy ip4 header */
- clib_memcpy (to_b->data, org_from_packet, sizeof (ip4_header_t));
+ clib_memcpy_fast (to_b->data, org_from_packet, sizeof (ip4_header_t));
to_ip4 = vlib_buffer_get_current (to_b);
to_data = (void *) (to_ip4 + 1);
/* Figure out how many bytes we can safely copy */
bytes_to_copy = left_in_to_buffer <= left_in_from_buffer ?
left_in_to_buffer : left_in_from_buffer;
- clib_memcpy (to_data + to_ptr, from_data + ptr, bytes_to_copy);
+ clib_memcpy_fast (to_data + to_ptr, from_data + ptr, bytes_to_copy);
left_in_to_buffer -= bytes_to_copy;
ptr += bytes_to_copy;
left_in_from_buffer -= bytes_to_copy;
clib_host_to_net_u16 (to_b->current_length -
sizeof (*encap_header6));
}
+
+ /* Copy mpls header if present */
+ copy_mpls_hdr (to_b, org_from_b);
+
rem -= len;
fo += len;
}
frag_set_sw_if_index (to_b, org_from_b);
/* Copy ip6 header */
- clib_memcpy (to_b->data, ip6, sizeof (ip6_header_t));
+ clib_memcpy_fast (to_b->data, ip6, sizeof (ip6_header_t));
to_ip6 = vlib_buffer_get_current (to_b);
to_frag_hdr = (ip6_frag_hdr_t *) (to_ip6 + 1);
to_data = (void *) (to_frag_hdr + 1);
/* Figure out how many bytes we can safely copy */
bytes_to_copy = left_in_to_buffer <= left_in_from_buffer ?
left_in_to_buffer : left_in_from_buffer;
- clib_memcpy (to_data + to_ptr, from_data + ptr, bytes_to_copy);
+ clib_memcpy_fast (to_data + to_ptr, from_data + ptr, bytes_to_copy);
left_in_to_buffer -= bytes_to_copy;
ptr += bytes_to_copy;
left_in_from_buffer -= bytes_to_copy;
to_frag_hdr->next_hdr = ip6->protocol;
to_frag_hdr->rsv = 0;
+ /* Copy mpls header if present */
+ copy_mpls_hdr (to_b, org_from_b);
+
rem -= len;
fo += len;
}
[IP4_FRAG_NEXT_IP4_REWRITE] = "ip4-rewrite",
[IP4_FRAG_NEXT_IP4_LOOKUP] = "ip4-lookup",
[IP4_FRAG_NEXT_IP6_LOOKUP] = "ip6-lookup",
+ [IP4_FRAG_NEXT_MPLS_OUTPUT] = "mpls-output",
[IP4_FRAG_NEXT_ICMP_ERROR] = "ip4-icmp-error",
[IP4_FRAG_NEXT_DROP] = "ip4-drop"
},
[IP6_FRAG_NEXT_IP6_REWRITE] = "ip6-rewrite",
[IP6_FRAG_NEXT_IP4_LOOKUP] = "ip4-lookup",
[IP6_FRAG_NEXT_IP6_LOOKUP] = "ip6-lookup",
+ [IP6_FRAG_NEXT_MPLS_OUTPUT] = "mpls-output",
[IP6_FRAG_NEXT_DROP] = "ip6-drop"
},
};