X-Git-Url: https://gerrit.fd.io/r/gitweb?a=blobdiff_plain;f=vnet%2Fvnet%2Fgre%2Fgre.c;h=9f8adc79ff0c8f03c13c20495aac8aaef646c644;hb=0bfe5d8c792abcdbcf27bfcc7b7b353fba04aee2;hp=f00977c8cd609ec3c0d5b6a2586456979d092c04;hpb=60537f3d83e83d0ce10a620ca99aad4eddf85f5e;p=vpp.git diff --git a/vnet/vnet/gre/gre.c b/vnet/vnet/gre/gre.c index f00977c8cd6..9f8adc79ff0 100644 --- a/vnet/vnet/gre/gre.c +++ b/vnet/vnet/gre/gre.c @@ -17,14 +17,10 @@ #include #include +#include gre_main_t gre_main; -typedef CLIB_PACKED (struct { - ip4_header_t ip4; - gre_header_t gre; -}) ip4_and_gre_header_t; - typedef struct { union { ip4_and_gre_header_t ip4_and_gre; @@ -233,179 +229,39 @@ gre_interface_tx (vlib_main_t * vm, vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next); /* - * As long as we have enough pkts left to process two pkts - * and prefetch two pkts... + * FIXME DUAL LOOP */ - while (n_left_from >= 4 && n_left_to_next >= 2) - { - vlib_buffer_t * b0, * b1; - ip4_header_t * ip0, * ip1; - ip4_and_gre_union_t * h0, * h1; - u32 bi0, next0, bi1, next1; - __attribute__((unused)) u8 error0, error1; - u16 gre_protocol0, gre_protocol1; - - /* Prefetch the 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); - - /* - * Prefetch packet data. We expect to overwrite - * the inbound L2 header with an ip header and a - * gre header. Might want to prefetch the last line - * of rewrite space as well; need profile data - */ - CLIB_PREFETCH (p2->data, CLIB_CACHE_LINE_BYTES, STORE); - CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, STORE); - } - - /* Pick up the next two buffer indices */ - bi0 = from[0]; - bi1 = from[1]; - - /* Speculatively enqueue them where we sent the last buffer */ - to_next[0] = bi0; - to_next[1] = bi1; - from += 2; - to_next += 2; - n_left_to_next -= 2; - n_left_from -= 2; - - b0 = vlib_get_buffer (vm, bi0); - b1 = vlib_get_buffer (vm, bi1); - - vnet_buffer (b0)->sw_if_index[VLIB_TX] = t->outer_fib_index; - vnet_buffer (b1)->sw_if_index[VLIB_TX] = t->outer_fib_index; - - if (PREDICT_FALSE(t->teb)) - { - gre_protocol0 = clib_net_to_host_u16(GRE_PROTOCOL_teb); - gre_protocol1 = clib_net_to_host_u16(GRE_PROTOCOL_teb); - } - else - { - ip0 = vlib_buffer_get_current (b0); - gre_protocol0 = clib_net_to_host_u16 (0x800); - gre_protocol0 = - ((ip0->ip_version_and_header_length & 0xF0) == 0x60) ? - 0x86DD : gre_protocol0; - - ip1 = vlib_buffer_get_current (b1); - gre_protocol1 = clib_net_to_host_u16 (0x800); - gre_protocol1 = - ((ip1->ip_version_and_header_length & 0xF0) == 0x60) ? - 0x86DD : gre_protocol1; - } - - vlib_buffer_advance (b0, -sizeof(*h0)); - vlib_buffer_advance (b1, -sizeof(*h1)); - - h0 = vlib_buffer_get_current (b0); - h1 = vlib_buffer_get_current (b1); - h0->as_u64[0] = 0; - h0->as_u64[1] = 0; - h0->as_u64[2] = 0; - - h1->as_u64[0] = 0; - h1->as_u64[1] = 0; - h1->as_u64[2] = 0; - - ip0 = &h0->ip4_and_gre.ip4; - h0->ip4_and_gre.gre.protocol = gre_protocol0; - ip0->ip_version_and_header_length = 0x45; - ip0->ttl = 254; - ip0->protocol = IP_PROTOCOL_GRE; - - ip1 = &h1->ip4_and_gre.ip4; - h1->ip4_and_gre.gre.protocol = gre_protocol1; - ip1->ip_version_and_header_length = 0x45; - ip1->ttl = 254; - ip1->protocol = IP_PROTOCOL_GRE; - - ip0->length = - clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0)); - ip1->length = - clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b1)); - ip0->src_address.as_u32 = t->tunnel_src.as_u32; - ip1->src_address.as_u32 = t->tunnel_src.as_u32; - ip0->dst_address.as_u32 = t->tunnel_dst.as_u32; - ip1->dst_address.as_u32 = t->tunnel_dst.as_u32; - ip0->checksum = ip4_header_checksum (ip0); - ip1->checksum = ip4_header_checksum (ip1); - - /* ip4_lookup will route to the tunnel partner */ - next0 = GRE_OUTPUT_NEXT_LOOKUP; - next1 = GRE_OUTPUT_NEXT_LOOKUP; - error0 = GRE_ERROR_NONE; - error1 = GRE_ERROR_NONE; - - /* - * Enqueue 2 pkts. This macro deals with next0 != next1, - * acquiring enqueue rights to the indicated next - * node input frame, etc. - */ - vlib_validate_buffer_enqueue_x2 (vm, node, next_index, - to_next, n_left_to_next, - bi0, bi1, next0, next1); - } while (n_left_from > 0 && n_left_to_next > 0) { - vlib_buffer_t * b0; + u32 bi0, adj_index0, next0; + const ip_adjacency_t * adj0; + const dpo_id_t *dpo0; ip4_header_t * ip0; - ip4_and_gre_union_t * h0; - u32 bi0, next0; - __attribute__((unused)) u8 error0; - u16 gre_protocol0; - - bi0 = to_next[0] = from[0]; - from += 1; - n_left_from -= 1; - to_next += 1; - n_left_to_next -= 1; - - b0 = vlib_get_buffer (vm, bi0); - - vnet_buffer (b0)->sw_if_index[VLIB_TX] = t->outer_fib_index; + vlib_buffer_t * b0; + + bi0 = from[0]; + to_next[0] = bi0; + from += 1; + to_next += 1; + n_left_from -= 1; + n_left_to_next -= 1; + + b0 = vlib_get_buffer(vm, bi0); ip0 = vlib_buffer_get_current (b0); - if (PREDICT_FALSE(t->teb)) - { - gre_protocol0 = clib_net_to_host_u16(GRE_PROTOCOL_teb); - } - else - { - gre_protocol0 = clib_net_to_host_u16 (0x800); - gre_protocol0 = - ((ip0->ip_version_and_header_length & 0xF0) == 0x60) ? - 0x86DD : gre_protocol0; - } - - vlib_buffer_advance (b0, -sizeof(*h0)); - - h0 = vlib_buffer_get_current (b0); - h0->as_u64[0] = 0; - h0->as_u64[1] = 0; - h0->as_u64[2] = 0; - - ip0 = &h0->ip4_and_gre.ip4; - h0->ip4_and_gre.gre.protocol = gre_protocol0; - ip0->ip_version_and_header_length = 0x45; - ip0->ttl = 254; - ip0->protocol = IP_PROTOCOL_GRE; + + /* Fixup the checksum and len fields in the LISP tunnel encap + * that was applied at the midchain node */ ip0->length = clib_host_to_net_u16 (vlib_buffer_length_in_chain (vm, b0)); - ip0->src_address.as_u32 = t->tunnel_src.as_u32; - ip0->dst_address.as_u32 = t->tunnel_dst.as_u32; ip0->checksum = ip4_header_checksum (ip0); - next0 = GRE_OUTPUT_NEXT_LOOKUP; - error0 = GRE_ERROR_NONE; + /* Follow the DPO on which the midchain is stacked */ + adj_index0 = vnet_buffer(b0)->ip.adj_index[VLIB_TX]; + adj0 = adj_get(adj_index0); + dpo0 = &adj0->sub_type.midchain.next_dpo; + next0 = dpo0->dpoi_next_node; + vnet_buffer(b0)->ip.adj_index[VLIB_TX] = dpo0->dpoi_index; if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED)) {