move unix_file_* code to vppinfra
[vpp.git] / src / plugins / memif / memif.c
index f082b58..8fec409 100644 (file)
@@ -33,6 +33,7 @@
 
 #include <vlib/vlib.h>
 #include <vlib/unix/unix.h>
+#include <vlib/linux/syscall.h>
 #include <vnet/plugin/plugin.h>
 #include <vnet/ethernet/ethernet.h>
 #include <vpp/app/version.h>
@@ -51,10 +52,10 @@ memif_eth_flag_change (vnet_main_t * vnm, vnet_hw_interface_t * hi, u32 flags)
 static void
 memif_queue_intfd_close (memif_queue_t * mq)
 {
-  if (mq->int_unix_file_index != ~0)
+  if (mq->int_clib_file_index != ~0)
     {
-      memif_file_del_by_index (mq->int_unix_file_index);
-      mq->int_unix_file_index = ~0;
+      memif_file_del_by_index (mq->int_clib_file_index);
+      mq->int_clib_file_index = ~0;
       mq->int_fd = -1;
     }
   else if (mq->int_fd > -1)
@@ -67,6 +68,7 @@ memif_queue_intfd_close (memif_queue_t * mq)
 void
 memif_disconnect (memif_if_t * mif, clib_error_t * err)
 {
+  memif_main_t *mm = &memif_main;
   vnet_main_t *vnm = vnet_get_main ();
   memif_region_t *mr;
   memif_queue_t *mq;
@@ -92,10 +94,13 @@ memif_disconnect (memif_if_t * mif, clib_error_t * err)
     vnet_hw_interface_set_flags (vnm, mif->hw_if_index, 0);
 
   /* close connection socket */
-  if (mif->conn_unix_file_index != ~0)
+  if (mif->conn_clib_file_index != ~0)
     {
-      memif_file_del_by_index (mif->conn_unix_file_index);
-      mif->conn_unix_file_index = ~0;
+      memif_socket_file_t *msf = vec_elt_at_index (mm->socket_files,
+                                                  mif->socket_file_index);
+      hash_unset (msf->dev_instance_by_fd, mif->conn_fd);
+      memif_file_del_by_index (mif->conn_clib_file_index);
+      mif->conn_clib_file_index = ~0;
     }
   else if (mif->conn_fd > -1)
     close (mif->conn_fd);
@@ -140,7 +145,7 @@ memif_disconnect (memif_if_t * mif, clib_error_t * err)
 }
 
 static clib_error_t *
-memif_int_fd_read_ready (unix_file_t * uf)
+memif_int_fd_read_ready (clib_file_t * uf)
 {
   memif_main_t *mm = &memif_main;
   vnet_main_t *vnm = vnet_get_main ();
@@ -168,7 +173,7 @@ clib_error_t *
 memif_connect (memif_if_t * mif)
 {
   vnet_main_t *vnm = vnet_get_main ();
-  unix_file_t template = { 0 };
+  clib_file_t template = { 0 };
   memif_region_t *mr;
   int i;
 
@@ -214,15 +219,23 @@ memif_connect (memif_if_t * mif)
       {
        template.file_descriptor = mq->int_fd;
        template.private_data = (mif->dev_instance << 16) | (i & 0xFFFF);
-       memif_file_add (&mq->int_unix_file_index, &template);
+       memif_file_add (&mq->int_clib_file_index, &template);
       }
     vnet_hw_interface_assign_rx_thread (vnm, mif->hw_if_index, i, ~0);
     rv = vnet_hw_interface_set_rx_mode (vnm, mif->hw_if_index, i,
-                                       VNET_HW_INTERFACE_RX_MODE_INTERRUPT);
+                                       VNET_HW_INTERFACE_RX_MODE_DEFAULT);
     if (rv)
       clib_warning
        ("Warning: unable to set rx mode for interface %d queue %d: "
         "rc=%d", mif->hw_if_index, i, rv);
+    else
+      {
+       vnet_hw_interface_rx_mode rxmode;
+       vnet_hw_interface_get_rx_mode (vnm, mif->hw_if_index, i, &rxmode);
+
+       if (rxmode == VNET_HW_INTERFACE_RX_MODE_POLLING)
+         mq->ring->flags |= MEMIF_RING_FLAG_MASK_INT;
+      }
   }
 
   mif->flags &= ~MEMIF_IF_FLAG_CONNECTING;
@@ -317,7 +330,7 @@ memif_init_regions_and_queues (memif_if_t * mif)
     memif_queue_t *mq = vec_elt_at_index (mif->tx_queues, i);
     if ((mq->int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
       return clib_error_return_unix (0, "eventfd[tx queue %u]", i);
-    mq->int_unix_file_index = ~0;
+    mq->int_clib_file_index = ~0;
     mq->ring = memif_get_ring (mif, MEMIF_RING_S2M, i);
     mq->log2_ring_size = mif->cfg.log2_ring_size;
     mq->region = 0;
@@ -333,7 +346,7 @@ memif_init_regions_and_queues (memif_if_t * mif)
     memif_queue_t *mq = vec_elt_at_index (mif->rx_queues, i);
     if ((mq->int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
       return clib_error_return_unix (0, "eventfd[rx queue %u]", i);
-    mq->int_unix_file_index = ~0;
+    mq->int_clib_file_index = ~0;
     mq->ring = memif_get_ring (mif, MEMIF_RING_M2S, i);
     mq->log2_ring_size = mif->cfg.log2_ring_size;
     mq->region = 0;
@@ -419,7 +432,7 @@ memif_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
                  (sockfd, (struct sockaddr *) &sun,
                   sizeof (struct sockaddr_un)) == 0)
                {
-                 unix_file_t t = { 0 };
+                 clib_file_t t = { 0 };
 
                  mif->conn_fd = sockfd;
                  t.read_function = memif_slave_conn_fd_read_ready;
@@ -427,7 +440,7 @@ memif_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
                  t.error_function = memif_slave_conn_fd_error;
                  t.file_descriptor = mif->conn_fd;
                  t.private_data = mif->dev_instance;
-                 memif_file_add (&mif->conn_unix_file_index, &t);
+                 memif_file_add (&mif->conn_clib_file_index, &t);
                  hash_set (msf->dev_instance_by_fd, mif->conn_fd, mif->dev_instance);
 
                  mif->flags |= MEMIF_IF_FLAG_CONNECTING;
@@ -478,7 +491,10 @@ memif_delete_if (vlib_main_t * vm, memif_if_t * mif)
   clib_error_free (err);
 
   /* remove the interface */
-  ethernet_delete_interface (vnm, mif->hw_if_index);
+  if (mif->mode == MEMIF_INTERFACE_MODE_IP)
+    vnet_delete_hw_interface (vnm, mif->hw_if_index);
+  else
+    ethernet_delete_interface (vnm, mif->hw_if_index);
   mif->hw_if_index = ~0;
 
   /* free interface data structures */
@@ -491,7 +507,7 @@ memif_delete_if (vlib_main_t * vm, memif_if_t * mif)
       if (msf->is_listener)
        {
          uword *x;
-         memif_file_del_by_index (msf->unix_file_index);
+         memif_file_del_by_index (msf->clib_file_index);
          vec_foreach (x, msf->pending_file_indices)
          {
            memif_file_del_by_index (*x);
@@ -515,6 +531,14 @@ memif_delete_if (vlib_main_t * vm, memif_if_t * mif)
   return 0;
 }
 
+/* *INDENT-OFF* */
+VNET_HW_INTERFACE_CLASS (memif_ip_hw_if_class, static) =
+{
+  .name = "memif-ip",
+  .flags = VNET_HW_INTERFACE_CLASS_FLAG_P2P,
+};
+/* *INDENT-ON* */
+
 int
 memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
 {
@@ -533,15 +557,19 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
 
   if (args->socket_filename == 0 || args->socket_filename[0] != '/')
     {
-      rv = mkdir (MEMIF_DEFAULT_SOCKET_DIR, 0755);
-      if (rv && errno != EEXIST)
-       return VNET_API_ERROR_SYSCALL_ERROR_1;
+      clib_error_t *error;
+      error = vlib_unix_recursive_mkdir (vlib_unix_get_runtime_dir ());
+      if (error)
+       {
+         clib_error_free (error);
+         return VNET_API_ERROR_SYSCALL_ERROR_1;
+       }
 
       if (args->socket_filename == 0)
-       socket_filename = format (0, "%s/%s%c", MEMIF_DEFAULT_SOCKET_DIR,
+       socket_filename = format (0, "%s/%s%c", vlib_unix_get_runtime_dir (),
                                  MEMIF_DEFAULT_SOCKET_FILENAME, 0);
       else
-       socket_filename = format (0, "%s/%s%c", MEMIF_DEFAULT_SOCKET_DIR,
+       socket_filename = format (0, "%s/%s%c", vlib_unix_get_runtime_dir (),
                                  args->socket_filename, 0);
 
     }
@@ -584,8 +612,11 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
            }
          else
            {
-             ret = VNET_API_ERROR_SYSCALL_ERROR_3;
-             goto error;
+             error = clib_error_return (0, "File exists for %s",
+                                        socket_filename);
+             clib_error_report (error);
+             rv = VNET_API_ERROR_VALUE_EXIST;
+             goto done;
            }
        }
       pool_get (mm->socket_files, msf);
@@ -608,30 +639,45 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
   mif->socket_file_index = msf - mm->socket_files;
   mif->id = args->id;
   mif->sw_if_index = mif->hw_if_index = mif->per_interface_next_index = ~0;
-  mif->conn_unix_file_index = ~0;
+  mif->conn_clib_file_index = ~0;
   mif->conn_fd = -1;
+  mif->mode = args->mode;
   if (args->secret)
     mif->secret = vec_dup (args->secret);
 
   if (tm->n_vlib_mains > 1)
     clib_spinlock_init (&mif->lockp);
 
-  if (!args->hw_addr_set)
+
+  if (mif->mode == MEMIF_INTERFACE_MODE_ETHERNET)
     {
-      f64 now = vlib_time_now (vm);
-      u32 rnd;
-      rnd = (u32) (now * 1e6);
-      rnd = random_u32 (&rnd);
-
-      memcpy (args->hw_addr + 2, &rnd, sizeof (rnd));
-      args->hw_addr[0] = 2;
-      args->hw_addr[1] = 0xfe;
-    }
 
-  error = ethernet_register_interface (vnm, memif_device_class.index,
-                                      mif->dev_instance, args->hw_addr,
-                                      &mif->hw_if_index,
-                                      memif_eth_flag_change);
+      if (!args->hw_addr_set)
+       {
+         f64 now = vlib_time_now (vm);
+         u32 rnd;
+         rnd = (u32) (now * 1e6);
+         rnd = random_u32 (&rnd);
+
+         memcpy (args->hw_addr + 2, &rnd, sizeof (rnd));
+         args->hw_addr[0] = 2;
+         args->hw_addr[1] = 0xfe;
+       }
+      error = ethernet_register_interface (vnm, memif_device_class.index,
+                                          mif->dev_instance, args->hw_addr,
+                                          &mif->hw_if_index,
+                                          memif_eth_flag_change);
+    }
+  else if (mif->mode == MEMIF_INTERFACE_MODE_IP)
+    {
+      mif->hw_if_index =
+       vnet_register_interface (vnm, memif_device_class.index,
+                                mif->dev_instance,
+                                memif_ip_hw_if_class.index,
+                                mif->dev_instance);
+    }
+  else
+    error = clib_error_return (0, "unsupported interface mode");
 
   if (error)
     {
@@ -691,12 +737,12 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
          goto error;
        }
 
-      msf->unix_file_index = ~0;
-      unix_file_t template = { 0 };
+      msf->clib_file_index = ~0;
+      clib_file_t template = { 0 };
       template.read_function = memif_conn_fd_accept_ready;
       template.file_descriptor = msf->fd;
       template.private_data = mif->socket_file_index;
-      memif_file_add (&msf->unix_file_index, &template);
+      memif_file_add (&msf->clib_file_index, &template);
     }
 
   msf->ref_cnt++;
@@ -721,7 +767,10 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
 error:
   if (mif->hw_if_index != ~0)
     {
-      ethernet_delete_interface (vnm, mif->hw_if_index);
+      if (mif->mode == MEMIF_INTERFACE_MODE_IP)
+       vnet_delete_hw_interface (vnm, mif->hw_if_index);
+      else
+       ethernet_delete_interface (vnm, mif->hw_if_index);
       mif->hw_if_index = ~0;
     }
   memif_delete_if (vm, mif);