aboutsummaryrefslogtreecommitdiffstats
path: root/vnet/vnet/ip/ip6_hop_by_hop.c
diff options
context:
space:
mode:
authorShwetha <shwethab@cisco.com>2016-08-08 15:51:04 +0100
committerDave Barach <openvpp@barachs.net>2016-08-22 17:19:04 +0000
commita91cbe698281ff339273b1624fb3860ee9c4c2c7 (patch)
treebf899879467d0a2d640e2e92643ccc8981a619ec /vnet/vnet/ip/ip6_hop_by_hop.c
parentaa88697b71878b0d28fd497e97300067aea735a1 (diff)
Raw export of IP6 packet with iOAM metadata
- is enabled on iOAM pop nodes with "set ioam export ipfix collector" - ioam_export_node Hooks into vlib graph b/n ip6-hop-by-hop node and ip6-pop-hop-by-hop node - A buffer per worker thread is created for collecting packet data to be exported - ioam_export_node exports first 3 cachelines by collecting it in a MTU sized frame, slaps on ipfix header for export - ioam_export_thread process node - checks for unsent record buffers for longer than 20 seconds and exports it - Added dual loop and prefetch in add, hop-by-hop and pop functions To be done: - IPfix template - Multi collector distribution of ipfix packets - Port to be configurable Change-Id: I959b4253036551382562bdaf10a83fd6f2f1c88b Signed-off-by: Shwetha <shwethab@cisco.com>
Diffstat (limited to 'vnet/vnet/ip/ip6_hop_by_hop.c')
-rw-r--r--vnet/vnet/ip/ip6_hop_by_hop.c223
1 files changed, 147 insertions, 76 deletions
diff --git a/vnet/vnet/ip/ip6_hop_by_hop.c b/vnet/vnet/ip/ip6_hop_by_hop.c
index c9b151599f0..7038556848c 100644
--- a/vnet/vnet/ip/ip6_hop_by_hop.c
+++ b/vnet/vnet/ip/ip6_hop_by_hop.c
@@ -285,80 +285,114 @@ ip6_add_hop_by_hop_node_fn (vlib_main_t * vm,
vlib_get_next_frame (vm, node, next_index,
to_next, n_left_to_next);
-
-#if 0
while (n_left_from >= 4 && n_left_to_next >= 2)
- {
- u32 next0 = IP6_ADD_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
- u32 next1 = IP6_ADD_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
- u32 sw_if_index0, sw_if_index1;
- u8 tmp0[6], tmp1[6];
- ethernet_header_t *en0, *en1;
+ {
u32 bi0, bi1;
- vlib_buffer_t * b0, * b1;
-
- /* Prefetch next iteration. */
- {
- vlib_buffer_t * p2, * p3;
-
- p2 = vlib_get_buffer (vm, from[2]);
- p3 = vlib_get_buffer (vm, from[3]);
-
- vlib_prefetch_buffer_header (p2, LOAD);
- vlib_prefetch_buffer_header (p3, LOAD);
+ vlib_buffer_t * b0, *b1;
+ u32 next0, next1;
+ ip6_header_t * ip0, *ip1;
+ ip6_hop_by_hop_header_t * hbh0, *hbh1;
+ u64 * copy_src0, * copy_dst0, *copy_src1, *copy_dst1;
+ u16 new_l0, new_l1;
- CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE);
- CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, STORE);
- }
+ /* Prefetch next iteration. */
+ {
+ vlib_buffer_t * p2, * p3;
+
+ p2 = vlib_get_buffer (vm, from[2]);
+ p3 = vlib_get_buffer (vm, from[3]);
+
+ vlib_prefetch_buffer_header (p2, LOAD);
+ vlib_prefetch_buffer_header (p3, LOAD);
+
+ CLIB_PREFETCH (p2->data - rewrite_length, 2 * CLIB_CACHE_LINE_BYTES, STORE);
+ CLIB_PREFETCH (p3->data - rewrite_length, 2 * CLIB_CACHE_LINE_BYTES, STORE);
+ }
/* speculatively enqueue b0 and b1 to the current next frame */
- to_next[0] = bi0 = from[0];
- to_next[1] = bi1 = from[1];
- from += 2;
- to_next += 2;
- n_left_from -= 2;
- n_left_to_next -= 2;
+ to_next[0] = bi0 = from[0];
+ to_next[1] = bi1 = from[1];
+ from += 2;
+ to_next += 2;
+ n_left_from -= 2;
+ n_left_to_next -= 2;
- b0 = vlib_get_buffer (vm, bi0);
- b1 = vlib_get_buffer (vm, bi1);
+ b0 = vlib_get_buffer (vm, bi0);
+ b1 = vlib_get_buffer (vm, bi1);
/* $$$$$ Dual loop: process 2 x packets here $$$$$ */
ASSERT (b0->current_data == 0);
ASSERT (b1->current_data == 0);
-
+
+ ip0 = vlib_buffer_get_current (b0);
+ ip1 = vlib_buffer_get_current (b1);
+
+ /* Copy the ip header left by the required amount */
+ copy_dst0 = (u64 *)(((u8 *)ip0) - rewrite_length);
+ copy_dst1 = (u64 *)(((u8 *)ip1) - rewrite_length);
+ copy_src0 = (u64 *) ip0;
+ copy_src1 = (u64 *) ip1;
+
+ copy_dst0 [0] = copy_src0 [0];
+ copy_dst0 [1] = copy_src0 [1];
+ copy_dst0 [2] = copy_src0 [2];
+ copy_dst0 [3] = copy_src0 [3];
+ copy_dst0 [4] = copy_src0 [4];
+
+ copy_dst1 [0] = copy_src1 [0];
+ copy_dst1 [1] = copy_src1 [1];
+ copy_dst1 [2] = copy_src1 [2];
+ copy_dst1 [3] = copy_src1 [3];
+ copy_dst1 [4] = copy_src1 [4];
+
+ vlib_buffer_advance (b0, - (word)rewrite_length);
+ vlib_buffer_advance (b1, - (word)rewrite_length);
ip0 = vlib_buffer_get_current (b0);
- ip1 = vlib_buffer_get_current (b0);
+ ip1 = vlib_buffer_get_current (b1);
+
+ hbh0 = (ip6_hop_by_hop_header_t *)(ip0 + 1);
+ hbh1 = (ip6_hop_by_hop_header_t *)(ip1 + 1);
+ /* $$$ tune, rewrite_length is a multiple of 8 */
+ clib_memcpy (hbh0, rewrite, rewrite_length);
+ clib_memcpy (hbh1, rewrite, rewrite_length);
+ /* Patch the protocol chain, insert the h-b-h (type 0) header */
+ hbh0->protocol = ip0->protocol;
+ hbh1->protocol = ip1->protocol;
+ ip0->protocol = 0;
+ ip1->protocol = 0;
+ new_l0 = clib_net_to_host_u16 (ip0->payload_length) + rewrite_length;
+ new_l1 = clib_net_to_host_u16 (ip1->payload_length) + rewrite_length;
+ ip0->payload_length = clib_host_to_net_u16 (new_l0);
+ ip1->payload_length = clib_host_to_net_u16 (new_l1);
+
+ /* Populate the (first) h-b-h list elt */
+ next0 = IP6_HBYH_IOAM_INPUT_NEXT_IP6_LOOKUP;
+ next1 = IP6_HBYH_IOAM_INPUT_NEXT_IP6_LOOKUP;
- sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
- sw_if_index1 = vnet_buffer(b1)->sw_if_index[VLIB_RX];
/* $$$$$ End of processing 2 x packets $$$$$ */
if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE)))
{
- if (b0->flags & VLIB_BUFFER_IS_TRACED)
+ if (b0->flags & VLIB_BUFFER_IS_TRACED)
{
- ip6_add_hop_by_hop_trace_t *t =
- vlib_add_trace (vm, node, b0, sizeof (*t));
- t->sw_if_index = sw_if_index0;
- t->next_index = next0;
- }
- if (b1->flags & VLIB_BUFFER_IS_TRACED)
- {
- ip6_add_hop_by_hop_trace_t *t =
- vlib_add_trace (vm, node, b1, sizeof (*t));
- t->sw_if_index = sw_if_index1;
- t->next_index = next1;
- }
- }
-
- /* verify speculative enqueues, maybe switch current next frame */
- vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
- to_next, n_left_to_next,
- bi0, bi1, next0, next1);
+ ip6_add_hop_by_hop_trace_t *t =
+ vlib_add_trace (vm, node, b0, sizeof (*t));
+ t->next_index = next0;
+ }
+ if (b1->flags & VLIB_BUFFER_IS_TRACED)
+ {
+ ip6_add_hop_by_hop_trace_t *t =
+ vlib_add_trace (vm, node, b1, sizeof (*t));
+ t->next_index = next1;
+ }
+ }
+ processed+=2;
+ /* verify speculative enqueues, maybe switch current next frame */
+ vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
+ to_next, n_left_to_next,
+ bi0, bi1, next0, next1);
}
-#endif
-
while (n_left_from > 0 && n_left_to_next > 0)
{
u32 bi0;
@@ -581,24 +615,25 @@ ip6_pop_hop_by_hop_node_fn (vlib_main_t * vm,
vlib_get_next_frame (vm, node, next_index,
to_next, n_left_to_next);
-#if 0
while (n_left_from >= 4 && n_left_to_next >= 2)
{
- u32 next0 = IP6_POP_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
- u32 next1 = IP6_POP_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
- u32 sw_if_index0, sw_if_index1;
- u8 tmp0[6], tmp1[6];
- ethernet_header_t *en0, *en1;
u32 bi0, bi1;
vlib_buffer_t * b0, * b1;
-
+ u32 next0, next1;
+ u32 adj_index0, adj_index1;
+ ip6_header_t * ip0, *ip1;
+ ip_adjacency_t * adj0, *adj1;
+ ip6_hop_by_hop_header_t *hbh0, *hbh1;
+ u64 *copy_dst0, *copy_src0, *copy_dst1, *copy_src1;
+ u16 new_l0, new_l1;
+
/* Prefetch next iteration. */
{
vlib_buffer_t * p2, * p3;
-
+
p2 = vlib_get_buffer (vm, from[2]);
p3 = vlib_get_buffer (vm, from[3]);
-
+
vlib_prefetch_buffer_header (p2, LOAD);
vlib_prefetch_buffer_header (p3, LOAD);
@@ -620,39 +655,75 @@ ip6_pop_hop_by_hop_node_fn (vlib_main_t * vm,
/* $$$$$ Dual loop: process 2 x packets here $$$$$ */
ASSERT (b0->current_data == 0);
ASSERT (b1->current_data == 0);
-
+
ip0 = vlib_buffer_get_current (b0);
- ip1 = vlib_buffer_get_current (b0);
+ ip1 = vlib_buffer_get_current (b1);
+ adj_index0 = vnet_buffer (b0)->ip.adj_index[VLIB_TX];
+ adj_index1 = vnet_buffer (b1)->ip.adj_index[VLIB_TX];
+ adj0 = ip_get_adjacency (lm, adj_index0);
+ adj1 = ip_get_adjacency (lm, adj_index1);
+
+ next0 = adj0->lookup_next_index;
+ next1 = adj1->lookup_next_index;
+
+ hbh0 = (ip6_hop_by_hop_header_t *)(ip0+1);
+ hbh1 = (ip6_hop_by_hop_header_t *)(ip1+1);
+
+ ioam_pop_hop_by_hop_processing(vm, ip0, hbh0);
+ ioam_pop_hop_by_hop_processing(vm, ip1, hbh1);
+
+ vlib_buffer_advance (b0, (hbh0->length+1)<<3);
+ vlib_buffer_advance (b1, (hbh1->length+1)<<3);
+
+ new_l0 = clib_net_to_host_u16 (ip0->payload_length) -
+ ((hbh0->length+1)<<3);
+ new_l1 = clib_net_to_host_u16 (ip1->payload_length) -
+ ((hbh1->length+1)<<3);
- sw_if_index0 = vnet_buffer(b0)->sw_if_index[VLIB_RX];
- sw_if_index1 = vnet_buffer(b1)->sw_if_index[VLIB_RX];
+ ip0->payload_length = clib_host_to_net_u16 (new_l0);
+ ip1->payload_length = clib_host_to_net_u16 (new_l1);
+
+ ip0->protocol = hbh0->protocol;
+ ip1->protocol = hbh1->protocol;
+ copy_src0 = (u64 *)ip0;
+ copy_src1 = (u64 *)ip1;
+ copy_dst0 = copy_src0 + (hbh0->length+1);
+ copy_dst0 [4] = copy_src0[4];
+ copy_dst0 [3] = copy_src0[3];
+ copy_dst0 [2] = copy_src0[2];
+ copy_dst0 [1] = copy_src0[1];
+ copy_dst0 [0] = copy_src0[0];
+ copy_dst1 = copy_src1 + (hbh1->length+1);
+ copy_dst1 [4] = copy_src1[4];
+ copy_dst1 [3] = copy_src1[3];
+ copy_dst1 [2] = copy_src1[2];
+ copy_dst1 [1] = copy_src1[1];
+ copy_dst1 [0] = copy_src1[0];
+ processed+=2;
/* $$$$$ End of processing 2 x packets $$$$$ */
if (PREDICT_FALSE((node->flags & VLIB_NODE_FLAG_TRACE)))
{
- if (b0->flags & VLIB_BUFFER_IS_TRACED)
+ if (b0->flags & VLIB_BUFFER_IS_TRACED)
{
- ip6_pop_hop_by_hop_trace_t *t =
+ ip6_pop_hop_by_hop_trace_t *t =
vlib_add_trace (vm, node, b0, sizeof (*t));
- t->sw_if_index = sw_if_index0;
t->next_index = next0;
}
- if (b1->flags & VLIB_BUFFER_IS_TRACED)
+ if (b1->flags & VLIB_BUFFER_IS_TRACED)
{
- ip6_pop_hop_by_hop_trace_t *t =
+ ip6_pop_hop_by_hop_trace_t *t =
vlib_add_trace (vm, node, b1, sizeof (*t));
- t->sw_if_index = sw_if_index1;
t->next_index = next1;
}
}
-
+
/* verify speculative enqueues, maybe switch current next frame */
vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
to_next, n_left_to_next,
bi0, bi1, next0, next1);
}
-#endif
while (n_left_from > 0 && n_left_to_next > 0)
{