Add memif - packet memory interface for intra-host communication
[vpp.git] / src / plugins / memif / memif.h
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2016 Cisco and/or its affiliates.
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at:
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  *------------------------------------------------------------------
16  */
17
18 typedef struct
19 {
20   u16 version;
21 #define MEMIF_VERSION_MAJOR 0
22 #define MEMIF_VERSION_MINOR 1
23 #define MEMIF_VERSION ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
24   u8 type;
25 #define MEMIF_MSG_TYPE_CONNECT_REQ  0
26 #define MEMIF_MSG_TYPE_CONNECT_RESP 1
27 #define MEMIF_MSG_TYPE_DISCONNECT   2
28
29   /* Connection-request parameters: */
30   u64 key;
31   u8 log2_ring_size;
32 #define MEMIF_DEFAULT_RING_SIZE 1024
33   u16 num_s2m_rings;
34   u16 num_m2s_rings;
35   u16 buffer_size;
36 #define MEMIF_DEFAULT_BUFFER_SIZE 2048
37   u32 shared_mem_size;
38
39   /* Connection-response parameters: */
40   u8 retval;
41 } memif_msg_t;
42
43 typedef struct __attribute__ ((packed))
44 {
45   u16 flags;
46 #define MEMIF_DESC_FLAG_NEXT (1 << 0)
47   u16 region;
48   u32 buffer_length;
49   u32 length;;
50   u8 reserved[4];
51   u64 offset;
52   u64 metadata;
53 } memif_desc_t;
54
55 STATIC_ASSERT_SIZEOF (memif_desc_t, 32);
56
57 typedef struct
58 {
59   u16 head __attribute__ ((aligned (128)));
60   u16 tail __attribute__ ((aligned (128)));
61   memif_desc_t desc[0] __attribute__ ((aligned (128)));
62 } memif_ring_t;
63
64 typedef struct
65 {
66   u32 cookie __attribute__ ((aligned (128)));
67 } memif_shm_t;
68
69
70 typedef struct
71 {
72   u16 last_head;
73   u16 last_tail;
74 } memif_ring_data_t;
75
76 typedef struct
77 {
78   int fd;
79   u32 index;
80 } memif_file_t;
81
82 typedef struct
83 {
84   uword index;
85   dev_t sock_dev;
86   ino_t sock_ino;
87   memif_file_t socket;
88   u16 usage_counter;
89 } memif_listener_t;
90
91 typedef struct
92 {
93   uword index;
94   memif_file_t connection;
95   uword listener_index;
96 } memif_pending_conn_t;
97
98 typedef struct
99 {
100   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
101   volatile u32 *lockp;
102   u32 flags;
103 #define MEMIF_IF_FLAG_ADMIN_UP   (1 << 0)
104 #define MEMIF_IF_FLAG_IS_SLAVE   (1 << 1)
105 #define MEMIF_IF_FLAG_CONNECTING (1 << 2)
106 #define MEMIF_IF_FLAG_CONNECTED  (1 << 3)
107 #define MEMIF_IF_FLAG_DELETING   (1 << 4)
108
109   u64 key;
110   uword if_index;
111   u32 hw_if_index;
112   u32 sw_if_index;
113
114   u32 per_interface_next_index;
115
116   uword listener_index;
117   memif_file_t connection;
118   memif_file_t interrupt_line;
119   u8 *socket_filename;
120
121   void **regions;
122
123   u8 log2_ring_size;
124   u8 num_s2m_rings;
125   u8 num_m2s_rings;
126   u16 buffer_size;
127
128   memif_ring_data_t *ring_data;
129
130   /* remote info */
131   pid_t remote_pid;
132   uid_t remote_uid;
133 } memif_if_t;
134
135 typedef struct
136 {
137   CLIB_CACHE_LINE_ALIGN_MARK (cacheline0);
138
139   /** API message ID base */
140   u16 msg_id_base;
141
142   /* pool of all memory interfaces */
143   memif_if_t *interfaces;
144
145   /* pool of all listeners */
146   memif_listener_t *listeners;
147
148   /* pool of pending connections */
149   memif_pending_conn_t *pending_conns;
150
151   /* bitmap of pending rx interfaces */
152   uword *pending_input_bitmap;
153
154   /* rx buffer cache */
155   u32 **rx_buffers;
156
157   /* hash of all registered keys */
158   mhash_t if_index_by_key;
159
160   /* first cpu index */
161   u32 input_cpu_first_index;
162
163   /* total cpu count */
164   u32 input_cpu_count;
165
166   /* configuration */
167   u8 *default_socket_filename;
168 #define MEMIF_DEFAULT_SOCKET_FILENAME  "/var/vpp/memif.sock"
169 } memif_main_t;
170
171 extern memif_main_t memif_main;
172 extern vnet_device_class_t memif_device_class;
173 extern vlib_node_registration_t memif_input_node;
174
175 enum
176 {
177   MEMIF_PROCESS_EVENT_START = 1,
178   MEMIF_PROCESS_EVENT_STOP = 2,
179 } memif_process_event_t;
180
181 typedef struct
182 {
183   u64 key;
184   u8 *socket_filename;
185   u8 is_master;
186   u8 log2_ring_size;
187   u16 buffer_size;
188   u8 hw_addr_set;
189   u8 hw_addr[6];
190
191   /* return */
192   u32 sw_if_index;
193 } memif_create_if_args_t;
194
195 int memif_create_if (vlib_main_t * vm, memif_create_if_args_t * args);
196 int memif_delete_if (vlib_main_t * vm, u64 key);
197 clib_error_t *memif_plugin_api_hookup (vlib_main_t * vm);
198
199 #ifndef __NR_memfd_create
200 #if defined __x86_64__
201 #define __NR_memfd_create 319
202 #elif defined __arm__
203 #define __NR_memfd_create 385
204 #elif defined __aarch64__
205 #define __NR_memfd_create 279
206 #else
207 #error "__NR_memfd_create unknown for this architecture"
208 #endif
209 #endif
210
211 static inline int
212 memfd_create (const char *name, unsigned int flags)
213 {
214   return syscall (__NR_memfd_create, name, flags);
215 }
216
217 typedef enum
218 {
219   MEMIF_RING_S2M = 0,
220   MEMIF_RING_M2S = 1
221 } memif_ring_type_t;
222
223 static_always_inline memif_ring_t *
224 memif_get_ring (memif_if_t * mif, memif_ring_type_t type, u16 ring_num)
225 {
226   if (vec_len (mif->regions) == 0)
227     return NULL;
228   void *p = mif->regions[0];
229   int ring_size =
230     sizeof (memif_ring_t) +
231     sizeof (memif_desc_t) * (1 << mif->log2_ring_size);
232   p += sizeof (memif_shm_t);
233   p += (ring_num + type * mif->num_s2m_rings) * ring_size;
234
235   return (memif_ring_t *) p;
236 }
237
238 static_always_inline void *
239 memif_get_buffer (memif_if_t * mif, memif_ring_t * ring, u16 slot)
240 {
241   u16 region = ring->desc[slot].region;
242   return mif->regions[region] + ring->desc[slot].offset;
243 }
244
245 #ifndef F_LINUX_SPECIFIC_BASE
246 #define F_LINUX_SPECIFIC_BASE 1024
247 #endif
248 #define MFD_ALLOW_SEALING       0x0002U
249 #define F_ADD_SEALS (F_LINUX_SPECIFIC_BASE + 9)
250 #define F_GET_SEALS (F_LINUX_SPECIFIC_BASE + 10)
251
252 #define F_SEAL_SEAL     0x0001  /* prevent further seals from being set */
253 #define F_SEAL_SHRINK   0x0002  /* prevent file from shrinking */
254 #define F_SEAL_GROW     0x0004  /* prevent file from growing */
255 #define F_SEAL_WRITE    0x0008  /* prevent writes */
256
257 /*
258  * fd.io coding-style-patch-verification: ON
259  *
260  * Local Variables:
261  * eval: (c-set-style "gnu")
262  * End:
263  */