/*
 *------------------------------------------------------------------
 * tapcli.c - dynamic tap interface hookup
 *
 * Copyright (c) 2009 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  dynamic tap interface hookup
 */

#include <fcntl.h>		/* for open */
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>		/* for iovec */
#include <netinet/in.h>

#include <linux/if_arp.h>
#include <linux/if_tun.h>

#include <vlib/vlib.h>
#include <vlib/unix/unix.h>

#include <vnet/ip/ip.h>

#include <vnet/ethernet/ethernet.h>

#include <vnet/feature/feature.h>
#include <vnet/devices/devices.h>
#include <vnet/unix/tuntap.h>
#include <vnet/unix/tapcli.h>

static vnet_device_class_t tapcli_dev_class;
static vnet_hw_interface_class_t tapcli_interface_class;
static vlib_node_registration_t tapcli_rx_node;

static void tapcli_nopunt_frame (vlib_main_t * vm,
				 vlib_node_runtime_t * node,
				 vlib_frame_t * frame);
/**
 * @brief Struct for the tapcli interface
 */
typedef struct
{
  u32 unix_fd;
  u32 clib_file_index;
  u32 provision_fd;
  /** For counters */
  u32 sw_if_index;
  u32 hw_if_index;
  u32 is_promisc;
  struct ifreq ifr;
  u32 per_interface_next_index;
  /** for delete */
  u8 active;
} tapcli_interface_t;

/**
 * @brief Struct for RX trace
 */
typedef struct
{
  u16 sw_if_index;
} tapcli_rx_trace_t;

/**
 * @brief Function to format TAP CLI trace
 *
 * @param *s - u8 - formatting string
 * @param *va - va_list
 *
 * @return *s - u8 - formatted string
 *
 */
u8 *
format_tapcli_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 *);
  vnet_main_t *vnm = vnet_get_main ();
  tapcli_rx_trace_t *t = va_arg (*va, tapcli_rx_trace_t *);
  s = format (s, "%U", format_vnet_sw_if_index_name, vnm, t->sw_if_index);
  return s;
}

/**
 * @brief TAPCLI per thread struct
 */
typedef struct
{
  /** Vector of VLIB rx buffers to use.  We allocate them in blocks
     of VLIB_FRAME_SIZE (256). */
  u32 *rx_buffers;

  /** Vector of iovecs for readv/writev calls. */
  struct iovec *iovecs;
} tapcli_per_thread_t;

/**
 * @brief TAPCLI main state struct
 */
typedef struct
{
  /** per thread variables */
  tapcli_per_thread_t *threads;

  /** tap device destination MAC address. Required, or Linux drops pkts */
  u8 ether_dst_mac[6];

  /** Interface MTU in bytes and # of default sized buffers. */
  u32 mtu_bytes, mtu_buffers;

  /** Vector of tap interfaces */
  tapcli_interface_t *tapcli_interfaces;

  /** Vector of deleted tap interfaces */
  u32 *tapcli_inactive_interfaces;

  /** Bitmap of tap interfaces with pending reads */
  uword *pending_read_bitmap;

  /** Hash table to find tapcli interface given hw_if_index */
  uword *tapcli_interface_index_by_sw_if_index;

  /** Hash table to find tapcli interface given unix fd */
  uword *tapcli_interface_index_by_unix_fd;

  /** renumbering table */
  u32 *show_dev_instance_by_real_dev_instance;

  /** 1 => disable CLI */
  int is_disabled;

  /** convenience - vlib_main_t */
  vlib_main_t *vlib_main;
  /** convenience - vnet_main_t */
  vnet_main_t *vnet_main;
} tapcli_main_t;

static tapcli_main_t tapcli_main;

/**
 * @brief tapcli TX node function
 * @node tap-cli-tx
 *
 * Output node, writes the buffers comprising the incoming frame
 * to the tun/tap device, aka hands them to the Linux kernel stack.
 *
 * @param *vm - vlib_main_t
 * @param *node - vlib_node_runtime_t
 * @param *frame - vlib_frame_t
 *
 * @return n_packets - uword
 *
 */
static uword
tapcli_tx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  u32 *buffers = vlib_frame_args (frame);
  uword n_packets = frame->n_vectors;
  tapcli_main_t *tm = &tapcli_main;
  tapcli_interface_t *ti;
  int i;
  u16 thread_index = vlib_get_thread_index ();

  for (i = 0; i < n_packets; i++)
    {
      struct iovec *iov;
      vlib_buffer_t *b;
      uword l;
      vnet_hw_interface_t *hw;
      uword *p;
      u32 tx_sw_if_index;

      b = vlib_get_buffer (vm, buffers[i]);

      tx_sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_TX];
      if (tx_sw_if_index == (u32) ~ 0)
	tx_sw_if_index = vnet_buffer (b)->sw_if_index[VLIB_RX];

      ASSERT (tx_sw_if_index != (u32) ~ 0);

      /* Use the sup intfc to finesse vlan subifs */
      hw = vnet_get_sup_hw_interface (tm->vnet_main, tx_sw_if_index);
      tx_sw_if_index = hw->sw_if_index;

      p = hash_get (tm->tapcli_interface_index_by_sw_if_index,
		    tx_sw_if_index);
      if (p == 0)
	{
	  clib_warning ("sw_if_index %d unknown", tx_sw_if_index);
	  /* $$$ leak, but this should never happen... */
	  continue;
	}
      else
	ti = vec_elt_at_index (tm->tapcli_interfaces, p[0]);

      /* Re-set iovecs if present. */
      if (tm->threads[thread_index].iovecs)
	_vec_len (tm->threads[thread_index].iovecs) = 0;

      /* VLIB buffer chain -> Unix iovec(s). */
      vec_add2 (tm->threads[thread_index].iovecs, iov, 1);
      iov->iov_base = b->data + b->current_data;
      iov->iov_len = l = b->current_length;

      if (PREDICT_FALSE (b->flags & VLIB_BUFFER_NEXT_PRESENT))
	{
	  do
	    {
	      b = vlib_get_buffer (vm, b->next_buffer);

	      vec_add2 (tm->threads[thread_index].iovecs, iov, 1);

	      iov->iov_base = b->data + b->current_data;
	      iov->iov_len = b->current_length;
	      l += b->current_length;
	    }
	  while (b->flags & VLIB_BUFFER_NEXT_PRESENT);
	}

      if (writev (ti->unix_fd, tm->threads[thread_index].iovecs,
		  vec_len (tm->threads[thread_index].iovecs)) < l)
	clib_unix_warning ("writev");
    }

  vlib_buffer_free (vm, vlib_frame_vector_args (frame), frame->n_vectors);

  return n_packets;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tapcli_tx_node,static) = {
  .function = tapcli_tx,
  .name = "tapcli-tx",
  .type = VLIB_NODE_TYPE_INTERNAL,
  .vector_size = 4,
};
/* *INDENT-ON* */

