libmemif: external region support
[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 "2.0"
27 /** Default name of application using libmemif. */
28 #define MEMIF_DEFAULT_APP_NAME "libmemif-app"
29
30 #include <inttypes.h>
31
32 /*! Error codes */
33 typedef enum
34 {
35   MEMIF_ERR_SUCCESS = 0,        /*!< success */
36 /* SYSCALL ERRORS */
37   MEMIF_ERR_SYSCALL,            /*!< other syscall error */
38   MEMIF_ERR_ACCES,              /*!< permission denied */
39   MEMIF_ERR_NO_FILE,            /*!< file does not exist */
40   MEMIF_ERR_FILE_LIMIT,         /*!< system open file limit */
41   MEMIF_ERR_PROC_FILE_LIMIT,    /*!< process open file limit */
42   MEMIF_ERR_ALREADY,            /*!< connection already requested */
43   MEMIF_ERR_AGAIN,              /*!< fd is not socket, or operation would block */
44   MEMIF_ERR_BAD_FD,             /*!< invalid fd */
45   MEMIF_ERR_NOMEM,              /*!< out of memory */
46 /* LIBMEMIF ERRORS */
47   MEMIF_ERR_INVAL_ARG,          /*!< invalid argument */
48   MEMIF_ERR_NOCONN,             /*!< handle points to no connection */
49   MEMIF_ERR_CONN,               /*!< handle points to existing connection */
50   MEMIF_ERR_CB_FDUPDATE,        /*!< user defined callback memif_control_fd_update_t error */
51   MEMIF_ERR_FILE_NOT_SOCK,      /*!< file specified by socket filename 
52                                    exists, but it's not socket */
53   MEMIF_ERR_NO_SHMFD,           /*!< missing shm fd */
54   MEMIF_ERR_COOKIE,             /*!< wrong cookie on ring */
55   MEMIF_ERR_NOBUF_RING,         /*!< ring buffer full */
56   MEMIF_ERR_NOBUF,              /*!< not enough memif buffers */
57   MEMIF_ERR_NOBUF_DET,          /*!< memif details needs larger buffer */
58   MEMIF_ERR_INT_WRITE,          /*!< send interrupt error */
59   MEMIF_ERR_MFMSG,              /*!< malformed msg received */
60   MEMIF_ERR_QID,                /*!< invalid queue id */
61 /* MEMIF PROTO ERRORS */
62   MEMIF_ERR_PROTO,              /*!< incompatible protocol version */
63   MEMIF_ERR_ID,                 /*!< unmatched interface id */
64   MEMIF_ERR_ACCSLAVE,           /*!< slave cannot accept connection requests */
65   MEMIF_ERR_ALRCONN,            /*!< memif is already connected */
66   MEMIF_ERR_MODE,               /*!< mode mismatch */
67   MEMIF_ERR_SECRET,             /*!< secret mismatch */
68   MEMIF_ERR_NOSECRET,           /*!< secret required */
69   MEMIF_ERR_MAXREG,             /*!< max region limit reached */
70   MEMIF_ERR_MAXRING,            /*!< max ring limit reached */
71   MEMIF_ERR_NO_INTFD,           /*!< missing interrupt fd */
72   MEMIF_ERR_DISCONNECT,         /*!< disconenct received */
73   MEMIF_ERR_DISCONNECTED,       /*!< peer interface disconnected */
74   MEMIF_ERR_UNKNOWN_MSG,        /*!< unknown message type */
75   MEMIF_ERR_POLL_CANCEL,        /*!< memif_poll_event() was cancelled */
76   MEMIF_ERR_MAX_RING,           /*!< too large ring size */
77   MEMIF_ERR_PRIVHDR,            /*!< private hdrs not supported */
78 } memif_err_t;
79
80 /**
81  * @defgroup MEMIF_FD_EVENT Types of events that need to be watched for specific fd.
82  * @ingroup libmemif
83  * @{
84  */
85
86 /** user needs to set events that occured on fd and pass them to memif_control_fd_handler */
87 #define MEMIF_FD_EVENT_READ  (1 << 0)
88 #define MEMIF_FD_EVENT_WRITE (1 << 1)
89 /** inform libmemif that error occured on fd */
90 #define MEMIF_FD_EVENT_ERROR (1 << 2)
91 /** if set, informs that fd is going to be closed (user may want to stop watching for events on this fd) */
92 #define MEMIF_FD_EVENT_DEL   (1 << 3)
93 /** update events */
94 #define MEMIF_FD_EVENT_MOD   (1 << 4)
95 /** @} */
96
97 /** \brief Memif connection handle
98     pointer of type void, pointing to internal structure
99 */
100 typedef void *memif_conn_handle_t;
101
102 /** \brief Memif allocator alloc
103     @param size - requested allocation size
104
105     custom memory allocator: alloc function template
106 */
107 typedef void *(memif_alloc_t) (size_t size);
108
109
110 /** \brief Memif realloc
111     @param ptr - pointer to memory block
112     @param size - requested allocation size
113
114     custom memory reallocation
115 */
116 typedef void *(memif_realloc_t) (void *ptr, size_t size);
117
118 /** \brief Memif allocator free
119     @param size - requested allocation size
120
121     custom memory allocator: free function template
122 */
123 typedef void (memif_free_t) (void *ptr);
124
125 /**
126  * @defgroup CALLBACKS Callback functions definitions
127  * @ingroup libmemif
128  *
129  * @{
130  */
131
132 /** \brief Memif control file descriptor update (callback function)
133     @param fd - new file descriptor to watch
134     @param events - event type(s) to watch for
135
136     This callback is called when there is new fd to watch for events on
137     or if fd is about to be closed (user mey want to stop watching for events on this fd).
138 */
139 typedef int (memif_control_fd_update_t) (int fd, uint8_t events);
140
141 /** \brief Memif connection status update (callback function)
142     @param conn - memif connection handle
143     @param private_ctx - private context
144
145     Informs user about connection status connected/disconnected.
146     On connected -> start watching for events on interrupt fd (optional).
147 */
148 typedef int (memif_connection_update_t) (memif_conn_handle_t conn,
149                                          void *private_ctx);
150
151 /** \brief Memif interrupt occured (callback function)
152     @param conn - memif connection handle
153     @param private_ctx - private context
154     @param qid - queue id on which interrupt occured
155
156     Called when event is received on interrupt fd.
157 */
158 typedef int (memif_interrupt_t) (memif_conn_handle_t conn, void *private_ctx,
159                                  uint16_t qid);
160
161 /** @} */
162
163 /**
164  * @defgroup EXTERNAL_REGION External region APIs
165  * @ingroup libmemif
166  *
167  * @{
168  */
169
170 /** \brief Get external buffer offset (optional)
171     @param private_ctx - private context
172
173     Find unallocated external buffer and return its offset.
174 */
175 typedef uint32_t (memif_get_external_buffer_offset_t) (void *private_ctx);
176
177 /** \brief Add external region
178     @param[out] addr - region address
179     @param size - requested region size
180     @param fd[out] - file descriptor
181     @param private_ctx - private context
182
183     Called by slave. Add external region created by client.
184 */
185 typedef int (memif_add_external_region_t) (void * *addr, uint32_t size,
186                                            int *fd, void *private_ctx);
187
188 /** \brief Get external region address
189     @param size - requested region size
190     @param fd - file descriptor
191     @param private_ctx - private context
192
193     Called by master. Get region address from client.
194
195    \return region address
196 */
197 typedef void *(memif_get_external_region_addr_t) (uint32_t size, int fd,
198                                                   void *private_ctx);
199
200 /** \brief Delete external region
201     @param addr - region address
202     @param size - region size
203     @param fd - file descriptor
204     @param private_ctx - private context
205
206     Delete external region.
207 */
208 typedef int (memif_del_external_region_t) (void *addr, uint32_t size, int fd,
209                                            void *private_ctx);
210
211 /** \brief Register external region
212     @param ar - add external region callback
213     @param gr - get external region addr callback
214     @param dr - delete external region callback
215     @param go - get external buffer offset callback (optional)
216 */
217 void memif_register_external_region (memif_add_external_region_t * ar,
218                                      memif_get_external_region_addr_t * gr,
219                                      memif_del_external_region_t * dr,
220                                      memif_get_external_buffer_offset_t * go);
221
222 /** @} */
223
224 /**
225  * @defgroup ARGS_N_BUFS Connection arguments and buffers
226  * @ingroup libmemif
227  *
228  * @{
229  */
230
231 #ifndef _MEMIF_H_
232 typedef enum
233 {
234   MEMIF_INTERFACE_MODE_ETHERNET = 0,
235   MEMIF_INTERFACE_MODE_IP = 1,
236   MEMIF_INTERFACE_MODE_PUNT_INJECT = 2,
237 } memif_interface_mode_t;
238 #endif /* _MEMIF_H_ */
239
240 /** \brief Memif connection arguments
241     @param socket_filename - socket filename
242     @param secret - otional parameter used as interface autenthication
243     @param num_s2m_rings - number of slave to master rings
244     @param num_m2s_rings - number of master to slave rings
245     @param buffer_size - size of buffer in shared memory
246     @param log2_ring_size - logarithm base 2 of ring size
247     @param is_master - 0 == master, 1 == slave
248     @param interface_id - id used to identify peer connection
249     @param interface_name - interface name
250     @param mode - 0 == ethernet, 1 == ip , 2 == punt/inject
251 */
252 typedef struct
253 {
254   uint8_t *socket_filename;     /*!< default = /run/vpp/memif.sock */
255   uint8_t secret[24];           /*!< optional (interface authentication) */
256
257   uint8_t num_s2m_rings;        /*!< default = 1 */
258   uint8_t num_m2s_rings;        /*!< default = 1 */
259   uint16_t buffer_size;         /*!< default = 2048 */
260   uint8_t log2_ring_size;       /*!< default = 10 (1024) */
261   uint8_t is_master;
262
263   uint32_t interface_id;
264   uint8_t interface_name[32];
265   memif_interface_mode_t mode:8;
266 } memif_conn_args_t;
267
268 /*! memif receive mode */
269 typedef enum
270 {
271   MEMIF_RX_MODE_INTERRUPT = 0,  /*!< interrupt mode */
272   MEMIF_RX_MODE_POLLING         /*!< polling mode */
273 } memif_rx_mode_t;
274
275 /** \brief Memif buffer
276     @param desc_index - ring descriptor index
277     @param ring - pointer to ring containing descriptor for this buffer
278     @param len - available length
279     @param flags - memif buffer flags
280     @param data - pointer to shared memory data
281 */
282 typedef struct
283 {
284   uint16_t desc_index;
285   void *ring;
286   uint32_t len;
287 /** next buffer present (chained buffers) */
288 #define MEMIF_BUFFER_FLAG_NEXT (1 << 0)
289 /** states that buffer is from rx ring */
290 #define MEMIF_BUFFER_FLAG_RX (1 << 1)
291   uint8_t flags;
292   void *data;
293 } memif_buffer_t;
294 /** @} */
295
296 /**
297  * @defgroup MEMIF_DETAILS Memif details structs
298  * @ingroup libmemif
299  *
300  * @{
301  */
302
303 /** \brief Memif queue details
304     @param region - region index
305     @param qid - queue id
306     @param ring_size - size of ring buffer in sharem memory
307     @param flags - ring flags
308     @param head - ring head pointer
309     @param tail - ring tail pointer
310     @param buffer_size - buffer size on sharem memory
311 */
312 typedef struct
313 {
314   uint8_t region;
315   uint8_t qid;
316   uint32_t ring_size;
317 /** if set queue is in polling mode, else in interrupt mode */
318 #define MEMIF_QUEUE_FLAG_POLLING 1
319   uint16_t flags;
320   uint16_t head;
321   uint16_t tail;
322   uint16_t buffer_size;
323 } memif_queue_details_t;
324
325 /** \brief Memif region details
326     @param index - region index
327     @param addr - region address
328     @param size - region size
329     @param fd - file descriptor
330     @param is_external - if not zero then region is defined by client
331 */
332 typedef struct
333 {
334   uint8_t index;
335   void *addr;
336   uint32_t size;
337   int fd;
338   uint8_t is_external;
339 } memif_region_details_t;
340
341 /** \brief Memif details
342     @param if_name - interface name
343     @param inst_name - application name
344     @param remote_if_name - peer interface name
345     @param remote_inst_name - peer application name
346     @param id - connection id
347     @param secret - secret
348     @param role - 0 = master, 1 = slave
349     @param mode - 0 = ethernet, 1 = ip , 2 = punt/inject
350     @param socket_filename - socket filename
351     @param regions_num - number of regions
352     @param regions - struct containing region details
353     @param rx_queues_num - number of receive queues
354     @param tx_queues_num - number of transmit queues
355     @param rx_queues - struct containing receive queue details
356     @param tx_queues - struct containing transmit queue details
357     @param link_up_down - 1 = up (connected), 2 = down (disconnected)
358 */
359 typedef struct
360 {
361   uint8_t *if_name;
362   uint8_t *inst_name;
363   uint8_t *remote_if_name;
364   uint8_t *remote_inst_name;
365
366   uint32_t id;
367   uint8_t *secret;              /* optional */
368   uint8_t role;                 /* 0 = master, 1 = slave */
369   uint8_t mode;                 /* 0 = ethernet, 1 = ip, 2 = punt/inject */
370   uint8_t *socket_filename;
371   uint8_t regions_num;
372   memif_region_details_t *regions;
373   uint8_t rx_queues_num;
374   uint8_t tx_queues_num;
375   memif_queue_details_t *rx_queues;
376   memif_queue_details_t *tx_queues;
377
378   uint8_t link_up_down;         /* 1 = up, 0 = down */
379 } memif_details_t;
380 /** @} */
381
382 /**
383  * @defgroup API_CALLS Api calls
384  * @ingroup libmemif
385  *
386  * @{
387  */
388
389 /** \brief Memif get version
390
391     \return ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
392 */
393 uint16_t memif_get_version ();
394
395 /** \biref Memif get queue event file descriptor
396     @param conn - memif connection handle
397     @param qid - queue id
398     @param[out] fd - returns event file descriptor
399
400     \return memif_err_t
401 */
402
403 int memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *fd);
404
405 /** \brief Memif set rx mode
406     @param conn - memif connection handle
407     @param rx_mode - receive mode
408     @param qid - queue id
409
410     \return memif_err_t
411 */
412 int memif_set_rx_mode (memif_conn_handle_t conn, memif_rx_mode_t rx_mode,
413                        uint16_t qid);
414
415 /** \brief Memif strerror
416     @param err_code - error code
417
418     Converts error code to error message.
419     
420     \return Error string
421 */
422 char *memif_strerror (int err_code);
423
424 /** \brief Memif get details
425     @param conn - memif conenction handle
426     @param md - pointer to memif details struct
427     @param buf - buffer containing details strings
428     @param buflen - length of buffer
429
430     \return memif_err_t
431 */
432 int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
433                        char *buf, ssize_t buflen);
434
435 /** \brief Memif initialization
436     @param on_control_fd_update - if control fd updates inform user to watch new fd
437     @param app_name - application name (will be truncated to 32 chars)
438     @param memif_alloc - cutom memory allocator, NULL = default
439     @param memif_realloc - custom memory reallocation, NULL = default
440     @param memif_free - custom memory free, NULL = default
441
442     if param on_control_fd_update is set to NULL,
443     libmemif will handle file descriptor event polling
444     if a valid callback is set, file descriptor event polling needs to be done by
445     user application, all file descriptors and event types will be passed in
446     this callback to user application
447
448     Initialize internal libmemif structures. Create timerfd (used to periodically request connection by
449     disconnected memifs in slave mode, with no additional API call). This fd is passed to user with memif_control_fd_update_t
450     timer is inactive at this state. It activates with if there is at least one memif in slave mode.
451
452     \return memif_err_t
453 */
454 int memif_init (memif_control_fd_update_t * on_control_fd_update,
455                 char *app_name, memif_alloc_t * memif_alloc,
456                 memif_realloc_t * memif_realloc, memif_free_t * memif_free);
457
458 /** \brief Memif cleanup
459
460     Free libmemif internal allocations.
461
462     \return 0
463 */
464 int memif_cleanup ();
465
466 /** \brief Memory interface create function
467     @param conn - connection handle for user app
468     @param args - memory interface connection arguments
469     @param on_connect - inform user about connected status
470     @param on_disconnect - inform user about disconnected status
471     @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
472     @param private_ctx - private contex passed back to user with callback
473
474     Creates memory interface.
475      
476     SLAVE-MODE - 
477         Start timer that will send events to timerfd. If this fd is passed to memif_control_fd_handler
478         every disconnected memif in slave mode will send connection request.
479         On success new fd is passed to user with memif_control_fd_update_t.
480
481     MASTER-MODE - 
482         Create listener socket and pass fd to user with memif_cntrol_fd_update_t.
483         If this fd is passed to memif_control_fd_handler accept will be called and
484         new fd will be passed to user with memif_control_fd_update_t.
485
486
487     \return memif_err_t
488 */
489 int memif_create (memif_conn_handle_t * conn, memif_conn_args_t * args,
490                   memif_connection_update_t * on_connect,
491                   memif_connection_update_t * on_disconnect,
492                   memif_interrupt_t * on_interrupt, void *private_ctx);
493
494 /** \brief Memif control file descriptor handler
495     @param fd - file descriptor on which the event occured
496     @param events - event type(s) that occured
497
498     If event occures on any control fd, call memif_control_fd_handler.
499     Internal - lib will "identify" fd (timerfd, lsitener, control) and handle event accordingly.
500  
501     FD-TYPE - 
502         TIMERFD - 
503             Every disconnected memif in slave mode will request connection.
504         LISTENER or CONTROL - 
505             Handle socket messaging (internal connection establishment).
506         INTERRUPT - 
507             Call on_interrupt callback (if set).
508         
509     \return memif_err_t
510
511 */
512 int memif_control_fd_handler (int fd, uint8_t events);
513
514 /** \brief Memif delete
515     @param conn - pointer to memif connection handle
516
517
518     disconnect session (free queues and regions, close file descriptors, unmap shared memory)
519     set connection handle to NULL, to avoid possible double free
520
521     \return memif_err_t
522 */
523 int memif_delete (memif_conn_handle_t * conn);
524
525 /** \brief Memif buffer enq tx
526     @param conn - memif conenction handle
527     @param qid - number indentifying queue
528     @param bufs - memif buffers
529     @param count - number of memif buffers to enque
530     @param count_out - returns number of allocated buffers
531
532     Slave is producer of buffers.
533     If connection handle points to master returns MEMIF_ERR_INVAL_ARG.
534
535     \return memif_err_t
536 */
537 int memif_buffer_enq_tx (memif_conn_handle_t conn, uint16_t qid,
538                          memif_buffer_t * bufs, uint16_t count,
539                          uint16_t * count_out);
540
541 /** \brief Memif buffer alloc
542     @param conn - memif conenction handle
543     @param qid - number indentifying queue
544     @param bufs - memif buffers
545     @param count - number of memif buffers to allocate
546     @param count_out - returns number of allocated buffers
547     @param size - buffer size, may return chained buffers if size > buffer_size
548
549     \return memif_err_t
550 */
551 int memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
552                         memif_buffer_t * bufs, uint16_t count,
553                         uint16_t * count_out, uint16_t size);
554
555 /** \brief Memif refill ring
556     @param conn - memif conenction handle
557     @param qid - number indentifying queue
558     @param count - number of buffers to be placed on ring
559     @param headroom - offset the buffer by headroom
560
561     \return memif_err_t
562 */
563 int memif_refill_queue (memif_conn_handle_t conn, uint16_t qid,
564                         uint16_t count, uint16_t headroom);
565
566 /** \brief Memif transmit buffer burst
567     @param conn - memif conenction handle
568     @param qid - number indentifying queue
569     @param bufs - memif buffers
570     @param count - number of memif buffers to transmit
571     @param tx - returns number of transmitted buffers
572
573     \return memif_err_t
574 */
575 int memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
576                     memif_buffer_t * bufs, uint16_t count, uint16_t * tx);
577
578 /** \brief Memif receive buffer burst
579     @param conn - memif conenction handle
580     @param qid - number indentifying queue
581     @param bufs - memif buffers
582     @param count - number of memif buffers to receive
583     @param rx - returns number of received buffers
584
585     \return memif_err_t
586 */
587 int memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
588                     memif_buffer_t * bufs, uint16_t count, uint16_t * rx);
589
590 /** \brief Memif poll event
591     @param timeout - timeout in seconds
592
593     Passive event polling - 
594     timeout = 0 - dont wait for event, check event queue if there is an event and return.
595     timeout = -1 - wait until event
596
597     \return memif_err_t
598 */
599 int memif_poll_event (int timeout);
600
601 /** \brief Send signal to stop concurrently running memif_poll_event().
602
603     The function, however, does not wait for memif_poll_event() to stop.
604     memif_poll_event() may still return simply because an event has occured
605     or the timeout has elapsed, but if called repeatedly in an infinite loop,
606     a canceled memif_poll_event() is guaranted to return MEMIF_ERR_POLL_CANCEL
607     in the shortest possible time.
608     This feature was not available in the first release.
609     Use macro MEMIF_HAVE_CANCEL_POLL_EVENT to check if the feature is present.
610
611     \return memif_err_t
612 */
613 #define MEMIF_HAVE_CANCEL_POLL_EVENT 1
614 int memif_cancel_poll_event ();
615 /** @} */
616
617 #endif /* _LIBMEMIF_H_ */