From eaabe073515e7722ed546b36f99efc6feea305a1 Mon Sep 17 00:00:00 2001 From: Damjan Marion Date: Wed, 22 Mar 2017 10:18:13 +0100 Subject: Add memif - packet memory interface for intra-host communication Change-Id: I94c06b07a39f07ceba87bf3e7fcfc70e43231e8a Signed-off-by: Damjan Marion Co-Authored-By: Milan Lenco --- src/plugins/memif/memif.h | 263 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 263 insertions(+) create mode 100644 src/plugins/memif/memif.h (limited to 'src/plugins/memif/memif.h') diff --git a/src/plugins/memif/memif.h b/src/plugins/memif/memif.h new file mode 100644 index 00000000..a7a88e07 --- /dev/null +++ b/src/plugins/memif/memif.h @@ -0,0 +1,263 @@ +/* + *------------------------------------------------------------------ + * Copyright (c) 2016 Cisco and/or its affiliates. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at: + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + *------------------------------------------------------------------ + */ + +typedef struct +{ + u16 version; +#define MEMIF_VERSION_MAJOR 0 +#define MEMIF_VERSION_MINOR 1 +#define MEMIF_VERSION ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR) + u8 type; +#define MEMIF_MSG_TYPE_CONNECT_REQ 0 +#define MEMIF_MSG_TYPE_CONNECT_RESP 1 +#define MEMIF_MSG_TYPE_DISCONNECT 2 + + /* Connection-request parameters: */ + u64 key; + u8 log2_ring_size; +#define MEMIF_DEFAULT_RING_SIZE 1024 + u16 num_s2m_rings; + u16 num_m2s_rings; + u16 buffer_size; +#define MEMIF_DEFAULT_BUFFER_SIZE 2048 + u32 shared_mem_size; + + /* Connection-response parameters: */ + u8 retval; +} memif_msg_t; + +typedef struct __attribute__ ((packed)) +{ + u16 flags; +#define MEMIF_DESC_FLAG_NEXT (1 << 0) + u16 region; + u32 buffer_length; + u32 length;; + u8 reserved[4]; + u64 offset; + u64 metadata; +} memif_desc_t; + +STATIC_ASSERT_SIZEOF (memif_desc_t, 32); + +typedef struct +{ + u16 head __attribute__ ((aligned (128))); + u16 tail __attribute__ ((aligned (128))); + memif_desc_t desc[0] __attribute__ ((aligned (128))); +} memif_ring_t; + +typedef struct +{ + u32 cookie __attribute__ ((aligned (128))); +} memif_shm_t; + + +typedef struct +{ + u16 last_head; + u16 last_tail; +} memif_ring_data_t; + +typedef struct +{ + int fd; + u32 index; +} memif_file_t; + +typedef struct +{ + uword index; + dev_t sock_dev; + ino_t sock_ino; + memif_file_t socket; + u16 usage_counter; +} memif_listener_t; + +typedef struct +{ + uword index; + memif_file_t connection; + uword listener_index; +} memif_pending_conn_t; + +typedef struct +{ + CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); + volatile u32 *lockp; + u32 flags; +#define MEMIF_IF_FLAG_ADMIN_UP (1 << 0) +#define MEMIF_IF_FLAG_IS_SLAVE (1 << 1) +#define MEMIF_IF_FLAG_CONNECTING (1 << 2) +#define MEMIF_IF_FLAG_CONNECTED (1 << 3) +#define MEMIF_IF_FLAG_DELETING (1 << 4) + + u64 key; + uword if_index; + u32 hw_if_index; + u32 sw_if_index; + + u32 per_interface_next_index; + + uword listener_index; + memif_file_t connection; + memif_file_t interrupt_line; + u8 *socket_filename; + + void **regions; + + u8 log2_ring_size; + u8 num_s2m_rings; + u8 num_m2s_rings; + u16 buffer_size; + + memif_ring_data_t *ring_data; + + /* remote info */ + pid_t remote_pid; + uid_t remote_uid; +} memif_if_t; + +typedef struct +{ + CLIB_CACHE_LINE_ALIGN_MARK (cacheline0); + + /** API message ID base */ + u16 msg_id_base; + + /* pool of all memory interfaces */ + memif_if_t *interfaces; + + /* pool of all listeners */ + memif_listener_t *listeners; + + /* pool of pending connections */ + memif_pending_conn_t *pending_conns; + + /* bitmap of pending rx interfaces */ + uword *pending_input_bitmap; + + /* rx buffer cache */ + u32 **rx_buffers; + + /* hash of all registered keys */ + mhash_t if_index_by_key; + + /* first cpu index */ + u32 input_cpu_first_index; + + /* total cpu count */ + u32 input_cpu_count; + + /* configuration */ + u8 *default_socket_filename; +#define MEMIF_DEFAULT_SOCKET_FILENAME "/var/vpp/memif.sock" +} memif_main_t; + +extern memif_main_t memif_main; +extern vnet_device_class_t memif_device_class; +extern vlib_node_registration_t memif_input_node; + +enum +{ + MEMIF_PROCESS_EVENT_START = 1, + MEMIF_PROCESS_EVENT_STOP = 2, +} memif_process_event_t; + +typedef struct +{ + u64 key; + u8 *socket_filename; + u8 is_master; + u8 log2_ring_size; + u16 buffer_size; + u8 hw_addr_set; + u8 hw_addr[6]; + + /* return */ + u32 sw_if_index; +} memif_create_if_args_t; + +int memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args); +int memif_delete_if (vlib_main_t * vm, u64 key); +clib_error_t *memif_plugin_api_hookup (vlib_main_t * vm); + +#ifndef __NR_memfd_create +#if defined __x86_64__ +#define __NR_memfd_create 319 +#elif defined __arm__ +#define __NR_memfd_create 385 +#elif defined __aarch64__ +#define __NR_memfd_create 279 +#else +#error "__NR_memfd_create unknown for this architecture" +#endif +#endif + +static inline int +memfd_create (const char *name, unsigned int flags) +{ + return syscall (__NR_memfd_create, name, flags); +} + +typedef enum +{ + MEMIF_RING_S2M = 0, + MEMIF_RING_M2S = 1 +} memif_ring_type_t; + +static_always_inline memif_ring_t * +memif_get_ring (memif_if_t * mif, memif_ring_type_t type, u16 ring_num) +{ + if (vec_len (mif->regions) == 0) + return NULL; + void *p = mif->regions[0]; + int ring_size = + sizeof (memif_ring_t) + + sizeof (memif_desc_t) * (1 << mif->log2_ring_size); + p += sizeof (memif_shm_t); + p += (ring_num + type * mif->num_s2m_rings) * ring_size; + + return (memif_ring_t *) p; +} + +static_always_inline void * +memif_get_buffer (memif_if_t * mif, memif_ring_t * ring, u16 slot) +{ + u16 region = ring->desc[slot].region; + return mif->regions[region] + ring->desc[slot].offset; +} + +#ifndef F_LINUX_SPECIFIC_BASE +#define F_LINUX_SPECIFIC_BASE 1024 +#endif +#define MFD_ALLOW_SEALING 0x0002U +#define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9) +#define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10) + +#define F_SEAL_SEAL 0x0001 /* prevent further seals from being set */ +#define F_SEAL_SHRINK 0x0002 /* prevent file from shrinking */ +#define F_SEAL_GROW 0x0004 /* prevent file from growing */ +#define F_SEAL_WRITE 0x0008 /* prevent writes */ + +/* + * fd.io coding-style-patch-verification: ON + * + * Local Variables: + * eval: (c-set-style "gnu") + * End: + */ -- cgit 1.2.3-korg