memif: migrate memif to use vnet device infra APIs
[vpp.git] / src / plugins / memif / memif.c
index 7ba67c5..41c882f 100644 (file)
@@ -85,7 +85,7 @@ memif_connect (vlib_main_t * vm, memif_if_t * mif)
                               VNET_HW_INTERFACE_FLAG_LINK_UP);
 }
 
-static void
+void
 memif_disconnect (vlib_main_t * vm, memif_if_t * mif)
 {
   vnet_main_t *vnm = vnet_get_main ();
@@ -241,6 +241,7 @@ memif_process_connect_req (memif_pending_conn_t * pending_conn,
   uf->private_data = mif->if_index << 1;
   mif->connection = pending_conn->connection;
   pool_put (mm->pending_conns, pending_conn);
+  pending_conn = 0;
 
   memif_connect (vm, mif);
 
@@ -248,7 +249,22 @@ response:
   resp.version = MEMIF_VERSION;
   resp.type = MEMIF_MSG_TYPE_CONNECT_RESP;
   resp.retval = retval;
-  send (fd, &resp, sizeof (resp), 0);
+  if (send (fd, &resp, sizeof (resp), 0) < 0)
+    {
+      DEBUG_UNIX_LOG ("Failed to send connection response");
+      error = clib_error_return_unix (0, "send fd %d", fd);
+      if (pending_conn)
+       memif_remove_pending_conn (pending_conn);
+      else
+       memif_disconnect (vm, mif);
+    }
+  if (retval > 0)
+    {
+      if (shm_fd >= 0)
+       close (shm_fd);
+      if (int_fd >= 0)
+       close (int_fd);
+    }
   return error;
 }
 
@@ -352,7 +368,7 @@ memif_conn_fd_read_ready (unix_file_t * uf)
          else if (cmsg->cmsg_level == SOL_SOCKET
                   && cmsg->cmsg_type == SCM_RIGHTS)
            {
-             clib_memcpy (fd_array, CMSG_DATA (cmsg), sizeof (fd_array));
+             memcpy (fd_array, CMSG_DATA (cmsg), sizeof (fd_array));
            }
          cmsg = CMSG_NXTHDR (&mh, cmsg);
        }
@@ -390,7 +406,7 @@ static clib_error_t *
 memif_int_fd_read_ready (unix_file_t * uf)
 {
   memif_main_t *mm = &memif_main;
-  vlib_main_t *vm = vlib_get_main ();
+  vnet_main_t *vnm = vnet_get_main ();
   memif_if_t *mif = vec_elt_at_index (mm->interfaces, uf->private_data);
   u8 b;
   ssize_t size;
@@ -404,7 +420,7 @@ memif_int_fd_read_ready (unix_file_t * uf)
       mif->interrupt_line.index = ~0;
       mif->interrupt_line.fd = -1;
     }
-  vlib_node_set_interrupt_pending (vm, memif_input_node.index);
+  vnet_device_input_set_interrupt_pending (vnm, mif->hw_if_index, 0);
   return 0;
 }
 
@@ -511,7 +527,8 @@ memif_connect_master (vlib_main_t * vm, memif_if_t * mif)
        {
          u16 slot = i * (1 << mif->log2_ring_size) + j;
          ring->desc[j].region = 0;
-         ring->desc[j].offset = buffer_offset + (slot * mif->buffer_size);
+         ring->desc[j].offset =
+           buffer_offset + (u32) (slot * mif->buffer_size);
          ring->desc[j].buffer_length = mif->buffer_size;
        }
     }
@@ -524,7 +541,8 @@ memif_connect_master (vlib_main_t * vm, memif_if_t * mif)
          u16 slot =
            (i + mif->num_s2m_rings) * (1 << mif->log2_ring_size) + j;
          ring->desc[j].region = 0;
-         ring->desc[j].offset = buffer_offset + (slot * mif->buffer_size);
+         ring->desc[j].offset =
+           buffer_offset + (u32) (slot * mif->buffer_size);
          ring->desc[j].buffer_length = mif->buffer_size;
        }
     }
@@ -555,7 +573,7 @@ memif_connect_master (vlib_main_t * vm, memif_if_t * mif)
   cmsg->cmsg_level = SOL_SOCKET;
   cmsg->cmsg_type = SCM_RIGHTS;
   fd_array[0] = mfd;
-  clib_memcpy (CMSG_DATA (cmsg), fd_array, sizeof (fd_array));
+  memcpy (CMSG_DATA (cmsg), fd_array, sizeof (fd_array));
 
   mif->flags |= MEMIF_IF_FLAG_CONNECTING;
   rv = sendmsg (mif->connection.fd, &mh, 0);
