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