/*
 * Copyright (c) 2018 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.
 */

#include <vnet/devices/pipe/pipe.h>

#include <vppinfra/sparse_vec.h>

/**
 * @file
 * @brief Pipe Interfaces.
 *
 * A pipe interface, like the UNIX pipe, is a pair of vpp interfaces
 * that are joined.
 */
const static pipe_t PIPE_INVALID = {
  .sw_if_index = ~0,
  .subint = {0},
};

/**
 * Various 'module' level variables
 */
typedef struct pipe_main_t_
{
  /**
   * Allocated pipe instances
   */
  uword *instances;

  /**
   * the per-swif-index array of pipes. Each end of the pipe is stored against
   * its respective sw_if_index
   */
  pipe_t *pipes;
} pipe_main_t;

static pipe_main_t pipe_main;

/*
 * The pipe rewrite is the same size as an ethernet header (since it
 * is an ethernet interface and the DP is optimised for writing
 * sizeof(ethernet_header_t) rewrites. However, there are no MAC addresses
 * since pipes don't have them.
 */
static u8 *
pipe_build_rewrite (vnet_main_t * vnm,
		    u32 sw_if_index,
		    vnet_link_t link_type, const void *dst_address)
{
  ethernet_header_t *h;
  ethernet_type_t type;
  u8 *rewrite = NULL;

  switch (link_type)
    {
#define _(a,b) case VNET_LINK_##a: type = ETHERNET_TYPE_##b; break
      _(IP4, IP4);
      _(IP6, IP6);
      _(MPLS, MPLS);
      _(ARP, ARP);
#undef _
    default:
      return NULL;
    }

  vec_validate (rewrite, sizeof (ethernet_header_t));

  h = (ethernet_header_t *) rewrite;
  h->type = clib_host_to_net_u16 (type);

  return (rewrite);
}

VNET_HW_INTERFACE_CLASS (pipe_hw_interface_class) = {
  .name = "Pipe",
  .build_rewrite = pipe_build_rewrite,
  .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
};

pipe_t *
pipe_get (u32 sw_if_index)
{
  vec_validate_init_empty (pipe_main.pipes, sw_if_index, PIPE_INVALID);

  return (&pipe_main.pipes[sw_if_index]);
}

uword
unformat_pipe_interface (unformat_input_t * input, va_list * args)
{
  vnet_main_t *vnm = va_arg (*args, vnet_main_t *);
  u32 *result = va_arg (*args, u32 *);
  u32 hw_if_index;
  ethernet_main_t *em = &ethernet_main;
  ethernet_interface_t *eif;

  if (!unformat_user (input, unformat_vnet_hw_interface, vnm, &hw_if_index))
    return 0;

  eif = ethernet_get_interface (em, hw_if_index);
  if (eif)
    {
      *result = hw_if_index;
      return 1;
    }
  return 0;
}

#define VNET_PIPE_TX_NEXT_ETHERNET_INPUT VNET_INTERFACE_TX_N_NEXT

/*
 * The TX function bounces the packets back to pipe-rx with the TX interface
 * swapped to the RX.
 */
static uword
pipe_tx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  u32 n_left_from, n_left_to_next, n_copy, *from, *to_next;
  u32 next_index = VNET_PIPE_TX_NEXT_ETHERNET_INPUT;
  u32 i, sw_if_index = 0;
  vlib_buffer_t *b;
  pipe_t *pipe;

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

  while (n_left_from > 0)
    {
      vlib_get_next_frame (vm, node, next_index, to_next, n_left_to_next);

      n_copy = clib_min (n_left_from, n_left_to_next);

      clib_memcpy_fast (to_next, from, n_copy * sizeof (from[0]));
      n_left_to_next -= n_copy;
      n_left_from -= n_copy;
      i = 0;
      while (i < n_copy)
	{
	  b = vlib_get_buffer (vm, from[i]);
	  sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_TX];

	  pipe = &pipe_main.pipes[sw_if_index];
	  // Set up RX index to be recv'd by the other end of the pipe
	  vnet_buffer (b)->sw_if_index[VLIB_RX] = pipe->sw_if_index;
	  vnet_buffer (b)->sw_if_index[VLIB_TX] = ~0;

	  i++;
	}
      from += n_copy;

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }

  return frame->n_vectors;
}

static u8 *
format_pipe_name (u8 * s, va_list * args)
{
  u32 dev_instance = va_arg (*args, u32);
  return format (s, "pipe%d", dev_instance);
}

