/*
 *------------------------------------------------------------------
 * vhost.c - vhost-user
 *
 * Copyright (c) 2014 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 <fcntl.h>		/* for open */
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/uio.h>		/* for iovec */
#include <netinet/in.h>
#include <sys/vfs.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/devices/devices.h>
#include <vnet/feature/feature.h>

#include <vnet/devices/virtio/vhost-user.h>

/**
 * @file
 * @brief vHost User Device Driver.
 *
 * This file contains the source code for vHost User interface.
 */


#define VHOST_USER_DEBUG_SOCKET 0
#define VHOST_DEBUG_VQ 0

#if VHOST_USER_DEBUG_SOCKET == 1
#define DBG_SOCK(args...) clib_warning(args);
#else
#define DBG_SOCK(args...)
#endif

#if VHOST_DEBUG_VQ == 1
#define DBG_VQ(args...) clib_warning(args);
#else
#define DBG_VQ(args...)
#endif

/*
 * When an RX queue is down but active, received packets
 * must be discarded. This value controls up to how many
 * packets will be discarded during each round.
 */
#define VHOST_USER_DOWN_DISCARD_COUNT 256

/*
 * When the number of available buffers gets under this threshold,
 * RX node will start discarding packets.
 */
#define VHOST_USER_RX_BUFFER_STARVATION 32

/*
 * On the receive side, the host should free descriptors as soon
 * as possible in order to avoid TX drop in the VM.
 * This value controls the number of copy operations that are stacked
 * before copy is done for all and descriptors are given back to
 * the guest.
 * The value 64 was obtained by testing (48 and 128 were not as good).
 */
#define VHOST_USER_RX_COPY_THRESHOLD 64

#define UNIX_GET_FD(unixfd_idx) \
    (unixfd_idx != ~0) ? \
	pool_elt_at_index (unix_main.file_pool, \
			   unixfd_idx)->file_descriptor : -1;

#define foreach_virtio_trace_flags \
  _ (SIMPLE_CHAINED, 0, "Simple descriptor chaining") \
  _ (SINGLE_DESC,  1, "Single descriptor packet") \
  _ (INDIRECT, 2, "Indirect descriptor") \
  _ (MAP_ERROR, 4, "Memory mapping error")

typedef enum
{
#define _(n,i,s) VIRTIO_TRACE_F_##n,
  foreach_virtio_trace_flags
#undef _
} virtio_trace_flag_t;

vlib_node_registration_t vhost_user_input_node;

#define foreach_vhost_user_tx_func_error      \
  _(NONE, "no error")  \
  _(NOT_READY, "vhost vring not ready")  \
  _(DOWN, "vhost interface is down")  \
  _(PKT_DROP_NOBUF, "tx packet drops (no available descriptors)")  \
  _(PKT_DROP_NOMRG, "tx packet drops (cannot merge descriptors)")  \
  _(MMAP_FAIL, "mmap failure") \
  _(INDIRECT_OVERFLOW, "indirect descriptor table overflow")

typedef enum
{
#define _(f,s) VHOST_USER_TX_FUNC_ERROR_##f,
  foreach_vhost_user_tx_func_error
#undef _
    VHOST_USER_TX_FUNC_N_ERROR,
} vhost_user_tx_func_error_t;

static char *vhost_user_tx_func_error_strings[] = {
#define _(n,s) s,
  foreach_vhost_user_tx_func_error
#undef _
};

#define foreach_vhost_user_input_func_error      \
  _(NO_ERROR, "no error")  \
  _(NO_BUFFER, "no available buffer")  \
  _(MMAP_FAIL, "mmap failure")  \
  _(INDIRECT_OVERFLOW, "indirect descriptor overflows table")  \
  _(UNDERSIZED_FRAME, "undersized ethernet frame received (< 14 bytes)") \
  _(FULL_RX_QUEUE, "full rx queue (possible driver tx drop)")

typedef enum
{
#define _(f,s) VHOST_USER_INPUT_FUNC_ERROR_##f,
  foreach_vhost_user_input_func_error
#undef _
    VHOST_USER_INPUT_FUNC_N_ERROR,
} vhost_user_input_func_error_t;

static char *vhost_user_input_func_error_strings[] = {
#define _(n,s) s,
  foreach_vhost_user_input_func_error
#undef _
};

/* *INDENT-OFF* */
static vhost_user_main_t vhost_user_main = {
  .mtu_bytes = 1518,
};

VNET_HW_INTERFACE_CLASS (vhost_interface_class, static) = {
  .name = "vhost-user",
};
/* *INDENT-ON* */

static u8 *
format_vhost_user_interface_name (u8 * s, va_list * args)
{
  u32 i = va_arg (*args, u32);
  u32 show_dev_instance = ~0;
  vhost_user_main_t *vum = &vhost_user_main;

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

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

  s = format (s, "VirtualEthernet0/0/%d", i);
  return s;
}

static int
vhost_user_name_renumber (vnet_hw_interface_t * hi, u32 new_dev_instance)
{
  // FIXME: check if the new dev instance is already used
  vhost_user_main_t *vum = &vhost_user_main;
  vec_validate_init_empty (vum->show_dev_instance_by_real_dev_instance,
			   hi->dev_instance, ~0);

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

  DBG_SOCK ("renumbered vhost-user interface dev_instance %d to %d",
	    hi->dev_instance, new_dev_instance);

  return 0;
}

static_always_inline void *
map_guest_mem (vhost_user_intf_t * vui, uword addr, u32 * hint)
{
  int i = *hint;
  if (PREDICT_TRUE ((vui->regions[i].guest_phys_addr <= addr) &&
		    ((vui->regions[i].guest_phys_addr +
		      vui->regions[i].memory_size) > addr)))
    {
      return (void *) (vui->region_mmap_addr[i] + addr -
		       vui->regions[i].guest_phys_addr);
    }
#if __SSE4_2__
  __m128i rl, rh, al, ah, r;
  al = _mm_set1_epi64x (addr + 1);
  ah = _mm_set1_epi64x (addr);

  rl = _mm_loadu_si128 ((__m128i *) & vui->region_guest_addr_lo[0]);
  rl = _mm_cmpgt_epi64 (al, rl);
  rh = _mm_loadu_si128 ((__m128i *) & vui->region_guest_addr_hi[0]);
  rh = _mm_cmpgt_epi64 (rh, ah);
  r = _mm_and_si128 (rl, rh);

  rl = _mm_loadu_si128 ((__m128i *) & vui->region_guest_addr_lo[2]);
  rl = _mm_cmpgt_epi64 (al, rl);
  rh = _mm_loadu_si128 ((__m128i *) & vui->region_guest_addr_hi[2]);
  rh = _mm_cmpgt_epi64 (rh, ah);
  r = _mm_blend_epi16 (r, _mm_and_si128 (rl, rh), 0x22);

  rl = _mm_loadu_si128 ((__m128i *) & vui->region_guest_addr_lo[4]);
  rl = _mm_cmpgt_epi64 (al, rl);
  rh = _mm_loadu_si128 ((__m128i *) & vui->region_guest_addr_hi[4]);
  rh = _mm_cmpgt_epi64 (rh, ah);
  r = _mm_blend_epi16 (r, _mm_and_si128 (rl, rh), 0x44);

  rl = _mm_loadu_si128 ((__m128i *) & vui->region_guest_addr_lo[6]);
  rl = _mm_cmpgt_epi64 (al, rl);
  rh = _mm_loadu_si128 ((__m128i *) & vui->region_guest_addr_hi[6]);
  rh = _mm_cmpgt_epi64 (rh, ah);
  r = _mm_blend_epi16 (r, _mm_and_si128 (rl, rh), 0x88);

  r = _mm_shuffle_epi8 (r, _mm_set_epi64x (0, 0x0e060c040a020800));
  i = __builtin_ctzll (_mm_movemask_epi8 (r) |
		       (1 << VHOST_MEMORY_MAX_NREGIONS));

  if (i < vui->nregions)
    {
      *hint = i;
      return (void *) (vui->region_mmap_addr[i] + addr -
		       vui->regions[i].guest_phys_addr);
    }

#else
  for (i = 0; i < vui->nregions; i++)
    {
      if ((vui->regions[i].guest_phys_addr <= addr) &&
	  ((vui->regions[i].guest_phys_addr + vui->regions[i].memory_size) >
	   addr))
	{
	  *hint = i;
	  return (void *) (vui->region_mmap_addr[i] + addr -
			   vui->regions[i].guest_phys_addr);
	}
    }
#endif
  DBG_VQ ("failed to map guest mem addr %llx", addr);
  *hint = 0;
  return 0;
}

static inline void *
map_user_mem (vhost_user_intf_t * vui, uword addr)
{
  int i;
  for (i = 0; i < vui->nregions; i++)
    {
      if ((vui->regions[i].userspace_addr <= addr) &&
	  ((vui->regions[i].userspace_addr + vui->regions[i].memory_size) >
	   addr))
	{
	  return (void *) (vui->region_mmap_addr[i] + addr -
			   vui->regions[i].userspace_addr);
	}
    }
  return 0;
}

static long
get_huge_page_size (int fd)
{
  struct statfs s;
  fstatfs (fd, &s);
  return s.f_bsize;
}

static void
unmap_all_mem_regions (vhost_user_intf_t * vui)
{
  int i, r;
  for (i = 0; i < vui->nregions; i++)
    {
      if (vui->region_mmap_addr[i] != (void *) -1)
	{

	  long page_sz = get_huge_page_size (vui->region_mmap_fd[i]);

	  ssize_t map_sz = (vui->regions[i].memory_size +
			    vui->regions[i].mmap_offset +
			    page_sz - 1) & ~(page_sz - 1);

	  r =
	    munmap (vui->region_mmap_addr[i] - vui->regions[i].mmap_offset,
		    map_sz);

	  DBG_SOCK
	    ("unmap memory region %d addr 0x%lx len 0x%lx page_sz 0x%x", i,
	     vui->region_mmap_addr[i], map_sz, page_sz);

	  vui->region_mmap_addr[i] = (void *) -1;

	  if (r == -1)
	    {
	      clib_warning ("failed to unmap memory region (errno %d)",
			    errno);
	    }
	  close (vui->region_mmap_fd[i]);
	}
    }
  vui->nregions = 0;
}

static void
vhost_user_tx_thread_placement (vhost_user_intf_t * vui)
{
  //Let's try to assign one queue to each thread
  u32 qid = 0;
  u32 thread_index = 0;
  vui->use_tx_spinlock = 0;
  while (1)
    {
      for (qid = 0; qid < VHOST_VRING_MAX_N / 2; qid++)
	{
	  vhost_user_vring_t *rxvq = &vui->vrings[VHOST_VRING_IDX_RX (qid)];
	  if (!rxvq->started || !rxvq->enabled)
	    continue;

	  vui->per_cpu_tx_qid[thread_index] = qid;
	  thread_index++;
	  if (thread_index == vlib_get_thread_main ()->n_vlib_mains)
	    return;
	}
      //We need to loop, meaning the spinlock has to be used
      vui->use_tx_spinlock = 1;
      if (thread_index == 0)
	{
	  //Could not find a single valid one
	  for (thread_index = 0;
	       thread_index < vlib_get_thread_main ()->n_vlib_mains;
	       thread_index++)
	    {
	      vui->per_cpu_tx_qid[thread_index] = 0;
	    }
	  return;
	}
    }
}

static void
vhost_user_rx_thread_placement ()
{
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;
  vhost_cpu_t *vhc;
  u32 *workers = 0;
  u32 thread_index;
  vlib_main_t *vm;

  //Let's list all workers cpu indexes
  u32 i;
  for (i = vum->input_cpu_first_index;
       i < vum->input_cpu_first_index + vum->input_cpu_count; i++)
    {
      vlib_node_set_state (vlib_mains[i], vhost_user_input_node.index,
			   VLIB_NODE_STATE_DISABLED);
      vec_add1 (workers, i);
    }

  vec_foreach (vhc, vum->cpus)
  {
    vec_reset_length (vhc->rx_queues);
  }

  i = 0;
  vhost_iface_and_queue_t iaq;
  /* *INDENT-OFF* */
  pool_foreach (vui, vum->vhost_user_interfaces, {
      u32 *vui_workers = vec_len (vui->workers) ? vui->workers : workers;
      u32 qid;
      for (qid = 0; qid < VHOST_VRING_MAX_N / 2; qid++)
	{
	  vhost_user_vring_t *txvq =
	      &vui->vrings[VHOST_VRING_IDX_TX (qid)];
	  if (!txvq->started)
	    continue;

	  i %= vec_len (vui_workers);
	  thread_index = vui_workers[i];
	  i++;
	  vhc = &vum->cpus[thread_index];
	  txvq->interrupt_thread_index = thread_index;

	  iaq.qid = qid;
	  iaq.vhost_iface_index = vui - vum->vhost_user_interfaces;
	  vec_add1 (vhc->rx_queues, iaq);
	}
  });
  /* *INDENT-ON* */

  vec_foreach (vhc, vum->cpus)
  {
    vhost_iface_and_queue_t *vhiq;
    u8 mode = VHOST_USER_INTERRUPT_MODE;

    vec_foreach (vhiq, vhc->rx_queues)
    {
      vui = &vum->vhost_user_interfaces[vhiq->vhost_iface_index];
      if (vui->operation_mode == VHOST_USER_POLLING_MODE)
	{
	  /* At least one interface is polling, cpu is set to polling */
	  mode = VHOST_USER_POLLING_MODE;
	  break;
	}
    }
    vhc->operation_mode = mode;
  }

  for (thread_index = vum->input_cpu_first_index;
       thread_index < vum->input_cpu_first_index + vum->input_cpu_count;
       thread_index++)
    {
      vlib_node_state_t state = VLIB_NODE_STATE_POLLING;

      vhc = &vum->cpus[thread_index];
      vm = vlib_mains ? vlib_mains[thread_index] : &vlib_global_main;
      switch (vhc->operation_mode)
	{
	case VHOST_USER_INTERRUPT_MODE:
	  state = VLIB_NODE_STATE_INTERRUPT;
	  break;
	case VHOST_USER_POLLING_MODE:
	  state = VLIB_NODE_STATE_POLLING;
	  break;
	default:
	  clib_warning ("BUG: bad operation mode %d", vhc->operation_mode);
	  break;
	}
      vlib_node_set_state (vm, vhost_user_input_node.index, state);
    }

  vec_free (workers);
}

static int
vhost_user_thread_placement (u32 sw_if_index, u32 worker_thread_index, u8 del)
{
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;
  vnet_hw_interface_t *hw;

  if (worker_thread_index < vum->input_cpu_first_index ||
      worker_thread_index >=
      vum->input_cpu_first_index + vum->input_cpu_count)
    return -1;

  if (!(hw = vnet_get_sup_hw_interface (vnet_get_main (), sw_if_index)))
    return -2;

  vui = pool_elt_at_index (vum->vhost_user_interfaces, hw->dev_instance);
  u32 found = ~0, *w;
  vec_foreach (w, vui->workers)
  {
    if (*w == worker_thread_index)
      {
	found = w - vui->workers;
	break;
      }
  }

  if (del)
    {
      if (found == ~0)
	return -3;
      vec_del1 (vui->workers, found);
    }
  else if (found == ~0)
    {
      vec_add1 (vui->workers, worker_thread_index);
    }

  vhost_user_rx_thread_placement ();
  return 0;
}

/** @brief Returns whether at least one TX and one RX vring are enabled */
int
vhost_user_intf_ready (vhost_user_intf_t * vui)
{
  int i, found[2] = { };	//RX + TX

  for (i = 0; i < VHOST_VRING_MAX_N; i++)
    if (vui->vrings[i].started && vui->vrings[i].enabled)
      found[i & 1] = 1;

  return found[0] && found[1];
}

static void
vhost_user_update_iface_state (vhost_user_intf_t * vui)
{
  /* if we have pointers to descriptor table, go up */
  int is_up = vhost_user_intf_ready (vui);
  if (is_up != vui->is_up)
    {
      DBG_SOCK ("interface %d %s", vui->sw_if_index,
		is_up ? "ready" : "down");
      vnet_hw_interface_set_flags (vnet_get_main (), vui->hw_if_index,
				   is_up ? VNET_HW_INTERFACE_FLAG_LINK_UP :
				   0);
      vui->is_up = is_up;
    }
  vhost_user_rx_thread_placement ();
  vhost_user_tx_thread_placement (vui);
}

