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