@@ -595,6 +613,11 @@ memif_process (vlib_main_t * vm, vlib_node_runtime_t * rt, vlib_frame_t * f)
   f64 start_time, last_run_duration = 0, now;
 
   sockfd = socket (AF_UNIX, SOCK_STREAM, 0);
+  if (sockfd < 0)
+    {
+      DEBUG_UNIX_LOG ("socket AF_UNIX");
+      return 0;
+    }
   sun.sun_family = AF_UNIX;
   template.read_function = memif_conn_fd_read_ready;
 
@@ -716,11 +739,7 @@ memif_close_if (memif_main_t * mm, memif_if_t * mif)
        }
     }
 
-  if (mif->lockp != 0)
-    {
-      clib_mem_free ((void *) mif->lockp);
-      mif->lockp = 0;
-    }
+  clib_spinlock_free (&mif->lockp);
 
   mhash_unset (&mm->if_index_by_key, &mif->key, &mif->if_index);
   vec_free (mif->socket_filename);
@@ -734,26 +753,28 @@ int
 memif_worker_thread_enable ()
 {
   /* if worker threads are enabled, switch to polling mode */
+  /* *INDENT-OFF* */
   foreach_vlib_main ((
                       {
                       vlib_node_set_state (this_vlib_main,
                                            memif_input_node.index,
                                            VLIB_NODE_STATE_POLLING);
                       }));
-
+  /* *INDENT-ON* */
   return 0;
 }
 
 int
 memif_worker_thread_disable ()
 {
+  /* *INDENT-OFF* */
   foreach_vlib_main ((
                       {
                       vlib_node_set_state (this_vlib_main,
                                            memif_input_node.index,
                                            VLIB_NODE_STATE_INTERRUPT);
                       }));
-
+  /* *INDENT-ON* */
   return 0;
 }
 
@@ -768,6 +789,7 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
   clib_error_t *error = 0;
   int ret = 0;
   uword *p;
+  vnet_hw_interface_t *hw;
 
   p = mhash_get (&mm->if_index_by_key, &args->key);
   if (p)
@@ -783,11 +805,7 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
   mif->connection.fd = mif->interrupt_line.fd = -1;
 
   if (tm->n_vlib_mains > 1)
-    {
-      mif->lockp = clib_mem_alloc_aligned (CLIB_CACHE_LINE_BYTES,
-                                          CLIB_CACHE_LINE_BYTES);
-      memset ((void *) mif->lockp, 0, CLIB_CACHE_LINE_BYTES);
-    }
+    clib_spinlock_init (&mif->lockp);
 
   if (!args->hw_addr_set)
     {
@@ -920,6 +938,17 @@ memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args)
       mif->flags |= MEMIF_IF_FLAG_IS_SLAVE;
     }
 
+  hw = vnet_get_hw_interface (vnm, mif->hw_if_index);
+  hw->flags |= VNET_HW_INTERFACE_FLAG_SUPPORTS_INT_MODE;
+  vnet_hw_interface_set_input_node (vnm, mif->hw_if_index,
+                                   memif_input_node.index);
+  vnet_hw_interface_assign_rx_thread (vnm, mif->hw_if_index, 0, ~0);
+  ret = vnet_hw_interface_set_rx_mode (vnm, mif->hw_if_index, 0,
+                                      VNET_HW_INTERFACE_RX_MODE_INTERRUPT);
+  if (ret)
+    clib_warning ("Warning: unable to set rx mode for interface %d: "
+                 "rc=%d", mif->hw_if_index, ret);
+
 #if 0
   /* use configured or generate random MAC address */
   if (!args->hw_addr_set &&
@@ -952,6 +981,7 @@ memif_delete_if (vlib_main_t * vm, u64 key)
   memif_main_t *mm = &memif_main;
   memif_if_t *mif;
   uword *p;
+  int ret;
 
   p = mhash_get (&mm->if_index_by_key, &key);
   if (p == NULL)
@@ -963,6 +993,11 @@ memif_delete_if (vlib_main_t * vm, u64 key)
   mif = pool_elt_at_index (mm->interfaces, p[0]);
   mif->flags |= MEMIF_IF_FLAG_DELETING;
 
+  ret = vnet_hw_interface_unassign_rx_thread (vnm, mif->hw_if_index, 0);
+  if (ret)
+    clib_warning ("Warning: unable to unassign interface %d: rc=%d",
+                 mif->hw_if_index, ret);
+
   /* bring down the interface */
   vnet_hw_interface_set_flags (vnm, mif->hw_if_index, 0);
   vnet_sw_interface_set_flags (vnm, mif->sw_if_index, 0);