22 #include <sys/types.h> 24 #include <sys/ioctl.h> 25 #include <sys/socket.h> 29 #include <sys/prctl.h> 30 #include <sys/eventfd.h> 39 #include <vpp/app/version.h> 92 mif->
flags &= ~(MEMIF_IF_FLAG_CONNECTED | MEMIF_IF_FLAG_CONNECTING);
117 DBG (
"Warning: unable to unassign interface %d, " 194 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
220 template.file_descriptor = mq->
int_fd;
221 template.private_data = (mif->
dev_instance << 16) | (i & 0xFFFF);
229 (
"Warning: unable to set rx mode for interface %d queue %d: " 241 mif->
flags &= ~MEMIF_IF_FLAG_CONNECTING;
242 mif->
flags |= MEMIF_IF_FLAG_CONNECTED;
284 alloc.
name =
"memif region";
331 if ((mq->
int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
347 if ((mq->
int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
365 struct sockaddr_un sun;
367 uword *event_data = 0, event_type;
369 f64 start_time, last_run_duration = 0, now;
371 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
377 sun.sun_family = AF_UNIX;
408 memif_socket_file_t * msf = vec_elt_at_index (mm->socket_files, mif->socket_file_index);
410 now = vlib_time_now (vm);
411 if (now > start_time + 10e-6)
413 vlib_process_suspend (vm, 100e-6);
414 start_time = vlib_time_now (vm);
417 if ((mif->
flags & MEMIF_IF_FLAG_ADMIN_UP) == 0)
420 if (mif->
flags & MEMIF_IF_FLAG_CONNECTING)
423 if (mif->
flags & MEMIF_IF_FLAG_CONNECTED)
426 if (mif->
flags & MEMIF_IF_FLAG_IS_SLAVE)
428 strncpy (sun.sun_path, (char *) msf->filename,
429 sizeof (sun.sun_path) - 1);
432 (sockfd, (struct sockaddr *) &sun,
433 sizeof (struct sockaddr_un)) == 0)
435 clib_file_t t = { 0 };
437 mif->conn_fd = sockfd;
438 t.read_function = memif_slave_conn_fd_read_ready;
439 t.write_function = memif_slave_conn_fd_write_ready;
440 t.error_function = memif_slave_conn_fd_error;
441 t.file_descriptor = mif->conn_fd;
442 t.private_data = mif->dev_instance;
443 memif_file_add (&mif->conn_clib_file_index, &t);
444 hash_set (msf->dev_instance_by_fd, mif->conn_fd, mif->dev_instance);
446 mif->flags |= MEMIF_IF_FLAG_CONNECTING;
449 sockfd = socket (AF_UNIX, SOCK_SEQPACKET, 0);
452 DBG_UNIX_LOG (
"socket AF_UNIX");
468 .name =
"memif-process",
481 mif->
flags |= MEMIF_IF_FLAG_DELETING;
524 memset (mif, 0,
sizeof (*mif));
565 return VNET_API_ERROR_SYSCALL_ERROR_1;
588 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
595 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
603 struct stat file_stat;
607 (stat ((
char *) socket_filename, &file_stat) == 0))
609 if (S_ISSOCK (file_stat.st_mode))
611 unlink ((
char *) socket_filename);
618 rv = VNET_API_ERROR_VALUE_EXIST;
637 memset (mif, 0,
sizeof (*mif));
659 rnd = (
u32) (now * 1e6);
662 memcpy (args->
hw_addr + 2, &rnd, sizeof (rnd));
676 memif_ip_hw_if_class.index,
685 ret = VNET_API_ERROR_SYSCALL_ERROR_2;
704 struct sockaddr_un un = { 0 };
705 struct stat file_stat;
708 if ((msf->
fd = socket (AF_UNIX, SOCK_SEQPACKET, 0)) < 0)
710 ret = VNET_API_ERROR_SYSCALL_ERROR_4;
714 un.sun_family = AF_UNIX;
715 strncpy ((
char *) un.sun_path, (
char *) msf->
filename,
716 sizeof (un.sun_path) - 1);
718 if (setsockopt (msf->
fd, SOL_SOCKET, SO_PASSCRED, &on, sizeof (on)) < 0)
720 ret = VNET_API_ERROR_SYSCALL_ERROR_5;
723 if (bind (msf->
fd, (
struct sockaddr *) &un, sizeof (un)) == -1)
725 ret = VNET_API_ERROR_SYSCALL_ERROR_6;
728 if (listen (msf->
fd, 1) == -1)
730 ret = VNET_API_ERROR_SYSCALL_ERROR_7;
734 if (stat ((
char *) msf->
filename, &file_stat) == -1)
736 ret = VNET_API_ERROR_SYSCALL_ERROR_8;
743 template.file_descriptor = msf->
fd;
751 mif->
flags |= MEMIF_IF_FLAG_IS_SLAVE;
808 .version = VPP_BUILD_VER,
809 .description =
"Packet Memory Interface (experimetal)",
#define DBG_UNIX_LOG(...)
#define vec_foreach_index(var, v)
Iterate over vector indices.
sll srl srl sll sra u16x4 i
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
#define hash_unset(h, key)
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_main_t * vnet_get_main(void)
mhash_t socket_file_index_by_filename
memif_socket_file_t * socket_files
memif_log2_ring_size_t log2_ring_size
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
void * addr
Pointer to allocated memory, set on successful allocation.
static f64 vlib_time_now(vlib_main_t *vm)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
static clib_error_t * memif_init(vlib_main_t *vm)
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
memif_interface_mode_t mode
#define VNET_HW_INTERFACE_FLAG_LINK_UP
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
#define memif_file_del_by_index(a)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
clib_file_function_t * read_function
static void clib_spinlock_free(clib_spinlock_t *p)
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
struct memif_if_t::@337 cfg
vnet_hw_interface_rx_mode
#define static_always_inline
clib_error_t * clib_mem_vm_ext_alloc(clib_mem_vm_alloc_t *a)
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
#define VLIB_INIT_FUNCTION(x)
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
clib_error_t * memif_plugin_api_hookup(vlib_main_t *vm)
static char * vlib_unix_get_runtime_dir(void)
char * name
Name for memory allocation, set by caller.
clib_error_t * memif_init_regions_and_queues(memif_if_t *mif)
static_always_inline void vnet_device_input_set_interrupt_pending(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
memif_log2_ring_size_t log2_ring_size
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
vnet_device_class_t memif_device_class
u32 per_interface_next_index
#define clib_error_return(e, args...)
memif_region_offset_t offset
uword size
Allocation size, set by caller.
#define memif_file_add(a, b)
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
static u32 memif_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
mhash_t dev_instance_by_id
static void clib_spinlock_init(clib_spinlock_t *p)
#define CLIB_MEM_VM_F_SHARED
memif_region_index_t region
vlib_node_registration_t memif_input_node
(constructor) VLIB_REGISTER_NODE (memif_input_node)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
int memif_delete_if(vlib_main_t *vm, memif_if_t *mif)
int fd
File desriptor, set on successful allocation if CLIB_MEM_VM_F_SHARED is set.
#define clib_error_return_unix(e, args...)
int vnet_hw_interface_get_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_interface_rx_mode *mode)
#define pool_put(P, E)
Free an object E in pool P.
#define vec_dup(V)
Return copy of vector (no header, no alignment)
int memif_create_if(vlib_main_t *vm, memif_create_if_args_t *args)
uword int_clib_file_index
#define VNET_HW_INTERFACE_FLAG_SUPPORTS_INT_MODE
VNET_HW_INTERFACE_CLASS(memif_ip_hw_if_class, static)
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
memif_queue_t * tx_queues
clib_error_t * memif_connect(memif_if_t *mif)
static void mhash_init_c_string(mhash_t *h, uword n_value_bytes)
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
#define vec_free(V)
Free vector's memory (no header).
#define clib_warning(format, args...)
uint32_t memif_interface_id_t
void memif_disconnect(memif_if_t *mif, clib_error_t *err)
u32 flags
vm allocation flags: CLIB_MEM_VM_F_SHARED: request shared memory, file destiptor will be provided o...
#define hash_create(elts, value_bytes)
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
static uword * mhash_get(mhash_t *h, const void *key)
static void memif_queue_intfd_close(memif_queue_t *mq)
static void mhash_free(mhash_t *h)
static clib_error_t * memif_int_fd_read_ready(clib_file_t *uf)
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
#define clib_error_report(e)
uword conn_clib_file_index
#define clib_fifo_free(f)
#define MEMIF_RING_FLAG_MASK_INT
void vnet_delete_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
memif_region_offset_t offset
uword * dev_instance_by_fd
struct memif_if_t::@338 run
clib_error_t * vlib_unix_recursive_mkdir(char *path)
static_always_inline memif_ring_t * memif_get_ring(memif_if_t *mif, memif_ring_type_t type, u16 ring_num)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
#define MEMIF_DEFAULT_SOCKET_FILENAME
a point 2 point interface
#define clib_error_free(e)
memif_log2_ring_size_t log2_ring_size
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
static u32 random_u32(u32 *seed)
32-bit random number generator
#define VLIB_REGISTER_NODE(x,...)
static vlib_thread_main_t * vlib_get_thread_main()
static vlib_node_registration_t memif_process_node
(constructor) VLIB_REGISTER_NODE (memif_process_node)
#define vec_foreach(var, vec)
Vector iterator.
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
memif_queue_t * rx_queues
int vnet_hw_interface_set_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_interface_rx_mode mode)
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
uword * pending_file_indices
#define CLIB_CACHE_LINE_BYTES
memif_msg_fifo_elt_t * msg_queue
memif_region_index_t region
static void vnet_hw_interface_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
memif_interface_mode_t mode
static uword memif_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
memif_region_size_t region_size
static uword pool_elts(void *v)
Number of active elements in a pool.