]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/libnetmap/libnetmap.h
Optionally bind ktls threads to NUMA domains
[FreeBSD/FreeBSD.git] / lib / libnetmap / libnetmap.h
1 /*-
2  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
3  *
4  * Copyright (C) 2018 Universita` di Pisa
5  * All rights reserved.
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  *
11  *   1. Redistributions of source code must retain the above copyright
12  *      notice, this list of conditions and the following disclaimer.
13  *   2. Redistributions in binary form must reproduce the above copyright
14  *      notice, this list of conditions and the following disclaimer in the
15  *      documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  * $FreeBSD$
29  */
30
31 #ifndef LIBNETMAP_H_
32 #define LIBNETMAP_H_
33 /* if thread-safety is not needed, define LIBNETMAP_NOTHREADSAFE before including
34  * this file.
35  */
36
37 /* NOTE: we include net/netmap_user.h without defining NETMAP_WITH_LIBS, which
38  * is deprecated. If you still need it, please define NETMAP_WITH_LIBS and
39  * include net/netmap_user.h before including this file.
40  */
41 #include <net/netmap_user.h>
42
43 struct nmctx;
44 struct nmport_d;
45 struct nmem_d;
46
47 /*
48  * A port open specification (portspec for brevity) has the following syntax
49  * (square brackets delimit optional parts):
50  *
51  *     subsystem:vpname[mode][options]
52  *
53  *  The "subsystem" is denoted by a prefix, possibly followed by an identifier.
54  *  There can be several kinds of subsystems, each one selected by a unique
55  *  prefix.  Currently defined subsystems are:
56  *
57  *  netmap              (no id allowed)
58  *                      the standard subsystem
59  *
60  *  vale                (followed by a possibly empty id)
61  *                      the vpname is connected to a VALE switch identified by
62  *                      the id (an empty id selects the default switch)
63  *
64  *  The "vpname" has the following syntax:
65  *
66  *     identifier                       or
67  *     identifier1{identifier2          or
68  *     identifier1}identifier2
69  *
70  *  Identifiers are sequences of alphanumeric characters. The part that begins
71  *  with either '{' or '}', when present, denotes a netmap pipe opened in the
72  *  same memory region as the subsystem:indentifier1 port.
73  *
74  * The "mode" can be one of the following:
75  *
76  *      ^               bind all host (sw) ring pairs
77  *      ^NN             bind individual host ring pair
78  *      *               bind host and NIC ring pairs
79  *      -NN             bind individual NIC ring pair
80  *      @NN             open the port in the NN memory region
81  *      a suffix starting with / and the following flags,
82  *      in any order:
83  *      x               exclusive access
84  *      z               zero copy monitor (both tx and rx)
85  *      t               monitor tx side (copy monitor)
86  *      r               monitor rx side (copy monitor)
87  *      R               bind only RX ring(s)
88  *      T               bind only TX ring(s)
89  *
90  *  The "options" start at the first '@' character not followed by a number.
91  *  Each option starts with '@' and has the following syntax:
92  *
93  *      option                                  (flag option)
94  *      option=value                            (single key option)
95  *      option:key1=value1,key2=value2,...      (multi-key option)
96  *
97  *  For multi-key options, the keys can be assigned in any order, but they
98  *  cannot be assigned more than once. It is not necessary to assign all the
99  *  option keys: unmentioned keys will receive default values.  Some multi-key
100  *  options define a default key and also accept the single-key syntax, by
101  *  assigning the value to this key.
102  *
103  *  NOTE: Options may be silently ignored if the port is already open by some
104  *  other process.
105  *
106  *  The currently available options are (default keys, when defined, are marked
107  *  with '*'):
108  *
109  *  share (single-key)
110  *                      open the port in the same memory region used by the
111  *                      given port name (the port name must be given in
112  *                      subsystem:vpname form)
113  *
114  *  conf  (multi-key)
115  *                      specify the rings/slots numbers (effective only on
116  *                      ports that are created by the open operation itself,
117  *                      and ignored otherwise).
118  *
119  *                      The keys are:
120  *
121  *                     *rings           number of tx and rx rings
122  *                      tx-rings        number of tx rings
123  *                      rx-rings        number of rx rings
124  *                      host-rings      number of tx and rx host rings
125  *                      host-tx-rings   number of host tx rings
126  *                      host-rx-rings   number of host rx rings
127  *                      slots           number of slots in each tx and rx
128  *                                      ring
129  *                      tx-slots        number of slots in each tx ring
130  *                      rx-slots        number of slots in each rx ring
131  *
132  *                      (more specific keys override the less specific ones)
133  *                      All keys default to zero if not assigned, and the
134  *                      corresponding value will be chosen by netmap.
135  *
136  *  extmem (multi-key)
137  *                      open the port in the memory region obtained by
138  *                      mmap()ing the given file.
139  *
140  *                      The keys are:
141  *
142  *                     *file            the file to mmap
143  *                      if-num          number of pre-allocated netmap_if's
144  *                      if-size         size of each netmap_if
145  *                      ring-num        number of pre-allocated netmap_ring's
146  *                      ring-size       size of each netmap_ring
147  *                      buf-num         number of pre-allocated buffers
148  *                      buf-size        size of each buffer
149  *
150  *                      file must be assigned. The other keys default to zero,
151  *                      causing netmap to take the corresponding values from
152  *                      the priv_{if,ring,buf}_{num,size} sysctls.
153  *
154  */
155
156
157 /* nmport manipulation */
158
159 /* struct nmport_d - describes a netmap port */
160 struct nmport_d {
161         /* see net/netmap.h for the definition of these fields */
162         struct nmreq_header hdr;
163         struct nmreq_register reg;
164
165         /* all the fields below should be considered read-only */
166
167         /* if the same context is used throughout the program, d1->mem ==
168          * d2->mem iff d1 and d2 are using the memory region (i.e., zero
169          * copy is possible between the two ports)
170          */
171         struct nmem_d *mem;
172
173         /* the nmctx used when this nmport_d was created */
174         struct nmctx *ctx;
175
176         int register_done;      /* nmport_register() has been called */
177         int mmap_done;          /* nmport_mmap() has been called */
178         /* pointer to the extmem option contained in the hdr options, if any */
179         struct nmreq_opt_extmem *extmem;
180
181         /* the fields below are compatible with nm_open() */
182         int fd;                         /* "/dev/netmap", -1 if not open */
183         struct netmap_if *nifp;         /* pointer to the netmap_if */
184         uint16_t first_tx_ring;
185         uint16_t last_tx_ring;
186         uint16_t first_rx_ring;
187         uint16_t last_rx_ring;
188         uint16_t cur_tx_ring;           /* used by nmport_inject */
189         uint16_t cur_rx_ring;
190
191         /* LIFO list of cleanup functions (used internally) */
192         struct nmport_cleanup_d *clist;
193 };
194
195 /* nmport_open - opens a port from a portspec
196  * @portspec    the port opening specification
197  *
198  * If successful, the function returns a new nmport_d describing a netmap
199  * port, opened according to the port specification, ready to be used for rx
200  * and/or tx.
201  *
202  * The rings available for tx are in the [first_tx_ring, last_tx_ring]
203  * interval, and similarly for rx. One or both intervals may be empty.
204  *
205  * When done using it, the nmport_d descriptor must be closed using
206  * nmport_close().
207  *
208  * In case of error, NULL is returned, errno is set to some error, and an
209  * error message is sent through the error() method of the current context.
210  */
211 struct nmport_d * nmport_open(const char *portspec);
212
213 /* nport_close - close a netmap port
214  * @d           the port we want to close
215  *
216  * Undoes the actions performed by the nmport_open that created d, then
217  * frees the descriptor.
218  */
219 void nmport_close(struct nmport_d *d);
220
221 /* nmport_inject - sends a packet
222  * @d           the port through which we want to send
223  * @buf         base address of the packet
224  * @size        its size in bytes
225  *
226  * Sends a packet using the cur_tx_ring and updates the index
227  * to use all available tx rings in turn. Note: the packet is copied.
228  *
229  * Returns 0 on success an -1 on error.
230  */
231 int nmport_inject(struct nmport_d *d, const void *buf, size_t size);
232
233 /*
234  * the functions below can be used to split the functionality of
235  * nmport_open when special features (e.g., extra buffers) are needed
236  *
237  * The relation among the functions is as follows:
238  *
239  *                                 |nmport_new
240  *              |nmport_prepare  = |
241  *              |                  |nmport_parse
242  * nmport_open =|
243  *              |                  |nmport_register
244  *              |nmport_open_desc =|
245  *                                 |nmport_mmap
246  *
247  */
248
249 /* nmport_new - create a new nmport_d
250  *
251  * Creates a new nmport_d using the malloc() method of the current default
252  * context. Returns NULL on error, setting errno to an error value.
253  */
254 struct nmport_d *nmport_new(void);
255
256 /* nmport_parse - fills the nmport_d netmap-register request
257  * @d           the nmport to be filled
258  * @portspec    the port opening specification
259  *
260  * This function parses the portspec and initizalizes the @d->hdr and @d->reg
261  * fields. It may need to allocate a list of options. If an extmem option is
262  * found, it may also mmap() the corresponding file.
263  *
264  * It returns 0 on success. On failure it returns -1, sets errno to an error
265  * value and sends an error message to the error() method of the context used
266  * when @d was created. Moreover, *@d is left unchanged.
267  */
268 int nmport_parse(struct nmport_d *d, const char *portspec);
269
270 /* nmport_register - registers the port with netmap
271  * @d           the nmport to be registered
272  *
273  * This function obtains a netmap file descriptor and registers the port with
274  * netmap. The @d->hdr and @d->reg data structures must have been previously
275  * initialized (via nmport_parse() or otherwise).
276  *
277  * It returns 0 on success. On failure it returns -1, sets errno to an error
278  * value and sends an error message to the error() method of the context used
279  * when @d was created. Moreover, *@d is left unchanged.
280  */
281 int nmport_register(struct nmport_d *);
282
283 /* nmport_mmap - maps the port resources into the process memory
284  * @d           the nmport to be mapped
285  *
286  * The port must have been previously been registered using nmport_register.
287  *
288  * Note that if extmem is used (either via an option or by calling an
289  * nmport_extmem_* function before nmport_register()), no new mmap() is issued.
290  *
291  * It returns 0 on success. On failure it returns -1, sets errno to an error
292  * value and sends an error message to the error() method of the context used
293  * when @d was created. Moreover, *@d is left unchanged.
294  */
295 int nmport_mmap(struct nmport_d *);
296
297 /* the following functions undo the actions of nmport_new(), nmport_parse(),
298  * nmport_register() and nmport_mmap(), respectively.
299  */
300 void nmport_delete(struct nmport_d *);
301 void nmport_undo_parse(struct nmport_d *);
302 void nmport_undo_register(struct nmport_d *);
303 void nmport_undo_mmap(struct nmport_d *);
304
305 /* nmport_prepare - create a port descriptor, but do not open it
306  * @portspec    the port opening specification
307  *
308  * This functions creates a new nmport_d and initializes it according to
309  * @portspec. It is equivalent to nmport_new() followed by nmport_parse().
310  *
311  * It returns 0 on success. On failure it returns -1, sets errno to an error
312  * value and sends an error message to the error() method of the context used
313  * when @d was created. Moreover, *@d is left unchanged.
314  */
315 struct nmport_d *nmport_prepare(const char *portspec);
316
317 /* nmport_open_desc - open an initialized port descriptor
318  * @d           the descriptor we want to open
319  *
320  * Registers the port with netmap and maps the rings and buffers into the
321  * process memory. It is equivalent to nmport_register() followed by
322  * nmport_mmap().
323  *
324  * It returns 0 on success. On failure it returns -1, sets errno to an error
325  * value and sends an error message to the error() method of the context used
326  * when @d was created. Moreover, *@d is left unchanged.
327  */
328 int nmport_open_desc(struct nmport_d *d);
329
330 /* the following functions undo the actions of nmport_prepare()
331  * and nmport_open_desc(), respectively.
332  */
333 void nmport_undo_prepare(struct nmport_d *);
334 void nmport_undo_open_desc(struct nmport_d *);
335
336 /* nmport_clone - copy an nmport_d
337  * @d           the nmport_d we want to copy
338  *
339  * Copying an nmport_d by hand should be avoided, since adjustments are needed
340  * and some part of the state cannot be easily duplicated. This function
341  * creates a copy of @d in a safe way. The returned nmport_d contains
342  * nmreq_header and nmreq_register structures equivalent to those contained in
343  * @d, except for the option list, which is ignored. The returned nmport_d is
344  * already nmport_prepare()d, but it must still be nmport_open_desc()ed. The
345  * new nmport_d uses the same nmctx as @d.
346  *
347  * If extmem was used for @d, then @d cannot be nmport_clone()d until it has
348  * been nmport_register()ed.
349  *
350  * In case of error, the function returns NULL, sets errno to an error value
351  * and sends an error message to the nmctx error() method.
352  */
353 struct nmport_d *nmport_clone(struct nmport_d *);
354
355 /* nmport_extmem - use extmem for this port
356  * @d           the port we want to use the extmem for
357  * @base        the base address of the extmem region
358  * @size        the size in bytes of the extmem region
359  *
360  * the memory that contains the netmap ifs, rings and buffers is usually
361  * allocated by netmap and later mmap()ed by the applications. It is sometimes
362  * useful to reverse this process, by having the applications allocate some
363  * memory (through mmap() or otherwise) and then let netmap use it.  The extmem
364  * option can be used to implement this latter strategy. The option can be
365  * passed through the portspec using the '@extmem:...' syntax, or
366  * programmatically by calling nmport_extmem() or nmport_extmem_from_file()
367  * between nmport_parse() and nmport_register() (or between nmport_prepare()
368  * and nmport_open_desc()).
369  *
370  * It returns 0 on success. On failure it returns -1, sets errno to an error
371  * value and sends an error message to the error() method of the context used
372  * when @d was created. Moreover, *@d is left unchanged.
373  */
374 int nmport_extmem(struct nmport_d *d, void *base, size_t size);
375
376 /* nmport_extmem_from_file - use the extmem obtained by mapping a file
377  * @d           the port we want to use the extmem for
378  * @fname       path of the file we want to map
379  *
380  * This works like nmport_extmem, but the extmem memory is obtained by
381  * mmap()ping @fname. nmport_close() will also automatically munmap() the file.
382  *
383  * It returns 0 on success. On failure it returns -1, sets errno to an error
384  * value and sends an error message to the error() method of the context used
385  * when @d was created. Moreover, *@d is left unchanged.
386  */
387 int nmport_extmem_from_file(struct nmport_d *d, const char *fname);
388
389 /* nmport_extmem_getinfo - opbtai a pointer to the extmem configuration
390  * @d           the port we want to obtain the pointer from
391  *
392  * Returns a pointer to the nmreq_pools_info structure containing the
393  * configuration of the extmem attached to port @d, or NULL if no extmem
394  * is attached. This can be used to set the desired configuration before
395  * registering the port, or to read the actual configuration after
396  * registration.
397  */
398 struct nmreq_pools_info* nmport_extmem_getinfo(struct nmport_d *d);
399
400
401 /* enable/disable options
402  *
403  * These functions can be used to disable options that the application cannot
404  * or doesn't want to handle, or to enable options that require special support
405  * from the application and are, therefore, disabled by default. Disabled
406  * options will cause an error if encountered during option parsing.
407  *
408  * If the option is unknown, nmport_disable_option is a NOP, while
409  * nmport_enable_option returns -1 and sets errno to EOPNOTSUPP.
410  *
411  * These functions are not threadsafe and are meant to be used at the beginning
412  * of the program.
413  */
414 void nmport_disable_option(const char *opt);
415 int nmport_enable_option(const char *opt);
416
417 /* nmreq manipulation
418  *
419  * nmreq_header_init - initialize an nmreq_header
420  * @hdr         the nmreq_header to initialize
421  * @reqtype     the kind of netmap request
422  * @body        the body of the request
423  *
424  * Initialize the nr_version, nr_reqtype and nr_body fields of *@hdr.
425  * The other fields are set to zero.
426  */
427 void nmreq_header_init(struct nmreq_header *hdr, uint16_t reqtype, void *body);
428
429 /*
430  * These functions allow for finer grained parsing of portspecs.  They are used
431  * internally by nmport_parse().
432  */
433
434 /* nmreq_header_decode - initialize an nmreq_header
435  * @ppspec:     (in/out) pointer to a pointer to the portspec
436  * @hdr:        pointer to the nmreq_header to be initialized
437  * @ctx:        pointer to the nmctx to use (for errors)
438  *
439  * This function fills the @hdr the nr_name field with the port name extracted
440  * from *@pifname.  The other fields of *@hdr are unchanged. The @pifname is
441  * updated to point at the first char past the port name.
442  *
443  * Returns 0 on success.  In case of error, -1 is returned with errno set to
444  * EINVAL, @pifname is unchanged, *@hdr is also unchanged, and an error message
445  * is sent through @ctx->error().
446  */
447 int nmreq_header_decode(const char **ppspec, struct nmreq_header *hdr,
448                 struct nmctx *ctx);
449
450 /* nmreq_regiter_decode - initialize an nmreq_register
451  * @pmode:      (in/out) pointer to a pointer to an opening mode
452  * @reg:        pointer to the nmreq_register to be initialized
453  * @ctx:        pointer to the nmctx to use (for errors)
454  *
455  * This function fills the nr_mode, nr_ringid, nr_flags and nr_mem_id fields of
456  * the structure pointed by @reg, according to the opening mode specified by
457  * *@pmode. The other fields of *@reg are unchanged.  The @pmode is updated to
458  * point at the first char past the opening mode.
459  *
460  * If a '@' is encountered followed by something which is not a number, parsing
461  * stops (without error) and @pmode is left pointing at the '@' char. The
462  * nr_mode, nr_ringid and nr_flags fields are still updated, but nr_mem_id is
463  * not touched and the interpretation of the '@' field is left to the caller.
464  *
465  * Returns 0 on success.  In case of error, -1 is returned with errno set to
466  * EINVAL, @pmode is unchanged, *@reg is also unchanged, and an error message
467  * is sent through @ctx->error().
468  */
469 int nmreq_register_decode(const char **pmode, struct nmreq_register *reg,
470                 struct nmctx *ctx);
471
472 /* nmreq_options_decode - parse the "options" part of the portspec
473  * @opt:        pointer to the option list
474  * @parsers:    list of option parsers
475  * @token:      token to pass to each parser
476  * @ctx:        pointer to the nmctx to use (for errors and malloc/free)
477  *
478  * This function parses each option in @opt. Each option is matched (based on
479  * the "option" prefix) to a corresponding parser in @parsers. The function
480  * checks that the syntax is appropriate for the parser and it assigns all the
481  * keys mentioned in the option. It then passes control to the parser, to
482  * interpret the keys values.
483  *
484  * Returns 0 on success. In case of error, -1 is returned, errno is set to an
485  * error value and a message is sent to @ctx->error(). The effects of partially
486  * interpreted options may not be undone.
487  */
488 struct nmreq_opt_parser;
489 int nmreq_options_decode(const char *opt, struct nmreq_opt_parser *parsers,
490                 void *token, struct nmctx *ctx);
491
492 struct nmreq_parse_ctx;
493 /* type of the option-parsers callbacks */
494 typedef int (*nmreq_opt_parser_cb)(struct nmreq_parse_ctx *);
495
496 #define NMREQ_OPT_MAXKEYS 16    /* max nr of recognized keys per option */
497
498 /* struct nmreq_opt_key - describes an option key */
499 struct nmreq_opt_key {
500         const char *key;        /* the key name */
501         int id;                 /* its position in the parse context */
502         unsigned int flags;
503 #define NMREQ_OPTK_ALLOWEMPTY   (1U << 0) /* =value may be omitted */
504 #define NMREQ_OPTK_MUSTSET      (1U << 1) /* the key is mandatory */
505 #define NMREQ_OPTK_DEFAULT      (1U << 2) /* this is the default key */
506 };
507
508 /* struct nmreq_opt_parser - describes an option parser */
509 struct nmreq_opt_parser {
510         const char *prefix;     /* matches one option prefix */
511         nmreq_opt_parser_cb parse;      /* the parse callback */
512         int default_key;        /* which option is the default if the
513                                    parser is multi-key (-1 if none) */
514         int nr_keys;
515         unsigned int flags;
516 #define NMREQ_OPTF_DISABLED     (1U << 0)
517 #define NMREQ_OPTF_ALLOWEMPTY   (1U << 1)       /* =value can be omitted */
518
519         struct nmreq_opt_parser *next;  /* list of options */
520
521         /* recognized keys */
522         struct nmreq_opt_key keys[NMREQ_OPT_MAXKEYS];
523 } __attribute__((aligned(16)));
524
525 /* struct nmreq_parse_ctx - the parse context received by the parse callback */
526 struct nmreq_parse_ctx {
527         struct nmctx *ctx;      /* the nmctx for errors and malloc/free */
528         void *token;            /* the token passed to nmreq_options_parse */
529
530         /* the value (i.e., the part after the = sign) of each recognized key
531          * is assigned to the corresponding entry in this array, based on the
532          * key id. Unassigned keys are left at NULL.
533          */
534         const char *keys[NMREQ_OPT_MAXKEYS];
535 };
536
537 /* nmreq_get_mem_id - get the mem_id of the given port
538  * @portname    pointer to a pointer to the portname
539  * @ctx         pointer to the nmctx to use (for errors)
540  *
541  * *@portname must point to a substem:vpname porname, possibly followed by
542  * something else.
543  *
544  * If successful, returns the mem_id of *@portname and moves @portname past the
545  * subsystem:vpname part of the input. In case of error it returns -1, sets
546  * errno to an error value and sends an error message to ctx->error().
547  */
548 int32_t nmreq_get_mem_id(const char **portname, struct nmctx *ctx);
549
550 /* option list manipulation */
551 void nmreq_push_option(struct nmreq_header *, struct nmreq_option *);
552 void nmreq_remove_option(struct nmreq_header *, struct nmreq_option *);
553 struct nmreq_option *nmreq_find_option(struct nmreq_header *, uint32_t);
554 void nmreq_free_options(struct nmreq_header *);
555 const char* nmreq_option_name(uint32_t);
556 #define nmreq_foreach_option(h_, o_) \
557         for ((o_) = (struct nmreq_option *)((uintptr_t)((h_)->nr_options));\
558              (o_) != NULL;\
559              (o_) = (struct nmreq_option *)((uintptr_t)((o_)->nro_next)))
560
561 /* nmctx manipulation */
562
563 /* the nmctx serves a few purposes:
564  *
565  * - maintain a list of all memory regions open by the program, so that two
566  *   ports that are using the same region (as identified by the mem_id) will
567  *   point to the same nmem_d instance.
568  *
569  * - allow the user to specify how to lock accesses to the above list, if
570  *   needed (lock() callback)
571  *
572  * - allow the user to specify how error messages should be delivered (error()
573  *   callback)
574  *
575  * - select the verbosity of the library (verbose field); if verbose==0, no
576  *   errors are sent to the error() callback
577  *
578  * - allow the user to override the malloc/free functions used by the library
579  *   (malloc() and free() callbacks)
580  *
581  */
582 typedef void  (*nmctx_error_cb)(struct nmctx *, const char *);
583 typedef void *(*nmctx_malloc_cb)(struct nmctx *,size_t);
584 typedef void  (*nmctx_free_cb)(struct nmctx *,void *);
585 typedef void  (*nmctx_lock_cb)(struct nmctx *, int);
586
587 struct nmctx {
588         int verbose;
589         nmctx_error_cb  error;
590         nmctx_malloc_cb malloc;
591         nmctx_free_cb   free;
592         nmctx_lock_cb   lock;
593
594         struct nmem_d  *mem_descs;
595 };
596
597 /* nmctx_get - obtain a pointer to the current default context */
598 struct nmctx *nmctx_get(void);
599
600 /* nmctx_set_default - change the default context
601  * @ctx         pointer to the new context
602  *
603  * Returns a pointer to the previous default context.
604  */
605 struct nmctx *nmctx_set_default(struct nmctx *ctx);
606
607 /* internal functions and data structures */
608
609 /* struct nmem_d - describes a memory region currently used */
610 struct nmem_d {
611         uint16_t mem_id;        /* the region netmap identifier */
612         int refcount;           /* how many nmport_d's point here */
613         void *mem;              /* memory region base address */
614         size_t size;            /* memory region size */
615         int is_extmem;          /* was it obtained via extmem? */
616
617         /* pointers for the circular list implementation.
618          * The list head is the mem_descs filed in the nmctx
619          */
620         struct nmem_d *next;
621         struct nmem_d *prev;
622 };
623
624 /* a trick to force the inclusion of libpthread only if requested. If
625  * LIBNETMAP_NOTHREADSAFE is defined, no pthread symbol is imported.
626  *
627  * There is no need to actually call this function: the ((used)) attribute is
628  * sufficient to include it in the image.
629  */
630 static  __attribute__((used)) void libnetmap_init(void)
631 {
632 #ifndef LIBNETMAP_NOTHREADSAFE
633         extern int nmctx_threadsafe;
634         /* dummy assignment to link-in the nmctx-pthread.o object.  The proper
635          * inizialization is performed only once in the library constructor
636          * defined there.
637          */
638         nmctx_threadsafe = 1;
639 #endif /* LIBNETMAP_NOTHREADSAFE */
640 }
641
642 /* nmctx_set_threadsafe - install a threadsafe default context
643  *
644  * called by the constructor in nmctx-pthread.o to initialize a lock and install
645  * the lock() callback in the default context.
646  */
647 void nmctx_set_threadsafe(void);
648
649 /* nmctx_ferror - format and send an error message */
650 void nmctx_ferror(struct nmctx *, const char *, ...);
651 /* nmctx_malloc - allocate memory */
652 void *nmctx_malloc(struct nmctx *, size_t);
653 /* nmctx_free - free memory allocated via nmctx_malloc */
654 void nmctx_free(struct nmctx *, void *);
655 /* nmctx_lock - lock the list of nmem_d */
656 void nmctx_lock(struct nmctx *);
657 /* nmctx_unlock - unlock the list of nmem_d */
658 void nmctx_unlock(struct nmctx *);
659
660 #endif /* LIBNETMAP_H_ */