static clib_error_t *
pipe_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  vnet_hw_interface_t *hi;
  u32 id, sw_if_index;

  u32 hw_flags = ((flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ?
		  VNET_HW_INTERFACE_FLAG_LINK_UP : 0);
  vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);

  hi = vnet_get_hw_interface (vnm, hw_if_index);
  hash_foreach (id, sw_if_index, hi->sub_interface_sw_if_index_by_id,
  ({
    vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
  }));

  return (NULL);
}

VNET_DEVICE_CLASS (pipe_device_class) = {
  .name = "Pipe",
  .format_device_name = format_pipe_name,
  .tx_function = pipe_tx,
  .admin_up_down_function = pipe_admin_up_down,
};

#define foreach_pipe_rx_next                    \
  _ (DROP, "error-drop")

typedef enum pipe_rx_next_t_
{
#define _(s,n) PIPE_RX_NEXT_##s,
  foreach_pipe_rx_next
#undef _
    PIPE_RX_N_NEXT,
} pipe_rx_next_t;

typedef struct pipe_rx_trace_t_
{
  u8 packet_data[32];
} pipe_rx_trace_t;

static u8 *
format_pipe_rx_trace (u8 * s, va_list * va)
{
  CLIB_UNUSED (vlib_main_t * vm) = va_arg (*va, vlib_main_t *);
  CLIB_UNUSED (vlib_node_t * node) = va_arg (*va, vlib_node_t *);
  pipe_rx_trace_t *t = va_arg (*va, pipe_rx_trace_t *);

  s = format (s, "%U", format_ethernet_header, t->packet_data);

  return s;
}

/*
 * The pipe-rx node is a sibling of ethernet-input so steal it's
 * next node mechanism
 */
static_always_inline void
pipe_determine_next_node (ethernet_main_t * em,
			  u32 is_l20,
			  u32 type0,
			  vlib_buffer_t * b0, pipe_rx_next_t * next0)
{
  if (is_l20)
    {
      *next0 = em->l2_next;
    }
  else if (type0 == ETHERNET_TYPE_IP4)
    {
      *next0 = em->l3_next.input_next_ip4;
    }
  else if (type0 == ETHERNET_TYPE_IP6)
    {
      *next0 = em->l3_next.input_next_ip6;
    }
  else if (type0 == ETHERNET_TYPE_MPLS)
    {
      *next0 = em->l3_next.input_next_mpls;

    }
  else if (em->redirect_l3)
    {
      // L3 Redirect is on, the cached common next nodes will be
      // pointing to the redirect node, catch the uncommon types here
      *next0 = em->redirect_l3_next;
    }
  else
    {
      // uncommon ethertype, check table
      u32 i0;
      i0 = sparse_vec_index (em->l3_next.input_next_by_type, type0);
      *next0 = vec_elt (em->l3_next.input_next_by_type, i0);

      // The table is not populated with LLC values, so check that now.
      if (type0 < 0x600)
	{
	  *next0 = PIPE_RX_NEXT_DROP;
	}
    }
}

