2 * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
4 * Copyright (C) 2018 Universita` di Pisa
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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.
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
33 /* if thread-safety is not needed, define LIBNETMAP_NOTHREADSAFE before including
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.
41 #include <net/netmap_user.h>
48 * A port open specification (portspec for brevity) has the following syntax
49 * (square brackets delimit optional parts):
51 * subsystem:vpname[mode][options]
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:
57 * netmap (no id allowed)
58 * the standard subsystem
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)
64 * The "vpname" has the following syntax:
67 * identifier1{identifier2 or
68 * identifier1}identifier2
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.
74 * The "mode" can be one of the following:
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,
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)
90 * The "options" start at the first '@' character not followed by a number.
91 * Each option starts with '@' and has the following syntax:
93 * option (flag option)
94 * option=value (single key option)
95 * option:key1=value1,key2=value2,... (multi-key option)
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.
103 * NOTE: Options may be silently ignored if the port is already open by some
106 * The currently available options are (default keys, when defined, are marked
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)
115 * specify the rings/slots numbers (effective only on
116 * ports that are created by the open operation itself,
117 * and ignored otherwise).
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
129 * tx-slots number of slots in each tx ring
130 * rx-slots number of slots in each rx ring
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.
137 * open the port in the memory region obtained by
138 * mmap()ing the given file.
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
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.
155 * reserve (part of) the ptr fields as an offset field
156 * and write an initial offset into them.
160 * bits number of bits of ptr to use
161 * *initial initial offset value
163 * initial must be assigned. If bits is omitted, it
164 * defaults to the entire ptr field. The max offset is set
165 * at the same value as the initial offset. Note that the
166 * actual values may be increased by the kernel.
168 * This option is disabled by default (see
169 * nmport_enable_option() below)
173 /* nmport manipulation */
175 /* struct nmport_d - describes a netmap port */
177 /* see net/netmap.h for the definition of these fields */
178 struct nmreq_header hdr;
179 struct nmreq_register reg;
181 /* all the fields below should be considered read-only */
183 /* if the same context is used throughout the program, d1->mem ==
184 * d2->mem iff d1 and d2 are using the memory region (i.e., zero
185 * copy is possible between the two ports)
189 /* the nmctx used when this nmport_d was created */
192 int register_done; /* nmport_register() has been called */
193 int mmap_done; /* nmport_mmap() has been called */
194 /* pointer to the extmem option contained in the hdr options, if any */
195 struct nmreq_opt_extmem *extmem;
197 /* the fields below are compatible with nm_open() */
198 int fd; /* "/dev/netmap", -1 if not open */
199 struct netmap_if *nifp; /* pointer to the netmap_if */
200 uint16_t first_tx_ring;
201 uint16_t last_tx_ring;
202 uint16_t first_rx_ring;
203 uint16_t last_rx_ring;
204 uint16_t cur_tx_ring; /* used by nmport_inject */
205 uint16_t cur_rx_ring;
207 /* LIFO list of cleanup functions (used internally) */
208 struct nmport_cleanup_d *clist;
211 /* nmport_open - opens a port from a portspec
212 * @portspec the port opening specification
214 * If successful, the function returns a new nmport_d describing a netmap
215 * port, opened according to the port specification, ready to be used for rx
218 * The rings available for tx are in the [first_tx_ring, last_tx_ring]
219 * interval, and similarly for rx. One or both intervals may be empty.
221 * When done using it, the nmport_d descriptor must be closed using
224 * In case of error, NULL is returned, errno is set to some error, and an
225 * error message is sent through the error() method of the current context.
227 struct nmport_d * nmport_open(const char *portspec);
229 /* nport_close - close a netmap port
230 * @d the port we want to close
232 * Undoes the actions performed by the nmport_open that created d, then
233 * frees the descriptor.
235 void nmport_close(struct nmport_d *d);
237 /* nmport_inject - sends a packet
238 * @d the port through which we want to send
239 * @buf base address of the packet
240 * @size its size in bytes
242 * Sends a packet using the cur_tx_ring and updates the index
243 * to use all available tx rings in turn. Note: the packet is copied.
245 * Returns 0 on success an -1 on error.
247 int nmport_inject(struct nmport_d *d, const void *buf, size_t size);
250 * the functions below can be used to split the functionality of
251 * nmport_open when special features (e.g., extra buffers) are needed
253 * The relation among the functions is as follows:
256 * |nmport_prepare = |
260 * |nmport_open_desc =|
265 /* nmport_new - create a new nmport_d
267 * Creates a new nmport_d using the malloc() method of the current default
268 * context. Returns NULL on error, setting errno to an error value.
270 struct nmport_d *nmport_new(void);
272 /* nmport_parse - fills the nmport_d netmap-register request
273 * @d the nmport to be filled
274 * @portspec the port opening specification
276 * This function parses the portspec and initizalizes the @d->hdr and @d->reg
277 * fields. It may need to allocate a list of options. If an extmem option is
278 * found, it may also mmap() the corresponding file.
280 * It returns 0 on success. On failure it returns -1, sets errno to an error
281 * value and sends an error message to the error() method of the context used
282 * when @d was created. Moreover, *@d is left unchanged.
284 int nmport_parse(struct nmport_d *d, const char *portspec);
286 /* nmport_register - registers the port with netmap
287 * @d the nmport to be registered
289 * This function obtains a netmap file descriptor and registers the port with
290 * netmap. The @d->hdr and @d->reg data structures must have been previously
291 * initialized (via nmport_parse() or otherwise).
293 * It returns 0 on success. On failure it returns -1, sets errno to an error
294 * value and sends an error message to the error() method of the context used
295 * when @d was created. Moreover, *@d is left unchanged.
297 int nmport_register(struct nmport_d *);
299 /* nmport_mmap - maps the port resources into the process memory
300 * @d the nmport to be mapped
302 * The port must have been previously been registered using nmport_register.
304 * Note that if extmem is used (either via an option or by calling an
305 * nmport_extmem_* function before nmport_register()), no new mmap() is issued.
307 * It returns 0 on success. On failure it returns -1, sets errno to an error
308 * value and sends an error message to the error() method of the context used
309 * when @d was created. Moreover, *@d is left unchanged.
311 int nmport_mmap(struct nmport_d *);
313 /* the following functions undo the actions of nmport_new(), nmport_parse(),
314 * nmport_register() and nmport_mmap(), respectively.
316 void nmport_delete(struct nmport_d *);
317 void nmport_undo_parse(struct nmport_d *);
318 void nmport_undo_register(struct nmport_d *);
319 void nmport_undo_mmap(struct nmport_d *);
321 /* nmport_prepare - create a port descriptor, but do not open it
322 * @portspec the port opening specification
324 * This functions creates a new nmport_d and initializes it according to
325 * @portspec. It is equivalent to nmport_new() followed by nmport_parse().
327 * It returns 0 on success. On failure it returns -1, sets errno to an error
328 * value and sends an error message to the error() method of the context used
329 * when @d was created. Moreover, *@d is left unchanged.
331 struct nmport_d *nmport_prepare(const char *portspec);
333 /* nmport_open_desc - open an initialized port descriptor
334 * @d the descriptor we want to open
336 * Registers the port with netmap and maps the rings and buffers into the
337 * process memory. It is equivalent to nmport_register() followed by
340 * It returns 0 on success. On failure it returns -1, sets errno to an error
341 * value and sends an error message to the error() method of the context used
342 * when @d was created. Moreover, *@d is left unchanged.
344 int nmport_open_desc(struct nmport_d *d);
346 /* the following functions undo the actions of nmport_prepare()
347 * and nmport_open_desc(), respectively.
349 void nmport_undo_prepare(struct nmport_d *);
350 void nmport_undo_open_desc(struct nmport_d *);
352 /* nmport_clone - copy an nmport_d
353 * @d the nmport_d we want to copy
355 * Copying an nmport_d by hand should be avoided, since adjustments are needed
356 * and some part of the state cannot be easily duplicated. This function
357 * creates a copy of @d in a safe way. The returned nmport_d contains
358 * nmreq_header and nmreq_register structures equivalent to those contained in
359 * @d, except for the option list, which is ignored. The returned nmport_d is
360 * already nmport_prepare()d, but it must still be nmport_open_desc()ed. The
361 * new nmport_d uses the same nmctx as @d.
363 * If extmem was used for @d, then @d cannot be nmport_clone()d until it has
364 * been nmport_register()ed.
366 * In case of error, the function returns NULL, sets errno to an error value
367 * and sends an error message to the nmctx error() method.
369 struct nmport_d *nmport_clone(struct nmport_d *);
371 /* nmport_extmem - use extmem for this port
372 * @d the port we want to use the extmem for
373 * @base the base address of the extmem region
374 * @size the size in bytes of the extmem region
376 * the memory that contains the netmap ifs, rings and buffers is usually
377 * allocated by netmap and later mmap()ed by the applications. It is sometimes
378 * useful to reverse this process, by having the applications allocate some
379 * memory (through mmap() or otherwise) and then let netmap use it. The extmem
380 * option can be used to implement this latter strategy. The option can be
381 * passed through the portspec using the '@extmem:...' syntax, or
382 * programmatically by calling nmport_extmem() or nmport_extmem_from_file()
383 * between nmport_parse() and nmport_register() (or between nmport_prepare()
384 * and nmport_open_desc()).
386 * It returns 0 on success. On failure it returns -1, sets errno to an error
387 * value and sends an error message to the error() method of the context used
388 * when @d was created. Moreover, *@d is left unchanged.
390 int nmport_extmem(struct nmport_d *d, void *base, size_t size);
392 /* nmport_extmem_from_file - use the extmem obtained by mapping a file
393 * @d the port we want to use the extmem for
394 * @fname path of the file we want to map
396 * This works like nmport_extmem, but the extmem memory is obtained by
397 * mmap()ping @fname. nmport_close() will also automatically munmap() the file.
399 * It returns 0 on success. On failure it returns -1, sets errno to an error
400 * value and sends an error message to the error() method of the context used
401 * when @d was created. Moreover, *@d is left unchanged.
403 int nmport_extmem_from_file(struct nmport_d *d, const char *fname);
405 /* nmport_extmem_getinfo - opbtai a pointer to the extmem configuration
406 * @d the port we want to obtain the pointer from
408 * Returns a pointer to the nmreq_pools_info structure containing the
409 * configuration of the extmem attached to port @d, or NULL if no extmem
410 * is attached. This can be used to set the desired configuration before
411 * registering the port, or to read the actual configuration after
414 struct nmreq_pools_info* nmport_extmem_getinfo(struct nmport_d *d);
417 /* nmport_offset - use offsets for this port
418 * @initial the initial offset for all the slots
419 * @maxoff the maximum offset
420 * @bits the number of bits of slot->ptr to use for the offsets
421 * @mingap the minimum gap between offsets (in shared buffers)
423 * With this option the lower @bits bits of the ptr field in the netmap_slot
424 * can be used to specify an offset into the buffer. All offsets will be set
425 * to the @initial value by netmap.
427 * The offset field can be read and updated using the bitmask found in
428 * ring->offset_mask after a successful register. netmap_user.h contains
429 * some helper macros (NETMAP_ROFFSET, NETMAP_WOFFSET and NETMAP_BUF_OFFSET).
431 * For RX rings, the user writes the offset o in an empty slot before passing
432 * it to netmap; then, netmap will write the incoming packet at an offset o' >=
433 * o in the buffer. o' may be larger than o because of, e.g., alignment
434 * constrains. If o' > o netmap will also update the offset field in the slot.
435 * Note that large offsets may cause the port to split the packet over several
436 * slots, setting the NS_MOREFRAG flag accordingly.
438 * For TX rings, the user may prepare the packet to send at an offset o into
439 * the buffer and write o in the offset field. Netmap will send the packets
440 * starting o bytes in the buffer. Note that the address of the packet must
441 * comply with any alignment constraints that the port may have, or the result
442 * will be undefined. The user may read the alignment constraint in the new
443 * ring->buf_align field. It is also possible that empty slots already come
444 * with a non-zero offset o specified in the offset field. In this case, the
445 * user will have to write the packet at an offset o' >= o.
447 * The user must also declare the @maxoff offset that she is going to use. Any
448 * offset larger than this will be truncated.
450 * The user may also declare a @mingap (ignored if zero) if she plans to use
451 * offsets to share the same buffer among several slots. Netmap will guarantee
452 * that it will never write more than @mingap bytes for each slot, irrespective
453 * of the buffer length.
455 int nmport_offset(struct nmport_d *d, uint64_t initial, uint64_t maxoff,
456 uint64_t bits, uint64_t mingap);
458 /* enable/disable options
460 * These functions can be used to disable options that the application cannot
461 * or doesn't want to handle, or to enable options that require special support
462 * from the application and are, therefore, disabled by default. Disabled
463 * options will cause an error if encountered during option parsing.
465 * If the option is unknown, nmport_disable_option is a NOP, while
466 * nmport_enable_option returns -1 and sets errno to EOPNOTSUPP.
468 * These functions are not threadsafe and are meant to be used at the beginning
471 void nmport_disable_option(const char *opt);
472 int nmport_enable_option(const char *opt);
474 /* nmreq manipulation
476 * nmreq_header_init - initialize an nmreq_header
477 * @hdr the nmreq_header to initialize
478 * @reqtype the kind of netmap request
479 * @body the body of the request
481 * Initialize the nr_version, nr_reqtype and nr_body fields of *@hdr.
482 * The other fields are set to zero.
484 void nmreq_header_init(struct nmreq_header *hdr, uint16_t reqtype, void *body);
487 * These functions allow for finer grained parsing of portspecs. They are used
488 * internally by nmport_parse().
491 /* nmreq_header_decode - initialize an nmreq_header
492 * @ppspec: (in/out) pointer to a pointer to the portspec
493 * @hdr: pointer to the nmreq_header to be initialized
494 * @ctx: pointer to the nmctx to use (for errors)
496 * This function fills the @hdr the nr_name field with the port name extracted
497 * from *@pifname. The other fields of *@hdr are unchanged. The @pifname is
498 * updated to point at the first char past the port name.
500 * Returns 0 on success. In case of error, -1 is returned with errno set to
501 * EINVAL, @pifname is unchanged, *@hdr is also unchanged, and an error message
502 * is sent through @ctx->error().
504 int nmreq_header_decode(const char **ppspec, struct nmreq_header *hdr,
507 /* nmreq_regiter_decode - initialize an nmreq_register
508 * @pmode: (in/out) pointer to a pointer to an opening mode
509 * @reg: pointer to the nmreq_register to be initialized
510 * @ctx: pointer to the nmctx to use (for errors)
512 * This function fills the nr_mode, nr_ringid, nr_flags and nr_mem_id fields of
513 * the structure pointed by @reg, according to the opening mode specified by
514 * *@pmode. The other fields of *@reg are unchanged. The @pmode is updated to
515 * point at the first char past the opening mode.
517 * If a '@' is encountered followed by something which is not a number, parsing
518 * stops (without error) and @pmode is left pointing at the '@' char. The
519 * nr_mode, nr_ringid and nr_flags fields are still updated, but nr_mem_id is
520 * not touched and the interpretation of the '@' field is left to the caller.
522 * Returns 0 on success. In case of error, -1 is returned with errno set to
523 * EINVAL, @pmode is unchanged, *@reg is also unchanged, and an error message
524 * is sent through @ctx->error().
526 int nmreq_register_decode(const char **pmode, struct nmreq_register *reg,
529 /* nmreq_options_decode - parse the "options" part of the portspec
530 * @opt: pointer to the option list
531 * @parsers: list of option parsers
532 * @token: token to pass to each parser
533 * @ctx: pointer to the nmctx to use (for errors and malloc/free)
535 * This function parses each option in @opt. Each option is matched (based on
536 * the "option" prefix) to a corresponding parser in @parsers. The function
537 * checks that the syntax is appropriate for the parser and it assigns all the
538 * keys mentioned in the option. It then passes control to the parser, to
539 * interpret the keys values.
541 * Returns 0 on success. In case of error, -1 is returned, errno is set to an
542 * error value and a message is sent to @ctx->error(). The effects of partially
543 * interpreted options may not be undone.
545 struct nmreq_opt_parser;
546 int nmreq_options_decode(const char *opt, struct nmreq_opt_parser *parsers,
547 void *token, struct nmctx *ctx);
549 struct nmreq_parse_ctx;
550 /* type of the option-parsers callbacks */
551 typedef int (*nmreq_opt_parser_cb)(struct nmreq_parse_ctx *);
553 #define NMREQ_OPT_MAXKEYS 16 /* max nr of recognized keys per option */
555 /* struct nmreq_opt_key - describes an option key */
556 struct nmreq_opt_key {
557 const char *key; /* the key name */
558 int id; /* its position in the parse context */
560 #define NMREQ_OPTK_ALLOWEMPTY (1U << 0) /* =value may be omitted */
561 #define NMREQ_OPTK_MUSTSET (1U << 1) /* the key is mandatory */
562 #define NMREQ_OPTK_DEFAULT (1U << 2) /* this is the default key */
565 /* struct nmreq_opt_parser - describes an option parser */
566 struct nmreq_opt_parser {
567 const char *prefix; /* matches one option prefix */
568 nmreq_opt_parser_cb parse; /* the parse callback */
569 int default_key; /* which option is the default if the
570 parser is multi-key (-1 if none) */
573 #define NMREQ_OPTF_DISABLED (1U << 0)
574 #define NMREQ_OPTF_ALLOWEMPTY (1U << 1) /* =value can be omitted */
576 struct nmreq_opt_parser *next; /* list of options */
578 /* recognized keys */
579 struct nmreq_opt_key keys[NMREQ_OPT_MAXKEYS];
580 } __attribute__((aligned(16)));
582 /* struct nmreq_parse_ctx - the parse context received by the parse callback */
583 struct nmreq_parse_ctx {
584 struct nmctx *ctx; /* the nmctx for errors and malloc/free */
585 void *token; /* the token passed to nmreq_options_parse */
587 /* the value (i.e., the part after the = sign) of each recognized key
588 * is assigned to the corresponding entry in this array, based on the
589 * key id. Unassigned keys are left at NULL.
591 const char *keys[NMREQ_OPT_MAXKEYS];
594 /* nmreq_get_mem_id - get the mem_id of the given port
595 * @portname pointer to a pointer to the portname
596 * @ctx pointer to the nmctx to use (for errors)
598 * *@portname must point to a substem:vpname porname, possibly followed by
601 * If successful, returns the mem_id of *@portname and moves @portname past the
602 * subsystem:vpname part of the input. In case of error it returns -1, sets
603 * errno to an error value and sends an error message to ctx->error().
605 int32_t nmreq_get_mem_id(const char **portname, struct nmctx *ctx);
607 /* option list manipulation */
608 void nmreq_push_option(struct nmreq_header *, struct nmreq_option *);
609 void nmreq_remove_option(struct nmreq_header *, struct nmreq_option *);
610 struct nmreq_option *nmreq_find_option(struct nmreq_header *, uint32_t);
611 void nmreq_free_options(struct nmreq_header *);
612 const char* nmreq_option_name(uint32_t);
613 #define nmreq_foreach_option(h_, o_) \
614 for ((o_) = (struct nmreq_option *)((uintptr_t)((h_)->nr_options));\
616 (o_) = (struct nmreq_option *)((uintptr_t)((o_)->nro_next)))
618 /* nmctx manipulation */
620 /* the nmctx serves a few purposes:
622 * - maintain a list of all memory regions open by the program, so that two
623 * ports that are using the same region (as identified by the mem_id) will
624 * point to the same nmem_d instance.
626 * - allow the user to specify how to lock accesses to the above list, if
627 * needed (lock() callback)
629 * - allow the user to specify how error messages should be delivered (error()
632 * - select the verbosity of the library (verbose field); if verbose==0, no
633 * errors are sent to the error() callback
635 * - allow the user to override the malloc/free functions used by the library
636 * (malloc() and free() callbacks)
639 typedef void (*nmctx_error_cb)(struct nmctx *, const char *);
640 typedef void *(*nmctx_malloc_cb)(struct nmctx *,size_t);
641 typedef void (*nmctx_free_cb)(struct nmctx *,void *);
642 typedef void (*nmctx_lock_cb)(struct nmctx *, int);
646 nmctx_error_cb error;
647 nmctx_malloc_cb malloc;
651 struct nmem_d *mem_descs;
654 /* nmctx_get - obtain a pointer to the current default context */
655 struct nmctx *nmctx_get(void);
657 /* nmctx_set_default - change the default context
658 * @ctx pointer to the new context
660 * Returns a pointer to the previous default context.
662 struct nmctx *nmctx_set_default(struct nmctx *ctx);
664 /* internal functions and data structures */
666 /* struct nmem_d - describes a memory region currently used */
668 uint16_t mem_id; /* the region netmap identifier */
669 int refcount; /* how many nmport_d's point here */
670 void *mem; /* memory region base address */
671 size_t size; /* memory region size */
672 int is_extmem; /* was it obtained via extmem? */
674 /* pointers for the circular list implementation.
675 * The list head is the mem_descs filed in the nmctx
681 /* a trick to force the inclusion of libpthread only if requested. If
682 * LIBNETMAP_NOTHREADSAFE is defined, no pthread symbol is imported.
684 * There is no need to actually call this function: the ((used)) attribute is
685 * sufficient to include it in the image.
687 static __attribute__((used)) void libnetmap_init(void)
689 #ifndef LIBNETMAP_NOTHREADSAFE
690 extern int nmctx_threadsafe;
691 /* dummy assignment to link-in the nmctx-pthread.o object. The proper
692 * inizialization is performed only once in the library constructor
695 nmctx_threadsafe = 1;
696 #endif /* LIBNETMAP_NOTHREADSAFE */
699 /* nmctx_set_threadsafe - install a threadsafe default context
701 * called by the constructor in nmctx-pthread.o to initialize a lock and install
702 * the lock() callback in the default context.
704 void nmctx_set_threadsafe(void);
706 /* nmctx_ferror - format and send an error message */
707 void nmctx_ferror(struct nmctx *, const char *, ...);
708 /* nmctx_malloc - allocate memory */
709 void *nmctx_malloc(struct nmctx *, size_t);
710 /* nmctx_free - free memory allocated via nmctx_malloc */
711 void nmctx_free(struct nmctx *, void *);
712 /* nmctx_lock - lock the list of nmem_d */
713 void nmctx_lock(struct nmctx *);
714 /* nmctx_unlock - unlock the list of nmem_d */
715 void nmctx_unlock(struct nmctx *);
717 #endif /* LIBNETMAP_H_ */