/*
 * 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.
 *
 * Add GRE header to thr packet and send it to the esp-encrypt node.
*/

#include <vnet/vnet.h>
#include <vnet/ipsec-gre/ipsec_gre.h>

ipsec_gre_main_t ipsec_gre_main;

/**
 * @brief IPv4 and GRE header union.
 *
*/
typedef struct
{
  union
  {
    ip4_and_gre_header_t ip4_and_gre;
    u64 as_u64[3];
  };
} ip4_and_gre_union_t;

/**
 * @brief Packet trace.
 *
*/
typedef struct
{
  u32 tunnel_id; /**< Tunnel-id / index in tunnel vector */

  u32 length; /**< pkt length */

  ip4_address_t src; /**< tunnel src IPv4 address */
  ip4_address_t dst; /**< tunnel dst IPv4 address */

  u32 sa_id; /**< tunnel IPSec SA id */
} ipsec_gre_tx_trace_t;

u8 *
format_ipsec_gre_tx_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_tx_trace_t *t = va_arg (*args, ipsec_gre_tx_trace_t *);

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

/**
 * @brief IPSec-GRE tunnel interface tx function.
 *
 * Add GRE header to the packet.
 *
 * @param vm vlib_main_t corresponding to the current thread.
 * @param node vlib_node_runtime_t data for this node.
 * @param frame vlib_frame_t whose contents should be dispatched.
 *
 * @par Graph mechanics: buffer metadata, next index usage
 *
 * <em>Uses:</em>
 * - <code>node->runtime_data</code>
 *     - Match tunnel by <code>rd->dev_instance</code> in IPSec-GRE tunnels
 *       pool.
 *
 * <em>Sets:</em>
 * - <code>vnet_buffer(b)->output_features.ipsec_sad_index</code>
 *     - Set IPSec Security Association for packet encryption.
 * - <code>vnet_buffer(b)->sw_if_index[VLIB_TX]</code>
 *     - Reset output sw_if_index.
 *
 * <em>Next Index:</em>
 * - Dispatches the packet to the esp-encrypt node.
*/
static uword
ipsec_gre_interface_tx (vlib_main_t * vm,
			vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  ipsec_gre_main_t *igm = &ipsec_gre_main;
  u32 next_index;
  u32 *from, *to_next, n_left_from, n_left_to_next;
  vnet_interface_output_runtime_t *rd = (void *) node->runtime_data;
  ipsec_gre_tunnel_t *t = pool_elt_at_index (igm->tunnels, rd->dev_instance);

  /* use an ethertype of 0x01 for l2-gre */
  u16 l2_gre_protocol_ethertype = clib_net_to_host_u16 (0x01);

  /* Vector of buffer / pkt indices we're supposed to process */
  from = vlib_frame_vector_args (frame);

  /* Number of buffers / pkts */
  n_left_from = frame->n_vectors;

  /* Speculatively send the first buffer to the last disposition we used */
  next_index = node->cached_next_index;

  while (n_left_from > 0)
    {
      /* set up to enqueue to our disposition with index = next_index */
      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...
       */
      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;

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

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

	  vnet_buffer (b0)->sw_if_index[VLIB_RX] =
	    vnet_buffer (b0)->sw_if_index[VLIB_TX];
	  vnet_buffer (b1)->sw_if_index[VLIB_RX] =
	    vnet_buffer (b1)->sw_if_index[VLIB_TX];

	  vnet_buffer (b0)->ipsec.sad_index = t->local_sa;
	  vnet_buffer (b1)->ipsec.sad_index = t->local_sa;

	  vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;
	  vnet_buffer (b1)->sw_if_index[VLIB_TX] = (u32) ~ 0;

	  next0 = IPSEC_GRE_OUTPUT_NEXT_ESP_ENCRYPT;
	  next1 = IPSEC_GRE_OUTPUT_NEXT_ESP_ENCRYPT;
	  error0 = IPSEC_GRE_ERROR_NONE;
	  error1 = IPSEC_GRE_ERROR_NONE;

	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      ipsec_gre_tx_trace_t *tr = vlib_add_trace (vm, node,
							 b0, sizeof (*tr));
	      tr->tunnel_id = t - igm->tunnels;
	      tr->length = ip0->length;
	      tr->src.as_u32 = ip0->src_address.as_u32;
	      tr->dst.as_u32 = ip0->dst_address.as_u32;
	      tr->sa_id = t->local_sa_id;
	    }

	  if (PREDICT_FALSE (b1->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      ipsec_gre_tx_trace_t *tr = vlib_add_trace (vm, node,
							 b1, sizeof (*tr));
	      tr->tunnel_id = t - igm->tunnels;
	      tr->length = ip1->length;
	      tr->src.as_u32 = ip1->src_address.as_u32;
	      tr->dst.as_u32 = ip1->dst_address.as_u32;
	      tr->sa_id = t->local_sa_id;
	    }

	  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;
	  ip4_header_t *ip0;
	  ip4_and_gre_union_t *h0;
	  u32 bi0, next0;
	  __attribute__ ((unused)) u8 error0;

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

	  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 = l2_gre_protocol_ethertype;
	  ip0->ip_version_and_header_length = 0x45;
	  ip0->ttl = 254;
	  ip0->protocol = IP_PROTOCOL_GRE;
	  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);

	  vnet_buffer (b0)->sw_if_index[VLIB_RX] =
	    vnet_buffer (b0)->sw_if_index[VLIB_TX];
	  vnet_buffer (b0)->ipsec.sad_index = t->local_sa;
	  vnet_buffer (b0)->sw_if_index[VLIB_TX] = (u32) ~ 0;

	  next0 = IPSEC_GRE_OUTPUT_NEXT_ESP_ENCRYPT;
	  error0 = IPSEC_GRE_ERROR_NONE;

	  if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	    {
	      ipsec_gre_tx_trace_t *tr = vlib_add_trace (vm, node,
							 b0, sizeof (*tr));
	      tr->tunnel_id = t - igm->tunnels;
	      tr->length = ip0->length;
	      tr->src.as_u32 = ip0->src_address.as_u32;
	      tr->dst.as_u32 = ip0->dst_address.as_u32;
	      tr->sa_id = t->local_sa_id;
	    }

	  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_ENCAP, frame->n_vectors);

  return frame->n_vectors;
}