static void
vhost_user_set_interrupt_pending (vhost_user_intf_t * vui, u32 ifq)
{
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_cpu_t *vhc;
  u32 thread_index;
  vlib_main_t *vm;
  u32 ifq2, qid;
  vhost_user_vring_t *txvq;

  qid = ifq & 0xff;
  if ((qid % 2) == 0)
    /* Only care about the odd number virtqueue which is TX */
    return;

  if (vhost_user_intf_ready (vui))
    {
      txvq = &vui->vrings[qid];
      thread_index = txvq->interrupt_thread_index;
      vhc = &vum->cpus[thread_index];
      if (vhc->operation_mode == VHOST_USER_INTERRUPT_MODE)
	{
	  vm = vlib_mains ? vlib_mains[thread_index] : &vlib_global_main;
	  /*
	   * Convert virtqueue number in the lower byte to vring
	   * queue index for the input node process. Top bytes contain
	   * the interface, lower byte contains the queue index.
	   */
	  ifq2 = ((ifq >> 8) << 8) | qid / 2;
	  vhc->pending_input_bitmap =
	    clib_bitmap_set (vhc->pending_input_bitmap, ifq2, 1);
	  vlib_node_set_interrupt_pending (vm, vhost_user_input_node.index);
	}
    }
}

static clib_error_t *
vhost_user_callfd_read_ready (unix_file_t * uf)
{
  __attribute__ ((unused)) int n;
  u8 buff[8];
  vhost_user_intf_t *vui =
    pool_elt_at_index (vhost_user_main.vhost_user_interfaces,
		       uf->private_data >> 8);

  n = read (uf->file_descriptor, ((char *) &buff), 8);
  DBG_SOCK ("if %d CALL queue %d", uf->private_data >> 8,
	    uf->private_data & 0xff);
  vhost_user_set_interrupt_pending (vui, uf->private_data);

  return 0;
}

static clib_error_t *
vhost_user_kickfd_read_ready (unix_file_t * uf)
{
  __attribute__ ((unused)) int n;
  u8 buff[8];
  vhost_user_intf_t *vui =
    pool_elt_at_index (vhost_user_main.vhost_user_interfaces,
		       uf->private_data >> 8);
  u32 qid = uf->private_data & 0xff;

  n = read (uf->file_descriptor, ((char *) &buff), 8);
  DBG_SOCK ("if %d KICK queue %d", uf->private_data >> 8, qid);
  if (!vui->vrings[qid].started ||
      (vhost_user_intf_ready (vui) != vui->is_up))
    {
      vlib_worker_thread_barrier_sync (vlib_get_main ());
      vui->vrings[qid].started = 1;
      vhost_user_update_iface_state (vui);
      vlib_worker_thread_barrier_release (vlib_get_main ());
    }

  vhost_user_set_interrupt_pending (vui, uf->private_data);
  return 0;
}

/**
 * @brief Try once to lock the vring
 * @return 0 on success, non-zero on failure.
 */
static inline int
vhost_user_vring_try_lock (vhost_user_intf_t * vui, u32 qid)
{
  return __sync_lock_test_and_set (vui->vring_locks[qid], 1);
}

/**
 * @brief Spin until the vring is successfully locked
 */
static inline void
vhost_user_vring_lock (vhost_user_intf_t * vui, u32 qid)
{
  while (vhost_user_vring_try_lock (vui, qid))
    ;
}

/**
 * @brief Unlock the vring lock
 */
static inline void
vhost_user_vring_unlock (vhost_user_intf_t * vui, u32 qid)
{
  *vui->vring_locks[qid] = 0;
}

static inline void
vhost_user_vring_init (vhost_user_intf_t * vui, u32 qid)
{
  vhost_user_vring_t *vring = &vui->vrings[qid];
  memset (vring, 0, sizeof (*vring));
  vring->kickfd_idx = ~0;
  vring->callfd_idx = ~0;
  vring->errfd = -1;

  /*
   * We have a bug with some qemu 2.5, and this may be a fix.
   * Feel like interpretation holy text, but this is from vhost-user.txt.
   * "
   * One queue pair is enabled initially. More queues are enabled
   * dynamically, by sending message VHOST_USER_SET_VRING_ENABLE.
   * "
   * Don't know who's right, but this is what DPDK does.
   */
  if (qid == 0 || qid == 1)
    vring->enabled = 1;
}

static inline void
vhost_user_vring_close (vhost_user_intf_t * vui, u32 qid)
{
  vhost_user_vring_t *vring = &vui->vrings[qid];
  if (vring->kickfd_idx != ~0)
    {
      unix_file_t *uf = pool_elt_at_index (unix_main.file_pool,
					   vring->kickfd_idx);
      unix_file_del (&unix_main, uf);
      vring->kickfd_idx = ~0;
    }
  if (vring->callfd_idx != ~0)
    {
      unix_file_t *uf = pool_elt_at_index (unix_main.file_pool,
					   vring->callfd_idx);
      unix_file_del (&unix_main, uf);
      vring->callfd_idx = ~0;
    }
  if (vring->errfd != -1)
    {
      close (vring->errfd);
      vring->errfd = -1;
    }
  vhost_user_vring_init (vui, qid);
}

static inline void
vhost_user_if_disconnect (vhost_user_intf_t * vui)
{
  vnet_main_t *vnm = vnet_get_main ();
  int q;

  vnet_hw_interface_set_flags (vnm, vui->hw_if_index, 0);

  if (vui->unix_file_index != ~0)
    {
      unix_file_del (&unix_main, unix_main.file_pool + vui->unix_file_index);
      vui->unix_file_index = ~0;
    }

  vui->is_up = 0;

  for (q = 0; q < VHOST_VRING_MAX_N; q++)
    vhost_user_vring_close (vui, q);

  unmap_all_mem_regions (vui);
  DBG_SOCK ("interface ifindex %d disconnected", vui->sw_if_index);
}

#define VHOST_LOG_PAGE 0x1000
static_always_inline void
vhost_user_log_dirty_pages_2 (vhost_user_intf_t * vui,
			      u64 addr, u64 len, u8 is_host_address)
{
  if (PREDICT_TRUE (vui->log_base_addr == 0
		    || !(vui->features & (1 << FEAT_VHOST_F_LOG_ALL))))
    {
      return;
    }
  if (is_host_address)
    {
      addr = pointer_to_uword (map_user_mem (vui, (uword) addr));
    }
  if (PREDICT_FALSE ((addr + len - 1) / VHOST_LOG_PAGE / 8 >= vui->log_size))
    {
      DBG_SOCK ("vhost_user_log_dirty_pages(): out of range\n");
      return;
    }

  CLIB_MEMORY_BARRIER ();
  u64 page = addr / VHOST_LOG_PAGE;
  while (page * VHOST_LOG_PAGE < addr + len)
    {
      ((u8 *) vui->log_base_addr)[page / 8] |= 1 << page % 8;
      page++;
    }
}

static_always_inline void
vhost_user_log_dirty_pages (vhost_user_intf_t * vui, u64 addr, u64 len)
{
  vhost_user_log_dirty_pages_2 (vui, addr, len, 0);
}

#define vhost_user_log_dirty_ring(vui, vq, member) \
  if (PREDICT_FALSE(vq->log_used)) { \
    vhost_user_log_dirty_pages(vui, vq->log_guest_addr + STRUCT_OFFSET_OF(vring_used_t, member), \
                             sizeof(vq->used->member)); \
  }

