#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>
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)
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;
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);
}
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 ();
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;
{
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;
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;
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;
(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;
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;
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 */
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);
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)
{
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);
}
}
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);
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)
{
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++;
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);