/**
 * @brief Dispatch tapcli RX node function for node tap_cli_rx
 *
 *
 * @param *vm - vlib_main_t
 * @param *node - vlib_node_runtime_t
 * @param *ti - tapcli_interface_t
 *
 * @return n_packets - uword
 *
 */
static uword
tapcli_rx_iface (vlib_main_t * vm,
		 vlib_node_runtime_t * node, tapcli_interface_t * ti)
{
  tapcli_main_t *tm = &tapcli_main;
  const uword buffer_size = VLIB_BUFFER_DATA_SIZE;
  u32 n_trace = vlib_get_trace_count (vm, node);
  u8 set_trace = 0;
  u16 thread_index = vlib_get_thread_index ();
  vnet_main_t *vnm;
  vnet_sw_interface_t *si;
  u8 admin_down;
  u32 next = node->cached_next_index;
  u32 n_left_to_next, next_index;
  u32 *to_next;

  vnm = vnet_get_main ();
  si = vnet_get_sw_interface (vnm, ti->sw_if_index);
  admin_down = !(si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP);

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

  while (n_left_to_next)
    {				// Fill at most one vector
      vlib_buffer_t *b_first, *b, *prev;
      u32 bi_first, bi;
      word n_bytes_in_packet;
      int j, n_bytes_left;

      if (PREDICT_FALSE (vec_len (tm->threads[thread_index].rx_buffers) <
			 tm->mtu_buffers))
	{
	  uword len = vec_len (tm->threads[thread_index].rx_buffers);
	  _vec_len (tm->threads[thread_index].rx_buffers) +=
	    vlib_buffer_alloc_from_free_list (vm,
					      &tm->threads[thread_index].
					      rx_buffers[len],
					      VLIB_FRAME_SIZE - len,
					      VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);
	  if (PREDICT_FALSE
	      (vec_len (tm->threads[thread_index].rx_buffers) <
	       tm->mtu_buffers))
	    {
	      vlib_node_increment_counter (vm, tapcli_rx_node.index,
					   TAPCLI_ERROR_BUFFER_ALLOC,
					   tm->mtu_buffers -
					   vec_len (tm->threads
						    [thread_index].
						    rx_buffers));
	      break;
	    }
	}

      uword i_rx = vec_len (tm->threads[thread_index].rx_buffers) - 1;

      /* Allocate RX buffers from end of rx_buffers.
         Turn them into iovecs to pass to readv. */
      vec_validate (tm->threads[thread_index].iovecs, tm->mtu_buffers - 1);
      for (j = 0; j < tm->mtu_buffers; j++)
	{
	  b =
	    vlib_get_buffer (vm,
			     tm->threads[thread_index].rx_buffers[i_rx - j]);
	  tm->threads[thread_index].iovecs[j].iov_base = b->data;
	  tm->threads[thread_index].iovecs[j].iov_len = buffer_size;
	}

      n_bytes_left = readv (ti->unix_fd, tm->threads[thread_index].iovecs,
			    tm->mtu_buffers);
      n_bytes_in_packet = n_bytes_left;
      if (n_bytes_left <= 0)
	{
	  if (errno != EAGAIN)
	    {
	      vlib_node_increment_counter (vm, tapcli_rx_node.index,
					   TAPCLI_ERROR_READ, 1);
	    }
	  break;
	}

      bi_first = tm->threads[thread_index].rx_buffers[i_rx];
      b = b_first = vlib_get_buffer (vm,
				     tm->threads[thread_index].
				     rx_buffers[i_rx]);
      prev = NULL;

      while (1)
	{
	  b->current_length =
	    n_bytes_left < buffer_size ? n_bytes_left : buffer_size;
	  n_bytes_left -= buffer_size;

	  if (prev)
	    {
	      prev->next_buffer = bi;
	      prev->flags |= VLIB_BUFFER_NEXT_PRESENT;
	    }
	  prev = b;

	  /* last segment */
	  if (n_bytes_left <= 0)
	    break;

	  i_rx--;
	  bi = tm->threads[thread_index].rx_buffers[i_rx];
	  b = vlib_get_buffer (vm, bi);
	}

      _vec_len (tm->threads[thread_index].rx_buffers) = i_rx;

      b_first->total_length_not_including_first_buffer =
	(n_bytes_in_packet >
	 buffer_size) ? n_bytes_in_packet - buffer_size : 0;
      b_first->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;

      VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b_first);

      vnet_buffer (b_first)->sw_if_index[VLIB_RX] = ti->sw_if_index;
      vnet_buffer (b_first)->sw_if_index[VLIB_TX] = (u32) ~ 0;

      b_first->error = node->errors[TAPCLI_ERROR_NONE];
      next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
      next_index = (ti->per_interface_next_index != ~0) ?
	ti->per_interface_next_index : next_index;
      next_index = admin_down ? VNET_DEVICE_INPUT_NEXT_DROP : next_index;

      to_next[0] = bi_first;
      to_next++;
      n_left_to_next--;

      vnet_feature_start_device_input_x1 (ti->sw_if_index, &next_index,
					  b_first);

      vlib_validate_buffer_enqueue_x1 (vm, node, next,
				       to_next, n_left_to_next,
				       bi_first, next_index);

      /* Interface counters for tapcli interface. */
      if (PREDICT_TRUE (!admin_down))
	{
	  vlib_increment_combined_counter (vnet_main.interface_main.
					   combined_sw_if_counters +
					   VNET_INTERFACE_COUNTER_RX,
					   thread_index, ti->sw_if_index, 1,
					   n_bytes_in_packet);

	  if (PREDICT_FALSE (n_trace > 0))
	    {
	      vlib_trace_buffer (vm, node, next_index,
				 b_first, /* follow_chain */ 1);
	      n_trace--;
	      set_trace = 1;
	      tapcli_rx_trace_t *t0 =
		vlib_add_trace (vm, node, b_first, sizeof (*t0));
	      t0->sw_if_index = si->sw_if_index;
	    }
	}
    }
  vlib_put_next_frame (vm, node, next, n_left_to_next);
  if (set_trace)
    vlib_set_trace_count (vm, node, n_trace);
  return VLIB_FRAME_SIZE - n_left_to_next;
}

