|
FD.io VPP
v21.06-3-gbb25fbf28
Vector Packet Processing
|
Go to the documentation of this file.
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>
72 u16 ring_size, n_slots,
mask, start;
111 mif->
flags &= ~(MEMIF_IF_FLAG_CONNECTED | MEMIF_IF_FLAG_CONNECTING);
141 if (mif->
flags & MEMIF_IF_FLAG_ZERO_COPY)
157 if (mif->
flags & MEMIF_IF_FLAG_ZERO_COPY)
199 memif_log_warn (mif,
"unexpected EPOLLOUT on RX for queue %u", qid);
255 if ((mr->
shm = mmap (NULL, mr->
region_size, PROT_READ | PROT_WRITE,
256 MAP_SHARED, mr->
fd, 0)) == MAP_FAILED)
298 template.file_descriptor = mq->
int_fd;
299 template.private_data = (mif->
dev_instance << 16) | (
i & 0xFFFF);
300 template.description =
format (0,
"%U rx %u int",
315 (mif,
"Warning: unable to set rx mode for interface %d queue %d: "
329 mif->
flags &= ~MEMIF_IF_FLAG_CONNECTING;
330 mif->
flags |= MEMIF_IF_FLAG_CONNECTED;
373 r->region_size = buffer_offset;
375 if ((mif->
flags & MEMIF_IF_FLAG_ZERO_COPY) == 0)
387 if ((ftruncate (fd,
r->region_size)) == -1)
405 if (mif->
flags & MEMIF_IF_FLAG_ZERO_COPY)
428 if (mif->
flags & MEMIF_IF_FLAG_ZERO_COPY)
446 if (mif->
flags & MEMIF_IF_FLAG_ZERO_COPY)
468 if ((mq->
int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
480 if (mif->
flags & MEMIF_IF_FLAG_ZERO_COPY)
494 if ((mq->
int_fd = eventfd (0, EFD_NONBLOCK)) < 0)
506 if (mif->
flags & MEMIF_IF_FLAG_ZERO_COPY)
525 uword *event_data = 0, event_type;
527 f64 start_time, last_run_duration = 0,
now;
567 if (
now > start_time + 10e-6)
573 if ((mif->
flags & MEMIF_IF_FLAG_ADMIN_UP) == 0)
576 if (mif->
flags & MEMIF_IF_FLAG_CONNECTING)
579 if (mif->
flags & MEMIF_IF_FLAG_CONNECTED)
582 if (mif->
flags & MEMIF_IF_FLAG_IS_SLAVE)
585 sock->config = (
char *) msf->
filename;
608 mif->
flags |= MEMIF_IF_FLAG_CONNECTING;
624 .name =
"memif-process",
639 if (strcmp ((
char *) msf->
filename, (
char *) socket_filename) == 0)
646 return VNET_API_ERROR_ENTRY_ALREADY_EXISTS;
672 return VNET_API_ERROR_INVALID_ARGUMENT;
678 return VNET_API_ERROR_UNEXPECTED_INTF_STATE;
696 if ((sock_id == 0 && is_add == 0) || sock_id == ~0)
698 return VNET_API_ERROR_INVALID_ARGUMENT;
706 if (sock_filename == 0 || sock_filename[0] == 0)
708 return VNET_API_ERROR_INVALID_ARGUMENT;
711 if (sock_filename[0] !=
'/')
721 tmp = strrchr ((
char *) sock_filename,
'/');
724 idx =
tmp - (
char *) sock_filename;
725 vec_add (dir, sock_filename, idx);
734 return VNET_API_ERROR_SYSCALL_ERROR_1;
742 sock_filename =
vec_dup (sock_filename);
745 tmp = strrchr ((
char *) sock_filename,
'/');
748 idx =
tmp - (
char *) sock_filename;
749 vec_add (dir, sock_filename, idx);
756 (faccessat ( -1, dir, F_OK | R_OK | W_OK, AT_EACCESS)
760 return VNET_API_ERROR_INVALID_ARGUMENT;
777 mif->
flags |= MEMIF_IF_FLAG_DELETING;
866 rv = VNET_API_ERROR_INVALID_ARGUMENT;
877 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
884 rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
892 struct stat file_stat;
898 if (S_ISSOCK (file_stat.st_mode))
906 rv = VNET_API_ERROR_VALUE_EXIST;
932 bt->
flags = VLIB_BUFFER_TOTAL_LENGTH_VALID;
968 memcpy (args->
hw_addr + 2, &rnd, sizeof (rnd));
982 memif_ip_hw_if_class.index,
990 ret = VNET_API_ERROR_SYSCALL_ERROR_2;
1009 struct stat file_stat;
1016 s->config = (
char *) msf->
filename;
1023 ret = VNET_API_ERROR_SYSCALL_ERROR_4;
1027 if (stat ((
char *) msf->
filename, &file_stat) == -1)
1029 ret = VNET_API_ERROR_SYSCALL_ERROR_8;
1035 template.file_descriptor = msf->
sock->fd;
1037 template.description =
format (0,
"memif listener %s", msf->
filename);
1045 mif->
flags |= MEMIF_IF_FLAG_IS_SLAVE;
1047 mif->
flags |= MEMIF_IF_FLAG_ZERO_COPY;
1084 mif->
flags |= MEMIF_IF_FLAG_ADMIN_UP;
1086 mif->
flags &= ~MEMIF_IF_FLAG_ADMIN_UP;
1120 .version = VPP_BUILD_VER,
1121 .description =
"Packet Memory Interface (memif) -- Experimental",
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
static void clib_spinlock_init(clib_spinlock_t *p)
clib_file_function_t * write_function
#define VNET_HW_IF_RXQ_THREAD_ANY
#define CLIB_SOCKET_F_IS_SERVER
memif_interface_mode_t mode
VNET_HW_INTERFACE_CLASS(memif_ip_hw_if_class, static)
vlib_log_class_t log_class
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
static_always_inline memif_ring_t * memif_get_ring(memif_if_t *mif, memif_ring_type_t type, u16 ring_num)
clib_error_t * memif_conn_fd_accept_ready(clib_file_t *uf)
int memif_socket_filename_add_del(u8 is_add, u32 sock_id, u8 *sock_filename)
#define memif_log_debug(dev, f,...)
vnet_hw_interface_capabilities_t caps
int vnet_hw_if_set_rx_queue_mode(vnet_main_t *vnm, u32 queue_index, vnet_hw_if_rx_mode mode)
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
u32 per_interface_next_index
#define CLIB_SOCKET_F_IS_CLIENT
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
memif_queue_t * tx_queues
memif_region_size_t region_size
vlib_log_class_t vlib_log_register_class(char *class, char *subclass)
static void clib_mem_free(void *p)
__clib_export void * clib_mem_vm_map_shared(void *base, uword size, int fd, uword offset, char *fmt,...)
memif_socket_file_t * socket_files
memif_log2_ring_size_t log2_ring_size
#define clib_error_return(e, args...)
clib_file_function_t * read_function
@ MEMIF_INTERFACE_MODE_IP
memif_per_thread_data_t * per_thread_data
vlib_node_registration_t memif_input_node
(constructor) VLIB_REGISTER_NODE (memif_input_node)
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
#define pool_put(P, E)
Free an object E in pool P.
static uword * mhash_get(mhash_t *h, const void *key)
@ VNET_HW_IF_RX_MODE_POLLING
void vnet_hw_if_unregister_all_rx_queues(vnet_main_t *vnm, u32 hw_if_index)
vlib_buffer_main_t * buffer_main
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
memif_msg_fifo_elt_t * msg_queue
clib_error_t * memif_init_regions_and_queues(memif_if_t *mif)
@ VNET_HW_INTERFACE_FLAG_LINK_UP
memif_queue_t * rx_queues
vlib_physmem_map_t * vlib_physmem_get_map(vlib_main_t *vm, u32 index)
clib_error_t * memif_interface_admin_up_down(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
#define CLIB_MEM_VM_MAP_FAILED
__clib_export void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
vnet_hw_if_output_node_runtime_t * r
#define hash_create(elts, value_bytes)
static void vlib_process_signal_event(vlib_main_t *vm, uword node_index, uword type_opaque, uword data)
static u32 memif_eth_flag_change(vnet_main_t *vnm, vnet_hw_interface_t *hi, u32 flags)
@ MEMIF_PROCESS_EVENT_START
memif_region_index_t region
#define CLIB_SOCKET_F_BLOCKING
memif_log2_ring_size_t log2_ring_size
__clib_export u8 * format_clib_error(u8 *s, va_list *va)
__clib_export int clib_mem_vm_create_fd(clib_mem_page_sz_t log2_page_size, char *fmt,...)
clib_error_t * memif_msg_send_disconnect(memif_if_t *mif, clib_error_t *err)
static u32 random_u32(u32 *seed)
32-bit random number generator
#define memif_file_del_by_index(a)
#define hash_set(h, key, value)
clib_socket_t ** pending_clients
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,...
static void vlib_buffer_free_from_ring(vlib_main_t *vm, u32 *ring, u32 start, u32 ring_size, u32 n_buffers)
Free buffers from ring.
#define pool_foreach(VAR, POOL)
Iterate through pool.
struct memif_if_t::@719 run
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
void memif_disconnect(memif_if_t *mif, clib_error_t *err)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
struct memif_if_t::@718 cfg
memif_interface_mode_t mode
#define vec_dup(V)
Return copy of vector (no header, no alignment)
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static clib_error_t * clib_socket_close(clib_socket_t *sock)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_main_t * vnet_get_main(void)
vnet_device_class_t memif_device_class
memif_region_index_t region
static clib_error_t * memif_int_fd_write_ready(clib_file_t *uf)
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
#define static_always_inline
#define vec_foreach_index(var, v)
Iterate over vector indices.
uint32_t memif_interface_id_t
void vnet_delete_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
if(node->flags &VLIB_NODE_FLAG_TRACE) vnet_interface_output_trace(vm
static int memif_add_socket_file(u32 sock_id, u8 *socket_filename)
void vnet_hw_if_update_runtime_data(vnet_main_t *vnm, u32 hw_if_index)
static char * vlib_unix_get_runtime_dir(void)
static uword clib_socket_is_connected(clib_socket_t *sock)
sll srl srl sll sra u16x4 i
u8 * format_memif_device_name(u8 *s, va_list *args)
static void clib_spinlock_free(clib_spinlock_t *p)
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
clib_error_t * vlib_unix_recursive_mkdir(char *path)
#define memif_file_add(a, b)
static_always_inline void vnet_hw_if_rx_queue_set_int_pending(vnet_main_t *vnm, u32 queue_index)
@ VNET_HW_IF_RX_MODE_DEFAULT
vlib_buffer_t buffer_template
clib_error_t * memif_connect(memif_if_t *mif)
#define CLIB_CACHE_LINE_BYTES
memif_copy_op_t * copy_ops
struct _vlib_node_registration vlib_node_registration_t
uword * socket_file_index_by_sock_id
clib_error_t * memif_slave_conn_fd_read_ready(clib_file_t *uf)
void vnet_hw_if_set_rx_queue_file_index(vnet_main_t *vnm, u32 queue_index, u32 file_index)
#define vec_add2_aligned(V, P, N, A)
Add N elements to end of vector V, return pointer to new elements in P.
#define vec_free(V)
Free vector's memory (no header).
mhash_t dev_instance_by_id
clib_error_t * memif_plugin_api_hookup(vlib_main_t *vm)
vlib_buffer_pool_t * buffer_pools
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...
description fragment has unexpected format
__clib_export clib_error_t * clib_socket_init(clib_socket_t *s)
static uword vlib_process_suspend(vlib_main_t *vm, f64 dt)
Suspend a vlib cooperative multi-tasking thread for a period of time.
static vnet_sw_interface_t * vnet_get_hw_sw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define VLIB_INIT_FUNCTION(x)
void ethernet_delete_interface(vnet_main_t *vnm, u32 hw_if_index)
@ CLIB_MEM_PAGE_SZ_DEFAULT
static clib_error_t * memif_init(vlib_main_t *vm)
#define CLIB_SOCKET_F_ALLOW_GROUP_WRITE
#define vec_foreach(var, vec)
Vector iterator.
static vlib_main_t * vlib_get_main_by_index(u32 thread_index)
#define clib_error_return_unix(e, args...)
static uword pool_elts(void *v)
Number of active elements in a pool.
vnet_hw_if_rx_mode vnet_hw_if_get_rx_queue_mode(vnet_main_t *vnm, u32 queue_index)
#define hash_unset(h, key)
static vlib_node_registration_t memif_process_node
(constructor) VLIB_REGISTER_NODE (memif_process_node)
static u8 vlib_buffer_pool_get_default_for_numa(vlib_main_t *vm, u32 numa_node)
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static int memif_delete_socket_file(u32 sock_id)
memif_region_offset_t offset
u32 vnet_hw_if_register_rx_queue(vnet_main_t *vnm, u32 hw_if_index, u32 queue_id, u32 thread_index)
clib_error_t * memif_slave_conn_fd_write_ready(clib_file_t *uf)
static uword memif_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
static vlib_main_t * vlib_get_main(void)
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
vnet_interface_output_runtime_t * rt
@ MEMIF_INTERFACE_MODE_ETHERNET
clib_error_t *() vlib_init_function_t(struct vlib_main_t *vm)
@ MEMIF_PROCESS_EVENT_STOP
#define CLIB_SOCKET_F_PASSCRED
@ VNET_HW_INTERFACE_CLASS_FLAG_P2P
a point 2 point interface
#define MEMIF_RING_FLAG_MASK_INT
#define memif_log_warn(dev, f,...)
@ VNET_HW_INTERFACE_CAP_SUPPORTS_INT_MODE
#define clib_error_free(e)
static void memif_disconnect_free_zc_queue_buffer(memif_queue_t *mq, u8 is_rx)
static f64 vlib_time_now(vlib_main_t *vm)
clib_file_function_t * error_function
void memif_socket_close(clib_socket_t **sock)
struct _socket_t clib_socket_t
#define clib_fifo_free(f)
clib_error_t * memif_slave_conn_fd_error(clib_file_t *uf)
static_always_inline u32 vnet_hw_if_get_rx_queue_thread_index(vnet_main_t *vnm, u32 queue_index)
memif_region_offset_t offset
int memif_delete_if(vlib_main_t *vm, memif_if_t *mif)
static vlib_thread_main_t * vlib_get_thread_main()
uword * dev_instance_by_fd
u32 total_length_not_including_first_buffer
Only valid for first buffer in chain.
static_always_inline clib_error_t * clib_mem_get_last_error(void)
#define memif_log_err(dev, f,...)
memif_log2_ring_size_t log2_ring_size
__clib_export uword mhash_unset(mhash_t *h, void *key, uword *old_value)
static void * clib_mem_alloc(uword size)
static void mhash_free(mhash_t *h)
vl_api_fib_path_type_t type
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
clib_error_t * ethernet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, const u8 *address, u32 *hw_if_index_return, ethernet_flag_change_function_t flag_change)
static clib_error_t * memif_int_fd_read_ready(clib_file_t *uf)
uword int_clib_file_index
#define CLIB_SOCKET_F_SEQPACKET
int memif_create_if(vlib_main_t *vm, memif_create_if_args_t *args)
static void memif_queue_intfd_close(memif_queue_t *mq)
void vnet_hw_if_set_input_node(vnet_main_t *vnm, u32 hw_if_index, u32 node_index)
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index,...
@ MEMIF_PROCESS_EVENT_ADMIN_UP_DOWN
#define MEMIF_DEFAULT_SOCKET_FILENAME
VLIB buffer representation.
#define VLIB_REGISTER_NODE(x,...)
static void vlib_buffer_free_from_ring_no_next(vlib_main_t *vm, u32 *ring, u32 start, u32 ring_size, u32 n_buffers)
Free buffers from ring without freeing tail buffers.
vl_api_wireguard_peer_flags_t flags