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:
8 * http://www.apache.org/licenses/LICENSE-2.0
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 *------------------------------------------------------------------
25 /** Libmemif version. */
26 #define LIBMEMIF_VERSION "2.1"
27 /** Default name of application using libmemif. */
28 #define MEMIF_DEFAULT_APP_NAME "libmemif-app"
31 #include <sys/timerfd.h>
36 MEMIF_ERR_SUCCESS = 0, /*!< success */
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 */
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 */
83 * @defgroup MEMIF_FD_EVENT Types of events that need to be watched for specific fd.
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)
96 #define MEMIF_FD_EVENT_MOD (1 << 4)
99 /** \brief Memif connection handle
100 pointer of type void, pointing to internal structure
102 typedef void *memif_conn_handle_t;
104 /** \brief Memif allocator alloc
105 @param size - requested allocation size
107 custom memory allocator: alloc function template
109 typedef void *(memif_alloc_t) (size_t size);
112 /** \brief Memif realloc
113 @param ptr - pointer to memory block
114 @param size - requested allocation size
116 custom memory reallocation
118 typedef void *(memif_realloc_t) (void *ptr, size_t size);
120 /** \brief Memif allocator free
121 @param size - requested allocation size
123 custom memory allocator: free function template
125 typedef void (memif_free_t) (void *ptr);
128 * @defgroup CALLBACKS Callback functions definitions
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
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).
141 typedef int (memif_control_fd_update_t) (int fd, uint8_t events);
143 /** \brief Memif connection status update (callback function)
144 @param conn - memif connection handle
145 @param private_ctx - private context
147 Informs user about connection status connected/disconnected.
148 On connected -> start watching for events on interrupt fd (optional).
150 typedef int (memif_connection_update_t) (memif_conn_handle_t conn,
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
158 Called when event is received on interrupt fd.
160 typedef int (memif_interrupt_t) (memif_conn_handle_t conn, void *private_ctx,
166 * @defgroup EXTERNAL_REGION External region APIs
172 /** \brief Get external buffer offset (optional)
173 @param private_ctx - private context
175 Find unallocated external buffer and return its offset.
177 typedef uint32_t (memif_get_external_buffer_offset_t) (void *private_ctx);
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
185 Called by slave. Add external region created by client.
187 typedef int (memif_add_external_region_t) (void * *addr, uint32_t size,
188 int *fd, void *private_ctx);
190 /** \brief Get external region address
191 @param size - requested region size
192 @param fd - file descriptor
193 @param private_ctx - private context
195 Called by master. Get region address from client.
197 \return region address
199 typedef void *(memif_get_external_region_addr_t) (uint32_t size, int fd,
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
208 Delete external region.
210 typedef int (memif_del_external_region_t) (void *addr, uint32_t size, int fd,
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)
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);
227 * @defgroup ARGS_N_BUFS Connection arguments and buffers
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_ */
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
256 uint8_t *socket_filename; /*!< default = /run/vpp/memif.sock */
257 uint8_t secret[24]; /*!< optional (interface authentication) */
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) */
265 uint32_t interface_id;
266 uint8_t interface_name[32];
267 memif_interface_mode_t mode:8;
270 /*! memif receive mode */
273 MEMIF_RX_MODE_INTERRUPT = 0, /*!< interrupt mode */
274 MEMIF_RX_MODE_POLLING /*!< polling mode */
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
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)
299 * @defgroup MEMIF_DETAILS Memif details structs
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
319 /** if set queue is in polling mode, else in interrupt mode */
320 #define MEMIF_QUEUE_FLAG_POLLING 1
324 uint16_t buffer_size;
325 } memif_queue_details_t;
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
341 } memif_region_details_t;
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)
366 uint8_t *remote_if_name;
367 uint8_t *remote_inst_name;
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;
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;
382 uint8_t link_up_down; /* 1 = up, 0 = down */
387 * @defgroup API_CALLS Api calls
393 /** \brief Memif get version
395 \return ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
397 uint16_t memif_get_version ();
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
407 int memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *fd);
409 /** \brief Memif set rx mode
410 @param conn - memif connection handle
411 @param rx_mode - receive mode
412 @param qid - queue id
416 int memif_set_rx_mode (memif_conn_handle_t conn, memif_rx_mode_t rx_mode,
419 /** \brief Memif strerror
420 @param err_code - error code
422 Converts error code to error message.
426 char *memif_strerror (int err_code);
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
436 int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
437 char *buf, ssize_t buflen);
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
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
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.
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);
462 /** \brief Memif cleanup
464 Free libmemif internal allocations.
468 int memif_cleanup ();
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
478 Creates memory interface.
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.
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.
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);
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
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.
507 Every disconnected memif in slave mode will request connection.
508 LISTENER or CONTROL -
509 Handle socket messaging (internal connection establishment).
511 Call on_interrupt callback (if set).
516 int memif_control_fd_handler (int fd, uint8_t events);
518 /** \brief Memif delete
519 @param conn - pointer to memif connection handle
522 disconnect session (free queues and regions, close file descriptors, unmap shared memory)
523 set connection handle to NULL, to avoid possible double free
527 int memif_delete (memif_conn_handle_t * conn);
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
536 Slave is producer of buffers.
537 If connection handle points to master returns MEMIF_ERR_INVAL_ARG.
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);
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
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);
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
567 int memif_refill_queue (memif_conn_handle_t conn, uint16_t qid,
568 uint16_t count, uint16_t headroom);
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
579 int memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
580 memif_buffer_t * bufs, uint16_t count, uint16_t * tx);
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
591 int memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
592 memif_buffer_t * bufs, uint16_t count, uint16_t * rx);
594 /** \brief Memif poll event
595 @param timeout - timeout in seconds
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
603 int memif_poll_event (int timeout);
605 /** \brief Send signal to stop concurrently running memif_poll_event().
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.
617 #define MEMIF_HAVE_CANCEL_POLL_EVENT 1
618 int memif_cancel_poll_event ();
620 /** \brief Set connection request timer value
621 @param timer - new timer value
623 Timer on which all disconnected slaves request connection.
624 See system call 'timer_settime' man-page.
628 int memif_set_connection_request_timer(struct itimerspec timer);
630 /** \brief Send connection request
631 @param conn - memif connection handle
633 Only slave interface can request connection.
637 int memif_request_connection(memif_conn_handle_t conn);
640 #endif /* _LIBMEMIF_H_ */