/**
 * @brief tapcli RX node function
 * @node tap-cli-rx
 *
 * Input node from the Kernel tun/tap device
 *
 * @param *vm - vlib_main_t
 * @param *node - vlib_node_runtime_t
 * @param *frame - vlib_frame_t
 *
 * @return n_packets - uword
 *
 */
static uword
tapcli_rx (vlib_main_t * vm, vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  tapcli_main_t *tm = &tapcli_main;
  static u32 *ready_interface_indices;
  tapcli_interface_t *ti;
  int i;
  u32 total_count = 0;

  vec_reset_length (ready_interface_indices);
  /* *INDENT-OFF* */
  clib_bitmap_foreach (i, tm->pending_read_bitmap,
  ({
    vec_add1 (ready_interface_indices, i);
  }));
  /* *INDENT-ON* */

  if (vec_len (ready_interface_indices) == 0)
    return 0;

  for (i = 0; i < vec_len (ready_interface_indices); i++)
    {
      tm->pending_read_bitmap =
	clib_bitmap_set (tm->pending_read_bitmap,
			 ready_interface_indices[i], 0);

      ti =
	vec_elt_at_index (tm->tapcli_interfaces, ready_interface_indices[i]);
      total_count += tapcli_rx_iface (vm, node, ti);
    }
  return total_count;		//This might return more than 256.
}

/** TAPCLI error strings */
static char *tapcli_rx_error_strings[] = {
#define _(sym,string) string,
  foreach_tapcli_error
#undef _
};

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (tapcli_rx_node, static) = {
  .function = tapcli_rx,
  .name = "tapcli-rx",
  .sibling_of = "device-input",
  .type = VLIB_NODE_TYPE_INPUT,
  .state = VLIB_NODE_STATE_INTERRUPT,
  .vector_size = 4,
  .n_errors = TAPCLI_N_ERROR,
  .error_strings = tapcli_rx_error_strings,
  .format_trace = format_tapcli_rx_trace,
};
/* *INDENT-ON* */


/**
 * @brief Gets called when file descriptor is ready from epoll.
 *
 * @param *uf - clib_file_t
 *
 * @return error - clib_error_t
 *
 */
static clib_error_t *
tapcli_read_ready (clib_file_t * uf)
{
  vlib_main_t *vm = vlib_get_main ();
  tapcli_main_t *tm = &tapcli_main;
  uword *p;

  /** Schedule the rx node */
  vlib_node_set_interrupt_pending (vm, tapcli_rx_node.index);

  p = hash_get (tm->tapcli_interface_index_by_unix_fd, uf->file_descriptor);

  /** Mark the specific tap interface ready-to-read */
  if (p)
    tm->pending_read_bitmap = clib_bitmap_set (tm->pending_read_bitmap,
					       p[0], 1);
  else
    clib_warning ("fd %d not in hash table", uf->file_descriptor);

  return 0;
}

/**
 * @brief CLI function for TAPCLI configuration
 *
 * @param *vm - vlib_main_t
 * @param *input - unformat_input_t
 *
 * @return error - clib_error_t
 *
 */
static clib_error_t *
tapcli_config (vlib_main_t * vm, unformat_input_t * input)
{
  tapcli_main_t *tm = &tapcli_main;
  const uword buffer_size = VLIB_BUFFER_DATA_SIZE;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "mtu %d", &tm->mtu_bytes))
	;
      else if (unformat (input, "disable"))
	tm->is_disabled = 1;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  if (tm->is_disabled)
    return 0;

  if (geteuid ())
    {
      clib_warning ("tapcli disabled: must be superuser");
      tm->is_disabled = 1;
      return 0;
    }

  tm->mtu_buffers = (tm->mtu_bytes + (buffer_size - 1)) / buffer_size;

  return 0;
}

/**
 * @brief Renumber TAPCLI interface
 *
 * @param *hi - vnet_hw_interface_t
 * @param new_dev_instance - u32
 *
 * @return rc - int
 *
 */
static int
tap_name_renumber (vnet_hw_interface_t * hi, u32 new_dev_instance)
{
  tapcli_main_t *tm = &tapcli_main;

  vec_validate_init_empty (tm->show_dev_instance_by_real_dev_instance,
			   hi->dev_instance, ~0);

  tm->show_dev_instance_by_real_dev_instance[hi->dev_instance] =
    new_dev_instance;

  return 0;
}

VLIB_CONFIG_FUNCTION (tapcli_config, "tapcli");