static clib_error_t *
vhost_user_socket_read (unix_file_t * uf)
{
  int n, i;
  int fd, number_of_fds = 0;
  int fds[VHOST_MEMORY_MAX_NREGIONS];
  vhost_user_msg_t msg;
  struct msghdr mh;
  struct iovec iov[1];
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;
  struct cmsghdr *cmsg;
  u8 q;
  unix_file_t template = { 0 };
  vnet_main_t *vnm = vnet_get_main ();

  vui = pool_elt_at_index (vum->vhost_user_interfaces, uf->private_data);

  char control[CMSG_SPACE (VHOST_MEMORY_MAX_NREGIONS * sizeof (int))];

  memset (&mh, 0, sizeof (mh));
  memset (control, 0, sizeof (control));

  for (i = 0; i < VHOST_MEMORY_MAX_NREGIONS; i++)
    fds[i] = -1;

  /* set the payload */
  iov[0].iov_base = (void *) &msg;
  iov[0].iov_len = VHOST_USER_MSG_HDR_SZ;

  mh.msg_iov = iov;
  mh.msg_iovlen = 1;
  mh.msg_control = control;
  mh.msg_controllen = sizeof (control);

  n = recvmsg (uf->file_descriptor, &mh, 0);

  /* Stop workers to avoid end of the world */
  vlib_worker_thread_barrier_sync (vlib_get_main ());

  if (n != VHOST_USER_MSG_HDR_SZ)
    {
      if (n == -1)
	{
	  DBG_SOCK ("recvmsg returned error %d %s", errno, strerror (errno));
	}
      else
	{
	  DBG_SOCK ("n (%d) != VHOST_USER_MSG_HDR_SZ (%d)",
		    n, VHOST_USER_MSG_HDR_SZ);
	}
      goto close_socket;
    }

  if (mh.msg_flags & MSG_CTRUNC)
    {
      DBG_SOCK ("MSG_CTRUNC is set");
      goto close_socket;
    }

  cmsg = CMSG_FIRSTHDR (&mh);

  if (cmsg && (cmsg->cmsg_len > 0) && (cmsg->cmsg_level == SOL_SOCKET) &&
      (cmsg->cmsg_type == SCM_RIGHTS) &&
      (cmsg->cmsg_len - CMSG_LEN (0) <=
       VHOST_MEMORY_MAX_NREGIONS * sizeof (int)))
    {
      number_of_fds = (cmsg->cmsg_len - CMSG_LEN (0)) / sizeof (int);
      clib_memcpy (fds, CMSG_DATA (cmsg), number_of_fds * sizeof (int));
    }

  /* version 1, no reply bit set */
  if ((msg.flags & 7) != 1)
    {
      DBG_SOCK ("malformed message received. closing socket");
      goto close_socket;
    }

  {
    int rv;
    rv =
      read (uf->file_descriptor, ((char *) &msg) + VHOST_USER_MSG_HDR_SZ,
	    msg.size);
    if (rv < 0)
      {
	DBG_SOCK ("read failed %s", strerror (errno));
	goto close_socket;
      }
    else if (rv != msg.size)
      {
	DBG_SOCK ("message too short (read %dB should be %dB)", rv, msg.size);
	goto close_socket;
      }
  }

  switch (msg.request)
    {
    case VHOST_USER_GET_FEATURES:
      msg.flags |= 4;
      msg.u64 = (1ULL << FEAT_VIRTIO_NET_F_MRG_RXBUF) |
	(1ULL << FEAT_VIRTIO_NET_F_CTRL_VQ) |
	(1ULL << FEAT_VIRTIO_F_ANY_LAYOUT) |
	(1ULL << FEAT_VIRTIO_F_INDIRECT_DESC) |
	(1ULL << FEAT_VHOST_F_LOG_ALL) |
	(1ULL << FEAT_VIRTIO_NET_F_GUEST_ANNOUNCE) |
	(1ULL << FEAT_VIRTIO_NET_F_MQ) |
	(1ULL << FEAT_VHOST_USER_F_PROTOCOL_FEATURES) |
	(1ULL << FEAT_VIRTIO_F_VERSION_1);
      msg.u64 &= vui->feature_mask;
      msg.size = sizeof (msg.u64);
      DBG_SOCK ("if %d msg VHOST_USER_GET_FEATURES - reply 0x%016llx",
		vui->hw_if_index, msg.u64);
      break;

    case VHOST_USER_SET_FEATURES:
      DBG_SOCK ("if %d msg VHOST_USER_SET_FEATURES features 0x%016llx",
		vui->hw_if_index, msg.u64);

      vui->features = msg.u64;

      if (vui->features &
	  ((1 << FEAT_VIRTIO_NET_F_MRG_RXBUF) |
	   (1ULL << FEAT_VIRTIO_F_VERSION_1)))
	vui->virtio_net_hdr_sz = 12;
      else
	vui->virtio_net_hdr_sz = 10;

      vui->is_any_layout =
	(vui->features & (1 << FEAT_VIRTIO_F_ANY_LAYOUT)) ? 1 : 0;

      ASSERT (vui->virtio_net_hdr_sz < VLIB_BUFFER_PRE_DATA_SIZE);
      vnet_hw_interface_set_flags (vnm, vui->hw_if_index, 0);
      vui->is_up = 0;

      /*for (q = 0; q < VHOST_VRING_MAX_N; q++)
         vhost_user_vring_close(&vui->vrings[q]); */

      break;

    case VHOST_USER_SET_MEM_TABLE:
      DBG_SOCK ("if %d msg VHOST_USER_SET_MEM_TABLE nregions %d",
		vui->hw_if_index, msg.memory.nregions);

      if ((msg.memory.nregions < 1) ||
	  (msg.memory.nregions > VHOST_MEMORY_MAX_NREGIONS))
	{

	  DBG_SOCK ("number of mem regions must be between 1 and %i",
		    VHOST_MEMORY_MAX_NREGIONS);

	  goto close_socket;
	}

      if (msg.memory.nregions != number_of_fds)
	{
	  DBG_SOCK ("each memory region must have FD");
	  goto close_socket;
	}
      unmap_all_mem_regions (vui);
      for (i = 0; i < msg.memory.nregions; i++)
	{
	  clib_memcpy (&(vui->regions[i]), &msg.memory.regions[i],
		       sizeof (vhost_user_memory_region_t));

	  long page_sz = get_huge_page_size (fds[i]);

	  /* align size to 2M page */
	  ssize_t map_sz = (vui->regions[i].memory_size +
			    vui->regions[i].mmap_offset +
			    page_sz - 1) & ~(page_sz - 1);

	  vui->region_mmap_addr[i] = mmap (0, map_sz, PROT_READ | PROT_WRITE,
					   MAP_SHARED, fds[i], 0);
	  vui->region_guest_addr_lo[i] = vui->regions[i].guest_phys_addr;
	  vui->region_guest_addr_hi[i] = vui->regions[i].guest_phys_addr +
	    vui->regions[i].memory_size;

	  DBG_SOCK
	    ("map memory region %d addr 0 len 0x%lx fd %d mapped 0x%lx "
	     "page_sz 0x%x", i, map_sz, fds[i], vui->region_mmap_addr[i],
	     page_sz);

	  if (vui->region_mmap_addr[i] == MAP_FAILED)
	    {
	      clib_warning ("failed to map memory. errno is %d", errno);
	      goto close_socket;
	    }
	  vui->region_mmap_addr[i] += vui->regions[i].mmap_offset;
	  vui->region_mmap_fd[i] = fds[i];
	}
      vui->nregions = msg.memory.nregions;
      break;

    case VHOST_USER_SET_VRING_NUM:
      DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_NUM idx %d num %d",
		vui->hw_if_index, msg.state.index, msg.state.num);

      if ((msg.state.num > 32768) ||	/* maximum ring size is 32768 */
	  (msg.state.num == 0) ||	/* it cannot be zero */
	  ((msg.state.num - 1) & msg.state.num))	/* must be power of 2 */
	goto close_socket;
      vui->vrings[msg.state.index].qsz = msg.state.num;
      break;

    case VHOST_USER_SET_VRING_ADDR:
      DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_ADDR idx %d",
		vui->hw_if_index, msg.state.index);

      if (msg.state.index >= VHOST_VRING_MAX_N)
	{
	  DBG_SOCK ("invalid vring index VHOST_USER_SET_VRING_ADDR:"
		    " %d >= %d", msg.state.index, VHOST_VRING_MAX_N);
	  goto close_socket;
	}

      if (msg.size < sizeof (msg.addr))
	{
	  DBG_SOCK ("vhost message is too short (%d < %d)",
		    msg.size, sizeof (msg.addr));
	  goto close_socket;
	}

      vui->vrings[msg.state.index].desc = (vring_desc_t *)
	map_user_mem (vui, msg.addr.desc_user_addr);
      vui->vrings[msg.state.index].used = (vring_used_t *)
	map_user_mem (vui, msg.addr.used_user_addr);
      vui->vrings[msg.state.index].avail = (vring_avail_t *)
	map_user_mem (vui, msg.addr.avail_user_addr);

      if ((vui->vrings[msg.state.index].desc == NULL) ||
	  (vui->vrings[msg.state.index].used == NULL) ||
	  (vui->vrings[msg.state.index].avail == NULL))
	{
	  DBG_SOCK ("failed to map user memory for hw_if_index %d",
		    vui->hw_if_index);
	  goto close_socket;
	}

      vui->vrings[msg.state.index].log_guest_addr = msg.addr.log_guest_addr;
      vui->vrings[msg.state.index].log_used =
	(msg.addr.flags & (1 << VHOST_VRING_F_LOG)) ? 1 : 0;

      /* Spec says: If VHOST_USER_F_PROTOCOL_FEATURES has not been negotiated,
         the ring is initialized in an enabled state. */
      if (!(vui->features & (1 << FEAT_VHOST_USER_F_PROTOCOL_FEATURES)))
	{
	  vui->vrings[msg.state.index].enabled = 1;
	}

      vui->vrings[msg.state.index].last_used_idx =
	vui->vrings[msg.state.index].last_avail_idx =
	vui->vrings[msg.state.index].used->idx;

      if (vui->operation_mode == VHOST_USER_POLLING_MODE)
	/* tell driver that we don't want interrupts */
	vui->vrings[msg.state.index].used->flags = VRING_USED_F_NO_NOTIFY;
      else
	/* tell driver that we want interrupts */
	vui->vrings[msg.state.index].used->flags = 0;
      break;

    case VHOST_USER_SET_OWNER:
      DBG_SOCK ("if %d msg VHOST_USER_SET_OWNER", vui->hw_if_index);
      break;

    case VHOST_USER_RESET_OWNER:
      DBG_SOCK ("if %d msg VHOST_USER_RESET_OWNER", vui->hw_if_index);
      break;

    case VHOST_USER_SET_VRING_CALL:
      DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_CALL u64 %d",
		vui->hw_if_index, msg.u64);

      q = (u8) (msg.u64 & 0xFF);

      /* if there is old fd, delete and close it */
      if (vui->vrings[q].callfd_idx != ~0)
	{
	  unix_file_t *uf = pool_elt_at_index (unix_main.file_pool,
					       vui->vrings[q].callfd_idx);
	  unix_file_del (&unix_main, uf);
	  vui->vrings[q].callfd_idx = ~0;
	}

      if (!(msg.u64 & 0x100))
	{
	  if (number_of_fds != 1)
	    {
	      DBG_SOCK ("More than one fd received !");
	      goto close_socket;
	    }

	  template.read_function = vhost_user_callfd_read_ready;
	  template.file_descriptor = fds[0];
	  template.private_data =
	    ((vui - vhost_user_main.vhost_user_interfaces) << 8) + q;
	  vui->vrings[q].callfd_idx = unix_file_add (&unix_main, &template);
	}
      else
	vui->vrings[q].callfd_idx = ~0;
      break;

    case VHOST_USER_SET_VRING_KICK:
      DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_KICK u64 %d",
		vui->hw_if_index, msg.u64);

      q = (u8) (msg.u64 & 0xFF);

      if (vui->vrings[q].kickfd_idx != ~0)
	{
	  unix_file_t *uf = pool_elt_at_index (unix_main.file_pool,
					       vui->vrings[q].kickfd_idx);
	  unix_file_del (&unix_main, uf);
	  vui->vrings[q].kickfd_idx = ~0;
	}

      if (!(msg.u64 & 0x100))
	{
	  if (number_of_fds != 1)
	    {
	      DBG_SOCK ("More than one fd received !");
	      goto close_socket;
	    }

	  template.read_function = vhost_user_kickfd_read_ready;
	  template.file_descriptor = fds[0];
	  template.private_data =
	    (((uword) (vui - vhost_user_main.vhost_user_interfaces)) << 8) +
	    q;
	  vui->vrings[q].kickfd_idx = unix_file_add (&unix_main, &template);
	}
      else
	{
	  //When no kickfd is set, the queue is initialized as started
	  vui->vrings[q].kickfd_idx = ~0;
	  vui->vrings[q].started = 1;
	}

      break;

    case VHOST_USER_SET_VRING_ERR:
      DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_ERR u64 %d",
		vui->hw_if_index, msg.u64);

      q = (u8) (msg.u64 & 0xFF);

      if (vui->vrings[q].errfd != -1)
	close (vui->vrings[q].errfd);

      if (!(msg.u64 & 0x100))
	{
	  if (number_of_fds != 1)
	    goto close_socket;

	  vui->vrings[q].errfd = fds[0];
	}
      else
	vui->vrings[q].errfd = -1;

      break;

    case VHOST_USER_SET_VRING_BASE:
      DBG_SOCK ("if %d msg VHOST_USER_SET_VRING_BASE idx %d num %d",
		vui->hw_if_index, msg.state.index, msg.state.num);

      vui->vrings[msg.state.index].last_avail_idx = msg.state.num;
      break;

    case VHOST_USER_GET_VRING_BASE:
      DBG_SOCK ("if %d msg VHOST_USER_GET_VRING_BASE idx %d num %d",
		vui->hw_if_index, msg.state.index, msg.state.num);

      if (msg.state.index >= VHOST_VRING_MAX_N)
	{
	  DBG_SOCK ("invalid vring index VHOST_USER_GET_VRING_BASE:"
		    " %d >= %d", msg.state.index, VHOST_VRING_MAX_N);
	  goto close_socket;
	}

      /*
       * Copy last_avail_idx from the vring before closing it because
       * closing the vring also initializes the vring last_avail_idx
       */
      msg.state.num = vui->vrings[msg.state.index].last_avail_idx;
      msg.flags |= 4;
      msg.size = sizeof (msg.state);

      /* Spec says: Client must [...] stop ring upon receiving VHOST_USER_GET_VRING_BASE. */
      vhost_user_vring_close (vui, msg.state.index);
      break;

    case VHOST_USER_NONE:
      DBG_SOCK ("if %d msg VHOST_USER_NONE", vui->hw_if_index);

      break;

    case VHOST_USER_SET_LOG_BASE:
      {
	DBG_SOCK ("if %d msg VHOST_USER_SET_LOG_BASE", vui->hw_if_index);

	if (msg.size != sizeof (msg.log))
	  {
	    DBG_SOCK
	      ("invalid msg size for VHOST_USER_SET_LOG_BASE: %d instead of %d",
	       msg.size, sizeof (msg.log));
	    goto close_socket;
	  }

	if (!
	    (vui->protocol_features & (1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD)))
	  {
	    DBG_SOCK
	      ("VHOST_USER_PROTOCOL_F_LOG_SHMFD not set but VHOST_USER_SET_LOG_BASE received");
	    goto close_socket;
	  }

	fd = fds[0];
	/* align size to 2M page */
	long page_sz = get_huge_page_size (fd);
	ssize_t map_sz =
	  (msg.log.size + msg.log.offset + page_sz - 1) & ~(page_sz - 1);

	vui->log_base_addr = mmap (0, map_sz, PROT_READ | PROT_WRITE,
				   MAP_SHARED, fd, 0);

	DBG_SOCK
	  ("map log region addr 0 len 0x%lx off 0x%lx fd %d mapped 0x%lx",
	   map_sz, msg.log.offset, fd, vui->log_base_addr);

	if (vui->log_base_addr == MAP_FAILED)
	  {
	    clib_warning ("failed to map memory. errno is %d", errno);
	    goto close_socket;
	  }

	vui->log_base_addr += msg.log.offset;
	vui->log_size = msg.log.size;

	msg.flags |= 4;
	msg.size = sizeof (msg.u64);

	break;
      }

    case VHOST_USER_SET_LOG_FD:
      DBG_SOCK ("if %d msg VHOST_USER_SET_LOG_FD", vui->hw_if_index);

      break;

    case VHOST_USER_GET_PROTOCOL_FEATURES:
      DBG_SOCK ("if %d msg VHOST_USER_GET_PROTOCOL_FEATURES",
		vui->hw_if_index);

      msg.flags |= 4;
      msg.u64 = (1 << VHOST_USER_PROTOCOL_F_LOG_SHMFD) |
	(1 << VHOST_USER_PROTOCOL_F_MQ);
      msg.size = sizeof (msg.u64);
      break;

    case VHOST_USER_SET_PROTOCOL_FEATURES:
      DBG_SOCK ("if %d msg VHOST_USER_SET_PROTOCOL_FEATURES features 0x%lx",
		vui->hw_if_index, msg.u64);

      vui->protocol_features = msg.u64;

      break;

    case VHOST_USER_GET_QUEUE_NUM:
      DBG_SOCK ("if %d msg VHOST_USER_GET_QUEUE_NUM", vui->hw_if_index);
      msg.flags |= 4;
      msg.u64 = VHOST_VRING_MAX_N;
      msg.size = sizeof (msg.u64);
      break;

    case VHOST_USER_SET_VRING_ENABLE:
      DBG_SOCK ("if %d VHOST_USER_SET_VRING_ENABLE: %s queue %d",
		vui->hw_if_index, msg.state.num ? "enable" : "disable",
		msg.state.index);
      if (msg.state.index >= VHOST_VRING_MAX_N)
	{
	  DBG_SOCK ("invalid vring index VHOST_USER_SET_VRING_ENABLE:"
		    " %d >= %d", msg.state.index, VHOST_VRING_MAX_N);
	  goto close_socket;
	}

      vui->vrings[msg.state.index].enabled = msg.state.num;
      break;

    default:
      DBG_SOCK ("unknown vhost-user message %d received. closing socket",
		msg.request);
      goto close_socket;
    }

  /* if we need to reply */
  if (msg.flags & 4)
    {
      n =
	send (uf->file_descriptor, &msg, VHOST_USER_MSG_HDR_SZ + msg.size, 0);
      if (n != (msg.size + VHOST_USER_MSG_HDR_SZ))
	{
	  DBG_SOCK ("could not send message response");
	  goto close_socket;
	}
    }

  vhost_user_update_iface_state (vui);
  vlib_worker_thread_barrier_release (vlib_get_main ());
  return 0;

close_socket:
  vhost_user_if_disconnect (vui);
  vhost_user_update_iface_state (vui);
  vlib_worker_thread_barrier_release (vlib_get_main ());
  return 0;
}

static clib_error_t *
vhost_user_socket_error (unix_file_t * uf)
{
  vlib_main_t *vm = vlib_get_main ();
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui =
    pool_elt_at_index (vum->vhost_user_interfaces, uf->private_data);

  DBG_SOCK ("socket error on if %d", vui->sw_if_index);
  vlib_worker_thread_barrier_sync (vm);
  vhost_user_if_disconnect (vui);
  vhost_user_rx_thread_placement ();
  vlib_worker_thread_barrier_release (vm);
  return 0;
}

static clib_error_t *
vhost_user_socksvr_accept_ready (unix_file_t * uf)
{
  int client_fd, client_len;
  struct sockaddr_un client;
  unix_file_t template = { 0 };
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;

  vui = pool_elt_at_index (vum->vhost_user_interfaces, uf->private_data);

  client_len = sizeof (client);
  client_fd = accept (uf->file_descriptor,
		      (struct sockaddr *) &client,
		      (socklen_t *) & client_len);

  if (client_fd < 0)
    return clib_error_return_unix (0, "accept");

  DBG_SOCK ("New client socket for vhost interface %d", vui->sw_if_index);
  template.read_function = vhost_user_socket_read;
  template.error_function = vhost_user_socket_error;
  template.file_descriptor = client_fd;
  template.private_data = vui - vhost_user_main.vhost_user_interfaces;
  vui->unix_file_index = unix_file_add (&unix_main, &template);
  return 0;
}

static clib_error_t *
vhost_user_init (vlib_main_t * vm)
{
  clib_error_t *error;
  vhost_user_main_t *vum = &vhost_user_main;
  vlib_thread_main_t *tm = vlib_get_thread_main ();
  vlib_thread_registration_t *tr;
  uword *p;

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

  vum->coalesce_frames = 32;
  vum->coalesce_time = 1e-3;

  vec_validate (vum->cpus, tm->n_vlib_mains - 1);

  vhost_cpu_t *cpu;
  vec_foreach (cpu, vum->cpus)
  {
    /* This is actually not necessary as validate already zeroes it
     * Just keeping the loop here for later because I am lazy. */
    cpu->rx_buffers_len = 0;
  }

  /* find out which cpus will be used for input */
  vum->input_cpu_first_index = 0;
  vum->input_cpu_count = 1;
  p = hash_get_mem (tm->thread_registrations_by_name, "workers");
  tr = p ? (vlib_thread_registration_t *) p[0] : 0;

  if (tr && tr->count > 0)
    {
      vum->input_cpu_first_index = tr->first_index;
      vum->input_cpu_count = tr->count;
    }

  vum->random = random_default_seed ();

  mhash_init_c_string (&vum->if_index_by_sock_name, sizeof (uword));

  return 0;
}

VLIB_INIT_FUNCTION (vhost_user_init);

static u8 *
format_vhost_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 *);
  CLIB_UNUSED (vnet_main_t * vnm) = vnet_get_main ();
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_trace_t *t = va_arg (*va, vhost_trace_t *);
  vhost_user_intf_t *vui = pool_elt_at_index (vum->vhost_user_interfaces,
					      t->device_index);

  vnet_sw_interface_t *sw = vnet_get_sw_interface (vnm, vui->sw_if_index);

  uword indent = format_get_indent (s);

  s = format (s, "%U %U queue %d\n", format_white_space, indent,
	      format_vnet_sw_interface_name, vnm, sw, t->qid);

  s = format (s, "%U virtio flags:\n", format_white_space, indent);