static_always_inline uword
pipe_rx (vlib_main_t * vm,
	 vlib_node_runtime_t * node, vlib_frame_t * from_frame)
{
  u32 n_left_from, next_index, *from, *to_next;
  u32 n_left_to_next;

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

  if (node->flags & VLIB_NODE_FLAG_TRACE)
    vlib_trace_frame_buffers_only (vm, node,
				   from,
				   n_left_from,
				   sizeof (from[0]),
				   sizeof (pipe_rx_trace_t));

  next_index = node->cached_next_index;

  while (n_left_from > 0)
    {
      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, sw_if_index0, bi1, sw_if_index1;
	  pipe_rx_next_t next0, next1;
	  ethernet_header_t *e0, *e1;
	  vlib_buffer_t *b0, *b1;
	  pipe_t *pipe0, *pipe1;
	  u8 is_l20, is_l21;
	  u16 type0, type1;

	  // 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, STORE);
	    vlib_prefetch_buffer_header (p3, STORE);
	    clib_prefetch_load (p2->data);
	    clib_prefetch_load (p3->data);
	  }

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

	  e0 = vlib_buffer_get_current (b0);
	  e1 = vlib_buffer_get_current (b1);
	  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
	  sw_if_index1 = vnet_buffer (b1)->sw_if_index[VLIB_RX];
	  type0 = clib_net_to_host_u16 (e0->type);
	  type1 = clib_net_to_host_u16 (e1->type);
	  pipe0 = &pipe_main.pipes[sw_if_index0];
	  pipe1 = &pipe_main.pipes[sw_if_index1];

	  vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
	  vnet_buffer (b1)->l2_hdr_offset = b1->current_data;

	  vnet_buffer (b0)->l3_hdr_offset =
	    vnet_buffer (b0)->l2_hdr_offset + sizeof (ethernet_header_t);
	  vnet_buffer (b1)->l3_hdr_offset =
	    vnet_buffer (b1)->l2_hdr_offset + sizeof (ethernet_header_t);
	  b0->flags |=
	    VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
	    VNET_BUFFER_F_L3_HDR_OFFSET_VALID;
	  b1->flags |=
	    VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
	    VNET_BUFFER_F_L3_HDR_OFFSET_VALID;

	  is_l20 = pipe0->subint.flags & SUBINT_CONFIG_L2;
	  is_l21 = pipe1->subint.flags & SUBINT_CONFIG_L2;

	  /*
	   * from discussion with Neale - we do not support the tagged traffic.
	   * So assume a simple ethernet header
	   */
	  vnet_buffer (b0)->l2.l2_len = sizeof (ethernet_header_t);
	  vnet_buffer (b1)->l2.l2_len = sizeof (ethernet_header_t);
	  vlib_buffer_advance (b0, is_l20 ? 0 : sizeof (ethernet_header_t));
	  vlib_buffer_advance (b1, is_l21 ? 0 : sizeof (ethernet_header_t));

	  pipe_determine_next_node (&ethernet_main, is_l20, type0, b0,
				    &next0);
	  pipe_determine_next_node (&ethernet_main, is_l21, type1, b1,
				    &next1);

	  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, sw_if_index0;
	  vlib_buffer_t *b0;
	  pipe_rx_next_t next0;
	  ethernet_header_t *e0;
	  pipe_t *pipe0;
	  u16 type0;
	  u8 is_l20;

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

	  e0 = vlib_buffer_get_current (b0);
	  sw_if_index0 = vnet_buffer (b0)->sw_if_index[VLIB_RX];
	  type0 = clib_net_to_host_u16 (e0->type);
	  pipe0 = &pipe_main.pipes[sw_if_index0];

	  vnet_buffer (b0)->l2_hdr_offset = b0->current_data;
	  vnet_buffer (b0)->l3_hdr_offset =
	    vnet_buffer (b0)->l2_hdr_offset + sizeof (ethernet_header_t);
	  b0->flags |=
	    VNET_BUFFER_F_L2_HDR_OFFSET_VALID |
	    VNET_BUFFER_F_L3_HDR_OFFSET_VALID;

	  is_l20 = pipe0->subint.flags & SUBINT_CONFIG_L2;

	  vnet_buffer (b0)->l2.l2_len = sizeof (ethernet_header_t);
	  vlib_buffer_advance (b0, is_l20 ? 0 : sizeof (ethernet_header_t));

	  pipe_determine_next_node (&ethernet_main, is_l20, type0, b0,
				    &next0);

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

  return from_frame->n_vectors;
}

VLIB_REGISTER_NODE (pipe_rx_node) = {
  .function = pipe_rx,
  .name = "pipe-rx",
  /* Takes a vector of packets. */
  .vector_size = sizeof (u32),
  .format_trace = format_pipe_rx_trace,

  .sibling_of = "ethernet-input",
};

/*
 * Maintain a bitmap of allocated pipe instance numbers.
 */
#define PIPE_MAX_INSTANCE		(16 * 1024)

static u32
pipe_instance_alloc (u8 is_specified, u32 want)
{
  /*
   * Check for dynamically allocaetd instance number.
   */
  if (!is_specified)
    {
      u32 bit;

      bit = clib_bitmap_first_clear (pipe_main.instances);
      if (bit >= PIPE_MAX_INSTANCE)
	{
	  return ~0;
	}
      pipe_main.instances = clib_bitmap_set (pipe_main.instances, bit, 1);
      return bit;
    }

  /*
   * In range?
   */
  if (want >= PIPE_MAX_INSTANCE)
    {
      return ~0;
    }

  /*
   * Already in use?
   */
  if (clib_bitmap_get (pipe_main.instances, want))
    {
      return ~0;
    }

  /*
   * Grant allocation request.
   */
  pipe_main.instances = clib_bitmap_set (pipe_main.instances, want, 1);

  return want;
}

