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