/*
 * Copyright (c) 2016 Cisco and/or its affiliates.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/**
 * @file
 * @brief L2-GRE over IPSec packet processing.
 *
 * Removes GRE header from the packet and sends it to the l2-input node.
*/

#include <vlib/vlib.h>
#include <vnet/pg/pg.h>
#include <vnet/ipsec-gre/ipsec_gre.h>
#include <vppinfra/sparse_vec.h>

#define foreach_ipsec_gre_input_next		\
_(PUNT, "error-punt")                           \
_(DROP, "error-drop")                           \
_(L2_INPUT, "l2-input")

typedef enum {
#define _(s,n) IPSEC_GRE_INPUT_NEXT_##s,
  foreach_ipsec_gre_input_next
#undef _
  IPSEC_GRE_INPUT_N_NEXT,
} ipsec_gre_input_next_t;

typedef struct {
  u32 tunnel_id;
  u32 length;
  ip4_address_t src;
  ip4_address_t dst;
} ipsec_gre_rx_trace_t;

u8 * format_ipsec_gre_rx_trace (u8 * s, va_list * args)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*args, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*args, vlib_node_t *);
  ipsec_gre_rx_trace_t * t = va_arg (*args, ipsec_gre_rx_trace_t *);

  s = format (s, "GRE: tunnel %d len %d src %U dst %U",
              t->tunnel_id, clib_net_to_host_u16(t->length),
              format_ip4_address, &t->src.as_u8,
              format_ip4_address, &t->dst.as_u8);
  return s;
}