/**
 * @brief Free "no punt" frame
 *
 * @param *vm - vlib_main_t
 * @param *node - vlib_node_runtime_t
 * @param *frame - vlib_frame_t
 *
 */
static void
tapcli_nopunt_frame (vlib_main_t * vm,
		     vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  u32 *buffers = vlib_frame_args (frame);
  uword n_packets = frame->n_vectors;
  vlib_buffer_free (vm, buffers, n_packets);
  vlib_frame_free (vm, node, frame);
}

/* *INDENT-OFF* */
VNET_HW_INTERFACE_CLASS (tapcli_interface_class,static) = {
  .name = "tapcli",
  .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
};
/* *INDENT-ON* */

/**
 * @brief Formatter for TAPCLI interface name
 *
 * @param *s - formatter string
 * @param *args - va_list
 *
 * @return *s - formatted string
 *
 */
static u8 *
format_tapcli_interface_name (u8 * s, va_list * args)
{
  u32 i = va_arg (*args, u32);
  u32 show_dev_instance = ~0;
  tapcli_main_t *tm = &tapcli_main;

  if (i < vec_len (tm->show_dev_instance_by_real_dev_instance))
    show_dev_instance = tm->show_dev_instance_by_real_dev_instance[i];

  if (show_dev_instance != ~0)
    i = show_dev_instance;

  s = format (s, "tapcli-%d", i);
  return s;
}

/**
 * @brief Modify interface flags for TAPCLI interface
 *
 * @param *vnm - vnet_main_t
 * @param *hw - vnet_hw_interface_t
 * @param flags - u32
 *
 * @return rc - u32
 *
 */
static u32
tapcli_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hw, u32 flags)
{
  tapcli_main_t *tm = &tapcli_main;
  tapcli_interface_t *ti;

  ti = vec_elt_at_index (tm->tapcli_interfaces, hw->dev_instance);

  if (flags & ETHERNET_INTERFACE_FLAG_MTU)
    {
      const uword buffer_size = VLIB_BUFFER_DATA_SIZE;
      tm->mtu_bytes = hw->max_packet_bytes;
      tm->mtu_buffers = (tm->mtu_bytes + (buffer_size - 1)) / buffer_size;
    }
  else
    {
      struct ifreq ifr;
      u32 want_promisc;

      memcpy (&ifr, &ti->ifr, sizeof (ifr));

      /* get flags, modify to bring up interface... */
      if (ioctl (ti->provision_fd, SIOCGIFFLAGS, &ifr) < 0)
	{
	  clib_unix_warning ("Couldn't get interface flags for %s", hw->name);
	  return 0;
	}

      want_promisc = (flags & ETHERNET_INTERFACE_FLAG_ACCEPT_ALL) != 0;

      if (want_promisc == ti->is_promisc)
	return 0;

      if (flags & ETHERNET_INTERFACE_FLAG_ACCEPT_ALL)
	ifr.ifr_flags |= IFF_PROMISC;
      else
	ifr.ifr_flags &= ~(IFF_PROMISC);

      /* get flags, modify to bring up interface... */
      if (ioctl (ti->provision_fd, SIOCSIFFLAGS, &ifr) < 0)
	{
	  clib_unix_warning ("Couldn't set interface flags for %s", hw->name);
	  return 0;
	}

      ti->is_promisc = want_promisc;
    }

  return 0;
}

/**
 * @brief Setting the TAP interface's next processing node
 *
 * @param *vnm - vnet_main_t
 * @param hw_if_index - u32
 * @param node_index - u32
 *
 */
static void
tapcli_set_interface_next_node (vnet_main_t * vnm,
				u32 hw_if_index, u32 node_index)
{
  tapcli_main_t *tm = &tapcli_main;
  tapcli_interface_t *ti;
  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);

  ti = vec_elt_at_index (tm->tapcli_interfaces, hw->dev_instance);

  /** Shut off redirection */
  if (node_index == ~0)
    {
      ti->per_interface_next_index = node_index;
      return;
    }

  ti->per_interface_next_index =
    vlib_node_add_next (tm->vlib_main, tapcli_rx_node.index, node_index);
}

/**
 * @brief Set link_state == admin_state otherwise things like ip6 neighbor discovery breaks
 *
 * @param *vnm - vnet_main_t
 * @param hw_if_index - u32
 * @param flags - u32
 *
 * @return error - clib_error_t
 */
