diff options
author | Shwetha <shwethab@cisco.com> | 2016-08-08 15:51:04 +0100 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2016-08-22 17:19:04 +0000 |
commit | a91cbe698281ff339273b1624fb3860ee9c4c2c7 (patch) | |
tree | bf899879467d0a2d640e2e92643ccc8981a619ec /vnet/vnet/ip/ip6_hop_by_hop.c | |
parent | aa88697b71878b0d28fd497e97300067aea735a1 (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.c | 223 |
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) { |