blob: f9e3dcd09b3f6fa66724f9004e7b9e05bd113608 [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{
38 MEMIF_ERR_SUCCESS = 0, /*!< success */
39/* SYSCALL ERRORS */
40 MEMIF_ERR_SYSCALL, /*!< other syscall error */
Jakub Grajciar568cc462018-09-05 12:11:35 +020041 MEMIF_ERR_CONNREFUSED, /*!< connection refused */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020042 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 error */
Jakub Grajciar84b83772019-03-04 12:42:19 +010055 MEMIF_ERR_FILE_NOT_SOCK, /*!< file specified by socket filename
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020056 exists, but it's not socket */
57 MEMIF_ERR_NO_SHMFD, /*!< missing shm fd */
58 MEMIF_ERR_COOKIE, /*!< wrong cookie on ring */
59 MEMIF_ERR_NOBUF_RING, /*!< ring buffer full */
60 MEMIF_ERR_NOBUF, /*!< not enough memif buffers */
61 MEMIF_ERR_NOBUF_DET, /*!< memif details needs larger buffer */
62 MEMIF_ERR_INT_WRITE, /*!< send interrupt error */
63 MEMIF_ERR_MFMSG, /*!< malformed msg received */
64 MEMIF_ERR_QID, /*!< invalid queue id */
65/* MEMIF PROTO ERRORS */
66 MEMIF_ERR_PROTO, /*!< incompatible protocol version */
67 MEMIF_ERR_ID, /*!< unmatched interface id */
68 MEMIF_ERR_ACCSLAVE, /*!< slave cannot accept connection requests */
69 MEMIF_ERR_ALRCONN, /*!< memif is already connected */
70 MEMIF_ERR_MODE, /*!< mode mismatch */
71 MEMIF_ERR_SECRET, /*!< secret mismatch */
72 MEMIF_ERR_NOSECRET, /*!< secret required */
73 MEMIF_ERR_MAXREG, /*!< max region limit reached */
74 MEMIF_ERR_MAXRING, /*!< max ring limit reached */
75 MEMIF_ERR_NO_INTFD, /*!< missing interrupt fd */
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -040076 MEMIF_ERR_DISCONNECT, /*!< disconnect received */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020077 MEMIF_ERR_DISCONNECTED, /*!< peer interface disconnected */
78 MEMIF_ERR_UNKNOWN_MSG, /*!< unknown message type */
Milan Lenco0a47c992017-10-12 14:19:31 +020079 MEMIF_ERR_POLL_CANCEL, /*!< memif_poll_event() was cancelled */
Damjan Marion6d56fa42017-11-03 12:24:37 +010080 MEMIF_ERR_MAX_RING, /*!< too large ring size */
Jakub Grajciarab7c2b02018-03-28 10:21:05 +020081 MEMIF_ERR_PRIVHDR, /*!< private hdrs not supported */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020082} memif_err_t;
83
84/**
85 * @defgroup MEMIF_FD_EVENT Types of events that need to be watched for specific fd.
Dave Wallace6cd396c2018-01-23 17:47:02 -050086 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020087 * @{
88 */
89
Paul Vinciguerra62237662020-05-29 23:03:06 -040090/** user needs to set events that occurred on fd and pass them to memif_control_fd_handler */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020091#define MEMIF_FD_EVENT_READ (1 << 0)
92#define MEMIF_FD_EVENT_WRITE (1 << 1)
Paul Vinciguerra62237662020-05-29 23:03:06 -040093/** inform libmemif that error occurred on fd */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +020094#define MEMIF_FD_EVENT_ERROR (1 << 2)
95/** if set, informs that fd is going to be closed (user may want to stop watching for events on this fd) */
96#define MEMIF_FD_EVENT_DEL (1 << 3)
97/** update events */
98#define MEMIF_FD_EVENT_MOD (1 << 4)
99/** @} */
100
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200101/** \brief Memif connection handle
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200102 pointer of type void, pointing to internal structure
103*/
104typedef void *memif_conn_handle_t;
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200105
Jakub Grajciar12df4972019-07-01 14:24:48 +0200106/** \brief Memif socket handle
107 pointer of type void, pointing to internal structure
108*/
109typedef void *memif_socket_handle_t;
110
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200111/** \brief Memif allocator alloc
112 @param size - requested allocation size
113
114 custom memory allocator: alloc function template
115*/
116typedef void *(memif_alloc_t) (size_t size);
117
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200118
119/** \brief Memif realloc
120 @param ptr - pointer to memory block
121 @param size - requested allocation size
122
123 custom memory reallocation
124*/
125typedef void *(memif_realloc_t) (void *ptr, size_t size);
126
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200127/** \brief Memif allocator free
128 @param size - requested allocation size
129
130 custom memory allocator: free function template
131*/
132typedef void (memif_free_t) (void *ptr);
133
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200134/**
135 * @defgroup CALLBACKS Callback functions definitions
Dave Wallace6cd396c2018-01-23 17:47:02 -0500136 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200137 *
138 * @{
139 */
140
141/** \brief Memif control file descriptor update (callback function)
142 @param fd - new file descriptor to watch
143 @param events - event type(s) to watch for
Jakub Grajciar6f090fa2019-11-14 10:47:25 +0100144 @param private_ctx - libmemif main private context. Is NULL for
145 libmemif main created by memif_init()
146
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200147
148 This callback is called when there is new fd to watch for events on
149 or if fd is about to be closed (user mey want to stop watching for events on this fd).
Jakub Grajciar6f090fa2019-11-14 10:47:25 +0100150 Private context is taken from libmemif_main, 'private_ctx' passed to memif_per_thread_init()
151 or NULL in case of memif_init()
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200152*/
Jakub Grajciar12df4972019-07-01 14:24:48 +0200153typedef int (memif_control_fd_update_t) (int fd, uint8_t events,
154 void *private_ctx);
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200155
156/** \brief Memif connection status update (callback function)
157 @param conn - memif connection handle
158 @param private_ctx - private context
159
160 Informs user about connection status connected/disconnected.
161 On connected -> start watching for events on interrupt fd (optional).
162*/
163typedef int (memif_connection_update_t) (memif_conn_handle_t conn,
164 void *private_ctx);
165
Paul Vinciguerra62237662020-05-29 23:03:06 -0400166/** \brief Memif interrupt occurred (callback function)
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200167 @param conn - memif connection handle
168 @param private_ctx - private context
Paul Vinciguerra62237662020-05-29 23:03:06 -0400169 @param qid - queue id on which interrupt occurred
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200170
171 Called when event is received on interrupt fd.
172*/
173typedef int (memif_interrupt_t) (memif_conn_handle_t conn, void *private_ctx,
174 uint16_t qid);
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200175
176/** @} */
177
178/**
179 * @defgroup EXTERNAL_REGION External region APIs
180 * @ingroup libmemif
181 *
182 * @{
183 */
184
185/** \brief Get external buffer offset (optional)
186 @param private_ctx - private context
187
188 Find unallocated external buffer and return its offset.
189*/
190typedef uint32_t (memif_get_external_buffer_offset_t) (void *private_ctx);
191
192/** \brief Add external region
193 @param[out] addr - region address
194 @param size - requested region size
195 @param fd[out] - file descriptor
196 @param private_ctx - private context
197
198 Called by slave. Add external region created by client.
199*/
200typedef int (memif_add_external_region_t) (void * *addr, uint32_t size,
201 int *fd, void *private_ctx);
202
203/** \brief Get external region address
204 @param size - requested region size
205 @param fd - file descriptor
206 @param private_ctx - private context
207
208 Called by master. Get region address from client.
209
210 \return region address
211*/
212typedef void *(memif_get_external_region_addr_t) (uint32_t size, int fd,
213 void *private_ctx);
214
215/** \brief Delete external region
216 @param addr - region address
217 @param size - region size
218 @param fd - file descriptor
219 @param private_ctx - private context
220
221 Delete external region.
222*/
223typedef int (memif_del_external_region_t) (void *addr, uint32_t size, int fd,
224 void *private_ctx);
225
226/** \brief Register external region
227 @param ar - add external region callback
228 @param gr - get external region addr callback
229 @param dr - delete external region callback
230 @param go - get external buffer offset callback (optional)
231*/
232void memif_register_external_region (memif_add_external_region_t * ar,
233 memif_get_external_region_addr_t * gr,
234 memif_del_external_region_t * dr,
235 memif_get_external_buffer_offset_t * go);
236
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200237/** \brief Register external region
238 @param pt_main - per thread main handle
239 @param ar - add external region callback
240 @param gr - get external region addr callback
241 @param dr - delete external region callback
242 @param go - get external buffer offset callback (optional)
Paul Vinciguerra62237662020-05-29 23:03:06 -0400243
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200244void memif_per_thread_register_external_region (memif_per_thread_main_handle_t
245 pt_main,
246 memif_add_external_region_t *
247 ar,
248 memif_get_external_region_addr_t
249 * gr,
250 memif_del_external_region_t *
251 dr,
252 memif_get_external_buffer_offset_t
253 * go);
254
Paul Vinciguerra62237662020-05-29 23:03:06 -0400255 @} */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200256
257/**
258 * @defgroup ARGS_N_BUFS Connection arguments and buffers
Dave Wallace6cd396c2018-01-23 17:47:02 -0500259 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200260 *
261 * @{
262 */
263
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200264#ifndef _MEMIF_H_
265typedef enum
266{
267 MEMIF_INTERFACE_MODE_ETHERNET = 0,
268 MEMIF_INTERFACE_MODE_IP = 1,
269 MEMIF_INTERFACE_MODE_PUNT_INJECT = 2,
270} memif_interface_mode_t;
271#endif /* _MEMIF_H_ */
272
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200273/** \brief Memif connection arguments
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200274 @param socket - Memif socket handle, if NULL default socket will be used.
275 Default socket is only supported in global database (see memif_init).
276 Custom database does not create a default socket
277 (see memif_per_thread_init).
278 Memif connection is stored in the same database as the socket.
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400279 @param secret - optional parameter used as interface authentication
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200280 @param num_s2m_rings - number of slave to master rings
281 @param num_m2s_rings - number of master to slave rings
282 @param buffer_size - size of buffer in shared memory
283 @param log2_ring_size - logarithm base 2 of ring size
284 @param is_master - 0 == master, 1 == slave
285 @param interface_id - id used to identify peer connection
286 @param interface_name - interface name
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200287 @param mode - 0 == ethernet, 1 == ip , 2 == punt/inject
288*/
289typedef struct
290{
Jakub Grajciar12df4972019-07-01 14:24:48 +0200291 memif_socket_handle_t socket; /*!< default = /run/vpp/memif.sock */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200292 uint8_t secret[24]; /*!< optional (interface authentication) */
293
294 uint8_t num_s2m_rings; /*!< default = 1 */
295 uint8_t num_m2s_rings; /*!< default = 1 */
296 uint16_t buffer_size; /*!< default = 2048 */
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200297 uint8_t log2_ring_size; /*!< default = 10 (1024) */
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200298 uint8_t is_master;
299
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200300 uint32_t interface_id;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200301 uint8_t interface_name[32];
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200302 memif_interface_mode_t mode:8;
303} memif_conn_args_t;
304
305/*! memif receive mode */
306typedef enum
307{
308 MEMIF_RX_MODE_INTERRUPT = 0, /*!< interrupt mode */
309 MEMIF_RX_MODE_POLLING /*!< polling mode */
310} memif_rx_mode_t;
311
312/** \brief Memif buffer
313 @param desc_index - ring descriptor index
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200314 @param ring - pointer to ring containing descriptor for this buffer
315 @param len - available length
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200316 @param flags - memif buffer flags
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200317 @param data - pointer to shared memory data
318*/
319typedef struct
320{
321 uint16_t desc_index;
Jakub Grajciarf35fef22021-01-08 15:01:13 +0100322 void *queue;
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200323 uint32_t len;
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200324/** next buffer present (chained buffers) */
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200325#define MEMIF_BUFFER_FLAG_NEXT (1 << 0)
326 uint8_t flags;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200327 void *data;
328} memif_buffer_t;
329/** @} */
330
331/**
332 * @defgroup MEMIF_DETAILS Memif details structs
Dave Wallace6cd396c2018-01-23 17:47:02 -0500333 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200334 *
335 * @{
336 */
337
338/** \brief Memif queue details
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200339 @param region - region index
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200340 @param qid - queue id
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400341 @param ring_size - size of ring buffer in shared memory
Jakub Grajciar84197552017-11-16 14:02:49 +0100342 @param flags - ring flags
343 @param head - ring head pointer
344 @param tail - ring tail pointer
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400345 @param buffer_size - buffer size on shared memory
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200346*/
347typedef struct
348{
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200349 uint8_t region;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200350 uint8_t qid;
351 uint32_t ring_size;
Jakub Grajciar84197552017-11-16 14:02:49 +0100352/** if set queue is in polling mode, else in interrupt mode */
353#define MEMIF_QUEUE_FLAG_POLLING 1
354 uint16_t flags;
355 uint16_t head;
356 uint16_t tail;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200357 uint16_t buffer_size;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200358} memif_queue_details_t;
359
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200360/** \brief Memif region details
361 @param index - region index
362 @param addr - region address
363 @param size - region size
364 @param fd - file descriptor
365 @param is_external - if not zero then region is defined by client
366*/
367typedef struct
368{
369 uint8_t index;
370 void *addr;
371 uint32_t size;
372 int fd;
373 uint8_t is_external;
374} memif_region_details_t;
375
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200376/** \brief Memif details
377 @param if_name - interface name
378 @param inst_name - application name
379 @param remote_if_name - peer interface name
380 @param remote_inst_name - peer application name
381 @param id - connection id
382 @param secret - secret
383 @param role - 0 = master, 1 = slave
384 @param mode - 0 = ethernet, 1 = ip , 2 = punt/inject
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200385 @param socket_filename - socket filename
386 @param regions_num - number of regions
387 @param regions - struct containing region details
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200388 @param rx_queues_num - number of receive queues
389 @param tx_queues_num - number of transmit queues
390 @param rx_queues - struct containing receive queue details
391 @param tx_queues - struct containing transmit queue details
Jakub Grajciar568cc462018-09-05 12:11:35 +0200392 @param error - error string
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200393 @param link_up_down - 1 = up (connected), 2 = down (disconnected)
394*/
395typedef struct
396{
397 uint8_t *if_name;
398 uint8_t *inst_name;
399 uint8_t *remote_if_name;
400 uint8_t *remote_inst_name;
401
402 uint32_t id;
403 uint8_t *secret; /* optional */
404 uint8_t role; /* 0 = master, 1 = slave */
405 uint8_t mode; /* 0 = ethernet, 1 = ip, 2 = punt/inject */
406 uint8_t *socket_filename;
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200407 uint8_t regions_num;
408 memif_region_details_t *regions;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200409 uint8_t rx_queues_num;
410 uint8_t tx_queues_num;
411 memif_queue_details_t *rx_queues;
412 memif_queue_details_t *tx_queues;
413
Jakub Grajciar568cc462018-09-05 12:11:35 +0200414 uint8_t *error;
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200415 uint8_t link_up_down; /* 1 = up, 0 = down */
416} memif_details_t;
417/** @} */
418
419/**
420 * @defgroup API_CALLS Api calls
Dave Wallace6cd396c2018-01-23 17:47:02 -0500421 * @ingroup libmemif
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200422 *
423 * @{
424 */
425
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200426/** \brief Memif get version
427
428 \return ((MEMIF_VERSION_MAJOR << 8) | MEMIF_VERSION_MINOR)
429*/
430uint16_t memif_get_version ();
431
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400432/** \brief Memif get queue event file descriptor
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200433 @param conn - memif connection handle
434 @param qid - queue id
435 @param[out] fd - returns event file descriptor
436
437 \return memif_err_t
438*/
439
440int memif_get_queue_efd (memif_conn_handle_t conn, uint16_t qid, int *fd);
441
442/** \brief Memif set rx mode
443 @param conn - memif connection handle
444 @param rx_mode - receive mode
445 @param qid - queue id
446
447 \return memif_err_t
448*/
449int memif_set_rx_mode (memif_conn_handle_t conn, memif_rx_mode_t rx_mode,
450 uint16_t qid);
451
452/** \brief Memif strerror
453 @param err_code - error code
454
455 Converts error code to error message.
Jakub Grajciar84b83772019-03-04 12:42:19 +0100456
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200457 \return Error string
458*/
459char *memif_strerror (int err_code);
460
461/** \brief Memif get details
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400462 @param conn - memif connection handle
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200463 @param md - pointer to memif details struct
464 @param buf - buffer containing details strings
465 @param buflen - length of buffer
466
467 \return memif_err_t
468*/
469int memif_get_details (memif_conn_handle_t conn, memif_details_t * md,
470 char *buf, ssize_t buflen);
471
472/** \brief Memif initialization
473 @param on_control_fd_update - if control fd updates inform user to watch new fd
Jakub Grajciar19418712018-03-13 13:57:50 +0100474 @param app_name - application name (will be truncated to 32 chars)
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400475 @param memif_alloc - custom memory allocator, NULL = default
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200476 @param memif_realloc - custom memory reallocation, NULL = default
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200477 @param memif_free - custom memory free, NULL = default
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200478
479 if param on_control_fd_update is set to NULL,
480 libmemif will handle file descriptor event polling
481 if a valid callback is set, file descriptor event polling needs to be done by
482 user application, all file descriptors and event types will be passed in
483 this callback to user application
484
485 Initialize internal libmemif structures. Create timerfd (used to periodically request connection by
486 disconnected memifs in slave mode, with no additional API call). This fd is passed to user with memif_control_fd_update_t
487 timer is inactive at this state. It activates with if there is at least one memif in slave mode.
488
489 \return memif_err_t
490*/
491int memif_init (memif_control_fd_update_t * on_control_fd_update,
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200492 char *app_name, memif_alloc_t * memif_alloc,
Jakub Grajciar93a5dd12018-08-20 14:26:32 +0200493 memif_realloc_t * memif_realloc, memif_free_t * memif_free);
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200494
495/** \brief Memif cleanup
496
497 Free libmemif internal allocations.
498
499 \return 0
500*/
501int memif_cleanup ();
502
503/** \brief Memory interface create function
Jakub Grajciar12df4972019-07-01 14:24:48 +0200504 @param conn - connection handle for client app
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200505 @param args - memory interface connection arguments
506 @param on_connect - inform user about connected status
507 @param on_disconnect - inform user about disconnected status
508 @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 -0400509 @param private_ctx - private context passed back to user with callback
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200510
511 Creates memory interface.
Jakub Grajciar84b83772019-03-04 12:42:19 +0100512
513 SLAVE-MODE -
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200514 Start timer that will send events to timerfd. If this fd is passed to memif_control_fd_handler
515 every disconnected memif in slave mode will send connection request.
516 On success new fd is passed to user with memif_control_fd_update_t.
517
Jakub Grajciar84b83772019-03-04 12:42:19 +0100518 MASTER-MODE -
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400519 Create listener socket and pass fd to user with memif_control_fd_update_t.
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200520 If this fd is passed to memif_control_fd_handler accept will be called and
521 new fd will be passed to user with memif_control_fd_update_t.
522
523
524 \return memif_err_t
525*/
526int memif_create (memif_conn_handle_t * conn, memif_conn_args_t * args,
527 memif_connection_update_t * on_connect,
528 memif_connection_update_t * on_disconnect,
529 memif_interrupt_t * on_interrupt, void *private_ctx);
530
531/** \brief Memif control file descriptor handler
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400532 @param fd - file descriptor on which the event occurred
533 @param events - event type(s) that occurred
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200534
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400535 If event occurs on any control fd, call memif_control_fd_handler.
536 Internal - lib will "identify" fd (timerfd, listener, control) and handle event accordingly.
Jakub Grajciar84b83772019-03-04 12:42:19 +0100537
538 FD-TYPE -
539 TIMERFD -
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200540 Every disconnected memif in slave mode will request connection.
Jakub Grajciar84b83772019-03-04 12:42:19 +0100541 LISTENER or CONTROL -
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200542 Handle socket messaging (internal connection establishment).
Jakub Grajciar84b83772019-03-04 12:42:19 +0100543 INTERRUPT -
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200544 Call on_interrupt callback (if set).
Jakub Grajciar84b83772019-03-04 12:42:19 +0100545
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200546 \return memif_err_t
547
548*/
549int memif_control_fd_handler (int fd, uint8_t events);
550
551/** \brief Memif delete
552 @param conn - pointer to memif connection handle
553
554
555 disconnect session (free queues and regions, close file descriptors, unmap shared memory)
556 set connection handle to NULL, to avoid possible double free
557
558 \return memif_err_t
559*/
560int memif_delete (memif_conn_handle_t * conn);
561
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200562/** \brief Memif buffer enq tx
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400563 @param conn - memif connection handle
564 @param qid - number identifying queue
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200565 @param bufs - memif buffers
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400566 @param count - number of memif buffers to enqueue
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200567 @param count_out - returns number of allocated buffers
568
Jakub Grajciarf35fef22021-01-08 15:01:13 +0100569 Enqueue buffers to specified tx queue. Can only be used by slave.
570 Updates desc_index field for each memif buffer.
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200571 If connection handle points to master returns MEMIF_ERR_INVAL_ARG.
572
573 \return memif_err_t
574*/
575int memif_buffer_enq_tx (memif_conn_handle_t conn, uint16_t qid,
576 memif_buffer_t * bufs, uint16_t count,
577 uint16_t * count_out);
578
Jakub Grajciarf35fef22021-01-08 15:01:13 +0100579/** \brief Memif buffer enq tx at idx
580 @param conn - memif connection handle
581 @param buf_a - memif buffer
582 @param buf_b - memif buffer
583
584 Swap descriptors for provided buffers and update the buffers
585*/
586int memif_buffer_requeue (memif_conn_handle_t conn, memif_buffer_t *buf_a,
587 memif_buffer_t *buf_b);
588
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200589/** \brief Memif buffer alloc
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400590 @param conn - memif connection handle
591 @param qid - number identifying queue
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200592 @param bufs - memif buffers
593 @param count - number of memif buffers to allocate
594 @param count_out - returns number of allocated buffers
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200595 @param size - buffer size, may return chained buffers if size > buffer_size
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200596
597 \return memif_err_t
598*/
599int memif_buffer_alloc (memif_conn_handle_t conn, uint16_t qid,
600 memif_buffer_t * bufs, uint16_t count,
Jakub Grajciarb467b2a2017-09-14 14:12:10 +0200601 uint16_t * count_out, uint16_t size);
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200602
Jakub Grajciar47e68de2021-01-08 15:32:43 +0100603/** \brief Memif set next free buffer
604 @param conn - memif connection handle
605 @param qid - number identifying queue
606 @param buf - next free buffer
607
608 Sets next free descriptor pointer for specified tx queue.
609 The next allocation will happen at this buffer.
610*/
611int memif_set_next_free_buffer (memif_conn_handle_t conn, uint16_t qid,
612 memif_buffer_t *buf);
613
Jakub Grajciarf35fef22021-01-08 15:01:13 +0100614/** \brief Memif refill queue
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400615 @param conn - memif connection handle
616 @param qid - number identifying queue
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200617 @param count - number of buffers to be placed on ring
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200618 @param headroom - offset the buffer by headroom
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200619
620 \return memif_err_t
621*/
Jakub Grajciarecfa2aa2018-03-26 11:26:34 +0200622int memif_refill_queue (memif_conn_handle_t conn, uint16_t qid,
Jakub Grajciar3744fc72018-03-29 13:15:10 +0200623 uint16_t count, uint16_t headroom);
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200624
625/** \brief Memif transmit buffer burst
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400626 @param conn - memif connection handle
627 @param qid - number identifying queue
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200628 @param bufs - memif buffers
629 @param count - number of memif buffers to transmit
630 @param tx - returns number of transmitted buffers
631
632 \return memif_err_t
633*/
634int memif_tx_burst (memif_conn_handle_t conn, uint16_t qid,
635 memif_buffer_t * bufs, uint16_t count, uint16_t * tx);
636
637/** \brief Memif receive buffer burst
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400638 @param conn - memif connection handle
639 @param qid - number identifying queue
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200640 @param bufs - memif buffers
641 @param count - number of memif buffers to receive
642 @param rx - returns number of received buffers
643
Jan Cavojsky77a95cd2020-03-03 16:25:58 +0100644 Consume interrupt event for receive queue.
645 The event is not consumed, if memif_rx_burst fails.
646
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200647 \return memif_err_t
648*/
649int memif_rx_burst (memif_conn_handle_t conn, uint16_t qid,
650 memif_buffer_t * bufs, uint16_t count, uint16_t * rx);
651
652/** \brief Memif poll event
653 @param timeout - timeout in seconds
654
Jakub Grajciar84b83772019-03-04 12:42:19 +0100655 Passive event polling -
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200656 timeout = 0 - dont wait for event, check event queue if there is an event and return.
657 timeout = -1 - wait until event
658
659 \return memif_err_t
660*/
661int memif_poll_event (int timeout);
Milan Lenco0a47c992017-10-12 14:19:31 +0200662
Paul Vinciguerra62237662020-05-29 23:03:06 -0400663/** \brief Memif per thread poll event
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200664 @param pt_main - per thread main handle
665 @param timeout - timeout in seconds
666
Milan Lenco0a47c992017-10-12 14:19:31 +0200667/** \brief Send signal to stop concurrently running memif_poll_event().
668
669 The function, however, does not wait for memif_poll_event() to stop.
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400670 memif_poll_event() may still return simply because an event has occurred
Milan Lenco0a47c992017-10-12 14:19:31 +0200671 or the timeout has elapsed, but if called repeatedly in an infinite loop,
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400672 a canceled memif_poll_event() is guaranteed to return MEMIF_ERR_POLL_CANCEL
Milan Lenco0a47c992017-10-12 14:19:31 +0200673 in the shortest possible time.
674 This feature was not available in the first release.
675 Use macro MEMIF_HAVE_CANCEL_POLL_EVENT to check if the feature is present.
676
677 \return memif_err_t
678*/
679#define MEMIF_HAVE_CANCEL_POLL_EVENT 1
680int memif_cancel_poll_event ();
Jakub Grajciar84b83772019-03-04 12:42:19 +0100681
682/** \brief Set connection request timer value
683 @param timer - new timer value
684
685 Timer on which all disconnected slaves request connection.
686 See system call 'timer_settime' man-page.
687
688 \return memif_err_t
689*/
Jakub Grajciar12df4972019-07-01 14:24:48 +0200690int memif_set_connection_request_timer (struct itimerspec timer);
Jakub Grajciar84b83772019-03-04 12:42:19 +0100691
692/** \brief Send connection request
693 @param conn - memif connection handle
694
695 Only slave interface can request connection.
696
697 \return memif_err_t
698*/
Jakub Grajciar12df4972019-07-01 14:24:48 +0200699int memif_request_connection (memif_conn_handle_t conn);
700
701/** \brief Create memif socket
702 @param sock - socket handle for client app
703 @param filename - path to socket file
704 @param private_ctx - private context
705
706 The first time an interface is assigned a socket, its type is determined.
707 For master role it's 'listener', for slave role it's 'client'. Each interface
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400708 requires socket of its respective type. Default socket is created if no
Jakub Grajciar12df4972019-07-01 14:24:48 +0200709 socket handle is passed to memif_create(). It's private context is NULL.
710 If all interfaces using this socket are deleted, the socket returns
711 to its default state.
712
713 \return memif_err_t
714*/
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200715int memif_create_socket (memif_socket_handle_t * sock, const char *filename,
716 void *private_ctx);
717
Jakub Grajciar12df4972019-07-01 14:24:48 +0200718/** \brief Delete memif socket
719 @param sock - socket handle for client app
720
721 When trying to free socket in use, socket will not be freed and
722 MEMIF_ERR_INVAL_ARG is returned.
723
724 \return memif_err_t
725*/
726int memif_delete_socket (memif_socket_handle_t * sock);
727
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200728/** \brief Get socket filename
729 @param sock - socket handle for client app
730
731 Return constant pointer to socket filename.
732
Paul Vinciguerraf4fbfd62020-05-15 23:13:36 -0400733 \return const char *
Jakub Grajciar17f2a7b2019-07-31 14:40:52 +0200734*/
735const char *memif_get_socket_filename (memif_socket_handle_t sock);
736
Jakub Grajciar7c5c40d2017-08-30 10:13:25 +0200737/** @} */
738
739#endif /* _LIBMEMIF_H_ */