static int
pipe_instance_free (u32 instance)
{
  if (instance >= PIPE_MAX_INSTANCE)
    {
      return -1;
    }

  if (clib_bitmap_get (pipe_main.instances, instance) == 0)
    {
      return -1;
    }

  pipe_main.instances = clib_bitmap_set (pipe_main.instances, instance, 0);
  return 0;
}

static clib_error_t *
pipe_create_sub_interface (vnet_hw_interface_t * hi,
			   u32 sub_id, u32 * sw_if_index)
{
  vnet_sw_interface_t template;

  clib_memset (&template, 0, sizeof (template));
  template.type = VNET_SW_INTERFACE_TYPE_PIPE;
  template.flood_class = VNET_FLOOD_CLASS_NORMAL;
  template.sup_sw_if_index = hi->sw_if_index;
  template.sub.id = sub_id;

  return (vnet_create_sw_interface (vnet_get_main (),
				    &template, sw_if_index));
}

int
vnet_create_pipe_interface (u8 is_specified,
			    u32 user_instance,
			    u32 * parent_sw_if_index, u32 pipe_sw_if_index[2])
{
  vnet_main_t *vnm = vnet_get_main ();
  vlib_main_t *vm = vlib_get_main ();
  vnet_eth_interface_registration_t eir = {};
  u8 address[6] = {
    [0] = 0x22,
    [1] = 0x22,
  };
  vnet_hw_interface_t *hi;
  clib_error_t *error;
  u32 hw_if_index;
  u32 instance;
  u32 slot;
  int rv = 0;

  ASSERT (parent_sw_if_index);

  clib_memset (address, 0, sizeof (address));

  /*
   * Allocate a pipe instance.  Either select one dynamically
   * or try to use the desired user_instance number.
   */
  instance = pipe_instance_alloc (is_specified, user_instance);
  if (instance == ~0)
    {
      return VNET_API_ERROR_INVALID_REGISTRATION;
    }

  /*
   * Default MAC address (0000:0000:0000 + instance) is allocated
   */
  address[5] = instance;

  eir.dev_class_index = pipe_device_class.index;
  eir.dev_instance = instance;
  eir.address = address;
  hw_if_index = vnet_eth_register_interface (vnm, &eir);

  hi = vnet_get_hw_interface (vnm, hw_if_index);
  *parent_sw_if_index = hi->sw_if_index;
  slot = vlib_node_add_named_next_with_slot (vm, hi->tx_node_index,
					     "pipe-rx",
					     VNET_PIPE_TX_NEXT_ETHERNET_INPUT);
  ASSERT (slot == VNET_PIPE_TX_NEXT_ETHERNET_INPUT);

  /*
   * create two sub-interfaces, one for each end of the pipe.
   */
  error = pipe_create_sub_interface (hi, 0, &pipe_sw_if_index[0]);

  if (error)
    goto oops;

  error = pipe_create_sub_interface (hi, 1, &pipe_sw_if_index[1]);

  if (error)
    goto oops;

  hash_set (hi->sub_interface_sw_if_index_by_id, 0, pipe_sw_if_index[0]);
  hash_set (hi->sub_interface_sw_if_index_by_id, 1, pipe_sw_if_index[1]);

  vec_validate_init_empty (pipe_main.pipes, pipe_sw_if_index[0],
			   PIPE_INVALID);
  vec_validate_init_empty (pipe_main.pipes, pipe_sw_if_index[1],
			   PIPE_INVALID);

  pipe_main.pipes[pipe_sw_if_index[0]].sw_if_index = pipe_sw_if_index[1];
  pipe_main.pipes[pipe_sw_if_index[1]].sw_if_index = pipe_sw_if_index[0];

  return 0;

oops:
  clib_error_report (error);
  return rv;
}

typedef struct pipe_hw_walk_ctx_t_
{
  pipe_cb_fn_t cb;
  void *ctx;
} pipe_hw_walk_ctx_t;