#define _(n,i,st) \
	  if (t->virtio_ring_flags & (1 << VIRTIO_TRACE_F_##n)) \
	    s = format (s, "%U  %s %s\n", format_white_space, indent, #n, st);
  foreach_virtio_trace_flags
#undef _
    s = format (s, "%U virtio_net_hdr first_desc_len %u\n",
		format_white_space, indent, t->first_desc_len);

  s = format (s, "%U   flags 0x%02x gso_type %u\n",
	      format_white_space, indent,
	      t->hdr.hdr.flags, t->hdr.hdr.gso_type);

  if (vui->virtio_net_hdr_sz == 12)
    s = format (s, "%U   num_buff %u",
		format_white_space, indent, t->hdr.num_buffers);

  return s;
}

void
vhost_user_rx_trace (vhost_trace_t * t,
		     vhost_user_intf_t * vui, u16 qid,
		     vlib_buffer_t * b, vhost_user_vring_t * txvq)
{
  vhost_user_main_t *vum = &vhost_user_main;
  u32 qsz_mask = txvq->qsz - 1;
  u32 last_avail_idx = txvq->last_avail_idx;
  u32 desc_current = txvq->avail->ring[last_avail_idx & qsz_mask];
  vring_desc_t *hdr_desc = 0;
  virtio_net_hdr_mrg_rxbuf_t *hdr;
  u32 hint = 0;

  memset (t, 0, sizeof (*t));
  t->device_index = vui - vum->vhost_user_interfaces;
  t->qid = qid;

  hdr_desc = &txvq->desc[desc_current];
  if (txvq->desc[desc_current].flags & VIRTQ_DESC_F_INDIRECT)
    {
      t->virtio_ring_flags |= 1 << VIRTIO_TRACE_F_INDIRECT;
      /* Header is the first here */
      hdr_desc = map_guest_mem (vui, txvq->desc[desc_current].addr, &hint);
    }
  if (txvq->desc[desc_current].flags & VIRTQ_DESC_F_NEXT)
    {
      t->virtio_ring_flags |= 1 << VIRTIO_TRACE_F_SIMPLE_CHAINED;
    }
  if (!(txvq->desc[desc_current].flags & VIRTQ_DESC_F_NEXT) &&
      !(txvq->desc[desc_current].flags & VIRTQ_DESC_F_INDIRECT))
    {
      t->virtio_ring_flags |= 1 << VIRTIO_TRACE_F_SINGLE_DESC;
    }

  t->first_desc_len = hdr_desc ? hdr_desc->len : 0;

  if (!hdr_desc || !(hdr = map_guest_mem (vui, hdr_desc->addr, &hint)))
    {
      t->virtio_ring_flags |= 1 << VIRTIO_TRACE_F_MAP_ERROR;
    }
  else
    {
      u32 len = vui->virtio_net_hdr_sz;
      memcpy (&t->hdr, hdr, len > hdr_desc->len ? hdr_desc->len : len);
    }
}

static inline void
vhost_user_send_call (vlib_main_t * vm, vhost_user_vring_t * vq)
{
  vhost_user_main_t *vum = &vhost_user_main;
  u64 x = 1;
  int fd = UNIX_GET_FD (vq->callfd_idx);
  int rv __attribute__ ((unused));
  /* TODO: pay attention to rv */
  rv = write (fd, &x, sizeof (x));
  vq->n_since_last_int = 0;
  vq->int_deadline = vlib_time_now (vm) + vum->coalesce_time;
}

static_always_inline u32
vhost_user_input_copy (vhost_user_intf_t * vui, vhost_copy_t * cpy,
		       u16 copy_len, u32 * map_hint)
{
  void *src0, *src1, *src2, *src3;
  if (PREDICT_TRUE (copy_len >= 4))
    {
      if (PREDICT_FALSE (!(src2 = map_guest_mem (vui, cpy[0].src, map_hint))))
	return 1;
      if (PREDICT_FALSE (!(src3 = map_guest_mem (vui, cpy[1].src, map_hint))))
	return 1;

      while (PREDICT_TRUE (copy_len >= 4))
	{
	  src0 = src2;
	  src1 = src3;

	  if (PREDICT_FALSE
	      (!(src2 = map_guest_mem (vui, cpy[2].src, map_hint))))
	    return 1;
	  if (PREDICT_FALSE
	      (!(src3 = map_guest_mem (vui, cpy[3].src, map_hint))))
	    return 1;

	  CLIB_PREFETCH (src2, 64, LOAD);
	  CLIB_PREFETCH (src3, 64, LOAD);

	  clib_memcpy ((void *) cpy[0].dst, src0, cpy[0].len);
	  clib_memcpy ((void *) cpy[1].dst, src1, cpy[1].len);
	  copy_len -= 2;
	  cpy += 2;
	}
    }
  while (copy_len)
    {
      if (PREDICT_FALSE (!(src0 = map_guest_mem (vui, cpy->src, map_hint))))
	return 1;
      clib_memcpy ((void *) cpy->dst, src0, cpy->len);
      copy_len -= 1;
      cpy += 1;
    }
  return 0;
}

/**
 * Try to discard packets from the tx ring (VPP RX path).
 * Returns the number of discarded packets.
 */
u32
vhost_user_rx_discard_packet (vlib_main_t * vm,
			      vhost_user_intf_t * vui,
			      vhost_user_vring_t * txvq, u32 discard_max)
{
  /*
   * On the RX side, each packet corresponds to one descriptor
   * (it is the same whether it is a shallow descriptor, chained, or indirect).
   * Therefore, discarding a packet is like discarding a descriptor.
   */
  u32 discarded_packets = 0;
  u32 avail_idx = txvq->avail->idx;
  u16 qsz_mask = txvq->qsz - 1;
  while (discarded_packets != discard_max)
    {
      if (avail_idx == txvq->last_avail_idx)
	goto out;

      u16 desc_chain_head =
	txvq->avail->ring[txvq->last_avail_idx & qsz_mask];
      txvq->last_avail_idx++;
      txvq->used->ring[txvq->last_used_idx & qsz_mask].id = desc_chain_head;
      txvq->used->ring[txvq->last_used_idx & qsz_mask].len = 0;
      vhost_user_log_dirty_ring (vui, txvq,
				 ring[txvq->last_used_idx & qsz_mask]);
      txvq->last_used_idx++;
      discarded_packets++;
    }

out:
  CLIB_MEMORY_BARRIER ();
  txvq->used->idx = txvq->last_used_idx;
  vhost_user_log_dirty_ring (vui, txvq, idx);
  return discarded_packets;
}

/*
 * In case of overflow, we need to rewind the array of allocated buffers.
 */
static void
vhost_user_input_rewind_buffers (vlib_main_t * vm,
				 vhost_cpu_t * cpu, vlib_buffer_t * b_head)
{
  u32 bi_current = cpu->rx_buffers[cpu->rx_buffers_len];
  vlib_buffer_t *b_current = vlib_get_buffer (vm, bi_current);
  b_current->current_length = 0;
  b_current->flags = 0;
  while (b_current != b_head)
    {
      cpu->rx_buffers_len++;
      bi_current = cpu->rx_buffers[cpu->rx_buffers_len];
      b_current = vlib_get_buffer (vm, bi_current);
      b_current->current_length = 0;
      b_current->flags = 0;
    }
}

static u32
vhost_user_if_input (vlib_main_t * vm,
		     vhost_user_main_t * vum,
		     vhost_user_intf_t * vui,
		     u16 qid, vlib_node_runtime_t * node)
{
  vhost_user_vring_t *txvq = &vui->vrings[VHOST_VRING_IDX_TX (qid)];
  u16 n_rx_packets = 0;
  u32 n_rx_bytes = 0;
  u16 n_left;
  u32 n_left_to_next, *to_next;
  u32 next_index = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;
  u32 n_trace = vlib_get_trace_count (vm, node);
  u16 qsz_mask;
  u32 map_hint = 0;
  u16 thread_index = vlib_get_thread_index ();
  u16 copy_len = 0;

  {
    /* do we have pending interrupts ? */
    vhost_user_vring_t *rxvq = &vui->vrings[VHOST_VRING_IDX_RX (qid)];
    f64 now = vlib_time_now (vm);

    if ((txvq->n_since_last_int) && (txvq->int_deadline < now))
      vhost_user_send_call (vm, txvq);

    if ((rxvq->n_since_last_int) && (rxvq->int_deadline < now))
      vhost_user_send_call (vm, rxvq);
  }

  if (PREDICT_FALSE (txvq->avail->flags & 0xFFFE))
    return 0;

  n_left = (u16) (txvq->avail->idx - txvq->last_avail_idx);

  /* nothing to do */
  if (PREDICT_FALSE (n_left == 0))
    return 0;

  if (PREDICT_FALSE (!vui->admin_up || !(txvq->enabled)))
    {
      /*
       * Discard input packet if interface is admin down or vring is not
       * enabled.
       * "For example, for a networking device, in the disabled state
       * client must not supply any new RX packets, but must process
       * and discard any TX packets."
       */
      vhost_user_rx_discard_packet (vm, vui, txvq,
				    VHOST_USER_DOWN_DISCARD_COUNT);
      return 0;
    }

  if (PREDICT_FALSE (n_left == txvq->qsz))
    {
      /*
       * Informational error logging when VPP is not
       * receiving packets fast enough.
       */
      vlib_error_count (vm, node->node_index,
			VHOST_USER_INPUT_FUNC_ERROR_FULL_RX_QUEUE, 1);
    }

  qsz_mask = txvq->qsz - 1;

  if (n_left > VLIB_FRAME_SIZE)
    n_left = VLIB_FRAME_SIZE;

  /*
   * For small packets (<2kB), we will not need more than one vlib buffer
   * per packet. In case packets are bigger, we will just yeld at some point
   * in the loop and come back later. This is not an issue as for big packet,
   * processing cost really comes from the memory copy.
   */
  if (PREDICT_FALSE (vum->cpus[thread_index].rx_buffers_len < n_left + 1))
    {
      u32 curr_len = vum->cpus[thread_index].rx_buffers_len;
      vum->cpus[thread_index].rx_buffers_len +=
	vlib_buffer_alloc_from_free_list (vm,
					  vum->cpus[thread_index].rx_buffers +
					  curr_len,
					  VHOST_USER_RX_BUFFERS_N - curr_len,
					  VLIB_BUFFER_DEFAULT_FREE_LIST_INDEX);

      if (PREDICT_FALSE
	  (vum->cpus[thread_index].rx_buffers_len <
	   VHOST_USER_RX_BUFFER_STARVATION))
	{
	  /* In case of buffer starvation, discard some packets from the queue
	   * and log the event.
	   * We keep doing best effort for the remaining packets. */
	  u32 flush = (n_left + 1 > vum->cpus[thread_index].rx_buffers_len) ?
	    n_left + 1 - vum->cpus[thread_index].rx_buffers_len : 1;
	  flush = vhost_user_rx_discard_packet (vm, vui, txvq, flush);

	  n_left -= flush;
	  vlib_increment_simple_counter (vnet_main.
					 interface_main.sw_if_counters +
					 VNET_INTERFACE_COUNTER_DROP,
					 vlib_get_thread_index (),
					 vui->sw_if_index, flush);

	  vlib_error_count (vm, vhost_user_input_node.index,
			    VHOST_USER_INPUT_FUNC_ERROR_NO_BUFFER, flush);
	}
    }

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

      while (n_left > 0 && n_left_to_next > 0)
	{
	  vlib_buffer_t *b_head, *b_current;
	  u32 bi_current;
	  u16 desc_current;
	  u32 desc_data_offset;
	  vring_desc_t *desc_table = txvq->desc;

	  if (PREDICT_FALSE (vum->cpus[thread_index].rx_buffers_len <= 1))
	    {
	      /* Not enough rx_buffers
	       * Note: We yeld on 1 so we don't need to do an additional
	       * check for the next buffer prefetch.
	       */
	      n_left = 0;
	      break;
	    }

	  desc_current = txvq->avail->ring[txvq->last_avail_idx & qsz_mask];
	  vum->cpus[thread_index].rx_buffers_len--;
	  bi_current = (vum->cpus[thread_index].rx_buffers)
	    [vum->cpus[thread_index].rx_buffers_len];
	  b_head = b_current = vlib_get_buffer (vm, bi_current);
	  to_next[0] = bi_current;	//We do that now so we can forget about bi_current
	  to_next++;
	  n_left_to_next--;

	  vlib_prefetch_buffer_with_index (vm,
					   (vum->
					    cpus[thread_index].rx_buffers)
					   [vum->cpus[thread_index].
					    rx_buffers_len - 1], LOAD);

	  /* Just preset the used descriptor id and length for later */
	  txvq->used->ring[txvq->last_used_idx & qsz_mask].id = desc_current;
	  txvq->used->ring[txvq->last_used_idx & qsz_mask].len = 0;
	  vhost_user_log_dirty_ring (vui, txvq,
				     ring[txvq->last_used_idx & qsz_mask]);

	  /* The buffer should already be initialized */
	  b_head->total_length_not_including_first_buffer = 0;
	  b_head->flags |= VLIB_BUFFER_TOTAL_LENGTH_VALID;

	  if (PREDICT_FALSE (n_trace))
	    {
	      //TODO: next_index is not exactly known at that point
	      vlib_trace_buffer (vm, node, next_index, b_head,
				 /* follow_chain */ 0);
	      vhost_trace_t *t0 =
		vlib_add_trace (vm, node, b_head, sizeof (t0[0]));
	      vhost_user_rx_trace (t0, vui, qid, b_head, txvq);
	      n_trace--;
	      vlib_set_trace_count (vm, node, n_trace);
	    }

	  /* This depends on the setup but is very consistent
	   * So I think the CPU branch predictor will make a pretty good job
	   * at optimizing the decision. */
	  if (txvq->desc[desc_current].flags & VIRTQ_DESC_F_INDIRECT)
	    {
	      desc_table = map_guest_mem (vui, txvq->desc[desc_current].addr,
					  &map_hint);
	      desc_current = 0;
	      if (PREDICT_FALSE (desc_table == 0))
		{
		  //FIXME: Handle error by shutdown the queue
		  goto out;
		}
	    }

	  if (PREDICT_TRUE (vui->is_any_layout) ||
	      (!(desc_table[desc_current].flags & VIRTQ_DESC_F_NEXT)))
	    {
	      /* ANYLAYOUT or single buffer */
	      desc_data_offset = vui->virtio_net_hdr_sz;
	    }
	  else
	    {
	      /* CSR case without ANYLAYOUT, skip 1st buffer */
	      desc_data_offset = desc_table[desc_current].len;
	    }

	  while (1)
	    {
	      /* Get more input if necessary. Or end of packet. */
	      if (desc_data_offset == desc_table[desc_current].len)
		{
		  if (PREDICT_FALSE (desc_table[desc_current].flags &
				     VIRTQ_DESC_F_NEXT))
		    {
		      desc_current = desc_table[desc_current].next;
		      desc_data_offset = 0;
		    }
		  else
		    {
		      goto out;
		    }
		}

	      /* Get more output if necessary. Or end of packet. */
	      if (PREDICT_FALSE
		  (b_current->current_length == VLIB_BUFFER_DATA_SIZE))
		{
		  if (PREDICT_FALSE
		      (vum->cpus[thread_index].rx_buffers_len == 0))
		    {
		      /* Cancel speculation */
		      to_next--;
		      n_left_to_next++;

		      /*
		       * Checking if there are some left buffers.
		       * If not, just rewind the used buffers and stop.
		       * Note: Scheduled copies are not cancelled. This is
		       * not an issue as they would still be valid. Useless,
		       * but valid.
		       */
		      vhost_user_input_rewind_buffers (vm,
						       &vum->cpus
						       [thread_index],
						       b_head);
		      n_left = 0;
		      goto stop;
		    }

		  /* Get next output */
		  vum->cpus[thread_index].rx_buffers_len--;
		  u32 bi_next =
		    (vum->cpus[thread_index].rx_buffers)[vum->cpus
							 [thread_index].rx_buffers_len];
		  b_current->next_buffer = bi_next;
		  b_current->flags |= VLIB_BUFFER_NEXT_PRESENT;
		  bi_current = bi_next;
		  b_current = vlib_get_buffer (vm, bi_current);
		}

	      /* Prepare a copy order executed later for the data */
	      vhost_copy_t *cpy = &vum->cpus[thread_index].copy[copy_len];
	      copy_len++;
	      u32 desc_data_l =
		desc_table[desc_current].len - desc_data_offset;
	      cpy->len = VLIB_BUFFER_DATA_SIZE - b_current->current_length;
	      cpy->len = (cpy->len > desc_data_l) ? desc_data_l : cpy->len;
	      cpy->dst = (uword) vlib_buffer_get_current (b_current);
	      cpy->src = desc_table[desc_current].addr + desc_data_offset;

	      desc_data_offset += cpy->len;

	      b_current->current_length += cpy->len;
	      b_head->total_length_not_including_first_buffer += cpy->len;
	    }

	out:
	  CLIB_PREFETCH (&n_left, sizeof (n_left), LOAD);

	  n_rx_bytes += b_head->total_length_not_including_first_buffer;
	  n_rx_packets++;

	  b_head->total_length_not_including_first_buffer -=
	    b_head->current_length;

	  /* consume the descriptor and return it as used */
	  txvq->last_avail_idx++;
	  txvq->last_used_idx++;

	  VLIB_BUFFER_TRACE_TRAJECTORY_INIT (b_head);

	  vnet_buffer (b_head)->sw_if_index[VLIB_RX] = vui->sw_if_index;
	  vnet_buffer (b_head)->sw_if_index[VLIB_TX] = (u32) ~ 0;
	  b_head->error = 0;

	  {
	    u32 next0 = VNET_DEVICE_INPUT_NEXT_ETHERNET_INPUT;

	    /* redirect if feature path enabled */
	    vnet_feature_start_device_input_x1 (vui->sw_if_index, &next0,
						b_head);

	    u32 bi = to_next[-1];	//Cannot use to_next[-1] in the macro
	    vlib_validate_buffer_enqueue_x1 (vm, node, next_index,
					     to_next, n_left_to_next,
					     bi, next0);
	  }

	  n_left--;

	  /*
	   * Although separating memory copies from virtio ring parsing
	   * is beneficial, we can offer to perform the copies from time
	   * to time in order to free some space in the ring.
	   */
	  if (PREDICT_FALSE (copy_len >= VHOST_USER_RX_COPY_THRESHOLD))
	    {
	      if (PREDICT_FALSE
		  (vhost_user_input_copy (vui, vum->cpus[thread_index].copy,
					  copy_len, &map_hint)))
		{
		  clib_warning
		    ("Memory mapping error on interface hw_if_index=%d "
		     "(Shutting down - Switch interface down and up to restart)",
		     vui->hw_if_index);
		  vui->admin_up = 0;
		  copy_len = 0;
		  break;
		}
	      copy_len = 0;

	      /* give buffers back to driver */
	      CLIB_MEMORY_BARRIER ();
	      txvq->used->idx = txvq->last_used_idx;
	      vhost_user_log_dirty_ring (vui, txvq, idx);
	    }
	}
    stop:
      vlib_put_next_frame (vm, node, next_index, n_left_to_next);
    }

  /* Do the memory copies */
  if (PREDICT_FALSE
      (vhost_user_input_copy (vui, vum->cpus[thread_index].copy,
			      copy_len, &map_hint)))
    {
      clib_warning ("Memory mapping error on interface hw_if_index=%d "
		    "(Shutting down - Switch interface down and up to restart)",
		    vui->hw_if_index);
      vui->admin_up = 0;
    }

  /* give buffers back to driver */
  CLIB_MEMORY_BARRIER ();
  txvq->used->idx = txvq->last_used_idx;
  vhost_user_log_dirty_ring (vui, txvq, idx);

  /* interrupt (call) handling */
  if ((txvq->callfd_idx != ~0) &&
      !(txvq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT))
    {
      txvq->n_since_last_int += n_rx_packets;

      if (txvq->n_since_last_int > vum->coalesce_frames)
	vhost_user_send_call (vm, txvq);
    }

  /* increase rx counters */
  vlib_increment_combined_counter
    (vnet_main.interface_main.combined_sw_if_counters
     + VNET_INTERFACE_COUNTER_RX,
     vlib_get_thread_index (), vui->sw_if_index, n_rx_packets, n_rx_bytes);

  vnet_device_increment_rx_packets (thread_index, n_rx_packets);

  return n_rx_packets;
}

static uword
vhost_user_input (vlib_main_t * vm,
		  vlib_node_runtime_t * node, vlib_frame_t * f)
{
  vhost_user_main_t *vum = &vhost_user_main;
  uword n_rx_packets = 0;
  u32 thread_index = vlib_get_thread_index ();
  vhost_iface_and_queue_t *vhiq;
  vhost_user_intf_t *vui;
  vhost_cpu_t *vhc;

  vhc = &vum->cpus[thread_index];
  if (PREDICT_TRUE (vhc->operation_mode == VHOST_USER_POLLING_MODE))
    {
      vec_foreach (vhiq, vum->cpus[thread_index].rx_queues)
      {
	vui = &vum->vhost_user_interfaces[vhiq->vhost_iface_index];
	n_rx_packets += vhost_user_if_input (vm, vum, vui, vhiq->qid, node);
      }
    }
  else
    {
      int i;

      /* *INDENT-OFF* */
      clib_bitmap_foreach (i, vhc->pending_input_bitmap, ({
	int qid = i & 0xff;

	clib_bitmap_set (vhc->pending_input_bitmap, i, 0);
	vui = pool_elt_at_index (vum->vhost_user_interfaces, i >> 8);
	n_rx_packets += vhost_user_if_input (vm, vum, vui, qid, node);
      }));
      /* *INDENT-ON* */
    }
  return n_rx_packets;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (vhost_user_input_node) = {
  .function = vhost_user_input,
  .type = VLIB_NODE_TYPE_INPUT,
  .name = "vhost-user-input",
  .sibling_of = "device-input",

  /* Will be enabled if/when hardware is detected. */
  .state = VLIB_NODE_STATE_DISABLED,

  .format_buffer = format_ethernet_header_with_length,
  .format_trace = format_vhost_trace,

  .n_errors = VHOST_USER_INPUT_FUNC_N_ERROR,
  .error_strings = vhost_user_input_func_error_strings,
};

VLIB_NODE_FUNCTION_MULTIARCH (vhost_user_input_node, vhost_user_input)
/* *INDENT-ON* */


void
vhost_user_tx_trace (vhost_trace_t * t,
		     vhost_user_intf_t * vui, u16 qid,
		     vlib_buffer_t * b, vhost_user_vring_t * rxvq)
{
  vhost_user_main_t *vum = &vhost_user_main;
  u32 qsz_mask = rxvq->qsz - 1;
  u32 last_avail_idx = rxvq->last_avail_idx;
  u32 desc_current = rxvq->avail->ring[last_avail_idx & qsz_mask];
  vring_desc_t *hdr_desc = 0;
  u32 hint = 0;

  memset (t, 0, sizeof (*t));
  t->device_index = vui - vum->vhost_user_interfaces;
  t->qid = qid;

  hdr_desc = &rxvq->desc[desc_current];
  if (rxvq->desc[desc_current].flags & VIRTQ_DESC_F_INDIRECT)
    {
      t->virtio_ring_flags |= 1 << VIRTIO_TRACE_F_INDIRECT;
      /* Header is the first here */
      hdr_desc = map_guest_mem (vui, rxvq->desc[desc_current].addr, &hint);
    }
  if (rxvq->desc[desc_current].flags & VIRTQ_DESC_F_NEXT)
    {
      t->virtio_ring_flags |= 1 << VIRTIO_TRACE_F_SIMPLE_CHAINED;
    }
  if (!(rxvq->desc[desc_current].flags & VIRTQ_DESC_F_NEXT) &&
      !(rxvq->desc[desc_current].flags & VIRTQ_DESC_F_INDIRECT))
    {
      t->virtio_ring_flags |= 1 << VIRTIO_TRACE_F_SINGLE_DESC;
    }

  t->first_desc_len = hdr_desc ? hdr_desc->len : 0;
}

static_always_inline u32
vhost_user_tx_copy (vhost_user_intf_t * vui, vhost_copy_t * cpy,
		    u16 copy_len, u32 * map_hint)
{
  void *dst0, *dst1, *dst2, *dst3;
  if (PREDICT_TRUE (copy_len >= 4))
    {
      if (PREDICT_FALSE (!(dst2 = map_guest_mem (vui, cpy[0].dst, map_hint))))
	return 1;
      if (PREDICT_FALSE (!(dst3 = map_guest_mem (vui, cpy[1].dst, map_hint))))
	return 1;
      while (PREDICT_TRUE (copy_len >= 4))
	{
	  dst0 = dst2;
	  dst1 = dst3;

	  if (PREDICT_FALSE
	      (!(dst2 = map_guest_mem (vui, cpy[2].dst, map_hint))))
	    return 1;
	  if (PREDICT_FALSE
	      (!(dst3 = map_guest_mem (vui, cpy[3].dst, map_hint))))
	    return 1;

	  CLIB_PREFETCH ((void *) cpy[2].src, 64, LOAD);
	  CLIB_PREFETCH ((void *) cpy[3].src, 64, LOAD);

	  clib_memcpy (dst0, (void *) cpy[0].src, cpy[0].len);
	  clib_memcpy (dst1, (void *) cpy[1].src, cpy[1].len);

	  vhost_user_log_dirty_pages_2 (vui, cpy[0].dst, cpy[0].len, 1);
	  vhost_user_log_dirty_pages_2 (vui, cpy[1].dst, cpy[1].len, 1);
	  copy_len -= 2;
	  cpy += 2;
	}
    }
  while (copy_len)
    {
      if (PREDICT_FALSE (!(dst0 = map_guest_mem (vui, cpy->dst, map_hint))))
	return 1;
      clib_memcpy (dst0, (void *) cpy->src, cpy->len);
      vhost_user_log_dirty_pages_2 (vui, cpy->dst, cpy->len, 1);
      copy_len -= 1;
      cpy += 1;
    }
  return 0;
}


static uword
vhost_user_tx (vlib_main_t * vm,
	       vlib_node_runtime_t * node, vlib_frame_t * frame)
{
  u32 *buffers = vlib_frame_args (frame);
  u32 n_left = frame->n_vectors;
  vhost_user_main_t *vum = &vhost_user_main;
  vnet_interface_output_runtime_t *rd = (void *) node->runtime_data;
  vhost_user_intf_t *vui =
    pool_elt_at_index (vum->vhost_user_interfaces, rd->dev_instance);
  u32 qid = ~0;
  vhost_user_vring_t *rxvq;
  u16 qsz_mask;
  u8 error;
  u32 thread_index = vlib_get_thread_index ();
  u32 map_hint = 0;
  u8 retry = 8;
  u16 copy_len;
  u16 tx_headers_len;

  if (PREDICT_FALSE (!vui->admin_up))
    {
      error = VHOST_USER_TX_FUNC_ERROR_DOWN;
      goto done3;
    }

  if (PREDICT_FALSE (!vui->is_up))
    {
      error = VHOST_USER_TX_FUNC_ERROR_NOT_READY;
      goto done3;
    }

  qid =
    VHOST_VRING_IDX_RX (*vec_elt_at_index
			(vui->per_cpu_tx_qid, vlib_get_thread_index ()));
  rxvq = &vui->vrings[qid];
  if (PREDICT_FALSE (vui->use_tx_spinlock))
    vhost_user_vring_lock (vui, qid);

  qsz_mask = rxvq->qsz - 1;	/* qsz is always power of 2 */

retry:
  error = VHOST_USER_TX_FUNC_ERROR_NONE;
  tx_headers_len = 0;
  copy_len = 0;
  while (n_left > 0)
    {
      vlib_buffer_t *b0, *current_b0;
      u16 desc_head, desc_index, desc_len;
      vring_desc_t *desc_table;
      uword buffer_map_addr;
      u32 buffer_len;
      u16 bytes_left;

      if (PREDICT_TRUE (n_left > 1))
	vlib_prefetch_buffer_with_index (vm, buffers[1], LOAD);

      b0 = vlib_get_buffer (vm, buffers[0]);

      if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	{
	  vum->cpus[thread_index].current_trace =
	    vlib_add_trace (vm, node, b0,
			    sizeof (*vum->cpus[thread_index].current_trace));
	  vhost_user_tx_trace (vum->cpus[thread_index].current_trace,
			       vui, qid / 2, b0, rxvq);
	}

      if (PREDICT_FALSE (rxvq->last_avail_idx == rxvq->avail->idx))
	{
	  error = VHOST_USER_TX_FUNC_ERROR_PKT_DROP_NOBUF;
	  goto done;
	}

      desc_table = rxvq->desc;
      desc_head = desc_index =
	rxvq->avail->ring[rxvq->last_avail_idx & qsz_mask];

      /* Go deeper in case of indirect descriptor
       * I don't know of any driver providing indirect for RX. */
      if (PREDICT_FALSE (rxvq->desc[desc_head].flags & VIRTQ_DESC_F_INDIRECT))
	{
	  if (PREDICT_FALSE
	      (rxvq->desc[desc_head].len < sizeof (vring_desc_t)))
	    {
	      error = VHOST_USER_TX_FUNC_ERROR_INDIRECT_OVERFLOW;
	      goto done;
	    }
	  if (PREDICT_FALSE
	      (!(desc_table =
		 map_guest_mem (vui, rxvq->desc[desc_index].addr,
				&map_hint))))
	    {
	      error = VHOST_USER_TX_FUNC_ERROR_MMAP_FAIL;
	      goto done;
	    }
	  desc_index = 0;
	}

      desc_len = vui->virtio_net_hdr_sz;
      buffer_map_addr = desc_table[desc_index].addr;
      buffer_len = desc_table[desc_index].len;

      {
	// Get a header from the header array
	virtio_net_hdr_mrg_rxbuf_t *hdr =
	  &vum->cpus[thread_index].tx_headers[tx_headers_len];
	tx_headers_len++;
	hdr->hdr.flags = 0;
	hdr->hdr.gso_type = 0;
	hdr->num_buffers = 1;	//This is local, no need to check

	// Prepare a copy order executed later for the header
	vhost_copy_t *cpy = &vum->cpus[thread_index].copy[copy_len];
	copy_len++;
	cpy->len = vui->virtio_net_hdr_sz;
	cpy->dst = buffer_map_addr;
	cpy->src = (uword) hdr;
      }

      buffer_map_addr += vui->virtio_net_hdr_sz;
      buffer_len -= vui->virtio_net_hdr_sz;
      bytes_left = b0->current_length;
      current_b0 = b0;
      while (1)
	{
	  if (buffer_len == 0)
	    {			//Get new output
	      if (desc_table[desc_index].flags & VIRTQ_DESC_F_NEXT)
		{
		  //Next one is chained
		  desc_index = desc_table[desc_index].next;
		  buffer_map_addr = desc_table[desc_index].addr;
		  buffer_len = desc_table[desc_index].len;
		}
	      else if (vui->virtio_net_hdr_sz == 12)	//MRG is available
		{
		  virtio_net_hdr_mrg_rxbuf_t *hdr =
		    &vum->cpus[thread_index].tx_headers[tx_headers_len - 1];

		  //Move from available to used buffer
		  rxvq->used->ring[rxvq->last_used_idx & qsz_mask].id =
		    desc_head;
		  rxvq->used->ring[rxvq->last_used_idx & qsz_mask].len =
		    desc_len;
		  vhost_user_log_dirty_ring (vui, rxvq,
					     ring[rxvq->last_used_idx &
						  qsz_mask]);

		  rxvq->last_avail_idx++;
		  rxvq->last_used_idx++;
		  hdr->num_buffers++;
		  desc_len = 0;

		  if (PREDICT_FALSE
		      (rxvq->last_avail_idx == rxvq->avail->idx))
		    {
		      //Dequeue queued descriptors for this packet
		      rxvq->last_used_idx -= hdr->num_buffers - 1;
		      rxvq->last_avail_idx -= hdr->num_buffers - 1;
		      error = VHOST_USER_TX_FUNC_ERROR_PKT_DROP_NOBUF;
		      goto done;
		    }

		  desc_table = rxvq->desc;
		  desc_head = desc_index =
		    rxvq->avail->ring[rxvq->last_avail_idx & qsz_mask];
		  if (PREDICT_FALSE
		      (rxvq->desc[desc_head].flags & VIRTQ_DESC_F_INDIRECT))
		    {
		      //It is seriously unlikely that a driver will put indirect descriptor
		      //after non-indirect descriptor.
		      if (PREDICT_FALSE
			  (rxvq->desc[desc_head].len < sizeof (vring_desc_t)))
			{
			  error = VHOST_USER_TX_FUNC_ERROR_INDIRECT_OVERFLOW;
			  goto done;
			}
		      if (PREDICT_FALSE
			  (!(desc_table =
			     map_guest_mem (vui,
					    rxvq->desc[desc_index].addr,
					    &map_hint))))
			{
			  error = VHOST_USER_TX_FUNC_ERROR_MMAP_FAIL;
			  goto done;
			}
		      desc_index = 0;
		    }
		  buffer_map_addr = desc_table[desc_index].addr;
		  buffer_len = desc_table[desc_index].len;
		}
	      else
		{
		  error = VHOST_USER_TX_FUNC_ERROR_PKT_DROP_NOMRG;
		  goto done;
		}
	    }

	  {
	    vhost_copy_t *cpy = &vum->cpus[thread_index].copy[copy_len];
	    copy_len++;
	    cpy->len = bytes_left;
	    cpy->len = (cpy->len > buffer_len) ? buffer_len : cpy->len;
	    cpy->dst = buffer_map_addr;
	    cpy->src = (uword) vlib_buffer_get_current (current_b0) +
	      current_b0->current_length - bytes_left;

	    bytes_left -= cpy->len;
	    buffer_len -= cpy->len;
	    buffer_map_addr += cpy->len;
	    desc_len += cpy->len;

	    CLIB_PREFETCH (&rxvq->desc, CLIB_CACHE_LINE_BYTES, LOAD);
	  }

	  // Check if vlib buffer has more data. If not, get more or break.
	  if (PREDICT_TRUE (!bytes_left))
	    {
	      if (PREDICT_FALSE
		  (current_b0->flags & VLIB_BUFFER_NEXT_PRESENT))
		{
		  current_b0 = vlib_get_buffer (vm, current_b0->next_buffer);
		  bytes_left = current_b0->current_length;
		}
	      else
		{
		  //End of packet
		  break;
		}
	    }
	}

      //Move from available to used ring
      rxvq->used->ring[rxvq->last_used_idx & qsz_mask].id = desc_head;
      rxvq->used->ring[rxvq->last_used_idx & qsz_mask].len = desc_len;
      vhost_user_log_dirty_ring (vui, rxvq,
				 ring[rxvq->last_used_idx & qsz_mask]);
      rxvq->last_avail_idx++;
      rxvq->last_used_idx++;

      if (PREDICT_FALSE (b0->flags & VLIB_BUFFER_IS_TRACED))
	{
	  vum->cpus[thread_index].current_trace->hdr =
	    vum->cpus[thread_index].tx_headers[tx_headers_len - 1];
	}

      n_left--;			//At the end for error counting when 'goto done' is invoked
      buffers++;
    }

done:
  //Do the memory copies
  if (PREDICT_FALSE
      (vhost_user_tx_copy (vui, vum->cpus[thread_index].copy,
			   copy_len, &map_hint)))
    {
      clib_warning ("Memory mapping error on interface hw_if_index=%d "
		    "(Shutting down - Switch interface down and up to restart)",
		    vui->hw_if_index);
      vui->admin_up = 0;
    }

  CLIB_MEMORY_BARRIER ();
  rxvq->used->idx = rxvq->last_used_idx;
  vhost_user_log_dirty_ring (vui, rxvq, idx);

  /*
   * When n_left is set, error is always set to something too.
   * In case error is due to lack of remaining buffers, we go back up and
   * retry.
   * The idea is that it is better to waste some time on packets
   * that have been processed already than dropping them and get
   * more fresh packets with a good likelyhood that they will be dropped too.
   * This technique also gives more time to VM driver to pick-up packets.
   * In case the traffic flows from physical to virtual interfaces, this
   * technique will end-up leveraging the physical NIC buffer in order to
   * absorb the VM's CPU jitter.
   */
  if (n_left && (error == VHOST_USER_TX_FUNC_ERROR_PKT_DROP_NOBUF) && retry)
    {
      retry--;
      goto retry;
    }

  /* interrupt (call) handling */
  if ((rxvq->callfd_idx != ~0) &&
      !(rxvq->avail->flags & VRING_AVAIL_F_NO_INTERRUPT))
    {
      rxvq->n_since_last_int += frame->n_vectors - n_left;

      if (rxvq->n_since_last_int > vum->coalesce_frames)
	vhost_user_send_call (vm, rxvq);
    }

  vhost_user_vring_unlock (vui, qid);

done3:
  if (PREDICT_FALSE (n_left && error != VHOST_USER_TX_FUNC_ERROR_NONE))
    {
      vlib_error_count (vm, node->node_index, error, n_left);
      vlib_increment_simple_counter
	(vnet_main.interface_main.sw_if_counters
	 + VNET_INTERFACE_COUNTER_DROP,
	 vlib_get_thread_index (), vui->sw_if_index, n_left);
    }

  vlib_buffer_free (vm, vlib_frame_args (frame), frame->n_vectors);
  return frame->n_vectors;
}

static clib_error_t *
vhost_user_interface_admin_up_down (vnet_main_t * vnm, u32 hw_if_index,
				    u32 flags)
{
  vnet_hw_interface_t *hif = vnet_get_hw_interface (vnm, hw_if_index);
  uword is_up = (flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) != 0;
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui =
    pool_elt_at_index (vum->vhost_user_interfaces, hif->dev_instance);

  vui->admin_up = is_up;

  if (is_up)
    vnet_hw_interface_set_flags (vnm, vui->hw_if_index,
				 VNET_HW_INTERFACE_FLAG_LINK_UP);

  return /* no error */ 0;
}

/* *INDENT-OFF* */
VNET_DEVICE_CLASS (vhost_user_dev_class,static) = {
  .name = "vhost-user",
  .tx_function = vhost_user_tx,
  .tx_function_n_errors = VHOST_USER_TX_FUNC_N_ERROR,
  .tx_function_error_strings = vhost_user_tx_func_error_strings,
  .format_device_name = format_vhost_user_interface_name,
  .name_renumber = vhost_user_name_renumber,
  .admin_up_down_function = vhost_user_interface_admin_up_down,
  .format_tx_trace = format_vhost_trace,
};

VLIB_DEVICE_TX_FUNCTION_MULTIARCH (vhost_user_dev_class,
				   vhost_user_tx)
/* *INDENT-ON* */

static uword
vhost_user_process (vlib_main_t * vm,
		    vlib_node_runtime_t * rt, vlib_frame_t * f)
{
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;
  struct sockaddr_un sun;
  int sockfd;
  unix_file_t template = { 0 };
  f64 timeout = 3153600000.0 /* 100 years */ ;
  uword *event_data = 0;

  sockfd = -1;
  sun.sun_family = AF_UNIX;
  template.read_function = vhost_user_socket_read;
  template.error_function = vhost_user_socket_error;

  while (1)
    {
      vlib_process_wait_for_event_or_clock (vm, timeout);
      vlib_process_get_events (vm, &event_data);
      vec_reset_length (event_data);

      timeout = 3.0;

      /* *INDENT-OFF* */
      pool_foreach (vui, vum->vhost_user_interfaces, {

	  if (vui->unix_server_index == ~0) { //Nothing to do for server sockets
	      if (vui->unix_file_index == ~0)
		{
		  if ((sockfd < 0) &&
		      ((sockfd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0))
		    {
		      /*
		       * 1st time error or new error for this interface,
		       * spit out the message and record the error
		       */
		      if (!vui->sock_errno || (vui->sock_errno != errno))
			{
			  clib_unix_warning
			    ("Error: Could not open unix socket for %s",
			     vui->sock_filename);
			  vui->sock_errno = errno;
			}
		      continue;
		    }

		  /* try to connect */
		  strncpy (sun.sun_path, (char *) vui->sock_filename,
			   sizeof (sun.sun_path) - 1);

		  /* Avoid hanging VPP if the other end does not accept */
		  if (fcntl(sockfd, F_SETFL, O_NONBLOCK) < 0)
                      clib_unix_warning ("fcntl");

		  if (connect (sockfd, (struct sockaddr *) &sun,
			       sizeof (struct sockaddr_un)) == 0)
		    {
		      /* Set the socket to blocking as it was before */
                      if (fcntl(sockfd, F_SETFL, 0) < 0)
                        clib_unix_warning ("fcntl2");

		      vui->sock_errno = 0;
		      template.file_descriptor = sockfd;
		      template.private_data =
			  vui - vhost_user_main.vhost_user_interfaces;
		      vui->unix_file_index = unix_file_add (&unix_main, &template);

		      /* This sockfd is considered consumed */
		      sockfd = -1;
		    }
		  else
		    {
		      vui->sock_errno = errno;
		    }
		}
	      else
		{
		  /* check if socket is alive */
		  int error = 0;
		  socklen_t len = sizeof (error);
		  int fd = UNIX_GET_FD(vui->unix_file_index);
		  int retval =
		      getsockopt (fd, SOL_SOCKET, SO_ERROR, &error, &len);

		  if (retval)
		    {
		      DBG_SOCK ("getsockopt returned %d", retval);
		      vhost_user_if_disconnect (vui);
		    }
		}
	  }
      });
      /* *INDENT-ON* */
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (vhost_user_process_node,static) = {
    .function = vhost_user_process,
    .type = VLIB_NODE_TYPE_PROCESS,
    .name = "vhost-user-process",
};
/* *INDENT-ON* */

/**
 * Disables and reset interface structure.
 * It can then be either init again, or removed from used interfaces.
 */
static void
vhost_user_term_if (vhost_user_intf_t * vui)
{
  int q;
  vhost_user_main_t *vum = &vhost_user_main;

  // Delete configured thread pinning
  vec_reset_length (vui->workers);
  // disconnect interface sockets
  vhost_user_if_disconnect (vui);
  vhost_user_update_iface_state (vui);

  for (q = 0; q < VHOST_VRING_MAX_N; q++)
    {
      clib_mem_free ((void *) vui->vring_locks[q]);
    }

  if (vui->unix_server_index != ~0)
    {
      //Close server socket
      unix_file_t *uf = pool_elt_at_index (unix_main.file_pool,
					   vui->unix_server_index);
      unix_file_del (&unix_main, uf);
      vui->unix_server_index = ~0;
      unlink (vui->sock_filename);
    }

  mhash_unset (&vum->if_index_by_sock_name, vui->sock_filename,
	       &vui->if_index);
}

int
vhost_user_delete_if (vnet_main_t * vnm, vlib_main_t * vm, u32 sw_if_index)
{
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;
  int rv = 0;
  vnet_hw_interface_t *hwif;

  if (!(hwif = vnet_get_sup_hw_interface (vnm, sw_if_index)) ||
      hwif->dev_class_index != vhost_user_dev_class.index)
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  DBG_SOCK ("Deleting vhost-user interface %s (instance %d)",
	    hwif->name, hwif->dev_instance);

  vui = pool_elt_at_index (vum->vhost_user_interfaces, hwif->dev_instance);

  // Disable and reset interface
  vhost_user_term_if (vui);

  // Reset renumbered iface
  if (hwif->dev_instance <
      vec_len (vum->show_dev_instance_by_real_dev_instance))
    vum->show_dev_instance_by_real_dev_instance[hwif->dev_instance] = ~0;

  // Delete ethernet interface
  ethernet_delete_interface (vnm, vui->hw_if_index);

  // Back to pool
  pool_put (vum->vhost_user_interfaces, vui);

  return rv;
}

static clib_error_t *
vhost_user_exit (vlib_main_t * vm)
{
  vnet_main_t *vnm = vnet_get_main ();
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;

  vlib_worker_thread_barrier_sync (vlib_get_main ());
  /* *INDENT-OFF* */
  pool_foreach (vui, vum->vhost_user_interfaces, {
      vhost_user_delete_if (vnm, vm, vui->sw_if_index);
  });
  /* *INDENT-ON* */
  vlib_worker_thread_barrier_release (vlib_get_main ());
  return 0;
}

VLIB_MAIN_LOOP_EXIT_FUNCTION (vhost_user_exit);

/**
 * Open server unix socket on specified sock_filename.
 */
static int
vhost_user_init_server_sock (const char *sock_filename, int *sock_fd)
{
  int rv = 0;
  struct sockaddr_un un = { };
  int fd;
  /* create listening socket */
  if ((fd = socket (AF_UNIX, SOCK_STREAM, 0)) < 0)
    return VNET_API_ERROR_SYSCALL_ERROR_1;

  un.sun_family = AF_UNIX;
  strncpy ((char *) un.sun_path, (char *) sock_filename,
	   sizeof (un.sun_path) - 1);

  /* remove if exists */
  unlink ((char *) sock_filename);

  if (bind (fd, (struct sockaddr *) &un, sizeof (un)) == -1)
    {
      rv = VNET_API_ERROR_SYSCALL_ERROR_2;
      goto error;
    }

  if (listen (fd, 1) == -1)
    {
      rv = VNET_API_ERROR_SYSCALL_ERROR_3;
      goto error;
    }

  *sock_fd = fd;
  return 0;

error:
  close (fd);
  return rv;
}

/**
 * Create ethernet interface for vhost user interface.
 */
static void
vhost_user_create_ethernet (vnet_main_t * vnm, vlib_main_t * vm,
			    vhost_user_intf_t * vui, u8 * hwaddress)
{
  vhost_user_main_t *vum = &vhost_user_main;
  u8 hwaddr[6];
  clib_error_t *error;

  /* create hw and sw interface */
  if (hwaddress)
    {
      clib_memcpy (hwaddr, hwaddress, 6);
    }
  else
    {
      random_u32 (&vum->random);
      clib_memcpy (hwaddr + 2, &vum->random, sizeof (vum->random));
      hwaddr[0] = 2;
      hwaddr[1] = 0xfe;
    }

  error = ethernet_register_interface
    (vnm,
     vhost_user_dev_class.index,
     vui - vum->vhost_user_interfaces /* device instance */ ,
     hwaddr /* ethernet address */ ,
     &vui->hw_if_index, 0 /* flag change */ );

  if (error)
    clib_error_report (error);

  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, vui->hw_if_index);
  hi->max_l3_packet_bytes[VLIB_RX] = hi->max_l3_packet_bytes[VLIB_TX] = 9000;
}

/*
 *  Initialize vui with specified attributes
 */
static void
vhost_user_vui_init (vnet_main_t * vnm,
		     vhost_user_intf_t * vui,
		     int server_sock_fd,
		     const char *sock_filename,
		     u64 feature_mask, u32 * sw_if_index, u8 operation_mode)
{
  vnet_sw_interface_t *sw;
  sw = vnet_get_hw_sw_interface (vnm, vui->hw_if_index);
  int q;
  vhost_user_main_t *vum = &vhost_user_main;

  if (server_sock_fd != -1)
    {
      unix_file_t template = { 0 };
      template.read_function = vhost_user_socksvr_accept_ready;
      template.file_descriptor = server_sock_fd;
      template.private_data = vui - vum->vhost_user_interfaces;	//hw index
      vui->unix_server_index = unix_file_add (&unix_main, &template);
    }
  else
    {
      vui->unix_server_index = ~0;
    }

  vui->sw_if_index = sw->sw_if_index;
  strncpy (vui->sock_filename, sock_filename,
	   ARRAY_LEN (vui->sock_filename) - 1);
  vui->sock_errno = 0;
  vui->is_up = 0;
  vui->feature_mask = feature_mask;
  vui->unix_file_index = ~0;
  vui->log_base_addr = 0;
  vui->operation_mode = operation_mode;
  vui->if_index = vui - vum->vhost_user_interfaces;
  mhash_set_mem (&vum->if_index_by_sock_name, vui->sock_filename,
		 &vui->if_index, 0);

  for (q = 0; q < VHOST_VRING_MAX_N; q++)
    vhost_user_vring_init (vui, q);

  vnet_hw_interface_set_flags (vnm, vui->hw_if_index, 0);

  if (sw_if_index)
    *sw_if_index = vui->sw_if_index;

  for (q = 0; q < VHOST_VRING_MAX_N; q++)
    {
      vui->vring_locks[q] = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
						    CLIB_CACHE_LINE_BYTES);
      memset ((void *) vui->vring_locks[q], 0, CLIB_CACHE_LINE_BYTES);
    }

  vec_validate (vui->per_cpu_tx_qid,
		vlib_get_thread_main ()->n_vlib_mains - 1);
  vhost_user_tx_thread_placement (vui);
}

static uword
vhost_user_send_interrupt_process (vlib_main_t * vm,
				   vlib_node_runtime_t * rt, vlib_frame_t * f)
{
  vhost_user_intf_t *vui;
  f64 timeout = 3153600000.0 /* 100 years */ ;
  uword event_type, *event_data = 0;
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_iface_and_queue_t *vhiq;
  vhost_cpu_t *vhc;
  f64 now, poll_time_remaining;

  while (1)
    {
      poll_time_remaining =
	vlib_process_wait_for_event_or_clock (vm, timeout);
      event_type = vlib_process_get_events (vm, &event_data);
      vec_reset_length (event_data);

      /*
       * Use the remaining timeout if it is less than coalesce time to avoid
       * resetting the existing timer in the middle of expiration
       */
      timeout = poll_time_remaining;
      if (vlib_process_suspend_time_is_zero (timeout) ||
	  (timeout > vum->coalesce_time))
	timeout = vum->coalesce_time;

      now = vlib_time_now (vm);
      switch (event_type)
	{
	case VHOST_USER_EVENT_START_TIMER:
	  if (!vlib_process_suspend_time_is_zero (poll_time_remaining))
	    break;
	  /* fall through */

	case ~0:
	  vec_foreach (vhc, vum->cpus)
	  {
	    u32 thread_index = vhc - vum->cpus;
	    f64 next_timeout;

	    next_timeout = timeout;
	    vec_foreach (vhiq, vum->cpus[thread_index].rx_queues)
	    {
	      vui = &vum->vhost_user_interfaces[vhiq->vhost_iface_index];
	      vhost_user_vring_t *rxvq =
		&vui->vrings[VHOST_VRING_IDX_RX (vhiq->qid)];
	      vhost_user_vring_t *txvq =
		&vui->vrings[VHOST_VRING_IDX_TX (vhiq->qid)];

	      if (txvq->n_since_last_int)
		{
		  if (now >= txvq->int_deadline)
		    vhost_user_send_call (vm, txvq);
		  else
		    next_timeout = txvq->int_deadline - now;
		}

	      if (rxvq->n_since_last_int)
		{
		  if (now >= rxvq->int_deadline)
		    vhost_user_send_call (vm, rxvq);
		  else
		    next_timeout = rxvq->int_deadline - now;
		}

	      if ((next_timeout < timeout) && (next_timeout > 0.0))
		timeout = next_timeout;
	    }
	  }
	  break;

	default:
	  clib_warning ("BUG: unhandled event type %d", event_type);
	  break;
	}
      /* No less than 1 millisecond */
      if (timeout < 1e-3)
	timeout = 1e-3;
    }
  return 0;
}

/* *INDENT-OFF* */
VLIB_REGISTER_NODE (vhost_user_send_interrupt_node,static) = {
    .function = vhost_user_send_interrupt_process,
    .type = VLIB_NODE_TYPE_PROCESS,
    .name = "vhost-user-send-interrupt-process",
};
/* *INDENT-ON* */

int
vhost_user_create_if (vnet_main_t * vnm, vlib_main_t * vm,
		      const char *sock_filename,
		      u8 is_server,
		      u32 * sw_if_index,
		      u64 feature_mask,
		      u8 renumber, u32 custom_dev_instance, u8 * hwaddr,
		      u8 operation_mode)
{
  vhost_user_intf_t *vui = NULL;
  u32 sw_if_idx = ~0;
  int rv = 0;
  int server_sock_fd = -1;
  vhost_user_main_t *vum = &vhost_user_main;
  uword *if_index;

  if ((operation_mode != VHOST_USER_POLLING_MODE) &&
      (operation_mode != VHOST_USER_INTERRUPT_MODE))
    return VNET_API_ERROR_UNIMPLEMENTED;

  if (sock_filename == NULL || !(strlen (sock_filename) > 0))
    {
      return VNET_API_ERROR_INVALID_ARGUMENT;
    }

  if_index = mhash_get (&vum->if_index_by_sock_name, (void *) sock_filename);
  if (if_index)
    {
      if (sw_if_index)
	{
	  vui = &vum->vhost_user_interfaces[*if_index];
	  *sw_if_index = vui->sw_if_index;
	}
      return VNET_API_ERROR_IF_ALREADY_EXISTS;
    }

  if (is_server)
    {
      if ((rv =
	   vhost_user_init_server_sock (sock_filename, &server_sock_fd)) != 0)
	{
	  return rv;
	}
    }

  pool_get (vhost_user_main.vhost_user_interfaces, vui);

  vhost_user_create_ethernet (vnm, vm, vui, hwaddr);
  vhost_user_vui_init (vnm, vui, server_sock_fd, sock_filename,
		       feature_mask, &sw_if_idx, operation_mode);

  if (renumber)
    vnet_interface_name_renumber (sw_if_idx, custom_dev_instance);

  if (sw_if_index)
    *sw_if_index = sw_if_idx;

  // Process node must connect
  vlib_process_signal_event (vm, vhost_user_process_node.index, 0, 0);

  if ((operation_mode == VHOST_USER_INTERRUPT_MODE) &&
      !vum->interrupt_mode && (vum->coalesce_time > 0.0) &&
      (vum->coalesce_frames > 0))
    {
      vum->interrupt_mode = 1;
      vlib_process_signal_event (vm, vhost_user_send_interrupt_node.index,
				 VHOST_USER_EVENT_START_TIMER, 0);
    }
  return rv;
}

int
vhost_user_modify_if (vnet_main_t * vnm, vlib_main_t * vm,
		      const char *sock_filename,
		      u8 is_server,
		      u32 sw_if_index,
		      u64 feature_mask, u8 renumber, u32 custom_dev_instance,
		      u8 operation_mode)
{
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui = NULL;
  u32 sw_if_idx = ~0;
  int server_sock_fd = -1;
  int rv = 0;
  vnet_hw_interface_t *hwif;
  uword *if_index;

  if ((operation_mode != VHOST_USER_POLLING_MODE) &&
      (operation_mode != VHOST_USER_INTERRUPT_MODE))
    return VNET_API_ERROR_UNIMPLEMENTED;
  if (!(hwif = vnet_get_sup_hw_interface (vnm, sw_if_index)) ||
      hwif->dev_class_index != vhost_user_dev_class.index)
    return VNET_API_ERROR_INVALID_SW_IF_INDEX;

  if (sock_filename == NULL || !(strlen (sock_filename) > 0))
    return VNET_API_ERROR_INVALID_ARGUMENT;

  vui = vec_elt_at_index (vum->vhost_user_interfaces, hwif->dev_instance);

  /*
   * Disallow changing the interface to have the same path name
   * as other interface
   */
  if_index = mhash_get (&vum->if_index_by_sock_name, (void *) sock_filename);
  if (if_index && (*if_index != vui->if_index))
    return VNET_API_ERROR_IF_ALREADY_EXISTS;

  // First try to open server socket
  if (is_server)
    if ((rv = vhost_user_init_server_sock (sock_filename,
					   &server_sock_fd)) != 0)
      return rv;

  vhost_user_term_if (vui);
  vhost_user_vui_init (vnm, vui, server_sock_fd,
		       sock_filename, feature_mask, &sw_if_idx,
		       operation_mode);

  if (renumber)
    vnet_interface_name_renumber (sw_if_idx, custom_dev_instance);

  // Process node must connect
  vlib_process_signal_event (vm, vhost_user_process_node.index, 0, 0);

  if ((operation_mode == VHOST_USER_INTERRUPT_MODE) &&
      !vum->interrupt_mode && (vum->coalesce_time > 0.0) &&
      (vum->coalesce_frames > 0))
    {
      vum->interrupt_mode = 1;
      vlib_process_signal_event (vm, vhost_user_send_interrupt_node.index,
				 VHOST_USER_EVENT_START_TIMER, 0);
    }
  return rv;
}

static uword
unformat_vhost_user_operation_mode (unformat_input_t * input, va_list * args)
{
  u8 *operation_mode = va_arg (*args, u8 *);
  uword rc = 1;

  if (unformat (input, "interrupt"))
    *operation_mode = VHOST_USER_INTERRUPT_MODE;
  else if (unformat (input, "polling"))
    *operation_mode = VHOST_USER_POLLING_MODE;
  else
    rc = 0;

  return rc;
}

clib_error_t *
vhost_user_connect_command_fn (vlib_main_t * vm,
			       unformat_input_t * input,
			       vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u8 *sock_filename = NULL;
  u32 sw_if_index;
  u8 is_server = 0;
  u64 feature_mask = (u64) ~ (0ULL);
  u8 renumber = 0;
  u32 custom_dev_instance = ~0;
  u8 hwaddr[6];
  u8 *hw = NULL;
  clib_error_t *error = NULL;
  u8 operation_mode = VHOST_USER_POLLING_MODE;

  /* Get a line of input. */
  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, "socket %s", &sock_filename))
	;
      else if (unformat (line_input, "server"))
	is_server = 1;
      else if (unformat (line_input, "feature-mask 0x%llx", &feature_mask))
	;
      else
	if (unformat
	    (line_input, "hwaddr %U", unformat_ethernet_address, hwaddr))
	hw = hwaddr;
      else if (unformat (line_input, "renumber %d", &custom_dev_instance))
	{
	  renumber = 1;
	}
      else if (unformat (line_input, "mode %U",
			 unformat_vhost_user_operation_mode, &operation_mode))
	;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  vnet_main_t *vnm = vnet_get_main ();

  int rv;
  if ((rv = vhost_user_create_if (vnm, vm, (char *) sock_filename,
				  is_server, &sw_if_index, feature_mask,
				  renumber, custom_dev_instance, hw,
				  operation_mode)))
    {
      error = clib_error_return (0, "vhost_user_create_if returned %d", rv);
      goto done;
    }

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

done:
  vec_free (sock_filename);
  unformat_free (line_input);

  return error;
}

clib_error_t *
vhost_user_delete_command_fn (vlib_main_t * vm,
			      unformat_input_t * input,
			      vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u32 sw_if_index = ~0;
  vnet_main_t *vnm = vnet_get_main ();
  clib_error_t *error = NULL;

  /* Get a line of input. */
  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, "sw_if_index %d", &sw_if_index))
	;
      else if (unformat
	       (line_input, "%U", unformat_vnet_sw_interface, vnm,
		&sw_if_index))
	{
	  vnet_hw_interface_t *hwif =
	    vnet_get_sup_hw_interface (vnm, sw_if_index);
	  if (hwif == NULL ||
	      vhost_user_dev_class.index != hwif->dev_class_index)
	    {
	      error = clib_error_return (0, "Not a vhost interface");
	      goto done;
	    }
	}
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, line_input);
	  goto done;
	}
    }

  vhost_user_delete_if (vnm, vm, sw_if_index);

