/*
 * 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 interfaces
 * that are joined.
 */
const static pipe_t PIPE_INVALID = {
  .sw_if_index = ~0,
  .subint = {0},
};

/**
 * Various 'module' lavel 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 againt
   * 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) rewirtes. Hwoever, 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);
}

/* *INDENT-OFF* */
VNET_HW_INTERFACE_CLASS (pipe_hw_interface_class) = {
  .name = "Pipe",
  .build_rewrite = pipe_build_rewrite,
  .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
};
/* *INDENT-ON* */

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;
  u32 n_pkts = 0, n_bytes = 0;
  u32 thread_index = vm->thread_index;
  vnet_main_t *vnm = vnet_get_main ();
  vnet_interface_main_t *im = &vnm->interface_main;
  vlib_buffer_t *b;
  pipe_t *pipe;

  n_left_from = frame->n_vectors;
  from = vlib_frame_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 (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++;
	  n_pkts++;
	  n_bytes += vlib_buffer_length_in_chain (vm, b);
	}
      from += n_copy;

      vlib_put_next_frame (vm, node, next_index, n_left_to_next);

      /* increment TX interface stat */
      vlib_increment_combined_counter (im->combined_sw_if_counters +
				       VNET_INTERFACE_COUNTER_TX,
				       thread_index, sw_if_index, n_pkts,
				       n_bytes);
    }

  return n_left_from;
}

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

  /* *INDENT-OFF* */
  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);
  }));
  /* *INDENT-ON* */

  return (NULL);
}

/* *INDENT-OFF* */
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,
};
/* *INDENT-ON* */

#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 (p2->data, CLIB_CACHE_LINE_BYTES, LOAD);
	    CLIB_PREFETCH (p3->data, CLIB_CACHE_LINE_BYTES, LOAD);
	  }

	  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)->l3_hdr_offset =
	    vnet_buffer (b0)->l2_hdr_offset + vnet_buffer (b0)->l2.l2_len;
	  vnet_buffer (b1)->l3_hdr_offset =
	    vnet_buffer (b1)->l2_hdr_offset + vnet_buffer (b1)->l2.l2_len;
	  b0->flags |= VNET_BUFFER_F_L3_HDR_OFFSET_VALID;
	  b1->flags |= VNET_BUFFER_F_L3_HDR_OFFSET_VALID;

	  is_l20 = pipe0->subint.flags & SUBINT_CONFIG_L2;
	  is_l21 = pipe1->subint.flags & SUBINT_CONFIG_L2;
	  pipe_determine_next_node (&ethernet_main, is_l20, type0, b0,
				    &next0);
	  pipe_determine_next_node (&ethernet_main, is_l21, type1, b1,
				    &next1);

	  if (!is_l20)
	    vlib_buffer_advance (b0, sizeof (ethernet_header_t));
	  else
	    {
	      u32 eth_start = vnet_buffer (b0)->l2_hdr_offset;
	      vnet_buffer (b0)->l2.l2_len = b0->current_data - eth_start;
	    }
	  if (!is_l21)
	    vlib_buffer_advance (b1, sizeof (ethernet_header_t));
	  else
	    {
	      u32 eth_start = vnet_buffer (b1)->l2_hdr_offset;
	      vnet_buffer (b1)->l2.l2_len = b1->current_data - eth_start;
	    }

	  vlib_validate_buffer_enqueue_x2 (vm, node, next_index,
					   to_next, n_left_to_next,
					   bi0, bi1, next0, next0);
	}
      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)->l3_hdr_offset =
	    vnet_buffer (b0)->l2_hdr_offset + vnet_buffer (b0)->l2.l2_len;
	  b0->flags |= VNET_BUFFER_F_L3_HDR_OFFSET_VALID;

	  is_l20 = pipe0->subint.flags & SUBINT_CONFIG_L2;
	  pipe_determine_next_node (&ethernet_main, is_l20, type0, b0,
				    &next0);

	  if (!is_l20)
	    vlib_buffer_advance (b0, sizeof (ethernet_header_t));
	  else
	    {
	      u32 eth_start = vnet_buffer (b0)->l2_hdr_offset;
	      vnet_buffer (b0)->l2.l2_len = b0->current_data - eth_start;
	    }

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

/* *INDENT-OFF* */
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",
};
/* *INDENT-ON* */

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

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

  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;

  error = ethernet_register_interface (vnm, pipe_device_class.index,
				       instance, address, &hw_if_index,
				       /* flag change */ 0);

  if (error)
    {
      rv = VNET_API_ERROR_INVALID_REGISTRATION;
      goto oops;
    }

  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;

      /* *INDENT-OFF* */
      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;
      }));
      /* *INDENT-ON* */

      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}
 ?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (pipe_create_interface_command, static) = {
  .path = "pipe create",
  .short_help = "pipe create [instance <instance>]",
  .function = create_pipe_interfaces,
};
/* *INDENT-ON* */

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

  /* *INDENT-OFF* */
  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;
  }));
  /* *INDENT-ON* */

  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}
 ?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (pipe_delete_interface_command, static) = {
  .path = "pipe delete",
  .short_help = "pipe delete <interface>",
  .function = delete_pipe_interfaces,
};
/* *INDENT-ON* */

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