blob: bb36c39047e2a0f90a44c97d61711185e5246277 [file] [log] [blame]
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +02001/*
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
Dave Wallace6cd396c2018-01-23 17:47:02 -050018/** @file
Paul Vinciguerrab5a575b2019-11-01 13:00:58 -040019 * @defgroup libmemif Example libmemif App
Dave Wallace6cd396c2018-01-23 17:47:02 -050020 */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020021
22#ifndef _LIBMEMIF_H_
23#define _LIBMEMIF_H_
24
25/** Libmemif version. */
Jakub Grajciar45cf1fc2021-01-04 10:39:30 +010026#define LIBMEMIF_VERSION "4.0"
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020027/** Default name of application using libmemif. */
28#define MEMIF_DEFAULT_APP_NAME "libmemif-app"
29
30#include <inttypes.h>
Andrew Yourtchenko085e8d42021-03-09 19:02:06 +000031#include <sys/types.h>
Jakub Grajciar84b83772019-03-04 12:42:19 +010032#include <sys/timerfd.h>
Andrew Yourtchenko387a08a2021-03-11 12:33:59 +000033#include <sys/types.h>
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020034
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020035/*! Error codes */
36typedef enum
37{
Jakub Grajciar134f1e02021-01-04 11:10:42 +010038 MEMIF_ERR_SUCCESS = 0, /*!< success */
39 /* SYSCALL ERRORS */
40 MEMIF_ERR_SYSCALL, /*!< other syscall error */
41 MEMIF_ERR_CONNREFUSED, /*!< connection refused */
42 MEMIF_ERR_ACCES, /*!< permission denied */
43 MEMIF_ERR_NO_FILE, /*!< file does not exist */
44 MEMIF_ERR_FILE_LIMIT, /*!< system open file limit */
45 MEMIF_ERR_PROC_FILE_LIMIT, /*!< process open file limit */
46 MEMIF_ERR_ALREADY, /*!< connection already requested */
47 MEMIF_ERR_AGAIN, /*!< fd is not socket, or operation would block */
48 MEMIF_ERR_BAD_FD, /*!< invalid fd */
49 MEMIF_ERR_NOMEM, /*!< out of memory */
50 /* LIBMEMIF ERRORS */
51 MEMIF_ERR_INVAL_ARG, /*!< invalid argument */
52 MEMIF_ERR_NOCONN, /*!< handle points to no connection */
53 MEMIF_ERR_CONN, /*!< handle points to existing connection */
54 MEMIF_ERR_CB_FDUPDATE, /*!< user defined callback memif_control_fd_update_t
55 error */
56 MEMIF_ERR_FILE_NOT_SOCK, /*!< file specified by socket path
57 exists, but it's not socket */
58 MEMIF_ERR_NO_SHMFD, /*!< missing shm fd */
59 MEMIF_ERR_COOKIE, /*!< wrong cookie on ring */
60 MEMIF_ERR_NOBUF_RING, /*!< ring buffer full */
61 MEMIF_ERR_NOBUF, /*!< not enough memif buffers */
62 MEMIF_ERR_NOBUF_DET, /*!< memif details needs larger buffer */
63 MEMIF_ERR_INT_WRITE, /*!< send interrupt error */
64 MEMIF_ERR_MFMSG, /*!< malformed msg received */
65 MEMIF_ERR_QID, /*!< invalid queue id */
66 /* MEMIF PROTO ERRORS */
67 MEMIF_ERR_PROTO, /*!< incompatible protocol version */
68 MEMIF_ERR_ID, /*!< unmatched interface id */
69 MEMIF_ERR_ACCSLAVE, /*!< slave cannot accept connection requests */
70 MEMIF_ERR_ALRCONN, /*!< memif is already connected */
71 MEMIF_ERR_MODE, /*!< mode mismatch */
72 MEMIF_ERR_SECRET, /*!< secret mismatch */
73 MEMIF_ERR_NOSECRET, /*!< secret required */
74 MEMIF_ERR_MAXREG, /*!< max region limit reached */
75 MEMIF_ERR_MAXRING, /*!< max ring limit reached */
76 MEMIF_ERR_NO_INTFD, /*!< missing interrupt fd */
77 MEMIF_ERR_DISCONNECT, /*!< disconnect received */
78 MEMIF_ERR_DISCONNECTED, /*!< peer interface disconnected */
79 MEMIF_ERR_UNKNOWN_MSG, /*!< unknown message type */
80 MEMIF_ERR_POLL_CANCEL, /*!< memif_poll_event() was cancelled */
81 MEMIF_ERR_MAX_RING, /*!< too large ring size */
82 MEMIF_ERR_PRIVHDR, /*!< private hdrs not supported */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020083} memif_err_t;
84
85/**
86 * @defgroup MEMIF_FD_EVENT Types of events that need to be watched for specific fd.
Dave Wallace6cd396c2018-01-23 17:47:02 -050087 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020088 * @{
89 */
90
Jakub Grajciar134f1e02021-01-04 11:10:42 +010091/** \brief Memif fd events
92 * User needs to set events that occurred on fd and pass them to
93 * memif_control_fd_handler
94 */
95typedef enum memif_fd_event_type
96{
97 MEMIF_FD_EVENT_READ = 1, /* 00001 */
98 MEMIF_FD_EVENT_WRITE = 2, /* 00010 */
99 /** inform libmemif that error occurred on fd */
100 MEMIF_FD_EVENT_ERROR = 4, /* 00100 */
101 /** if set, informs that fd is going to be closed (user may want to stop
102 watching for events on this fd) */
103 MEMIF_FD_EVENT_DEL = 8, /* 01000 */
104 /** update events */
105 MEMIF_FD_EVENT_MOD = 16 /* 10000 */
106} memif_fd_event_type_t;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200107/** @} */
108
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200109/** \brief Memif connection handle
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200110 pointer of type void, pointing to internal structure
111*/
112typedef void *memif_conn_handle_t;
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200113
Jakub Grajciar12df4972019-07-01 14:24:48 +0200114/** \brief Memif socket handle
115 pointer of type void, pointing to internal structure
116*/
117typedef void *memif_socket_handle_t;
118
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200119/** \brief Memif allocator alloc
120 @param size - requested allocation size
121
122 custom memory allocator: alloc function template
123*/
124typedef void *(memif_alloc_t) (size_t size);
125
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200126
127/** \brief Memif realloc
128 @param ptr - pointer to memory block
129 @param size - requested allocation size
130
131 custom memory reallocation
132*/
133typedef void *(memif_realloc_t) (void *ptr, size_t size);
134
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200135/** \brief Memif allocator free
136 @param size - requested allocation size
137
138 custom memory allocator: free function template
139*/
140typedef void (memif_free_t) (void *ptr);
141
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200142/**
143 * @defgroup CALLBACKS Callback functions definitions
Dave Wallace6cd396c2018-01-23 17:47:02 -0500144 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200145 *
146 * @{
147 */
148
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100149/** \brief Memif fd event
150 @param fd - interrupt file descriptor
151 @param type - memif fd event type
152 @param private_ctx - private event data
153*/
154typedef struct memif_fd_event
155{
156 int fd;
157 memif_fd_event_type_t type;
158 void *private_ctx;
159} memif_fd_event_t;
160
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200161/** \brief Memif control file descriptor update (callback function)
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100162 @param fde - memif fd event
163 @param private_ctx - private context of socket this fd belongs to
Jakub Grajciar6f090fa2019-11-14 10:47:25 +0100164
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200165
166 This callback is called when there is new fd to watch for events on
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100167 or if fd is about to be closed (user mey want to stop watching for events
168 on this fd). Private context is taken from libmemif_main, 'private_ctx'
169 passed to memif_per_thread_init() or NULL in case of memif_init()
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200170*/
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100171typedef int (memif_control_fd_update_t) (memif_fd_event_t fde,
Jakub Grajciar12df4972019-07-01 14:24:48 +0200172 void *private_ctx);
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200173
174/** \brief Memif connection status update (callback function)
175 @param conn - memif connection handle
176 @param private_ctx - private context
177
178 Informs user about connection status connected/disconnected.
179 On connected -> start watching for events on interrupt fd (optional).
180*/
181typedef int (memif_connection_update_t) (memif_conn_handle_t conn,
182 void *private_ctx);
183
Paul Vinciguerra62237662020-05-29 23:03:06 -0400184/** \brief Memif interrupt occurred (callback function)
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200185 @param conn - memif connection handle
186 @param private_ctx - private context
Paul Vinciguerra62237662020-05-29 23:03:06 -0400187 @param qid - queue id on which interrupt occurred
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200188
189 Called when event is received on interrupt fd.
190*/
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100191typedef int (memif_on_interrupt_t) (memif_conn_handle_t conn,
192 void *private_ctx, uint16_t qid);
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200193
194/** @} */
195
196/**
197 * @defgroup EXTERNAL_REGION External region APIs
198 * @ingroup libmemif
199 *
200 * @{
201 */
202
203/** \brief Get external buffer offset (optional)
204 @param private_ctx - private context
205
206 Find unallocated external buffer and return its offset.
207*/
208typedef uint32_t (memif_get_external_buffer_offset_t) (void *private_ctx);
209
210/** \brief Add external region
211 @param[out] addr - region address
212 @param size - requested region size
213 @param fd[out] - file descriptor
214 @param private_ctx - private context
215
216 Called by slave. Add external region created by client.
217*/
218typedef int (memif_add_external_region_t) (void * *addr, uint32_t size,
219 int *fd, void *private_ctx);
220
221/** \brief Get external region address
222 @param size - requested region size
223 @param fd - file descriptor
224 @param private_ctx - private context
225
226 Called by master. Get region address from client.
227
228 \return region address
229*/
230typedef void *(memif_get_external_region_addr_t) (uint32_t size, int fd,
231 void *private_ctx);
232
233/** \brief Delete external region
234 @param addr - region address
235 @param size - region size
236 @param fd - file descriptor
237 @param private_ctx - private context
238
239 Delete external region.
240*/
241typedef int (memif_del_external_region_t) (void *addr, uint32_t size, int fd,
242 void *private_ctx);
243
244/** \brief Register external region
245 @param ar - add external region callback
246 @param gr - get external region addr callback
247 @param dr - delete external region callback
248 @param go - get external buffer offset callback (optional)
249*/
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100250void memif_register_external_region (memif_socket_handle_t sock,
251 memif_add_external_region_t *ar,
252 memif_get_external_region_addr_t *gr,
253 memif_del_external_region_t *dr,
254 memif_get_external_buffer_offset_t *go);
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200255
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200256/** \brief Register external region
257 @param pt_main - per thread main handle
258 @param ar - add external region callback
259 @param gr - get external region addr callback
260 @param dr - delete external region callback
261 @param go - get external buffer offset callback (optional)
Paul Vinciguerra62237662020-05-29 23:03:06 -0400262
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200263void memif_per_thread_register_external_region (memif_per_thread_main_handle_t
264 pt_main,
265 memif_add_external_region_t *
266 ar,
267 memif_get_external_region_addr_t
268 * gr,
269 memif_del_external_region_t *
270 dr,
271 memif_get_external_buffer_offset_t
272 * go);
273
Paul Vinciguerra62237662020-05-29 23:03:06 -0400274 @} */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200275
276/**
277 * @defgroup ARGS_N_BUFS Connection arguments and buffers
Dave Wallace6cd396c2018-01-23 17:47:02 -0500278 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200279 *
280 * @{
281 */
282
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200283#ifndef _MEMIF_H_
284typedef enum
285{
286 MEMIF_INTERFACE_MODE_ETHERNET = 0,
287 MEMIF_INTERFACE_MODE_IP = 1,
288 MEMIF_INTERFACE_MODE_PUNT_INJECT = 2,
289} memif_interface_mode_t;
290#endif /* _MEMIF_H_ */
291
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100292/** \brief Memif socket arguments
293 @param path - UNIX socket path, supports abstract socket (have '\0' or '@'
294 as the first char of the path)
295 @param app_name - application name
296 @param connection_request_timer - automaticaly request connection each time
297 this timer expires, must be non-zero to enable this feature
298 @param on_control_fd_update - if control fd updates inform user to watch
299 new fd
300 @param alloc - custom memory allocator, NULL = default
301 @param realloc - custom memory reallocation, NULL = default
302 @param free - custom memory free, NULL = default
303
304 If param on_control_fd_update is set to NULL,
305 libmemif will handle file descriptor event polling
306 if a valid callback is set, file descriptor event polling needs to be done
307 by user application, all file descriptors and event types will be passed in
308 this callback to user application
309*/
310typedef struct memif_socket_args
311{
312 char path[108];
313 char app_name[32];
314
315 struct itimerspec connection_request_timer;
316
317 memif_control_fd_update_t *on_control_fd_update;
318 memif_alloc_t *alloc;
319 memif_realloc_t *realloc;
320 memif_free_t *free;
321} memif_socket_args_t;
322
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200323/** \brief Memif connection arguments
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200324 @param socket - Memif socket handle, if NULL default socket will be used.
325 Default socket is only supported in global database (see memif_init).
326 Custom database does not create a default socket
327 (see memif_per_thread_init).
328 Memif connection is stored in the same database as the socket.
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400329 @param secret - optional parameter used as interface authentication
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200330 @param num_s2m_rings - number of slave to master rings
331 @param num_m2s_rings - number of master to slave rings
332 @param buffer_size - size of buffer in shared memory
333 @param log2_ring_size - logarithm base 2 of ring size
334 @param is_master - 0 == master, 1 == slave
335 @param interface_id - id used to identify peer connection
336 @param interface_name - interface name
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200337 @param mode - 0 == ethernet, 1 == ip , 2 == punt/inject
338*/
339typedef struct
340{
Jakub Grajciar12df4972019-07-01 14:24:48 +0200341 memif_socket_handle_t socket; /*!< default = /run/vpp/memif.sock */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200342 uint8_t secret[24]; /*!< optional (interface authentication) */
343
344 uint8_t num_s2m_rings; /*!< default = 1 */
345 uint8_t num_m2s_rings; /*!< default = 1 */
346 uint16_t buffer_size; /*!< default = 2048 */
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200347 uint8_t log2_ring_size; /*!< default = 10 (1024) */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200348 uint8_t is_master;
349
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200350 uint32_t interface_id;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200351 uint8_t interface_name[32];
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200352 memif_interface_mode_t mode:8;
353} memif_conn_args_t;
354
355/*! memif receive mode */
356typedef enum
357{
358 MEMIF_RX_MODE_INTERRUPT = 0, /*!< interrupt mode */
359 MEMIF_RX_MODE_POLLING /*!< polling mode */
360} memif_rx_mode_t;
361
362/** \brief Memif buffer
363 @param desc_index - ring descriptor index
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200364 @param ring - pointer to ring containing descriptor for this buffer
365 @param len - available length
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200366 @param flags - memif buffer flags
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200367 @param data - pointer to shared memory data
368*/
369typedef struct
370{
371 uint16_t desc_index;
Jakub Grajciarf35fef22021-01-08 15:01:13 +0100372 void *queue;
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200373 uint32_t len;
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200374/** next buffer present (chained buffers) */
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200375#define MEMIF_BUFFER_FLAG_NEXT (1 << 0)
376 uint8_t flags;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200377 void *data;
378} memif_buffer_t;
379/** @} */
380
381/**
382 * @defgroup MEMIF_DETAILS Memif details structs
Dave Wallace6cd396c2018-01-23 17:47:02 -0500383 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200384 *
385 * @{
386 */
387
388/** \brief Memif queue details
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200389 @param region - region index
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200390 @param qid - queue id
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400391 @param ring_size - size of ring buffer in shared memory
Jakub Grajciar84197552017-11-16 14:02:49 +0100392 @param flags - ring flags
393 @param head - ring head pointer
394 @param tail - ring tail pointer
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400395 @param buffer_size - buffer size on shared memory
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200396*/
397typedef struct
398{
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200399 uint8_t region;
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100400 uint16_t qid;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200401 uint32_t ring_size;
Jakub Grajciar84197552017-11-16 14:02:49 +0100402/** if set queue is in polling mode, else in interrupt mode */
403#define MEMIF_QUEUE_FLAG_POLLING 1
404 uint16_t flags;
405 uint16_t head;
406 uint16_t tail;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200407 uint16_t buffer_size;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200408} memif_queue_details_t;
409
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200410/** \brief Memif region details
411 @param index - region index
412 @param addr - region address
413 @param size - region size
414 @param fd - file descriptor
415 @param is_external - if not zero then region is defined by client
416*/
417typedef struct
418{
419 uint8_t index;
420 void *addr;
421 uint32_t size;
422 int fd;
423 uint8_t is_external;
424} memif_region_details_t;
425
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200426/** \brief Memif details
427 @param if_name - interface name
428 @param inst_name - application name
429 @param remote_if_name - peer interface name
430 @param remote_inst_name - peer application name
431 @param id - connection id
432 @param secret - secret
433 @param role - 0 = master, 1 = slave
434 @param mode - 0 = ethernet, 1 = ip , 2 = punt/inject
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100435 @param socket_path - socket path
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200436 @param regions_num - number of regions
437 @param regions - struct containing region details
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200438 @param rx_queues_num - number of receive queues
439 @param tx_queues_num - number of transmit queues
440 @param rx_queues - struct containing receive queue details
441 @param tx_queues - struct containing transmit queue details
Jakub Grajciar568cc462018-09-05 12:11:35 +0200442 @param error - error string
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200443 @param link_up_down - 1 = up (connected), 2 = down (disconnected)
444*/
445typedef struct
446{
447 uint8_t *if_name;
448 uint8_t *inst_name;
449 uint8_t *remote_if_name;
450 uint8_t *remote_inst_name;
451
452 uint32_t id;
453 uint8_t *secret; /* optional */
454 uint8_t role; /* 0 = master, 1 = slave */
455 uint8_t mode; /* 0 = ethernet, 1 = ip, 2 = punt/inject */
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100456 uint8_t *socket_path;
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200457 uint8_t regions_num;
458 memif_region_details_t *regions;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200459 uint8_t rx_queues_num;
460 uint8_t tx_queues_num;
461 memif_queue_details_t *rx_queues;
462 memif_queue_details_t *tx_queues;
463
Jakub Grajciar568cc462018-09-05 12:11:35 +0200464 uint8_t *error;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200465 uint8_t link_up_down; /* 1 = up, 0 = down */
466} memif_details_t;
467/** @} */
468
469/**
470 * @defgroup API_CALLS Api calls
Dave Wallace6cd396c2018-01-23 17:47:02 -0500471 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200472 *
473 * @{
474 */
475
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200476/** \brief Memif get version
477
478 \return ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
479*/
480uint16_t memif_get_version ();
481
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100482/** \brief Get memif version as string
483 \return major.minor
484*/
485const char *memif_get_version_str ();
486
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400487/** \brief Memif get queue event file descriptor
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200488 @param conn - memif connection handle
489 @param qid - queue id
490 @param[out] fd - returns event file descriptor
491
492 \return memif_err_t
493*/
494
495int memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *fd);
496
497/** \brief Memif set rx mode
498 @param conn - memif connection handle
499 @param rx_mode - receive mode
500 @param qid - queue id
501
502 \return memif_err_t
503*/
504int memif_set_rx_mode (memif_conn_handle_t conn, memif_rx_mode_t rx_mode,
505 uint16_t qid);
506
507/** \brief Memif strerror
508 @param err_code - error code
509
510 Converts error code to error message.
Jakub Grajciar84b83772019-03-04 12:42:19 +0100511
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200512 \return Error string
513*/
514char *memif_strerror (int err_code);
515
516/** \brief Memif get details
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400517 @param conn - memif connection handle
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200518 @param md - pointer to memif details struct
519 @param buf - buffer containing details strings
520 @param buflen - length of buffer
521
522 \return memif_err_t
523*/
524int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
525 char *buf, ssize_t buflen);
526
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200527/** \brief Memory interface create function
Jakub Grajciar12df4972019-07-01 14:24:48 +0200528 @param conn - connection handle for client app
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200529 @param args - memory interface connection arguments
530 @param on_connect - inform user about connected status
531 @param on_disconnect - inform user about disconnected status
532 @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
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400533 @param private_ctx - private context passed back to user with callback
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200534
535 Creates memory interface.
Jakub Grajciar84b83772019-03-04 12:42:19 +0100536
537 SLAVE-MODE -
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200538 Start timer that will send events to timerfd. If this fd is passed to memif_control_fd_handler
539 every disconnected memif in slave mode will send connection request.
540 On success new fd is passed to user with memif_control_fd_update_t.
541
Jakub Grajciar84b83772019-03-04 12:42:19 +0100542 MASTER-MODE -
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400543 Create listener socket and pass fd to user with memif_control_fd_update_t.
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200544 If this fd is passed to memif_control_fd_handler accept will be called and
545 new fd will be passed to user with memif_control_fd_update_t.
546
547
548 \return memif_err_t
549*/
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100550int memif_create (memif_conn_handle_t *conn, memif_conn_args_t *args,
551 memif_connection_update_t *on_connect,
552 memif_connection_update_t *on_disconnect,
553 memif_on_interrupt_t *on_interrupt, void *private_ctx);
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200554
555/** \brief Memif control file descriptor handler
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100556 @param ptr - pointer to event data
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400557 @param events - event type(s) that occurred
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200558
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200559 \return memif_err_t
560
561*/
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100562int memif_control_fd_handler (void *ptr, memif_fd_event_type_t events);
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200563
564/** \brief Memif delete
565 @param conn - pointer to memif connection handle
566
567
568 disconnect session (free queues and regions, close file descriptors, unmap shared memory)
569 set connection handle to NULL, to avoid possible double free
570
571 \return memif_err_t
572*/
573int memif_delete (memif_conn_handle_t * conn);
574
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200575/** \brief Memif buffer enq tx
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400576 @param conn - memif connection handle
577 @param qid - number identifying queue
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200578 @param bufs - memif buffers
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400579 @param count - number of memif buffers to enqueue
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200580 @param count_out - returns number of allocated buffers
581
Jakub Grajciarf35fef22021-01-08 15:01:13 +0100582 Enqueue buffers to specified tx queue. Can only be used by slave.
583 Updates desc_index field for each memif buffer.
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200584 If connection handle points to master returns MEMIF_ERR_INVAL_ARG.
585
586 \return memif_err_t
587*/
588int memif_buffer_enq_tx (memif_conn_handle_t conn, uint16_t qid,
589 memif_buffer_t * bufs, uint16_t count,
590 uint16_t * count_out);
591
Jakub Grajciarf35fef22021-01-08 15:01:13 +0100592/** \brief Memif buffer enq tx at idx
593 @param conn - memif connection handle
594 @param buf_a - memif buffer
595 @param buf_b - memif buffer
596
597 Swap descriptors for provided buffers and update the buffers
598*/
599int memif_buffer_requeue (memif_conn_handle_t conn, memif_buffer_t *buf_a,
600 memif_buffer_t *buf_b);
601
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200602/** \brief Memif buffer alloc
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400603 @param conn - memif connection handle
604 @param qid - number identifying queue
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200605 @param bufs - memif buffers
606 @param count - number of memif buffers to allocate
607 @param count_out - returns number of allocated buffers
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200608 @param size - buffer size, may return chained buffers if size > buffer_size
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200609
610 \return memif_err_t
611*/
612int memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
613 memif_buffer_t * bufs, uint16_t count,
Jakub Grajciarb467b2a2017-09-14 14:12:10 +0200614 uint16_t * count_out, uint16_t size);
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200615
Jakub Grajciar47e68de2021-01-08 15:32:43 +0100616/** \brief Memif set next free buffer
617 @param conn - memif connection handle
618 @param qid - number identifying queue
619 @param buf - next free buffer
620
621 Sets next free descriptor pointer for specified tx queue.
622 The next allocation will happen at this buffer.
623*/
624int memif_set_next_free_buffer (memif_conn_handle_t conn, uint16_t qid,
625 memif_buffer_t *buf);
626
Jakub Grajciarf35fef22021-01-08 15:01:13 +0100627/** \brief Memif refill queue
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400628 @param conn - memif connection handle
629 @param qid - number identifying queue
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200630 @param count - number of buffers to be placed on ring
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200631 @param headroom - offset the buffer by headroom
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200632
633 \return memif_err_t
634*/
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200635int memif_refill_queue (memif_conn_handle_t conn, uint16_t qid,
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200636 uint16_t count, uint16_t headroom);
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200637
638/** \brief Memif transmit buffer burst
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400639 @param conn - memif connection handle
640 @param qid - number identifying queue
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200641 @param bufs - memif buffers
642 @param count - number of memif buffers to transmit
643 @param tx - returns number of transmitted buffers
644
645 \return memif_err_t
646*/
647int memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
648 memif_buffer_t * bufs, uint16_t count, uint16_t * tx);
649
650/** \brief Memif receive buffer burst
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400651 @param conn - memif connection handle
652 @param qid - number identifying queue
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200653 @param bufs - memif buffers
654 @param count - number of memif buffers to receive
655 @param rx - returns number of received buffers
656
Jan Cavojsky77a95cd2020-03-03 16:25:58 +0100657 Consume interrupt event for receive queue.
658 The event is not consumed, if memif_rx_burst fails.
659
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200660 \return memif_err_t
661*/
662int memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
663 memif_buffer_t * bufs, uint16_t count, uint16_t * rx);
664
665/** \brief Memif poll event
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100666 @param sock - socket to poll events on
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200667 @param timeout - timeout in seconds
668
Jakub Grajciar84b83772019-03-04 12:42:19 +0100669 Passive event polling -
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100670 timeout = 0 - dont wait for event, check event queue if there is an event
671 and return. timeout = -1 - wait until event
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200672
673 \return memif_err_t
674*/
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100675int memif_poll_event (memif_socket_handle_t sock, int timeout);
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200676
Milan Lenco0a47c992017-10-12 14:19:31 +0200677/** \brief Send signal to stop concurrently running memif_poll_event().
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100678 @param sock - stop polling on this socket
Milan Lenco0a47c992017-10-12 14:19:31 +0200679
680 The function, however, does not wait for memif_poll_event() to stop.
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400681 memif_poll_event() may still return simply because an event has occurred
Milan Lenco0a47c992017-10-12 14:19:31 +0200682 or the timeout has elapsed, but if called repeatedly in an infinite loop,
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400683 a canceled memif_poll_event() is guaranteed to return MEMIF_ERR_POLL_CANCEL
Milan Lenco0a47c992017-10-12 14:19:31 +0200684 in the shortest possible time.
685 This feature was not available in the first release.
686 Use macro MEMIF_HAVE_CANCEL_POLL_EVENT to check if the feature is present.
687
688 \return memif_err_t
689*/
690#define MEMIF_HAVE_CANCEL_POLL_EVENT 1
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100691int memif_cancel_poll_event (memif_socket_handle_t sock);
Jakub Grajciar84b83772019-03-04 12:42:19 +0100692
693/** \brief Send connection request
694 @param conn - memif connection handle
695
696 Only slave interface can request connection.
697
698 \return memif_err_t
699*/
Jakub Grajciar12df4972019-07-01 14:24:48 +0200700int memif_request_connection (memif_conn_handle_t conn);
701
702/** \brief Create memif socket
703 @param sock - socket handle for client app
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100704 @param args - memif socket arguments
Jakub Grajciar12df4972019-07-01 14:24:48 +0200705 @param private_ctx - private context
706
707 The first time an interface is assigned a socket, its type is determined.
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100708 For master role it's 'listener', for slave role it's 'client'. Each
709 interface requires socket of its respective type. Default socket is created
710 if no socket handle is passed to memif_create(). It's private context is
711 NULL. If all interfaces using this socket are deleted, the socket returns to
712 its default state.
Jakub Grajciar12df4972019-07-01 14:24:48 +0200713
714 \return memif_err_t
715*/
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100716int memif_create_socket (memif_socket_handle_t *sock,
717 memif_socket_args_t *args, void *private_ctx);
718
719/** \brief Get memif socket handle from connection
720 @param conn - memif connection handle
721
722 \return memif_socket_handle_t
723*/
724memif_socket_handle_t memif_get_socket_handle (memif_conn_handle_t conn);
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200725
Jakub Grajciar12df4972019-07-01 14:24:48 +0200726/** \brief Delete memif socket
727 @param sock - socket handle for client app
728
729 When trying to free socket in use, socket will not be freed and
730 MEMIF_ERR_INVAL_ARG is returned.
731
732 \return memif_err_t
733*/
734int memif_delete_socket (memif_socket_handle_t * sock);
735
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100736/** \brief Get socket path
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200737 @param sock - socket handle for client app
738
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100739 Return constant pointer to socket path.
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200740
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400741 \return const char *
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200742*/
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100743const char *memif_get_socket_path (memif_socket_handle_t sock);
744
745/** \brief Get listener file descriptor
746 @param sock - memif socket handle
747
748 \return listener fd
749*/
750int memif_get_listener_fd (memif_socket_handle_t sock);
751
752/** \brief Set listener file descriptor
753 @param sock - memif socket handle
754 @param if - file descriptor
755
756 \return memif_err_t
757*/
758int memif_set_listener_fd (memif_socket_handle_t sock, int fd);
759
760/** \brief Set connection request timer value
761 @param sock - memif socket handle
762 @param timer - new timer value
763
764 Timer on which all disconnected slaves request connection.
765 If the timer doesn't exist (timerspec is 0) create new timer.
766 See system call 'timer_settime' man-page.
767 \return memif_err_t
768*/
769int memif_set_connection_request_timer (memif_socket_handle_t sock,
770 struct itimerspec timer);
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200771
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200772/** @} */
773
Jakub Grajciar134f1e02021-01-04 11:10:42 +0100774#endif /* _LIBMEMIF_H_ */