done:
  unformat_free (line_input);

  return error;
}

int
vhost_user_dump_ifs (vnet_main_t * vnm, vlib_main_t * vm,
		     vhost_user_intf_details_t ** out_vuids)
{
  int rv = 0;
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;
  vhost_user_intf_details_t *r_vuids = NULL;
  vhost_user_intf_details_t *vuid = NULL;
  u32 *hw_if_indices = 0;
  vnet_hw_interface_t *hi;
  u8 *s = NULL;
  int i;

  if (!out_vuids)
    return -1;

  pool_foreach (vui, vum->vhost_user_interfaces,
		vec_add1 (hw_if_indices, vui->hw_if_index);
    );

  for (i = 0; i < vec_len (hw_if_indices); i++)
    {
      hi = vnet_get_hw_interface (vnm, hw_if_indices[i]);
      vui = pool_elt_at_index (vum->vhost_user_interfaces, hi->dev_instance);

      vec_add2 (r_vuids, vuid, 1);
      vuid->operation_mode = vui->operation_mode;
      vuid->sw_if_index = vui->sw_if_index;
      vuid->virtio_net_hdr_sz = vui->virtio_net_hdr_sz;
      vuid->features = vui->features;
      vuid->num_regions = vui->nregions;
      vuid->is_server = vui->unix_server_index != ~0;
      vuid->sock_errno = vui->sock_errno;
      strncpy ((char *) vuid->sock_filename, (char *) vui->sock_filename,
	       ARRAY_LEN (vuid->sock_filename) - 1);

      s = format (s, "%v%c", hi->name, 0);

      strncpy ((char *) vuid->if_name, (char *) s,
	       ARRAY_LEN (vuid->if_name) - 1);
      _vec_len (s) = 0;
    }

  vec_free (s);
  vec_free (hw_if_indices);

  *out_vuids = r_vuids;

  return rv;
}