static walk_rc_t
pipe_hw_walk (vnet_main_t * vnm, u32 hw_if_index, void *args)
{
  vnet_hw_interface_t *hi;
  pipe_hw_walk_ctx_t *ctx;

  ctx = args;
  hi = vnet_get_hw_interface (vnm, hw_if_index);

  if (hi->dev_class_index == pipe_device_class.index)
    {
      u32 pipe_sw_if_index[2], id, sw_if_index;

      hash_foreach (id, sw_if_index, hi->sub_interface_sw_if_index_by_id,
      ({
        ASSERT(id < 2);
        pipe_sw_if_index[id] = sw_if_index;
      }));

      ctx->cb (hi->sw_if_index, pipe_sw_if_index, hi->dev_instance, ctx->ctx);
    }

  return (WALK_CONTINUE);
}

void
pipe_walk (pipe_cb_fn_t fn, void *ctx)
{
  pipe_hw_walk_ctx_t wctx = {
    .cb = fn,
    .ctx = ctx,
  };

  ASSERT (fn);

  vnet_hw_interface_walk (vnet_get_main (), pipe_hw_walk, &wctx);
}

static clib_error_t *
create_pipe_interfaces (vlib_main_t * vm,
			unformat_input_t * input, vlib_cli_command_t * cmd)
{
  int rv;
  u32 sw_if_index;
  u32 pipe_sw_if_index[2];
  u8 is_specified = 0;
  u32 user_instance = 0;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "instance %d", &user_instance))
	is_specified = 1;
      else
	break;
    }

  rv = vnet_create_pipe_interface (is_specified, user_instance,
				   &sw_if_index, pipe_sw_if_index);

  if (rv)
    return clib_error_return (0, "vnet_create_pipe_interface failed");

  vlib_cli_output (vm, "%U\n", format_vnet_sw_if_index_name,
		   vnet_get_main (), sw_if_index);
  return 0;
}

/*?
 * Create a pipe interface.
 *
 * @cliexpar
 * The following two command syntaxes are equivalent:
 * @cliexcmd{pipe create-interface [mac <mac-addr>] [instance <instance>]}
 * Example of how to create a pipe interface:
 * @cliexcmd{pipe create}
 ?*/
VLIB_CLI_COMMAND (pipe_create_interface_command, static) = {
  .path = "pipe create",
  .short_help = "pipe create [instance <instance>]",
  .function = create_pipe_interfaces,
};

int
vnet_delete_pipe_interface (u32 sw_if_index)
{
  vnet_main_t *vnm = vnet_get_main ();
  vnet_sw_interface_t *si;
  vnet_hw_interface_t *hi;
  u32 instance, id;
  u32 hw_if_index;

  if (pool_is_free_index (vnm->interface_main.sw_interfaces, sw_if_index))
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  si = vnet_get_sw_interface (vnm, sw_if_index);
  hw_if_index = si->hw_if_index;
  hi = vnet_get_hw_interface (vnm, hw_if_index);
  instance = hi->dev_instance;

  if (pipe_instance_free (instance) < 0)
    {
      return VNET_API_ERROR_INVALID_SW_IF_INDEX;
    }

  hash_foreach (id, sw_if_index, hi->sub_interface_sw_if_index_by_id,
  ({
    vnet_delete_sub_interface(sw_if_index);
    pipe_main.pipes[sw_if_index] = PIPE_INVALID;
  }));

  ethernet_delete_interface (vnm, hw_if_index);

  return 0;
}

static clib_error_t *
delete_pipe_interfaces (vlib_main_t * vm,
			unformat_input_t * input, vlib_cli_command_t * cmd)
{
  vnet_main_t *vnm = vnet_get_main ();
  u32 sw_if_index = ~0;
  int rv;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "%U",
		    unformat_vnet_sw_interface, vnm, &sw_if_index))
	;
      else
	break;
    }

  if (sw_if_index == ~0)
    return clib_error_return (0, "interface not specified");

  rv = vnet_delete_pipe_interface (sw_if_index);

  if (rv)
    return clib_error_return (0, "vnet_delete_pipe_interface failed");

  return 0;
}

/*?
 * Delete a pipe interface.
 *
 * @cliexpar
 * The following two command syntaxes are equivalent:
 * @cliexcmd{pipe delete intfc <interface>}
 * Example of how to delete a pipe interface:
 * @cliexcmd{pipe delete-interface intfc loop0}
 ?*/
VLIB_CLI_COMMAND (pipe_delete_interface_command, static) = {
  .path = "pipe delete",
  .short_help = "pipe delete <interface>",
  .function = delete_pipe_interfaces,
};

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