static clib_error_t *
tapcli_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
{
  uword is_admin_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
  u32 hw_flags;
  u32 speed_duplex = VNET_HW_INTERFACE_FLAG_FULL_DUPLEX
    | VNET_HW_INTERFACE_FLAG_SPEED_1G;

  if (is_admin_up)
    hw_flags = VNET_HW_INTERFACE_FLAG_LINK_UP | speed_duplex;
  else
    hw_flags = speed_duplex;

  vnet_hw_interface_set_flags (vnm, hw_if_index, hw_flags);
  return 0;
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (tapcli_dev_class,static) = {
  .name = "tapcli",
  .tx_function = tapcli_tx,
  .format_device_name = format_tapcli_interface_name,
  .rx_redirect_to_node = tapcli_set_interface_next_node,
  .name_renumber = tap_name_renumber,
  .admin_up_down_function = tapcli_interface_admin_up_down,
};
/* *INDENT-ON* */

/**
 * @brief Dump TAP interfaces
 *
 * @param **out_tapids - tapcli_interface_details_t
 *
 * @return rc - int
 *
 */
int
vnet_tap_dump_ifs (tapcli_interface_details_t ** out_tapids)
{
  tapcli_main_t *tm = &tapcli_main;
  tapcli_interface_t *ti;

  tapcli_interface_details_t *r_tapids = NULL;
  tapcli_interface_details_t *tapid = NULL;

  vec_foreach (ti, tm->tapcli_interfaces)
  {
    if (!ti->active)
      continue;
    vec_add2 (r_tapids, tapid, 1);
    tapid->sw_if_index = ti->sw_if_index;
    strncpy ((char *) tapid->dev_name, ti->ifr.ifr_name,
	     sizeof (ti->ifr.ifr_name) - 1);
  }

  *out_tapids = r_tapids;

  return 0;
}

/**
 * @brief Get tap interface from inactive interfaces or create new
 *
 * @return interface - tapcli_interface_t
 *
 */
static tapcli_interface_t *
tapcli_get_new_tapif ()
{
  tapcli_main_t *tm = &tapcli_main;
  tapcli_interface_t *ti = NULL;

  int inactive_cnt = vec_len (tm->tapcli_inactive_interfaces);
  // if there are any inactive ifaces
  if (inactive_cnt > 0)
    {
      // take last
      u32 ti_idx = tm->tapcli_inactive_interfaces[inactive_cnt - 1];
      if (vec_len (tm->tapcli_interfaces) > ti_idx)
	{
	  ti = vec_elt_at_index (tm->tapcli_interfaces, ti_idx);
	  clib_warning ("reusing tap interface");
	}
      // "remove" from inactive list
      _vec_len (tm->tapcli_inactive_interfaces) -= 1;
    }

  // ti was not retrieved from inactive ifaces - create new
  if (!ti)
    vec_add2 (tm->tapcli_interfaces, ti, 1);

  return ti;
}

typedef struct
{
  ip6_address_t addr;
  u32 mask_width;
  unsigned int ifindex;
} ip6_ifreq_t;

/**
 * @brief Connect a TAP interface
 *
 * @param vm - vlib_main_t
 * @param ap - vnet_tap_connect_args_t
 *
 * @return rc - int
 *
 */
int
vnet_tap_connect (vlib_main_t * vm, vnet_tap_connect_args_t * ap)
{
  tapcli_main_t *tm = &tapcli_main;
  tapcli_interface_t *ti = NULL;
  struct ifreq ifr;
  int flags;
  int dev_net_tun_fd;
  int dev_tap_fd = -1;
  clib_error_t *error;
  u8 hwaddr[6];
  int rv = 0;

  if (tm->is_disabled)
    {
      return VNET_API_ERROR_FEATURE_DISABLED;
    }

  flags = IFF_TAP | IFF_NO_PI;

  if ((dev_net_tun_fd = open ("/dev/net/tun", O_RDWR)) < 0)
    return VNET_API_ERROR_SYSCALL_ERROR_1;

  memset (&ifr, 0, sizeof (ifr));
  strncpy (ifr.ifr_name, (char *) ap->intfc_name, sizeof (ifr.ifr_name) - 1);
  ifr.ifr_flags = flags;
  if (ioctl (dev_net_tun_fd, TUNSETIFF, (void *) &ifr) < 0)
    {
      rv = VNET_API_ERROR_SYSCALL_ERROR_2;
      goto error;
    }

  /* Open a provisioning socket */
  if ((dev_tap_fd = socket (PF_PACKET, SOCK_RAW, htons (ETH_P_ALL))) < 0)
    {
      rv = VNET_API_ERROR_SYSCALL_ERROR_3;
      goto error;
    }

  /* Find the interface index. */
  {
    struct ifreq ifr;
    struct sockaddr_ll sll;

    memset (&ifr, 0, sizeof (ifr));
    strncpy (ifr.ifr_name, (char *) ap->intfc_name,
	     sizeof (ifr.ifr_name) - 1);
    if (ioctl (dev_tap_fd, SIOCGIFINDEX, &ifr) < 0)
      {
	rv = VNET_API_ERROR_SYSCALL_ERROR_4;
	goto error;
      }

    /* Bind the provisioning socket to the interface. */
    memset (&sll, 0, sizeof (sll));
    sll.sll_family = AF_PACKET;
    sll.sll_ifindex = ifr.ifr_ifindex;
    sll.sll_protocol = htons (ETH_P_ALL);

    if (bind (dev_tap_fd, (struct sockaddr *) &sll, sizeof (sll)) < 0)
      {
	rv = VNET_API_ERROR_SYSCALL_ERROR_5;
	goto error;
      }
  }

  /* non-blocking I/O on /dev/tapX */
  {
    int one = 1;
    if (ioctl (dev_net_tun_fd, FIONBIO, &one) < 0)
      {
	rv = VNET_API_ERROR_SYSCALL_ERROR_6;
	goto error;
      }
  }
  ifr.ifr_mtu = tm->mtu_bytes;
  if (ioctl (dev_tap_fd, SIOCSIFMTU, &ifr) < 0)
    {
      rv = VNET_API_ERROR_SYSCALL_ERROR_7;
      goto error;
    }

  /* get flags, modify to bring up interface... */
  if (ioctl (dev_tap_fd, SIOCGIFFLAGS, &ifr) < 0)
    {
      rv = VNET_API_ERROR_SYSCALL_ERROR_8;
      goto error;
    }

  ifr.ifr_flags |= (IFF_UP | IFF_RUNNING);

  if (ioctl (dev_tap_fd, SIOCSIFFLAGS, &ifr) < 0)
    {
      rv = VNET_API_ERROR_SYSCALL_ERROR_9;
      goto error;
    }

  if (ap->ip4_address_set)
    {
      struct sockaddr_in sin;
      /* ip4: mask defaults to /24 */
      u32 mask = clib_host_to_net_u32 (0xFFFFFF00);

      memset (&sin, 0, sizeof (sin));
      sin.sin_family = AF_INET;
      /* sin.sin_port = 0; */
      sin.sin_addr.s_addr = ap->ip4_address->as_u32;
      memcpy (&ifr.ifr_ifru.ifru_addr, &sin, sizeof (sin));

      if (ioctl (dev_tap_fd, SIOCSIFADDR, &ifr) < 0)
	{
	  rv = VNET_API_ERROR_SYSCALL_ERROR_10;
	  goto error;
	}

      if (ap->ip4_mask_width > 0 && ap->ip4_mask_width < 33)
	{
	  mask = ~0;
	  mask <<= (32 - ap->ip4_mask_width);
	}

      mask = clib_host_to_net_u32 (mask);
      sin.sin_family = AF_INET;
      sin.sin_port = 0;
      sin.sin_addr.s_addr = mask;
      memcpy (&ifr.ifr_ifru.ifru_addr, &sin, sizeof (sin));

      if (ioctl (dev_tap_fd, SIOCSIFNETMASK, &ifr) < 0)
	{
	  rv = VNET_API_ERROR_SYSCALL_ERROR_10;
	  goto error;
	}
    }

  if (ap->ip6_address_set)
    {
      struct ifreq ifr2;
      ip6_ifreq_t ifr6;
      int sockfd6;

      sockfd6 = socket (AF_INET6, SOCK_DGRAM, IPPROTO_IP);
      if (sockfd6 < 0)
	{
	  rv = VNET_API_ERROR_SYSCALL_ERROR_10;
	  goto error;
	}

      memset (&ifr2, 0, sizeof (ifr));
      strncpy (ifr2.ifr_name, (char *) ap->intfc_name,
	       sizeof (ifr2.ifr_name) - 1);
      if (ioctl (sockfd6, SIOCGIFINDEX, &ifr2) < 0)
	{
	  close (sockfd6);
	  rv = VNET_API_ERROR_SYSCALL_ERROR_4;
	  goto error;
	}

      memcpy (&ifr6.addr, ap->ip6_address, sizeof (ip6_address_t));
      ifr6.mask_width = ap->ip6_mask_width;
      ifr6.ifindex = ifr2.ifr_ifindex;

      if (ioctl (sockfd6, SIOCSIFADDR, &ifr6) < 0)
	{
	  close (sockfd6);
	  clib_unix_warning ("ifr6");
	  rv = VNET_API_ERROR_SYSCALL_ERROR_10;
	  goto error;
	}
      close (sockfd6);
    }

  ti = tapcli_get_new_tapif ();
  ti->per_interface_next_index = ~0;

  if (ap->hwaddr_arg != 0)
    clib_memcpy (hwaddr, ap->hwaddr_arg, 6);
  else
    {
      f64 now = vlib_time_now (vm);
      u32 rnd;
      rnd = (u32) (now * 1e6);
      rnd = random_u32 (&rnd);

      memcpy (hwaddr + 2, &rnd, sizeof (rnd));
      hwaddr[0] = 2;
      hwaddr[1] = 0xfe;
    }

  error = ethernet_register_interface
    (tm->vnet_main,
     tapcli_dev_class.index,
     ti - tm->tapcli_interfaces /* device instance */ ,
     hwaddr /* ethernet address */ ,
     &ti->hw_if_index, tapcli_flag_change);

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

  {
    clib_file_t template = { 0 };
    template.read_function = tapcli_read_ready;
    template.file_descriptor = dev_net_tun_fd;
    ti->clib_file_index = clib_file_add (&file_main, &template);
    ti->unix_fd = dev_net_tun_fd;
    ti->provision_fd = dev_tap_fd;
    clib_memcpy (&ti->ifr, &ifr, sizeof (ifr));
  }

  {
    vnet_hw_interface_t *hw;
    hw = vnet_get_hw_interface (tm->vnet_main, ti->hw_if_index);
    hw->min_supported_packet_bytes = TAP_MTU_MIN;
    hw->max_supported_packet_bytes = TAP_MTU_MAX;
    hw->max_l3_packet_bytes[VLIB_RX] = hw->max_l3_packet_bytes[VLIB_TX] =
      hw->max_supported_packet_bytes - sizeof (ethernet_header_t);
    ti->sw_if_index = hw->sw_if_index;
    if (ap->sw_if_indexp)
      *(ap->sw_if_indexp) = hw->sw_if_index;
  }

  ti->active = 1;

  hash_set (tm->tapcli_interface_index_by_sw_if_index, ti->sw_if_index,
	    ti - tm->tapcli_interfaces);

  hash_set (tm->tapcli_interface_index_by_unix_fd, ti->unix_fd,
	    ti - tm->tapcli_interfaces);

  return rv;

error:
  close (dev_net_tun_fd);
  if (dev_tap_fd >= 0)
    close (dev_tap_fd);

  return rv;
}

/**
 * @brief Renumber a TAP interface
 *
 * @param *vm - vlib_main_t
 * @param *intfc_name - u8
 * @param *hwaddr_arg - u8
 * @param *sw_if_indexp - u32
 * @param renumber - u8
 * @param custom_dev_instance - u32
 *
 * @return rc - int
 *
 */
int
vnet_tap_connect_renumber (vlib_main_t * vm, vnet_tap_connect_args_t * ap)
{
  int rv = vnet_tap_connect (vm, ap);

  if (!rv && ap->renumber)
    vnet_interface_name_renumber (*(ap->sw_if_indexp),
				  ap->custom_dev_instance);

  return rv;
}

/**
 * @brief Disconnect TAP CLI interface
 *
 * @param *ti - tapcli_interface_t
 *
 * @return rc - int
 *
 */
static int
tapcli_tap_disconnect (tapcli_interface_t * ti)
{
  int rv = 0;
  vnet_main_t *vnm = vnet_get_main ();
  tapcli_main_t *tm = &tapcli_main;
  u32 sw_if_index = ti->sw_if_index;

  // bring interface down
  vnet_sw_interface_set_flags (vnm, sw_if_index, 0);

  if (ti->clib_file_index != ~0)
    {
      clib_file_del (&file_main, file_main.file_pool + ti->clib_file_index);
      ti->clib_file_index = ~0;
    }
  else
    close (ti->unix_fd);

  hash_unset (tm->tapcli_interface_index_by_unix_fd, ti->unix_fd);
  hash_unset (tm->tapcli_interface_index_by_sw_if_index, ti->sw_if_index);
  close (ti->provision_fd);
  ti->unix_fd = -1;
  ti->provision_fd = -1;

  return rv;
}

/**
 * @brief Delete TAP interface
 *
 * @param *vm - vlib_main_t
 * @param sw_if_index - u32
 *
 * @return rc - int
 *
 */
int
vnet_tap_delete (vlib_main_t * vm, u32 sw_if_index)
{
  int rv = 0;
  tapcli_main_t *tm = &tapcli_main;
  tapcli_interface_t *ti;
  uword *p = NULL;

  p = hash_get (tm->tapcli_interface_index_by_sw_if_index, sw_if_index);
  if (p == 0)
    {
      clib_warning ("sw_if_index %d unknown", sw_if_index);
      return VNET_API_ERROR_INVALID_SW_IF_INDEX;
    }
  ti = vec_elt_at_index (tm->tapcli_interfaces, p[0]);

  // inactive
  ti->active = 0;
  tapcli_tap_disconnect (ti);
  // add to inactive list
  vec_add1 (tm->tapcli_inactive_interfaces, ti - tm->tapcli_interfaces);

  // reset renumbered iface
  if (p[0] < vec_len (tm->show_dev_instance_by_real_dev_instance))
    tm->show_dev_instance_by_real_dev_instance[p[0]] = ~0;

  ethernet_delete_interface (tm->vnet_main, ti->hw_if_index);
  return rv;
}

/**
 * @brief CLI function to delete TAP interface
 *
 * @param *vm - vlib_main_t
 * @param *input - unformat_input_t
 * @param *cmd - vlib_cli_command_t
 *
 * @return error - clib_error_t
 *
 */
static clib_error_t *
tap_delete_command_fn (vlib_main_t * vm,
		       unformat_input_t * input, vlib_cli_command_t * cmd)
{
  tapcli_main_t *tm = &tapcli_main;
  u32 sw_if_index = ~0;

  if (tm->is_disabled)
    {
      return clib_error_return (0, "device disabled...");
    }

  if (unformat (input, "%U", unformat_vnet_sw_interface, tm->vnet_main,
		&sw_if_index))
    ;
  else
    return clib_error_return (0, "unknown input `%U'",
			      format_unformat_error, input);


  int rc = vnet_tap_delete (vm, sw_if_index);

  if (!rc)
    {
      vlib_cli_output (vm, "Deleted.");
    }
  else
    {
      vlib_cli_output (vm, "Error during deletion of tap interface. (rc: %d)",
		       rc);
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tap_delete_command, static) = {
    .path = "tap delete",
    .short_help = "tap delete <vpp-tap-intfc-name>",
    .function = tap_delete_command_fn,
};
/* *INDENT-ON* */

/**
 * @brief Modifies tap interface - can result in new interface being created
 *
 * @param *vm - vlib_main_t
 * @param orig_sw_if_index - u32
 * @param *intfc_name - u8
 * @param *hwaddr_arg - u8
 * @param *sw_if_indexp - u32
 * @param renumber - u8
 * @param custom_dev_instance - u32
 *
 * @return rc - int
 *
 */
int
vnet_tap_modify (vlib_main_t * vm, vnet_tap_connect_args_t * ap)
{
  int rv = vnet_tap_delete (vm, ap->orig_sw_if_index);

  if (rv)
    return rv;

  rv = vnet_tap_connect_renumber (vm, ap);

  return rv;
}

/**
 * @brief CLI function to modify TAP interface
 *
 * @param *vm - vlib_main_t
 * @param *input - unformat_input_t
 * @param *cmd - vlib_cli_command_t
 *
 * @return error - clib_error_t
 *
 */
static clib_error_t *
tap_modify_command_fn (vlib_main_t * vm,
		       unformat_input_t * input, vlib_cli_command_t * cmd)
{
  u8 *intfc_name;
  tapcli_main_t *tm = &tapcli_main;
  u32 sw_if_index = ~0;
  u32 new_sw_if_index = ~0;
  int user_hwaddr = 0;
  u8 hwaddr[6];
  vnet_tap_connect_args_t _a, *ap = &_a;

  if (tm->is_disabled)
    {
      return clib_error_return (0, "device disabled...");
    }

  if (unformat (input, "%U", unformat_vnet_sw_interface, tm->vnet_main,
		&sw_if_index))
    ;
  else
    return clib_error_return (0, "unknown input `%U'",
			      format_unformat_error, input);

  if (unformat (input, "%s", &intfc_name))
    ;
  else
    return clib_error_return (0, "unknown input `%U'",
			      format_unformat_error, input);

  if (unformat (input, "hwaddr %U", unformat_ethernet_address, &hwaddr))
    user_hwaddr = 1;


  memset (ap, 0, sizeof (*ap));
  ap->orig_sw_if_index = sw_if_index;
  ap->intfc_name = intfc_name;
  ap->sw_if_indexp = &new_sw_if_index;
  if (user_hwaddr)
    ap->hwaddr_arg = hwaddr;

  int rc = vnet_tap_modify (vm, ap);

  if (!rc)
    {
      vlib_cli_output (vm, "Modified %U for Linux tap '%s'",
		       format_vnet_sw_if_index_name, tm->vnet_main,
		       *(ap->sw_if_indexp), ap->intfc_name);
    }
  else
    {
      vlib_cli_output (vm,
		       "Error during modification of tap interface. (rc: %d)",
		       rc);
    }

  return 0;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tap_modify_command, static) = {
    .path = "tap modify",
    .short_help = "tap modify <vpp-tap-intfc-name> <linux-intfc-name> [hwaddr <addr>]",
    .function = tap_modify_command_fn,
};
/* *INDENT-ON* */

/**
 * @brief CLI function to connect TAP interface
 *
 * @param *vm - vlib_main_t
 * @param *input - unformat_input_t
 * @param *cmd - vlib_cli_command_t
 *
 * @return error - clib_error_t
 *
 */
static clib_error_t *
tap_connect_command_fn (vlib_main_t * vm,
			unformat_input_t * input, vlib_cli_command_t * cmd)
{
  u8 *intfc_name = 0;
  unformat_input_t _line_input, *line_input = &_line_input;
  vnet_tap_connect_args_t _a, *ap = &_a;
  tapcli_main_t *tm = &tapcli_main;
  u8 hwaddr[6];
  u8 *hwaddr_arg = 0;
  u32 sw_if_index;
  ip4_address_t ip4_address;
  int ip4_address_set = 0;
  ip6_address_t ip6_address;
  int ip6_address_set = 0;
  u32 ip4_mask_width = 0;
  u32 ip6_mask_width = 0;
  clib_error_t *error = NULL;

  if (tm->is_disabled)
    return clib_error_return (0, "device disabled...");

  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (line_input, "hwaddr %U", unformat_ethernet_address,
		    &hwaddr))
	hwaddr_arg = hwaddr;

      /* It is here for backward compatibility */
      else if (unformat (line_input, "hwaddr random"))
	;

      else if (unformat (line_input, "address %U/%d",
			 unformat_ip4_address, &ip4_address, &ip4_mask_width))
	ip4_address_set = 1;

      else if (unformat (line_input, "address %U/%d",
			 unformat_ip6_address, &ip6_address, &ip6_mask_width))
	ip6_address_set = 1;

      else if (unformat (line_input, "%s", &intfc_name))
	;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  if (intfc_name == 0)
    {
      error = clib_error_return (0, "interface name must be specified");
      goto done;
    }

  memset (ap, 0, sizeof (*ap));

  ap->intfc_name = intfc_name;
  ap->hwaddr_arg = hwaddr_arg;
  if (ip4_address_set)
    {
      ap->ip4_address = &ip4_address;
      ap->ip4_mask_width = ip4_mask_width;
      ap->ip4_address_set = 1;
    }
  if (ip6_address_set)
    {
      ap->ip6_address = &ip6_address;
      ap->ip6_mask_width = ip6_mask_width;
      ap->ip6_address_set = 1;
    }

  ap->sw_if_indexp = &sw_if_index;

  int rv = vnet_tap_connect (vm, ap);

  switch (rv)
    {
    case VNET_API_ERROR_SYSCALL_ERROR_1:
      error = clib_error_return (0, "Couldn't open /dev/net/tun");
      goto done;

    case VNET_API_ERROR_SYSCALL_ERROR_2:
      error =
	clib_error_return (0, "Error setting flags on '%s'", intfc_name);
      goto done;

    case VNET_API_ERROR_SYSCALL_ERROR_3:
      error = clib_error_return (0, "Couldn't open provisioning socket");
      goto done;

    case VNET_API_ERROR_SYSCALL_ERROR_4:
      error = clib_error_return (0, "Couldn't get if_index");
      goto done;

    case VNET_API_ERROR_SYSCALL_ERROR_5:
      error = clib_error_return (0, "Couldn't bind provisioning socket");
      goto done;

    case VNET_API_ERROR_SYSCALL_ERROR_6:
      error = clib_error_return (0, "Couldn't set device non-blocking flag");
      goto done;

    case VNET_API_ERROR_SYSCALL_ERROR_7:
      error = clib_error_return (0, "Couldn't set device MTU");
      goto done;

    case VNET_API_ERROR_SYSCALL_ERROR_8:
      error = clib_error_return (0, "Couldn't get interface flags");
      goto done;

    case VNET_API_ERROR_SYSCALL_ERROR_9:
      error = clib_error_return (0, "Couldn't set intfc admin state up");
      goto done;

    case VNET_API_ERROR_SYSCALL_ERROR_10:
      error = clib_error_return (0, "Couldn't set intfc address/mask");
      goto done;

    case VNET_API_ERROR_INVALID_REGISTRATION:
      error = clib_error_return (0, "Invalid registration");
      goto done;

    case 0:
      break;

    default:
      error = clib_error_return (0, "Unknown error: %d", rv);
      goto done;
    }

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

done:
  unformat_free (line_input);

  return error;
}

/* *INDENT-OFF* */
VLIB_CLI_COMMAND (tap_connect_command, static) = {
    .path = "tap connect",
    .short_help =
        "tap connect <intfc-name> [address <ip-addr>/mw] [hwaddr <addr>]",
    .function = tap_connect_command_fn,
};
/* *INDENT-ON* */

/**
 * @brief TAPCLI main init
 *
 * @param *vm - vlib_main_t
 *
 * @return error - clib_error_t
 *
 */
clib_error_t *
tapcli_init (vlib_main_t * vm)
{
  tapcli_main_t *tm = &tapcli_main;
  vlib_thread_main_t *m = vlib_get_thread_main ();
  tapcli_per_thread_t *thread;

  tm->vlib_main = vm;
  tm->vnet_main = vnet_get_main ();
  tm->mtu_bytes = TAP_MTU_DEFAULT;
  tm->tapcli_interface_index_by_sw_if_index = hash_create (0, sizeof (uword));
  tm->tapcli_interface_index_by_unix_fd = hash_create (0, sizeof (uword));
  vm->os_punt_frame = tapcli_nopunt_frame;
  vec_validate_aligned (tm->threads, m->n_vlib_mains - 1,
			CLIB_CACHE_LINE_BYTES);
  vec_foreach (thread, tm->threads)
  {
    thread->iovecs = 0;
    thread->rx_buffers = 0;
    vec_alloc (thread->rx_buffers, VLIB_FRAME_SIZE);
    vec_reset_length (thread->rx_buffers);
  }

  return 0;
}

VLIB_INIT_FUNCTION (tapcli_init);

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