static u8 *
format_vhost_user_operation_mode (u8 * s, va_list * va)
{
  int operation_mode = va_arg (*va, int);

  switch (operation_mode)
    {
    case VHOST_USER_POLLING_MODE:
      s = format (s, "%s", "polling");
      break;
    case VHOST_USER_INTERRUPT_MODE:
      s = format (s, "%s", "interrupt");
      break;
    default:
      s = format (s, "%s", "invalid");
    }
  return s;
}

clib_error_t *
show_vhost_user_command_fn (vlib_main_t * vm,
			    unformat_input_t * input,
			    vlib_cli_command_t * cmd)
{
  clib_error_t *error = 0;
  vnet_main_t *vnm = vnet_get_main ();
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;
  u32 hw_if_index, *hw_if_indices = 0;
  vnet_hw_interface_t *hi;
  vhost_cpu_t *vhc;
  vhost_iface_and_queue_t *vhiq;
  u32 ci;

  int i, j, q;
  int show_descr = 0;
  struct feat_struct
  {
    u8 bit;
    char *str;
  };
  struct feat_struct *feat_entry;

  static struct feat_struct feat_array[] = {
#define _(s,b) { .str = #s, .bit = b, },
    foreach_virtio_net_feature
#undef _
    {.str = NULL}
  };

#define foreach_protocol_feature \
  _(VHOST_USER_PROTOCOL_F_MQ) \
  _(VHOST_USER_PROTOCOL_F_LOG_SHMFD)

  static struct feat_struct proto_feat_array[] = {
#define _(s) { .str = #s, .bit = s},
    foreach_protocol_feature
#undef _
    {.str = NULL}
  };

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat
	  (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
	{
	  vec_add1 (hw_if_indices, hw_if_index);
	}
      else if (unformat (input, "descriptors") || unformat (input, "desc"))
	show_descr = 1;
      else
	{
	  error = clib_error_return (0, "unknown input `%U'",
				     format_unformat_error, input);
	  goto done;
	}
    }
  if (vec_len (hw_if_indices) == 0)
    {
      pool_foreach (vui, vum->vhost_user_interfaces,
		    vec_add1 (hw_if_indices, vui->hw_if_index);
	);
    }
  vlib_cli_output (vm, "Virtio vhost-user interfaces");
  vlib_cli_output (vm, "Global:\n  coalesce frames %d time %e",
		   vum->coalesce_frames, vum->coalesce_time);

  for (i = 0; i < vec_len (hw_if_indices); i++)
    {
      hi = vnet_get_hw_interface (vnm, hw_if_indices[i]);
      vui = pool_elt_at_index (vum->vhost_user_interfaces, hi->dev_instance);
      vlib_cli_output (vm, "Interface: %s (ifindex %d)",
		       hi->name, hw_if_indices[i]);

      vlib_cli_output (vm, "virtio_net_hdr_sz %d\n"
		       " features mask (0x%llx): \n"
		       " features (0x%llx): \n",
		       vui->virtio_net_hdr_sz, vui->feature_mask,
		       vui->features);

      feat_entry = (struct feat_struct *) &feat_array;
      while (feat_entry->str)
	{
	  if (vui->features & (1ULL << feat_entry->bit))
	    vlib_cli_output (vm, "   %s (%d)", feat_entry->str,
			     feat_entry->bit);
	  feat_entry++;
	}

      vlib_cli_output (vm, "  protocol features (0x%llx)",
		       vui->protocol_features);
      feat_entry = (struct feat_struct *) &proto_feat_array;
      while (feat_entry->str)
	{
	  if (vui->protocol_features & (1ULL << feat_entry->bit))
	    vlib_cli_output (vm, "   %s (%d)", feat_entry->str,
			     feat_entry->bit);
	  feat_entry++;
	}

      vlib_cli_output (vm, "\n");

      vlib_cli_output (vm, " socket filename %s type %s errno \"%s\"\n\n",
		       vui->sock_filename,
		       (vui->unix_server_index != ~0) ? "server" : "client",
		       strerror (vui->sock_errno));

      vlib_cli_output (vm, " configured mode: %U\n",
		       format_vhost_user_operation_mode, vui->operation_mode);
      vlib_cli_output (vm, " rx placement: ");
      vec_foreach (vhc, vum->cpus)
      {
	vec_foreach (vhiq, vhc->rx_queues)
	{
	  if (vhiq->vhost_iface_index == vui - vum->vhost_user_interfaces)
	    {
	      vlib_cli_output (vm, "   thread %d on vring %d\n",
			       vhc - vum->cpus,
			       VHOST_VRING_IDX_TX (vhiq->qid));
	      vlib_cli_output (vm, "   mode: %U\n",
			       format_vhost_user_operation_mode,
			       vhc->operation_mode);
	    }
	}
      }

      vlib_cli_output (vm, " tx placement: %s\n",
		       vui->use_tx_spinlock ? "spin-lock" : "lock-free");

      vec_foreach_index (ci, vui->per_cpu_tx_qid)
      {
	vlib_cli_output (vm, "   thread %d on vring %d\n", ci,
			 VHOST_VRING_IDX_RX (vui->per_cpu_tx_qid[ci]));
      }

      vlib_cli_output (vm, "\n");

      vlib_cli_output (vm, " Memory regions (total %d)\n", vui->nregions);

      if (vui->nregions)
	{
	  vlib_cli_output (vm,
			   " region fd    guest_phys_addr    memory_size        userspace_addr     mmap_offset        mmap_addr\n");
	  vlib_cli_output (vm,
			   " ====== ===== ================== ================== ================== ================== ==================\n");
	}
      for (j = 0; j < vui->nregions; j++)
	{
	  vlib_cli_output (vm,
			   "  %d     %-5d 0x%016lx 0x%016lx 0x%016lx 0x%016lx 0x%016lx\n",
			   j, vui->region_mmap_fd[j],
			   vui->regions[j].guest_phys_addr,
			   vui->regions[j].memory_size,
			   vui->regions[j].userspace_addr,
			   vui->regions[j].mmap_offset,
			   pointer_to_uword (vui->region_mmap_addr[j]));
	}
      for (q = 0; q < VHOST_VRING_MAX_N; q++)
	{
	  if (!vui->vrings[q].started)
	    continue;

	  vlib_cli_output (vm, "\n Virtqueue %d (%s%s)\n", q,
			   (q & 1) ? "RX" : "TX",
			   vui->vrings[q].enabled ? "" : " disabled");

	  vlib_cli_output (vm,
			   "  qsz %d last_avail_idx %d last_used_idx %d\n",
			   vui->vrings[q].qsz, vui->vrings[q].last_avail_idx,
			   vui->vrings[q].last_used_idx);

	  if (vui->vrings[q].avail && vui->vrings[q].used)
	    vlib_cli_output (vm,
			     "  avail.flags %x avail.idx %d used.flags %x used.idx %d\n",
			     vui->vrings[q].avail->flags,
			     vui->vrings[q].avail->idx,
			     vui->vrings[q].used->flags,
			     vui->vrings[q].used->idx);

	  int kickfd = UNIX_GET_FD (vui->vrings[q].kickfd_idx);
	  int callfd = UNIX_GET_FD (vui->vrings[q].callfd_idx);
	  vlib_cli_output (vm, "  kickfd %d callfd %d errfd %d\n",
			   kickfd, callfd, vui->vrings[q].errfd);

	  if (show_descr)
	    {
	      vlib_cli_output (vm, "\n  descriptor table:\n");
	      vlib_cli_output (vm,
			       "   id          addr         len  flags  next      user_addr\n");
	      vlib_cli_output (vm,
			       "  ===== ================== ===== ====== ===== ==================\n");
	      for (j = 0; j < vui->vrings[q].qsz; j++)
		{
		  u32 mem_hint = 0;
		  vlib_cli_output (vm,
				   "  %-5d 0x%016lx %-5d 0x%04x %-5d 0x%016lx\n",
				   j, vui->vrings[q].desc[j].addr,
				   vui->vrings[q].desc[j].len,
				   vui->vrings[q].desc[j].flags,
				   vui->vrings[q].desc[j].next,
				   pointer_to_uword (map_guest_mem
						     (vui,
						      vui->vrings[q].desc[j].
						      addr, &mem_hint)));
		}
	    }
	}
      vlib_cli_output (vm, "\n");
    }
done:
  vec_free (hw_if_indices);
  return error;
}

