libmemif: ubuntu 18.04 build fix
[vpp.git] / extras / libmemif / src / libmemif.h
1 /*
2  *------------------------------------------------------------------
3  * Copyright (c) 2017 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 /** @file
19  *  @defgroup libmemif
20  */
21
22 #ifndef _LIBMEMIF_H_
23 #define _LIBMEMIF_H_
24
25 /** Libmemif version. */
26 #define LIBMEMIF_VERSION "1.0"
27 /** Default name of application using libmemif. */
28 #define MEMIF_DEFAULT_APP_NAME "libmemif-app"
29
30 #include <inttypes.h>
31
32 #include <memif.h>
33
34 /*! Error codes */
35 typedef enum
36 {
37   MEMIF_ERR_SUCCESS = 0,        /*!< success */
38 /* SYSCALL ERRORS */
39   MEMIF_ERR_SYSCALL,            /*!< other syscall error */
40   MEMIF_ERR_ACCES,              /*!< permission denied */
41   MEMIF_ERR_NO_FILE,            /*!< file does not exist */
42   MEMIF_ERR_FILE_LIMIT,         /*!< system open file limit */
43   MEMIF_ERR_PROC_FILE_LIMIT,    /*!< process open file limit */
44   MEMIF_ERR_ALREADY,            /*!< connection already requested */
45   MEMIF_ERR_AGAIN,              /*!< fd is not socket, or operation would block */
46   MEMIF_ERR_BAD_FD,             /*!< invalid fd */
47   MEMIF_ERR_NOMEM,              /*!< out of memory */
48 /* LIBMEMIF ERRORS */
49   MEMIF_ERR_INVAL_ARG,          /*!< invalid argument */
50   MEMIF_ERR_NOCONN,             /*!< handle points to no connection */
51   MEMIF_ERR_CONN,               /*!< handle points to existing connection */
52   MEMIF_ERR_CB_FDUPDATE,        /*!< user defined callback memif_control_fd_update_t error */
53   MEMIF_ERR_FILE_NOT_SOCK,      /*!< file specified by socket filename 
54                                    exists, but it's not socket */
55   MEMIF_ERR_NO_SHMFD,           /*!< missing shm fd */
56   MEMIF_ERR_COOKIE,             /*!< wrong cookie on ring */
57   MEMIF_ERR_NOBUF_RING,         /*!< ring buffer full */
58   MEMIF_ERR_NOBUF,              /*!< not enough memif buffers */
59   MEMIF_ERR_NOBUF_DET,          /*!< memif details needs larger buffer */
60   MEMIF_ERR_INT_WRITE,          /*!< send interrupt error */
61   MEMIF_ERR_MFMSG,              /*!< malformed msg received */
62   MEMIF_ERR_QID,                /*!< invalid queue id */
63 /* MEMIF PROTO ERRORS */
64   MEMIF_ERR_PROTO,              /*!< incompatible protocol version */
65   MEMIF_ERR_ID,                 /*!< unmatched interface id */
66   MEMIF_ERR_ACCSLAVE,           /*!< slave cannot accept connection requests */
67   MEMIF_ERR_ALRCONN,            /*!< memif is already connected */
68   MEMIF_ERR_MODE,               /*!< mode mismatch */
69   MEMIF_ERR_SECRET,             /*!< secret mismatch */
70   MEMIF_ERR_NOSECRET,           /*!< secret required */
71   MEMIF_ERR_MAXREG,             /*!< max region limit reached */
72   MEMIF_ERR_MAXRING,            /*!< max ring limit reached */
73   MEMIF_ERR_NO_INTFD,           /*!< missing interrupt fd */
74   MEMIF_ERR_DISCONNECT,         /*!< disconenct received */
75   MEMIF_ERR_DISCONNECTED,       /*!< peer interface disconnected */
76   MEMIF_ERR_UNKNOWN_MSG,        /*!< unknown message type */
77   MEMIF_ERR_POLL_CANCEL,        /*!< memif_poll_event() was cancelled */
78   MEMIF_ERR_MAX_RING,           /*!< too large ring size */
79 } memif_err_t;
80
81 /**
82  * @defgroup MEMIF_FD_EVENT Types of events that need to be watched for specific fd.
83  * @ingroup libmemif
84  * @{
85  */
86
87 /** user needs to set events that occured on fd and pass them to memif_control_fd_handler */
88 #define MEMIF_FD_EVENT_READ  (1 << 0)
89 #define MEMIF_FD_EVENT_WRITE (1 << 1)
90 /** inform libmemif that error occured on fd */
91 #define MEMIF_FD_EVENT_ERROR (1 << 2)
92 /** if set, informs that fd is going to be closed (user may want to stop watching for events on this fd) */
93 #define MEMIF_FD_EVENT_DEL   (1 << 3)
94 /** update events */
95 #define MEMIF_FD_EVENT_MOD   (1 << 4)
96 /** @} */
97
98 /** *brief Memif connection handle
99     pointer of type void, pointing to internal structure
100 */
101 typedef void *memif_conn_handle_t;
102 /**
103  * @defgroup CALLBACKS Callback functions definitions
104  * @ingroup libmemif
105  *
106  * @{
107  */
108
109 /** \brief Memif control file descriptor update (callback function)
110     @param fd - new file descriptor to watch
111     @param events - event type(s) to watch for
112
113     This callback is called when there is new fd to watch for events on
114     or if fd is about to be closed (user mey want to stop watching for events on this fd).
115 */
116 typedef int (memif_control_fd_update_t) (int fd, uint8_t events);
117
118 /** \brief Memif connection status update (callback function)
119     @param conn - memif connection handle
120     @param private_ctx - private context
121
122     Informs user about connection status connected/disconnected.
123     On connected -> start watching for events on interrupt fd (optional).
124 */
125 typedef int (memif_connection_update_t) (memif_conn_handle_t conn,
126                                          void *private_ctx);
127
128 /** \brief Memif interrupt occured (callback function)
129     @param conn - memif connection handle
130     @param private_ctx - private context
131     @param qid - queue id on which interrupt occured
132
133     Called when event is received on interrupt fd.
134 */
135 typedef int (memif_interrupt_t) (memif_conn_handle_t conn, void *private_ctx,
136                                  uint16_t qid);
137 /** @} */
138
139 /**
140  * @defgroup ARGS_N_BUFS Connection arguments and buffers
141  * @ingroup libmemif
142  *
143  * @{
144  */
145
146 /** \brief Memif connection arguments
147     @param socket_filename - socket filename
148     @param secret - otional parameter used as interface autenthication
149     @param num_s2m_rings - number of slave to master rings
150     @param num_m2s_rings - number of master to slave rings
151     @param buffer_size - size of buffer in shared memory
152     @param log2_ring_size - logarithm base 2 of ring size
153     @param is_master - 0 == master, 1 == slave
154     @param interface_id - id used to identify peer connection
155     @param interface_name - interface name
156     @param instance_name - application name
157     @param mode - 0 == ethernet, 1 == ip , 2 == punt/inject
158 */
159 typedef struct
160 {
161   uint8_t *socket_filename;     /*!< default = /run/vpp/memif.sock */
162   uint8_t secret[24];           /*!< optional (interface authentication) */
163
164   uint8_t num_s2m_rings;        /*!< default = 1 */
165   uint8_t num_m2s_rings;        /*!< default = 1 */
166   uint16_t buffer_size;         /*!< default = 2048 */
167   memif_log2_ring_size_t log2_ring_size;        /*!< default = 10 (1024) */
168   uint8_t is_master;
169
170   memif_interface_id_t interface_id;
171   uint8_t interface_name[32];
172   uint8_t instance_name[32];    /*!< deprecated, will be removed in 2.0 */
173   memif_interface_mode_t mode:8;
174 } memif_conn_args_t;
175
176 /*! memif receive mode */
177 typedef enum
178 {
179   MEMIF_RX_MODE_INTERRUPT = 0,  /*!< interrupt mode */
180   MEMIF_RX_MODE_POLLING         /*!< polling mode */
181 } memif_rx_mode_t;
182
183 /** \brief Memif buffer
184     @param desc_index - ring descriptor index
185     @param buffer_len - shared meory buffer length
186     @param data_len - data length
187     @param data - pointer to shared memory data
188 */
189 typedef struct
190 {
191   uint16_t desc_index;
192   uint32_t buffer_len;
193   uint32_t data_len;
194   void *data;
195 } memif_buffer_t;
196 /** @} */
197
198 /**
199  * @defgroup MEMIF_DETAILS Memif details structs
200  * @ingroup libmemif
201  *
202  * @{
203  */
204
205 /** \brief Memif queue details
206     @param qid - queue id
207     @param ring_size - size of ring buffer in sharem memory
208     @param flags - ring flags
209     @param head - ring head pointer
210     @param tail - ring tail pointer
211     @param buffer_size - buffer size on sharem memory
212 */
213 typedef struct
214 {
215   uint8_t qid;
216   uint32_t ring_size;
217 /** if set queue is in polling mode, else in interrupt mode */
218 #define MEMIF_QUEUE_FLAG_POLLING 1
219   uint16_t flags;
220   uint16_t head;
221   uint16_t tail;
222   uint16_t buffer_size;
223 } memif_queue_details_t;
224
225 /** \brief Memif details
226     @param if_name - interface name
227     @param inst_name - application name
228     @param remote_if_name - peer interface name
229     @param remote_inst_name - peer application name
230     @param id - connection id
231     @param secret - secret
232     @param role - 0 = master, 1 = slave
233     @param mode - 0 = ethernet, 1 = ip , 2 = punt/inject
234     @param socket_filename = socket filename
235     @param rx_queues_num - number of receive queues
236     @param tx_queues_num - number of transmit queues
237     @param rx_queues - struct containing receive queue details
238     @param tx_queues - struct containing transmit queue details
239     @param link_up_down - 1 = up (connected), 2 = down (disconnected)
240 */
241 typedef struct
242 {
243   uint8_t *if_name;
244   uint8_t *inst_name;
245   uint8_t *remote_if_name;
246   uint8_t *remote_inst_name;
247
248   uint32_t id;
249   uint8_t *secret;              /* optional */
250   uint8_t role;                 /* 0 = master, 1 = slave */
251   uint8_t mode;                 /* 0 = ethernet, 1 = ip, 2 = punt/inject */
252   uint8_t *socket_filename;
253   uint8_t rx_queues_num;
254   uint8_t tx_queues_num;
255   memif_queue_details_t *rx_queues;
256   memif_queue_details_t *tx_queues;
257
258   uint8_t link_up_down;         /* 1 = up, 0 = down */
259 } memif_details_t;
260 /** @} */
261
262 /**
263  * @defgroup API_CALLS Api calls
264  * @ingroup libmemif
265  *
266  * @{
267  */
268
269 /** \biref Memif get queue event file descriptor
270     @param conn - memif connection handle
271     @param qid - queue id
272     @param[out] fd - returns event file descriptor
273
274     \return memif_err_t
275 */
276
277 int memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *fd);
278
279 /** \brief Memif set rx mode
280     @param conn - memif connection handle
281     @param rx_mode - receive mode
282     @param qid - queue id
283
284     \return memif_err_t
285 */
286 int memif_set_rx_mode (memif_conn_handle_t conn, memif_rx_mode_t rx_mode,
287                        uint16_t qid);
288
289 /** \brief Memif strerror
290     @param err_code - error code
291
292     Converts error code to error message.
293     
294     \return Error string
295 */
296 char *memif_strerror (int err_code);
297
298 /** \brief Memif get details
299     @param conn - memif conenction handle
300     @param md - pointer to memif details struct
301     @param buf - buffer containing details strings
302     @param buflen - length of buffer
303
304     \return memif_err_t
305 */
306 int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
307                        char *buf, ssize_t buflen);
308
309 /** \brief Memif initialization
310     @param on_control_fd_update - if control fd updates inform user to watch new fd
311     @param app_name - application name (will be truncated to 32 chars)
312
313     if param on_control_fd_update is set to NULL,
314     libmemif will handle file descriptor event polling
315     if a valid callback is set, file descriptor event polling needs to be done by
316     user application, all file descriptors and event types will be passed in
317     this callback to user application
318
319     Initialize internal libmemif structures. Create timerfd (used to periodically request connection by
320     disconnected memifs in slave mode, with no additional API call). This fd is passed to user with memif_control_fd_update_t
321     timer is inactive at this state. It activates with if there is at least one memif in slave mode.
322
323     \return memif_err_t
324 */
325 int memif_init (memif_control_fd_update_t * on_control_fd_update,
326                 char *app_name);
327
328 /** \brief Memif cleanup
329
330     Free libmemif internal allocations.
331
332     \return 0
333 */
334 int memif_cleanup ();
335
336 /** \brief Memory interface create function
337     @param conn - connection handle for user app
338     @param args - memory interface connection arguments
339     @param on_connect - inform user about connected status
340     @param on_disconnect - inform user about disconnected status
341     @param on_interrupt - informs user about interrupt, if set to null user will not be notified about interrupt, user can use memif_get_queue_efd call to get interrupt fd to poll for events
342     @param private_ctx - private contex passed back to user with callback
343
344     Creates memory interface.
345      
346     SLAVE-MODE - 
347         Start timer that will send events to timerfd. If this fd is passed to memif_control_fd_handler
348         every disconnected memif in slave mode will send connection request.
349         On success new fd is passed to user with memif_control_fd_update_t.
350
351     MASTER-MODE - 
352         Create listener socket and pass fd to user with memif_cntrol_fd_update_t.
353         If this fd is passed to memif_control_fd_handler accept will be called and
354         new fd will be passed to user with memif_control_fd_update_t.
355
356
357     \return memif_err_t
358 */
359 int memif_create (memif_conn_handle_t * conn, memif_conn_args_t * args,
360                   memif_connection_update_t * on_connect,
361                   memif_connection_update_t * on_disconnect,
362                   memif_interrupt_t * on_interrupt, void *private_ctx);
363
364 /** \brief Memif control file descriptor handler
365     @param fd - file descriptor on which the event occured
366     @param events - event type(s) that occured
367
368     If event occures on any control fd, call memif_control_fd_handler.
369     Internal - lib will "identify" fd (timerfd, lsitener, control) and handle event accordingly.
370  
371     FD-TYPE - 
372         TIMERFD - 
373             Every disconnected memif in slave mode will request connection.
374         LISTENER or CONTROL - 
375             Handle socket messaging (internal connection establishment).
376         INTERRUPT - 
377             Call on_interrupt callback (if set).
378         
379     \return memif_err_t
380
381 */
382 int memif_control_fd_handler (int fd, uint8_t events);
383
384 /** \brief Memif delete
385     @param conn - pointer to memif connection handle
386
387
388     disconnect session (free queues and regions, close file descriptors, unmap shared memory)
389     set connection handle to NULL, to avoid possible double free
390
391     \return memif_err_t
392 */
393 int memif_delete (memif_conn_handle_t * conn);
394
395 /** \brief Memif buffer alloc
396     @param conn - memif conenction handle
397     @param qid - number indentifying queue
398     @param bufs - memif buffers
399     @param count - number of memif buffers to allocate
400     @param count_out - returns number of allocated buffers
401     @param size - minimal buffer size, 0 = standard buffer size
402
403     \return memif_err_t
404 */
405 int memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
406                         memif_buffer_t * bufs, uint16_t count,
407                         uint16_t * count_out, uint16_t size);
408
409 /** \brief Memif buffer free
410     @param conn - memif conenction handle
411     @param qid - number indentifying queue
412     @param bufs - memif buffers
413     @param count - number of memif buffers to free
414     @param count_out - returns number of freed buffers
415
416     \return memif_err_t
417 */
418 int memif_buffer_free (memif_conn_handle_t conn, uint16_t qid,
419                        memif_buffer_t * bufs, uint16_t count,
420                        uint16_t * count_out);
421
422 /** \brief Memif transmit buffer burst
423     @param conn - memif conenction handle
424     @param qid - number indentifying queue
425     @param bufs - memif buffers
426     @param count - number of memif buffers to transmit
427     @param tx - returns number of transmitted buffers
428
429     \return memif_err_t
430 */
431 int memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
432                     memif_buffer_t * bufs, uint16_t count, uint16_t * tx);
433
434 /** \brief Memif receive buffer burst
435     @param conn - memif conenction handle
436     @param qid - number indentifying queue
437     @param bufs - memif buffers
438     @param count - number of memif buffers to receive
439     @param rx - returns number of received buffers
440
441     \return memif_err_t
442 */
443 int memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
444                     memif_buffer_t * bufs, uint16_t count, uint16_t * rx);
445
446 /** \brief Memif poll event
447     @param timeout - timeout in seconds
448
449     Passive event polling - 
450     timeout = 0 - dont wait for event, check event queue if there is an event and return.
451     timeout = -1 - wait until event
452
453     \return memif_err_t
454 */
455 int memif_poll_event (int timeout);
456
457 /** \brief Send signal to stop concurrently running memif_poll_event().
458
459     The function, however, does not wait for memif_poll_event() to stop.
460     memif_poll_event() may still return simply because an event has occured
461     or the timeout has elapsed, but if called repeatedly in an infinite loop,
462     a canceled memif_poll_event() is guaranted to return MEMIF_ERR_POLL_CANCEL
463     in the shortest possible time.
464     This feature was not available in the first release.
465     Use macro MEMIF_HAVE_CANCEL_POLL_EVENT to check if the feature is present.
466
467     \return memif_err_t
468 */
469 #define MEMIF_HAVE_CANCEL_POLL_EVENT 1
470 int memif_cancel_poll_event ();
471 /** @} */
472
473 #endif /* _LIBMEMIF_H_ */