static clib_error_t *
ipsec_gre_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index,
				   u32 flags)
{
  if (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP)
    vnet_hw_interface_set_flags (vnm, hw_if_index,
				 VNET_HW_INTERFACE_FLAG_LINK_UP);
  else
    vnet_hw_interface_set_flags (vnm, hw_if_index, 0 /* down */ );

  return /* no error */ 0;
}

static u8 *
format_ipsec_gre_tunnel_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  return format (s, "ipsec-gre%d", dev_instance);
}

static u8 *
format_ipsec_gre_device (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  CLIB_UNUSED (int verbose) = va_arg (*args, int);

  s = format (s, "IPSEC-GRE tunnel: id %d\n", dev_instance);
  return s;
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (ipsec_gre_device_class) = {
  .name = "IPSec GRE tunnel device",
  .format_device_name = format_ipsec_gre_tunnel_name,
  .format_device = format_ipsec_gre_device,
  .format_tx_trace = format_ipsec_gre_tx_trace,
  .tx_function = ipsec_gre_interface_tx,
  .admin_up_down_function = ipsec_gre_interface_admin_up_down,
};

VLIB_DEVICE_TX_FUNCTION_MULTIARCH (ipsec_gre_device_class,
				   ipsec_gre_interface_tx)


VNET_HW_INTERFACE_CLASS (ipsec_gre_hw_interface_class) = {
  .name = "IPSEC-GRE",
};
/* *INDENT-ON* */

static clib_error_t *
ipsec_gre_init (vlib_main_t * vm)
{
  ipsec_gre_main_t *igm = &ipsec_gre_main;
  clib_error_t *error;

  clib_memset (igm, 0, sizeof (igm[0]));
  igm->vlib_main = vm;
  igm->vnet_main = vnet_get_main ();

  if ((error = vlib_call_init_function (vm, ip_main_init)))
    return error;

  if ((error = vlib_call_init_function (vm, ip4_lookup_init)))
    return error;

  igm->tunnel_by_key = hash_create (0, sizeof (uword));

  return vlib_call_init_function (vm, ipsec_gre_input_init);
}

VLIB_INIT_FUNCTION (ipsec_gre_init);

/*
* fd.io coding-style-patch-verification: ON
*
* Local Variables:
* eval: (c-set-style "gnu")
* End:
*/