/*
 * CLI functions
 */

/*?
 * Create a vHost User interface. Once created, a new virtual interface
 * will exist with the name '<em>VirtualEthernet0/0/x</em>', where '<em>x</em>'
 * is the next free index.
 *
 * There are several parameters associated with a vHost interface:
 *
 * - <b>socket <socket-filename></b> - Name of the linux socket used by QEMU/VM and
 * VPP to manage the vHost interface. If socket does not already exist, VPP will
 * create the socket.
 *
 * - <b>server</b> - Optional flag to indicate that VPP should be the server for the
 * linux socket. If not provided, VPP will be the client.
 *
 * - <b>feature-mask <hex></b> - Optional virtio/vhost feature set negotiated at
 * startup. By default, all supported features will be advertised. Otherwise,
 * provide the set of features desired.
 *   - 0x000008000 (15) - VIRTIO_NET_F_MRG_RXBUF
 *   - 0x000020000 (17) - VIRTIO_NET_F_CTRL_VQ
 *   - 0x000200000 (21) - VIRTIO_NET_F_GUEST_ANNOUNCE
 *   - 0x000400000 (22) - VIRTIO_NET_F_MQ
 *   - 0x004000000 (26) - VHOST_F_LOG_ALL
 *   - 0x008000000 (27) - VIRTIO_F_ANY_LAYOUT
 *   - 0x010000000 (28) - VIRTIO_F_INDIRECT_DESC
 *   - 0x040000000 (30) - VHOST_USER_F_PROTOCOL_FEATURES
 *   - 0x100000000 (32) - VIRTIO_F_VERSION_1
 *
 * - <b>hwaddr <mac-addr></b> - Optional ethernet address, can be in either
 * X:X:X:X:X:X unix or X.X.X cisco format.
 *
 * - <b>renumber <dev_instance></b> - Optional parameter which allows the instance
 * in the name to be specified. If instance already exists, name will be used
 * anyway and multiple instances will have the same name. Use with caution.
 *
 * - <b>mode [interrupt | polling]</b> - Optional parameter specifying
 * the input thread polling policy.
 *
 * @cliexpar
 * Example of how to create a vhost interface with VPP as the client and all features enabled:
 * @cliexstart{create vhost-user socket /tmp/vhost1.sock}
 * VirtualEthernet0/0/0
 * @cliexend
 * Example of how to create a vhost interface with VPP as the server and with just
 * multiple queues enabled:
 * @cliexstart{create vhost-user socket /tmp/vhost2.sock server feature-mask 0x40400000}
 * VirtualEthernet0/0/1
 * @cliexend
 * Once the vHost interface is created, enable the interface using:
 * @cliexcmd{set interface state VirtualEthernet0/0/0 up}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (vhost_user_connect_command, static) = {
    .path = "create vhost-user",
    .short_help = "create vhost-user socket <socket-filename> [server] "
    "[feature-mask <hex>] [hwaddr <mac-addr>] [renumber <dev_instance>] "
    "[mode {interrupt | polling}]",
    .function = vhost_user_connect_command_fn,
};
/* *INDENT-ON* */