/**
 * @brief L2-GRE over IPSec input node.
 * @node ipsec-gre-input
 *
 * This node remove GRE header.
 *
 * @param vm         vlib_main_t corresponding to the current thread.
 * @param node       vlib_node_runtime_t data for this node.
 * @param from_frame vlib_frame_t whose contents should be dispatched.
 *
 * @par Graph mechanics: buffer metadata, next index usage
 *
 * <em>Uses:</em>
 * - <code>ip->src_address</code> and <code>ip->dst_address</code>
 *     - Match tunnel by source and destination addresses in GRE IP header.
 *
 * <em>Sets:</em>
 * - <code>vnet_buffer(b)->gre.src</code>
 *     - Save tunnel source IPv4 address.
 * - <code>vnet_buffer(b)->gre.dst</code>
 *     - Save tunnel destination IPv4 address.
 * - <code>vnet_buffer(b)->sw_if_index[VLIB_RX]</code>
 *     - Set input sw_if_index to IPSec-GRE tunnel for learning.
 *
 * <em>Next Index:</em>
 * - Dispatches the packet to the l2-input node.
*/
static uword
ipsec_gre_input (vlib_main_t * vm,
                 vlib_node_runtime_t * node,
                 vlib_frame_t * from_frame)
{
  ipsec_gre_main_t * igm = &ipsec_gre_main;
  u32 n_left_from, next_index, * from, * to_next;
  u64 cached_tunnel_key = (u64) ~0;
  u32 cached_tunnel_sw_if_index = 0, tunnel_sw_if_index;

  from = vlib_frame_vector_args (from_frame);
  n_left_from = from_frame->n_vectors;

  next_index = node->cached_next_index;

  while (n_left_from > 0)
    {
      u32 n_left_to_next;

      vlib_get_next_frame (vm, node, next_index,
			   to_next, n_left_to_next);

      while (n_left_from >= 4 && n_left_to_next >= 2)
	{
	  u32 bi0, bi1;
	  vlib_buffer_t * b0, * b1;
	  gre_header_t * h0, * h1;
          u16 version0, version1, protocol0, protocol1;
          int verr0, verr1;
	  u32 next0, next1;
          ip4_header_t *ip0, *ip1;

	  /* 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, sizeof (h0[0]), LOAD);
	    CLIB_PREFETCH (p3->data, sizeof (h1[0]), LOAD);
	  }

	  bi0 = from[0];
	  bi1 = from[1];
	  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);

          /* ip4_local hands us the ip header, not the gre header */
          ip0 = vlib_buffer_get_current (b0);
          ip1 = vlib_buffer_get_current (b1);

          /* Save src + dst ip4 address */
          vnet_buffer(b0)->gre.src = ip0->src_address.as_u32;
          vnet_buffer(b0)->gre.dst = ip0->dst_address.as_u32;
          vnet_buffer(b1)->gre.src = ip1->src_address.as_u32;
          vnet_buffer(b1)->gre.dst = ip1->dst_address.as_u32;

          vlib_buffer_advance (b0, sizeof (*ip0));
          vlib_buffer_advance (b1, sizeof (*ip1));

	  h0 = vlib_buffer_get_current (b0);
	  h1 = vlib_buffer_get_current (b1);

          protocol0 = clib_net_to_host_u16 (h0->protocol);
          protocol1 = clib_net_to_host_u16 (h1->protocol);
          if (PREDICT_TRUE(protocol0 == 0x0001))
            {
              next0 = IPSEC_GRE_INPUT_NEXT_L2_INPUT;
              b0->error = node->errors[IPSEC_GRE_ERROR_NONE];
            }
          else
            {
              clib_warning("unknown GRE protocol: %d", protocol0);
              b0->error = node->errors[IPSEC_GRE_ERROR_UNKNOWN_PROTOCOL];
              next0 = IPSEC_GRE_INPUT_NEXT_DROP;
            }
          if (PREDICT_TRUE(protocol1 == 0x0001))
            {
              next1 = IPSEC_GRE_INPUT_NEXT_L2_INPUT;
              b1->error = node->errors[IPSEC_GRE_ERROR_NONE];
            }
          else
            {
              clib_warning("unknown GRE protocol: %d", protocol1);
              b1->error = node->errors[IPSEC_GRE_ERROR_UNKNOWN_PROTOCOL];
              next1 = IPSEC_GRE_INPUT_NEXT_DROP;
            }

          version0 = clib_net_to_host_u16 (h0->flags_and_version);
          verr0 =  version0 & GRE_VERSION_MASK;
          version1 = clib_net_to_host_u16 (h1->flags_and_version);
          verr1 =  version1 & GRE_VERSION_MASK;

          b0->error = verr0 ? node->errors[IPSEC_GRE_ERROR_UNSUPPORTED_VERSION]
              : b0->error;
          next0 = verr0 ? IPSEC_GRE_INPUT_NEXT_DROP : next0;
          b1->error = verr1 ? node->errors[IPSEC_GRE_ERROR_UNSUPPORTED_VERSION]
              : b1->error;
          next1 = verr1 ? IPSEC_GRE_INPUT_NEXT_DROP : next1;

          /* For L2 payload set input sw_if_index to GRE tunnel for learning */
          if (PREDICT_TRUE(next0 == IPSEC_GRE_INPUT_NEXT_L2_INPUT))
            {
              u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
                         (u64)(vnet_buffer(b0)->gre.src);

              if (cached_tunnel_key != key)
                {
                  vnet_hw_interface_t * hi;
                  ipsec_gre_tunnel_t * t;
                  uword * p;

                  p = hash_get (igm->tunnel_by_key, key);
                  if (!p)
                    {
                      next0 = IPSEC_GRE_INPUT_NEXT_DROP;
                      b0->error = node->errors[IPSEC_GRE_ERROR_NO_SUCH_TUNNEL];
                      goto drop0;
                    }
                  t = pool_elt_at_index (igm->tunnels, p[0]);
                  hi = vnet_get_hw_interface (igm->vnet_main,
                            t->hw_if_index);
                  tunnel_sw_if_index = hi->sw_if_index;
                  cached_tunnel_sw_if_index = tunnel_sw_if_index;
                }
              else
                {
                  tunnel_sw_if_index = cached_tunnel_sw_if_index;
                }
              vnet_buffer(b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
            }

drop0:
          /* For L2 payload set input sw_if_index to GRE tunnel for learning */
          if (PREDICT_TRUE(next1 == IPSEC_GRE_INPUT_NEXT_L2_INPUT))
            {
              u64 key = ((u64)(vnet_buffer(b1)->gre.dst) << 32) |
                         (u64)(vnet_buffer(b1)->gre.src);

              if (cached_tunnel_key != key)
                {
                  vnet_hw_interface_t * hi;
                  ipsec_gre_tunnel_t * t;
                  uword * p;

                  p = hash_get (igm->tunnel_by_key, key);
                  if (!p)
                    {
                      next1 = IPSEC_GRE_INPUT_NEXT_DROP;
                      b1->error = node->errors[IPSEC_GRE_ERROR_NO_SUCH_TUNNEL];
                      goto drop1;
                    }
                  t = pool_elt_at_index (igm->tunnels, p[0]);
                  hi = vnet_get_hw_interface (igm->vnet_main,
                            t->hw_if_index);
                  tunnel_sw_if_index = hi->sw_if_index;
                  cached_tunnel_sw_if_index = tunnel_sw_if_index;
                }
              else
                {
                  tunnel_sw_if_index = cached_tunnel_sw_if_index;
                }
              vnet_buffer(b1)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
            }

drop1:
          if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
            {
              ipsec_gre_rx_trace_t *tr = vlib_add_trace (vm, node,
                                                   b0, sizeof (*tr));
              tr->tunnel_id = ~0;
              tr->length = ip0->length;
              tr->src.as_u32 = ip0->src_address.as_u32;
              tr->dst.as_u32 = ip0->dst_address.as_u32;
            }

          if (PREDICT_FALSE(b1->flags & VLIB_BUFFER_IS_TRACED))
            {
              ipsec_gre_rx_trace_t *tr = vlib_add_trace (vm, node,
                                                   b1, sizeof (*tr));
              tr->tunnel_id = ~0;
              tr->length = ip1->length;
              tr->src.as_u32 = ip1->src_address.as_u32;
              tr->dst.as_u32 = ip1->dst_address.as_u32;
            }

          vlib_buffer_advance (b0, sizeof (*h0));
          vlib_buffer_advance (b1, sizeof (*h1));

	  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)
	{
	  u32 bi0;
	  vlib_buffer_t * b0;
	  gre_header_t * h0;
          ip4_header_t * ip0;
          u16 version0, protocol0;
          int verr0;
	  u32 next0;

	  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);

          vnet_buffer(b0)->gre.src = ip0->src_address.as_u32;
          vnet_buffer(b0)->gre.dst = ip0->dst_address.as_u32;

          vlib_buffer_advance (b0, sizeof (*ip0));

	  h0 = vlib_buffer_get_current (b0);

          protocol0 = clib_net_to_host_u16 (h0->protocol);
          if (PREDICT_TRUE(protocol0 == 0x0001))
            {
              next0 = IPSEC_GRE_INPUT_NEXT_L2_INPUT;
              b0->error = node->errors[IPSEC_GRE_ERROR_NONE];
            }
          else
            {
              clib_warning("unknown GRE protocol: %d", protocol0);
              b0->error = node->errors[IPSEC_GRE_ERROR_UNKNOWN_PROTOCOL];
              next0 = IPSEC_GRE_INPUT_NEXT_DROP;
            }

          version0 = clib_net_to_host_u16 (h0->flags_and_version);
          verr0 =  version0 & GRE_VERSION_MASK;
          b0->error = verr0 ? node->errors[IPSEC_GRE_ERROR_UNSUPPORTED_VERSION]
              : b0->error;
          next0 = verr0 ? IPSEC_GRE_INPUT_NEXT_DROP : next0;

          /* For L2 payload set input sw_if_index to GRE tunnel for learning */
          if (PREDICT_FALSE(next0 == IPSEC_GRE_INPUT_NEXT_L2_INPUT))
            {
              u64 key = ((u64)(vnet_buffer(b0)->gre.dst) << 32) |
                         (u64)(vnet_buffer(b0)->gre.src);

              if (cached_tunnel_key != key)
                {
                  vnet_hw_interface_t * hi;
                  ipsec_gre_tunnel_t * t;
                  uword * p;

                  p = hash_get (igm->tunnel_by_key, key);
                  if (!p)
                    {
                      next0 = IPSEC_GRE_INPUT_NEXT_DROP;
                      b0->error = node->errors[IPSEC_GRE_ERROR_NO_SUCH_TUNNEL];
                      goto drop;
                    }
                  t = pool_elt_at_index (igm->tunnels, p[0]);
                  hi = vnet_get_hw_interface (igm->vnet_main,
                            t->hw_if_index);
                  tunnel_sw_if_index = hi->sw_if_index;
                  cached_tunnel_sw_if_index = tunnel_sw_if_index;
                }
              else
                {
                  tunnel_sw_if_index = cached_tunnel_sw_if_index;
                }
              vnet_buffer(b0)->sw_if_index[VLIB_RX] = tunnel_sw_if_index;
            }

drop:
          if (PREDICT_FALSE(b0->flags & VLIB_BUFFER_IS_TRACED))
            {
              ipsec_gre_rx_trace_t *tr = vlib_add_trace (vm, node,
                                                   b0, sizeof (*tr));
              tr->tunnel_id = ~0;
              tr->length = ip0->length;
              tr->src.as_u32 = ip0->src_address.as_u32;
              tr->dst.as_u32 = ip0->dst_address.as_u32;
            }

          vlib_buffer_advance (b0, sizeof (*h0));

	  vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, next0);
	}

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }
  vlib_node_increment_counter (vm, ipsec_gre_input_node.index,
                               IPSEC_GRE_ERROR_PKTS_DECAP, from_frame->n_vectors);
  return from_frame->n_vectors;
}

static char * ipsec_gre_error_strings[] = {
#define ipsec_gre_error(n,s) s,
#include "error.def"
#undef ipsec_gre_error
};

VLIB_REGISTER_NODE (ipsec_gre_input_node) = {
  .function = ipsec_gre_input,
  .name = "ipsec-gre-input",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),

  .n_errors = IPSEC_GRE_N_ERROR,
  .error_strings = ipsec_gre_error_strings,

  .n_next_nodes = IPSEC_GRE_INPUT_N_NEXT,
  .next_nodes = {
#define _(s,n) [IPSEC_GRE_INPUT_NEXT_##s] = n,
    foreach_ipsec_gre_input_next
#undef _
  },

  .format_trace = format_ipsec_gre_rx_trace,
};

VLIB_NODE_FUNCTION_MULTIARCH (ipsec_gre_input_node, ipsec_gre_input)

static clib_error_t * ipsec_gre_input_init (vlib_main_t * vm)
{
  {
    clib_error_t * error;
    error = vlib_call_init_function (vm, ipsec_gre_init);
    if (error)
      clib_error_report (error);
  }

  return 0;
}

VLIB_INIT_FUNCTION (ipsec_gre_input_init);