/*?
 * Delete a vHost User interface using the interface name or the
 * software interface index. Use the '<em>show interface</em>'
 * command to determine the software interface index. On deletion,
 * the linux socket will not be deleted.
 *
 * @cliexpar
 * Example of how to delete a vhost interface by name:
 * @cliexcmd{delete vhost-user VirtualEthernet0/0/1}
 * Example of how to delete a vhost interface by software interface index:
 * @cliexcmd{delete vhost-user sw_if_index 1}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (vhost_user_delete_command, static) = {
    .path = "delete vhost-user",
    .short_help = "delete vhost-user {<interface> | sw_if_index <sw_idx>}",
    .function = vhost_user_delete_command_fn,
};

/*?
 * Display the attributes of a single vHost User interface (provide interface
 * name), multiple vHost User interfaces (provide a list of interface names seperated
 * by spaces) or all Vhost User interfaces (omit an interface name to display all
 * vHost interfaces).
 *
 * @cliexpar
 * @parblock
 * Example of how to display a vhost interface:
 * @cliexstart{show vhost-user VirtualEthernet0/0/0}
 * Virtio vhost-user interfaces
 * Global:
 *   coalesce frames 32 time 1e-3
 * Interface: VirtualEthernet0/0/0 (ifindex 1)
 * virtio_net_hdr_sz 12
 *  features mask (0xffffffffffffffff):
 *  features (0x50408000):
 *    VIRTIO_NET_F_MRG_RXBUF (15)
 *    VIRTIO_NET_F_MQ (22)
 *    VIRTIO_F_INDIRECT_DESC (28)
 *    VHOST_USER_F_PROTOCOL_FEATURES (30)
 *   protocol features (0x3)
 *    VHOST_USER_PROTOCOL_F_MQ (0)
 *    VHOST_USER_PROTOCOL_F_LOG_SHMFD (1)
 *
 *  socket filename /tmp/vhost1.sock type client errno "Success"
 *
 * rx placement:
 *    thread 1 on vring 1
 *    thread 1 on vring 5
 *    thread 2 on vring 3
 *    thread 2 on vring 7
 *  tx placement: spin-lock
 *    thread 0 on vring 0
 *    thread 1 on vring 2
 *    thread 2 on vring 0
 *
 * Memory regions (total 2)
 * region fd    guest_phys_addr    memory_size        userspace_addr     mmap_offset        mmap_addr
 * ====== ===== ================== ================== ================== ================== ==================
 *   0     60    0x0000000000000000 0x00000000000a0000 0x00002aaaaac00000 0x0000000000000000 0x00002aab2b400000
 *   1     61    0x00000000000c0000 0x000000003ff40000 0x00002aaaaacc0000 0x00000000000c0000 0x00002aababcc0000
 *
 *  Virtqueue 0 (TX)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 *   avail.flags 1 avail.idx 128 used.flags 1 used.idx 0
 *   kickfd 62 callfd 64 errfd -1
 *
 *  Virtqueue 1 (RX)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 *   avail.flags 1 avail.idx 0 used.flags 1 used.idx 0
 *   kickfd 65 callfd 66 errfd -1
 *
 *  Virtqueue 2 (TX)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 *   avail.flags 1 avail.idx 128 used.flags 1 used.idx 0
 *   kickfd 63 callfd 70 errfd -1
 *
 *  Virtqueue 3 (RX)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 *   avail.flags 1 avail.idx 0 used.flags 1 used.idx 0
 *   kickfd 72 callfd 74 errfd -1
 *
 *  Virtqueue 4 (TX disabled)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 *   avail.flags 1 avail.idx 0 used.flags 1 used.idx 0
 *   kickfd 76 callfd 78 errfd -1
 *
 *  Virtqueue 5 (RX disabled)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 *   avail.flags 1 avail.idx 0 used.flags 1 used.idx 0
 *   kickfd 80 callfd 82 errfd -1
 *
 *  Virtqueue 6 (TX disabled)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 *  avail.flags 1 avail.idx 0 used.flags 1 used.idx 0
 *   kickfd 84 callfd 86 errfd -1
 *
 *  Virtqueue 7 (RX disabled)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 *   avail.flags 1 avail.idx 0 used.flags 1 used.idx 0
 *   kickfd 88 callfd 90 errfd -1
 *
 * @cliexend
 *
 * The optional '<em>descriptors</em>' parameter will display the same output as
 * the previous example but will include the descriptor table for each queue.
 * The output is truncated below:
 * @cliexstart{show vhost-user VirtualEthernet0/0/0 descriptors}
 * Virtio vhost-user interfaces
 * Global:
 *   coalesce frames 32 time 1e-3
 * Interface: VirtualEthernet0/0/0 (ifindex 1)
 * virtio_net_hdr_sz 12
 *  features mask (0xffffffffffffffff):
 *  features (0x50408000):
 *    VIRTIO_NET_F_MRG_RXBUF (15)
 *    VIRTIO_NET_F_MQ (22)
 * :
 *  Virtqueue 0 (TX)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 *   avail.flags 1 avail.idx 128 used.flags 1 used.idx 0
 *   kickfd 62 callfd 64 errfd -1
 *
 *   descriptor table:
 *    id          addr         len  flags  next      user_addr
 *   ===== ================== ===== ====== ===== ==================
 *   0     0x0000000010b6e974 2060  0x0002 1     0x00002aabbc76e974
 *   1     0x0000000010b6e034 2060  0x0002 2     0x00002aabbc76e034
 *   2     0x0000000010b6d6f4 2060  0x0002 3     0x00002aabbc76d6f4
 *   3     0x0000000010b6cdb4 2060  0x0002 4     0x00002aabbc76cdb4
 *   4     0x0000000010b6c474 2060  0x0002 5     0x00002aabbc76c474
 *   5     0x0000000010b6bb34 2060  0x0002 6     0x00002aabbc76bb34
 *   6     0x0000000010b6b1f4 2060  0x0002 7     0x00002aabbc76b1f4
 *   7     0x0000000010b6a8b4 2060  0x0002 8     0x00002aabbc76a8b4
 *   8     0x0000000010b69f74 2060  0x0002 9     0x00002aabbc769f74
 *   9     0x0000000010b69634 2060  0x0002 10    0x00002aabbc769634
 *   10    0x0000000010b68cf4 2060  0x0002 11    0x00002aabbc768cf4
 * :
 *   249   0x0000000000000000 0     0x0000 250   0x00002aab2b400000
 *   250   0x0000000000000000 0     0x0000 251   0x00002aab2b400000
 *   251   0x0000000000000000 0     0x0000 252   0x00002aab2b400000
 *   252   0x0000000000000000 0     0x0000 253   0x00002aab2b400000
 *   253   0x0000000000000000 0     0x0000 254   0x00002aab2b400000
 *   254   0x0000000000000000 0     0x0000 255   0x00002aab2b400000
 *   255   0x0000000000000000 0     0x0000 32768 0x00002aab2b400000
 *
 *  Virtqueue 1 (RX)
 *   qsz 256 last_avail_idx 0 last_used_idx 0
 * :
 * @cliexend
 * @endparblock
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (show_vhost_user_command, static) = {
    .path = "show vhost-user",
    .short_help = "show vhost-user [<interface> [<interface> [..]]] [descriptors]",
    .function = show_vhost_user_command_fn,
};
/* *INDENT-ON* */

static clib_error_t *
vhost_user_config (vlib_main_t * vm, unformat_input_t * input)
{
  vhost_user_main_t *vum = &vhost_user_main;

  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
    {
      if (unformat (input, "coalesce-frames %d", &vum->coalesce_frames))
	;
      else if (unformat (input, "coalesce-time %f", &vum->coalesce_time))
	;
      else if (unformat (input, "dont-dump-memory"))
	vum->dont_dump_vhost_user_memory = 1;
      else
	return clib_error_return (0, "unknown input `%U'",
				  format_unformat_error, input);
    }

  return 0;
}

/* vhost-user { ... } configuration. */
VLIB_CONFIG_FUNCTION (vhost_user_config, "vhost-user");

void
vhost_user_unmap_all (void)
{
  vhost_user_main_t *vum = &vhost_user_main;
  vhost_user_intf_t *vui;

  if (vum->dont_dump_vhost_user_memory)
    {
      pool_foreach (vui, vum->vhost_user_interfaces,
		    unmap_all_mem_regions (vui);
	);
    }
}

static clib_error_t *
vhost_thread_command_fn (vlib_main_t * vm,
			 unformat_input_t * input, vlib_cli_command_t * cmd)
{
  unformat_input_t _line_input, *line_input = &_line_input;
  u32 worker_thread_index;
  u32 sw_if_index;
  u8 del = 0;
  int rv;
  clib_error_t *error = NULL;

  /* Get a line of input. */
  if (!unformat_user (input, unformat_line_input, line_input))
    return 0;

  if (!unformat
      (line_input, "%U %d", unformat_vnet_sw_interface, vnet_get_main (),
       &sw_if_index, &worker_thread_index))
    {
      error = clib_error_return (0, "unknown input `%U'",
				 format_unformat_error, line_input);
      goto done;
    }

  if (unformat (line_input, "del"))
    del = 1;

  if ((rv =
       vhost_user_thread_placement (sw_if_index, worker_thread_index, del)))
    {
      error = clib_error_return (0, "vhost_user_thread_placement returned %d",
				 rv);
      goto done;
    }

done:
  unformat_free (line_input);

  return error;
}


/*?
 * This command is used to move the RX processing for the given
 * interfaces to the provided thread. If the '<em>del</em>' option is used,
 * the forced thread assignment is removed and the thread assigment is
 * reassigned automatically. Use '<em>show vhost-user <interface></em>'
 * to see the thread assignment.
 *
 * @cliexpar
 * Example of how to move the RX processing for a given interface to a given thread:
 * @cliexcmd{vhost thread VirtualEthernet0/0/0 1}
 * Example of how to remove the forced thread assignment for a given interface:
 * @cliexcmd{vhost thread VirtualEthernet0/0/0 1 del}
?*/
/* *INDENT-OFF* */
VLIB_CLI_COMMAND (vhost_user_thread_command, static) = {
    .path = "vhost thread",
    .short_help = "vhost thread <iface> <worker-index> [del]",
    .function = vhost_thread_command_fn,
};
/* *INDENT-ON* */

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