xref: /freebsd/lib/libnetmap/libnetmap.h (revision 45c67e8f6b56b9744f01142747fadf291fe3fad2)
15c4f8d80SVincenzo Maffione /*-
25c4f8d80SVincenzo Maffione  * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
35c4f8d80SVincenzo Maffione  *
45c4f8d80SVincenzo Maffione  * Copyright (C) 2018 Universita` di Pisa
55c4f8d80SVincenzo Maffione  * All rights reserved.
65c4f8d80SVincenzo Maffione  *
75c4f8d80SVincenzo Maffione  * Redistribution and use in source and binary forms, with or without
85c4f8d80SVincenzo Maffione  * modification, are permitted provided that the following conditions
95c4f8d80SVincenzo Maffione  * are met:
105c4f8d80SVincenzo Maffione  *
115c4f8d80SVincenzo Maffione  *   1. Redistributions of source code must retain the above copyright
125c4f8d80SVincenzo Maffione  *      notice, this list of conditions and the following disclaimer.
135c4f8d80SVincenzo Maffione  *   2. Redistributions in binary form must reproduce the above copyright
145c4f8d80SVincenzo Maffione  *      notice, this list of conditions and the following disclaimer in the
155c4f8d80SVincenzo Maffione  *      documentation and/or other materials provided with the distribution.
165c4f8d80SVincenzo Maffione  *
175c4f8d80SVincenzo Maffione  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
185c4f8d80SVincenzo Maffione  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
195c4f8d80SVincenzo Maffione  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
205c4f8d80SVincenzo Maffione  * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
215c4f8d80SVincenzo Maffione  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
225c4f8d80SVincenzo Maffione  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
235c4f8d80SVincenzo Maffione  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
245c4f8d80SVincenzo Maffione  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
255c4f8d80SVincenzo Maffione  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
265c4f8d80SVincenzo Maffione  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
275c4f8d80SVincenzo Maffione  * SUCH DAMAGE.
285c4f8d80SVincenzo Maffione  * $FreeBSD$
295c4f8d80SVincenzo Maffione  */
305c4f8d80SVincenzo Maffione 
315c4f8d80SVincenzo Maffione #ifndef LIBNETMAP_H_
325c4f8d80SVincenzo Maffione #define LIBNETMAP_H_
335c4f8d80SVincenzo Maffione /* if thread-safety is not needed, define LIBNETMAP_NOTHREADSAFE before including
345c4f8d80SVincenzo Maffione  * this file.
355c4f8d80SVincenzo Maffione  */
365c4f8d80SVincenzo Maffione 
375c4f8d80SVincenzo Maffione /* NOTE: we include net/netmap_user.h without defining NETMAP_WITH_LIBS, which
385c4f8d80SVincenzo Maffione  * is deprecated. If you still need it, please define NETMAP_WITH_LIBS and
395c4f8d80SVincenzo Maffione  * include net/netmap_user.h before including this file.
405c4f8d80SVincenzo Maffione  */
415c4f8d80SVincenzo Maffione #include <net/netmap_user.h>
425c4f8d80SVincenzo Maffione 
435c4f8d80SVincenzo Maffione struct nmctx;
445c4f8d80SVincenzo Maffione struct nmport_d;
455c4f8d80SVincenzo Maffione struct nmem_d;
465c4f8d80SVincenzo Maffione 
475c4f8d80SVincenzo Maffione /*
485c4f8d80SVincenzo Maffione  * A port open specification (portspec for brevity) has the following syntax
495c4f8d80SVincenzo Maffione  * (square brackets delimit optional parts):
505c4f8d80SVincenzo Maffione  *
515c4f8d80SVincenzo Maffione  *     subsystem:vpname[mode][options]
525c4f8d80SVincenzo Maffione  *
535c4f8d80SVincenzo Maffione  *  The "subsystem" is denoted by a prefix, possibly followed by an identifier.
545c4f8d80SVincenzo Maffione  *  There can be several kinds of subsystems, each one selected by a unique
555c4f8d80SVincenzo Maffione  *  prefix.  Currently defined subsystems are:
565c4f8d80SVincenzo Maffione  *
575c4f8d80SVincenzo Maffione  *  netmap 		(no id allowed)
585c4f8d80SVincenzo Maffione  *  			the standard subsystem
595c4f8d80SVincenzo Maffione  *
605c4f8d80SVincenzo Maffione  *  vale 		(followed by a possibly empty id)
615c4f8d80SVincenzo Maffione  *  			the vpname is connected to a VALE switch identified by
625c4f8d80SVincenzo Maffione  *  			the id (an empty id selects the default switch)
635c4f8d80SVincenzo Maffione  *
645c4f8d80SVincenzo Maffione  *  The "vpname" has the following syntax:
655c4f8d80SVincenzo Maffione  *
665c4f8d80SVincenzo Maffione  *     identifier			or
675c4f8d80SVincenzo Maffione  *     identifier1{identifier2		or
685c4f8d80SVincenzo Maffione  *     identifier1}identifier2
695c4f8d80SVincenzo Maffione  *
705c4f8d80SVincenzo Maffione  *  Identifiers are sequences of alphanumeric characters. The part that begins
715c4f8d80SVincenzo Maffione  *  with either '{' or '}', when present, denotes a netmap pipe opened in the
725c4f8d80SVincenzo Maffione  *  same memory region as the subsystem:indentifier1 port.
735c4f8d80SVincenzo Maffione  *
745c4f8d80SVincenzo Maffione  * The "mode" can be one of the following:
755c4f8d80SVincenzo Maffione  *
765c4f8d80SVincenzo Maffione  *	^		bind all host (sw) ring pairs
775c4f8d80SVincenzo Maffione  *	^NN		bind individual host ring pair
785c4f8d80SVincenzo Maffione  *	*		bind host and NIC ring pairs
795c4f8d80SVincenzo Maffione  *	-NN		bind individual NIC ring pair
805c4f8d80SVincenzo Maffione  *	@NN		open the port in the NN memory region
815c4f8d80SVincenzo Maffione  *	a suffix starting with / and the following flags,
825c4f8d80SVincenzo Maffione  *	in any order:
835c4f8d80SVincenzo Maffione  *	x		exclusive access
845c4f8d80SVincenzo Maffione  *	z		zero copy monitor (both tx and rx)
855c4f8d80SVincenzo Maffione  *	t		monitor tx side (copy monitor)
865c4f8d80SVincenzo Maffione  *	r		monitor rx side (copy monitor)
875c4f8d80SVincenzo Maffione  *	R		bind only RX ring(s)
885c4f8d80SVincenzo Maffione  *	T		bind only TX ring(s)
895c4f8d80SVincenzo Maffione  *
905c4f8d80SVincenzo Maffione  *  The "options" start at the first '@' character not followed by a number.
915c4f8d80SVincenzo Maffione  *  Each option starts with '@' and has the following syntax:
925c4f8d80SVincenzo Maffione  *
935c4f8d80SVincenzo Maffione  *      option					(flag option)
945c4f8d80SVincenzo Maffione  *      option=value				(single key option)
955c4f8d80SVincenzo Maffione  *      option:key1=value1,key2=value2,...	(multi-key option)
965c4f8d80SVincenzo Maffione  *
975c4f8d80SVincenzo Maffione  *  For multi-key options, the keys can be assigned in any order, but they
985c4f8d80SVincenzo Maffione  *  cannot be assigned more than once. It is not necessary to assign all the
995c4f8d80SVincenzo Maffione  *  option keys: unmentioned keys will receive default values.  Some multi-key
1005c4f8d80SVincenzo Maffione  *  options define a default key and also accept the single-key syntax, by
1015c4f8d80SVincenzo Maffione  *  assigning the value to this key.
1025c4f8d80SVincenzo Maffione  *
1035c4f8d80SVincenzo Maffione  *  NOTE: Options may be silently ignored if the port is already open by some
1045c4f8d80SVincenzo Maffione  *  other process.
1055c4f8d80SVincenzo Maffione  *
1065c4f8d80SVincenzo Maffione  *  The currently available options are (default keys, when defined, are marked
1075c4f8d80SVincenzo Maffione  *  with '*'):
1085c4f8d80SVincenzo Maffione  *
1095c4f8d80SVincenzo Maffione  *  share (single-key)
1105c4f8d80SVincenzo Maffione  *  			open the port in the same memory region used by the
1115c4f8d80SVincenzo Maffione  *  			given port name (the port name must be given in
1125c4f8d80SVincenzo Maffione  *  			subsystem:vpname form)
1135c4f8d80SVincenzo Maffione  *
1145c4f8d80SVincenzo Maffione  *  conf  (multi-key)
1155c4f8d80SVincenzo Maffione  *  			specify the rings/slots numbers (effective only on
1165c4f8d80SVincenzo Maffione  *  			ports that are created by the open operation itself,
1175c4f8d80SVincenzo Maffione  *  			and ignored otherwise).
1185c4f8d80SVincenzo Maffione  *
1195c4f8d80SVincenzo Maffione  *			The keys are:
1205c4f8d80SVincenzo Maffione  *
1215c4f8d80SVincenzo Maffione  *  		       *rings		number of tx and rx rings
1225c4f8d80SVincenzo Maffione  *  			tx-rings	number of tx rings
1235c4f8d80SVincenzo Maffione  *  			rx-rings	number of rx rings
1245c4f8d80SVincenzo Maffione  *			host-rings	number of tx and rx host rings
1255c4f8d80SVincenzo Maffione  *  			host-tx-rings	number of host tx rings
1265c4f8d80SVincenzo Maffione  *  			host-rx-rings	number of host rx rings
1275c4f8d80SVincenzo Maffione  *  			slots		number of slots in each tx and rx
1285c4f8d80SVincenzo Maffione  *  					ring
1295c4f8d80SVincenzo Maffione  *  			tx-slots	number of slots in each tx ring
1305c4f8d80SVincenzo Maffione  *  			rx-slots	number of slots in each rx ring
1315c4f8d80SVincenzo Maffione  *
1325c4f8d80SVincenzo Maffione  *  			(more specific keys override the less specific ones)
1335c4f8d80SVincenzo Maffione  *			All keys default to zero if not assigned, and the
1345c4f8d80SVincenzo Maffione  *			corresponding value will be chosen by netmap.
1355c4f8d80SVincenzo Maffione  *
1365c4f8d80SVincenzo Maffione  *  extmem (multi-key)
1375c4f8d80SVincenzo Maffione  *			open the port in the memory region obtained by
1385c4f8d80SVincenzo Maffione  *			mmap()ing the given file.
1395c4f8d80SVincenzo Maffione  *
1405c4f8d80SVincenzo Maffione  *			The keys are:
1415c4f8d80SVincenzo Maffione  *
1425c4f8d80SVincenzo Maffione  *		       *file		the file to mmap
1435c4f8d80SVincenzo Maffione  *			if-num		number of pre-allocated netmap_if's
1445c4f8d80SVincenzo Maffione  *			if-size		size of each netmap_if
1455c4f8d80SVincenzo Maffione  *			ring-num	number of pre-allocated netmap_ring's
1465c4f8d80SVincenzo Maffione  *			ring-size	size of each netmap_ring
1475c4f8d80SVincenzo Maffione  *			buf-num		number of pre-allocated buffers
1485c4f8d80SVincenzo Maffione  *			buf-size	size of each buffer
1495c4f8d80SVincenzo Maffione  *
1505c4f8d80SVincenzo Maffione  *			file must be assigned. The other keys default to zero,
1515c4f8d80SVincenzo Maffione  *			causing netmap to take the corresponding values from
1525c4f8d80SVincenzo Maffione  *			the priv_{if,ring,buf}_{num,size} sysctls.
1535c4f8d80SVincenzo Maffione  *
154f8113f0aSVincenzo Maffione  *  offset (multi-key)
155f8113f0aSVincenzo Maffione  *			reserve (part of) the ptr fields as an offset field
156f8113f0aSVincenzo Maffione  *			and write an initial offset into them.
157f8113f0aSVincenzo Maffione  *
158f8113f0aSVincenzo Maffione  *			The keys are:
159f8113f0aSVincenzo Maffione  *
160f8113f0aSVincenzo Maffione  *		        bits		number of bits of ptr to use
161f8113f0aSVincenzo Maffione  *		       *initial		initial offset value
162f8113f0aSVincenzo Maffione  *
163f8113f0aSVincenzo Maffione  *		        initial must be assigned. If bits is omitted, it
164f8113f0aSVincenzo Maffione  *		        defaults to the entire ptr field. The max offset is set
165f8113f0aSVincenzo Maffione  *		        at the same value as the initial offset. Note that the
166f8113f0aSVincenzo Maffione  *		        actual values may be increased by the kernel.
167f8113f0aSVincenzo Maffione  *
168f8113f0aSVincenzo Maffione  *		        This option is disabled by default (see
169f8113f0aSVincenzo Maffione  *			nmport_enable_option() below)
1705c4f8d80SVincenzo Maffione  */
1715c4f8d80SVincenzo Maffione 
1725c4f8d80SVincenzo Maffione 
1735c4f8d80SVincenzo Maffione /* nmport manipulation */
1745c4f8d80SVincenzo Maffione 
1755c4f8d80SVincenzo Maffione /* struct nmport_d - describes a netmap port */
1765c4f8d80SVincenzo Maffione struct nmport_d {
1775c4f8d80SVincenzo Maffione 	/* see net/netmap.h for the definition of these fields */
1785c4f8d80SVincenzo Maffione 	struct nmreq_header hdr;
1795c4f8d80SVincenzo Maffione 	struct nmreq_register reg;
1805c4f8d80SVincenzo Maffione 
1815c4f8d80SVincenzo Maffione 	/* all the fields below should be considered read-only */
1825c4f8d80SVincenzo Maffione 
1835c4f8d80SVincenzo Maffione 	/* if the same context is used throughout the program, d1->mem ==
1845c4f8d80SVincenzo Maffione 	 * d2->mem iff d1 and d2 are using the memory region (i.e., zero
1855c4f8d80SVincenzo Maffione 	 * copy is possible between the two ports)
1865c4f8d80SVincenzo Maffione 	 */
1875c4f8d80SVincenzo Maffione 	struct nmem_d *mem;
1885c4f8d80SVincenzo Maffione 
1895c4f8d80SVincenzo Maffione 	/* the nmctx used when this nmport_d was created */
1905c4f8d80SVincenzo Maffione 	struct nmctx *ctx;
1915c4f8d80SVincenzo Maffione 
1925c4f8d80SVincenzo Maffione 	int register_done;	/* nmport_register() has been called */
1935c4f8d80SVincenzo Maffione 	int mmap_done;		/* nmport_mmap() has been called */
1945c4f8d80SVincenzo Maffione 	/* pointer to the extmem option contained in the hdr options, if any */
1955c4f8d80SVincenzo Maffione 	struct nmreq_opt_extmem *extmem;
1965c4f8d80SVincenzo Maffione 
1975c4f8d80SVincenzo Maffione 	/* the fields below are compatible with nm_open() */
1985c4f8d80SVincenzo Maffione 	int fd;				/* "/dev/netmap", -1 if not open */
1995c4f8d80SVincenzo Maffione 	struct netmap_if *nifp;		/* pointer to the netmap_if */
2005c4f8d80SVincenzo Maffione 	uint16_t first_tx_ring;
2015c4f8d80SVincenzo Maffione 	uint16_t last_tx_ring;
2025c4f8d80SVincenzo Maffione 	uint16_t first_rx_ring;
2035c4f8d80SVincenzo Maffione 	uint16_t last_rx_ring;
2045c4f8d80SVincenzo Maffione 	uint16_t cur_tx_ring;		/* used by nmport_inject */
2055c4f8d80SVincenzo Maffione 	uint16_t cur_rx_ring;
2065c4f8d80SVincenzo Maffione 
2075c4f8d80SVincenzo Maffione 	/* LIFO list of cleanup functions (used internally) */
2085c4f8d80SVincenzo Maffione 	struct nmport_cleanup_d *clist;
2095c4f8d80SVincenzo Maffione };
2105c4f8d80SVincenzo Maffione 
2115c4f8d80SVincenzo Maffione /* nmport_open - opens a port from a portspec
2125c4f8d80SVincenzo Maffione  * @portspec	the port opening specification
2135c4f8d80SVincenzo Maffione  *
2145c4f8d80SVincenzo Maffione  * If successful, the function returns a new nmport_d describing a netmap
2155c4f8d80SVincenzo Maffione  * port, opened according to the port specification, ready to be used for rx
2165c4f8d80SVincenzo Maffione  * and/or tx.
2175c4f8d80SVincenzo Maffione  *
2185c4f8d80SVincenzo Maffione  * The rings available for tx are in the [first_tx_ring, last_tx_ring]
2195c4f8d80SVincenzo Maffione  * interval, and similarly for rx. One or both intervals may be empty.
2205c4f8d80SVincenzo Maffione  *
2215c4f8d80SVincenzo Maffione  * When done using it, the nmport_d descriptor must be closed using
2225c4f8d80SVincenzo Maffione  * nmport_close().
2235c4f8d80SVincenzo Maffione  *
2245c4f8d80SVincenzo Maffione  * In case of error, NULL is returned, errno is set to some error, and an
2255c4f8d80SVincenzo Maffione  * error message is sent through the error() method of the current context.
2265c4f8d80SVincenzo Maffione  */
2275c4f8d80SVincenzo Maffione struct nmport_d * nmport_open(const char *portspec);
2285c4f8d80SVincenzo Maffione 
2295c4f8d80SVincenzo Maffione /* nport_close - close a netmap port
2305c4f8d80SVincenzo Maffione  * @d		the port we want to close
2315c4f8d80SVincenzo Maffione  *
2325c4f8d80SVincenzo Maffione  * Undoes the actions performed by the nmport_open that created d, then
2335c4f8d80SVincenzo Maffione  * frees the descriptor.
2345c4f8d80SVincenzo Maffione  */
2355c4f8d80SVincenzo Maffione void nmport_close(struct nmport_d *d);
2365c4f8d80SVincenzo Maffione 
2375c4f8d80SVincenzo Maffione /* nmport_inject - sends a packet
2385c4f8d80SVincenzo Maffione  * @d		the port through which we want to send
2395c4f8d80SVincenzo Maffione  * @buf		base address of the packet
2405c4f8d80SVincenzo Maffione  * @size	its size in bytes
2415c4f8d80SVincenzo Maffione  *
2425c4f8d80SVincenzo Maffione  * Sends a packet using the cur_tx_ring and updates the index
2435c4f8d80SVincenzo Maffione  * to use all available tx rings in turn. Note: the packet is copied.
2445c4f8d80SVincenzo Maffione  *
2455c4f8d80SVincenzo Maffione  * Returns 0 on success an -1 on error.
2465c4f8d80SVincenzo Maffione  */
2475c4f8d80SVincenzo Maffione int nmport_inject(struct nmport_d *d, const void *buf, size_t size);
2485c4f8d80SVincenzo Maffione 
2495c4f8d80SVincenzo Maffione /*
2505c4f8d80SVincenzo Maffione  * the functions below can be used to split the functionality of
2515c4f8d80SVincenzo Maffione  * nmport_open when special features (e.g., extra buffers) are needed
2525c4f8d80SVincenzo Maffione  *
2535c4f8d80SVincenzo Maffione  * The relation among the functions is as follows:
2545c4f8d80SVincenzo Maffione  *
2555c4f8d80SVincenzo Maffione  *				   |nmport_new
2565c4f8d80SVincenzo Maffione  * 		|nmport_prepare	 = |
2575c4f8d80SVincenzo Maffione  *		|		   |nmport_parse
2585c4f8d80SVincenzo Maffione  * nmport_open =|
2595c4f8d80SVincenzo Maffione  *		|		   |nmport_register
2605c4f8d80SVincenzo Maffione  *		|nmport_open_desc =|
2615c4f8d80SVincenzo Maffione  *				   |nmport_mmap
2625c4f8d80SVincenzo Maffione  *
2635c4f8d80SVincenzo Maffione  */
2645c4f8d80SVincenzo Maffione 
2655c4f8d80SVincenzo Maffione /* nmport_new - create a new nmport_d
2665c4f8d80SVincenzo Maffione  *
2675c4f8d80SVincenzo Maffione  * Creates a new nmport_d using the malloc() method of the current default
2685c4f8d80SVincenzo Maffione  * context. Returns NULL on error, setting errno to an error value.
2695c4f8d80SVincenzo Maffione  */
2705c4f8d80SVincenzo Maffione struct nmport_d *nmport_new(void);
2715c4f8d80SVincenzo Maffione 
2725c4f8d80SVincenzo Maffione /* nmport_parse - fills the nmport_d netmap-register request
2735c4f8d80SVincenzo Maffione  * @d		the nmport to be filled
2745c4f8d80SVincenzo Maffione  * @portspec	the port opening specification
2755c4f8d80SVincenzo Maffione  *
2765c4f8d80SVincenzo Maffione  * This function parses the portspec and initizalizes the @d->hdr and @d->reg
2775c4f8d80SVincenzo Maffione  * fields. It may need to allocate a list of options. If an extmem option is
2785c4f8d80SVincenzo Maffione  * found, it may also mmap() the corresponding file.
2795c4f8d80SVincenzo Maffione  *
2805c4f8d80SVincenzo Maffione  * It returns 0 on success. On failure it returns -1, sets errno to an error
2815c4f8d80SVincenzo Maffione  * value and sends an error message to the error() method of the context used
2825c4f8d80SVincenzo Maffione  * when @d was created. Moreover, *@d is left unchanged.
2835c4f8d80SVincenzo Maffione  */
2845c4f8d80SVincenzo Maffione int nmport_parse(struct nmport_d *d, const char *portspec);
2855c4f8d80SVincenzo Maffione 
2865c4f8d80SVincenzo Maffione /* nmport_register - registers the port with netmap
2875c4f8d80SVincenzo Maffione  * @d		the nmport to be registered
2885c4f8d80SVincenzo Maffione  *
2895c4f8d80SVincenzo Maffione  * This function obtains a netmap file descriptor and registers the port with
2905c4f8d80SVincenzo Maffione  * netmap. The @d->hdr and @d->reg data structures must have been previously
2915c4f8d80SVincenzo Maffione  * initialized (via nmport_parse() or otherwise).
2925c4f8d80SVincenzo Maffione  *
2935c4f8d80SVincenzo Maffione  * It returns 0 on success. On failure it returns -1, sets errno to an error
2945c4f8d80SVincenzo Maffione  * value and sends an error message to the error() method of the context used
2955c4f8d80SVincenzo Maffione  * when @d was created. Moreover, *@d is left unchanged.
2965c4f8d80SVincenzo Maffione  */
2975c4f8d80SVincenzo Maffione int nmport_register(struct nmport_d *);
2985c4f8d80SVincenzo Maffione 
2995c4f8d80SVincenzo Maffione /* nmport_mmap - maps the port resources into the process memory
3005c4f8d80SVincenzo Maffione  * @d		the nmport to be mapped
3015c4f8d80SVincenzo Maffione  *
3025c4f8d80SVincenzo Maffione  * The port must have been previously been registered using nmport_register.
3035c4f8d80SVincenzo Maffione  *
3045c4f8d80SVincenzo Maffione  * Note that if extmem is used (either via an option or by calling an
3055c4f8d80SVincenzo Maffione  * nmport_extmem_* function before nmport_register()), no new mmap() is issued.
3065c4f8d80SVincenzo Maffione  *
3075c4f8d80SVincenzo Maffione  * It returns 0 on success. On failure it returns -1, sets errno to an error
3085c4f8d80SVincenzo Maffione  * value and sends an error message to the error() method of the context used
3095c4f8d80SVincenzo Maffione  * when @d was created. Moreover, *@d is left unchanged.
3105c4f8d80SVincenzo Maffione  */
3115c4f8d80SVincenzo Maffione int nmport_mmap(struct nmport_d *);
3125c4f8d80SVincenzo Maffione 
3135c4f8d80SVincenzo Maffione /* the following functions undo the actions of nmport_new(), nmport_parse(),
3145c4f8d80SVincenzo Maffione  * nmport_register() and nmport_mmap(), respectively.
3155c4f8d80SVincenzo Maffione  */
3165c4f8d80SVincenzo Maffione void nmport_delete(struct nmport_d *);
3175c4f8d80SVincenzo Maffione void nmport_undo_parse(struct nmport_d *);
3185c4f8d80SVincenzo Maffione void nmport_undo_register(struct nmport_d *);
3195c4f8d80SVincenzo Maffione void nmport_undo_mmap(struct nmport_d *);
3205c4f8d80SVincenzo Maffione 
3215c4f8d80SVincenzo Maffione /* nmport_prepare - create a port descriptor, but do not open it
3225c4f8d80SVincenzo Maffione  * @portspec	the port opening specification
3235c4f8d80SVincenzo Maffione  *
3245c4f8d80SVincenzo Maffione  * This functions creates a new nmport_d and initializes it according to
3255c4f8d80SVincenzo Maffione  * @portspec. It is equivalent to nmport_new() followed by nmport_parse().
3265c4f8d80SVincenzo Maffione  *
3275c4f8d80SVincenzo Maffione  * It returns 0 on success. On failure it returns -1, sets errno to an error
3285c4f8d80SVincenzo Maffione  * value and sends an error message to the error() method of the context used
3295c4f8d80SVincenzo Maffione  * when @d was created. Moreover, *@d is left unchanged.
3305c4f8d80SVincenzo Maffione  */
3315c4f8d80SVincenzo Maffione struct nmport_d *nmport_prepare(const char *portspec);
3325c4f8d80SVincenzo Maffione 
3335c4f8d80SVincenzo Maffione /* nmport_open_desc - open an initialized port descriptor
3345c4f8d80SVincenzo Maffione  * @d		the descriptor we want to open
3355c4f8d80SVincenzo Maffione  *
3365c4f8d80SVincenzo Maffione  * Registers the port with netmap and maps the rings and buffers into the
3375c4f8d80SVincenzo Maffione  * process memory. It is equivalent to nmport_register() followed by
3385c4f8d80SVincenzo Maffione  * nmport_mmap().
3395c4f8d80SVincenzo Maffione  *
3405c4f8d80SVincenzo Maffione  * It returns 0 on success. On failure it returns -1, sets errno to an error
3415c4f8d80SVincenzo Maffione  * value and sends an error message to the error() method of the context used
3425c4f8d80SVincenzo Maffione  * when @d was created. Moreover, *@d is left unchanged.
3435c4f8d80SVincenzo Maffione  */
3445c4f8d80SVincenzo Maffione int nmport_open_desc(struct nmport_d *d);
3455c4f8d80SVincenzo Maffione 
3465c4f8d80SVincenzo Maffione /* the following functions undo the actions of nmport_prepare()
3475c4f8d80SVincenzo Maffione  * and nmport_open_desc(), respectively.
3485c4f8d80SVincenzo Maffione  */
3495c4f8d80SVincenzo Maffione void nmport_undo_prepare(struct nmport_d *);
3505c4f8d80SVincenzo Maffione void nmport_undo_open_desc(struct nmport_d *);
3515c4f8d80SVincenzo Maffione 
3525c4f8d80SVincenzo Maffione /* nmport_clone - copy an nmport_d
3535c4f8d80SVincenzo Maffione  * @d		the nmport_d we want to copy
3545c4f8d80SVincenzo Maffione  *
3555c4f8d80SVincenzo Maffione  * Copying an nmport_d by hand should be avoided, since adjustments are needed
3565c4f8d80SVincenzo Maffione  * and some part of the state cannot be easily duplicated. This function
3575c4f8d80SVincenzo Maffione  * creates a copy of @d in a safe way. The returned nmport_d contains
3585c4f8d80SVincenzo Maffione  * nmreq_header and nmreq_register structures equivalent to those contained in
3595c4f8d80SVincenzo Maffione  * @d, except for the option list, which is ignored. The returned nmport_d is
3605c4f8d80SVincenzo Maffione  * already nmport_prepare()d, but it must still be nmport_open_desc()ed. The
3615c4f8d80SVincenzo Maffione  * new nmport_d uses the same nmctx as @d.
3625c4f8d80SVincenzo Maffione  *
3635c4f8d80SVincenzo Maffione  * If extmem was used for @d, then @d cannot be nmport_clone()d until it has
3645c4f8d80SVincenzo Maffione  * been nmport_register()ed.
3655c4f8d80SVincenzo Maffione  *
3665c4f8d80SVincenzo Maffione  * In case of error, the function returns NULL, sets errno to an error value
3675c4f8d80SVincenzo Maffione  * and sends an error message to the nmctx error() method.
3685c4f8d80SVincenzo Maffione  */
3695c4f8d80SVincenzo Maffione struct nmport_d *nmport_clone(struct nmport_d *);
3705c4f8d80SVincenzo Maffione 
3715c4f8d80SVincenzo Maffione /* nmport_extmem - use extmem for this port
3725c4f8d80SVincenzo Maffione  * @d		the port we want to use the extmem for
3735c4f8d80SVincenzo Maffione  * @base	the base address of the extmem region
3745c4f8d80SVincenzo Maffione  * @size	the size in bytes of the extmem region
3755c4f8d80SVincenzo Maffione  *
3765c4f8d80SVincenzo Maffione  * the memory that contains the netmap ifs, rings and buffers is usually
3775c4f8d80SVincenzo Maffione  * allocated by netmap and later mmap()ed by the applications. It is sometimes
3785c4f8d80SVincenzo Maffione  * useful to reverse this process, by having the applications allocate some
3795c4f8d80SVincenzo Maffione  * memory (through mmap() or otherwise) and then let netmap use it.  The extmem
3805c4f8d80SVincenzo Maffione  * option can be used to implement this latter strategy. The option can be
3815c4f8d80SVincenzo Maffione  * passed through the portspec using the '@extmem:...' syntax, or
3825c4f8d80SVincenzo Maffione  * programmatically by calling nmport_extmem() or nmport_extmem_from_file()
3835c4f8d80SVincenzo Maffione  * between nmport_parse() and nmport_register() (or between nmport_prepare()
3845c4f8d80SVincenzo Maffione  * and nmport_open_desc()).
3855c4f8d80SVincenzo Maffione  *
3865c4f8d80SVincenzo Maffione  * It returns 0 on success. On failure it returns -1, sets errno to an error
3875c4f8d80SVincenzo Maffione  * value and sends an error message to the error() method of the context used
3885c4f8d80SVincenzo Maffione  * when @d was created. Moreover, *@d is left unchanged.
3895c4f8d80SVincenzo Maffione  */
3905c4f8d80SVincenzo Maffione int nmport_extmem(struct nmport_d *d, void *base, size_t size);
3915c4f8d80SVincenzo Maffione 
3925c4f8d80SVincenzo Maffione /* nmport_extmem_from_file - use the extmem obtained by mapping a file
3935c4f8d80SVincenzo Maffione  * @d		the port we want to use the extmem for
3945c4f8d80SVincenzo Maffione  * @fname	path of the file we want to map
3955c4f8d80SVincenzo Maffione  *
3965c4f8d80SVincenzo Maffione  * This works like nmport_extmem, but the extmem memory is obtained by
3975c4f8d80SVincenzo Maffione  * mmap()ping @fname. nmport_close() will also automatically munmap() the file.
3985c4f8d80SVincenzo Maffione  *
3995c4f8d80SVincenzo Maffione  * It returns 0 on success. On failure it returns -1, sets errno to an error
4005c4f8d80SVincenzo Maffione  * value and sends an error message to the error() method of the context used
4015c4f8d80SVincenzo Maffione  * when @d was created. Moreover, *@d is left unchanged.
4025c4f8d80SVincenzo Maffione  */
4035c4f8d80SVincenzo Maffione int nmport_extmem_from_file(struct nmport_d *d, const char *fname);
4045c4f8d80SVincenzo Maffione 
4055c4f8d80SVincenzo Maffione /* nmport_extmem_getinfo - opbtai a pointer to the extmem configuration
4065c4f8d80SVincenzo Maffione  * @d		the port we want to obtain the pointer from
4075c4f8d80SVincenzo Maffione  *
4085c4f8d80SVincenzo Maffione  * Returns a pointer to the nmreq_pools_info structure containing the
4095c4f8d80SVincenzo Maffione  * configuration of the extmem attached to port @d, or NULL if no extmem
4105c4f8d80SVincenzo Maffione  * is attached. This can be used to set the desired configuration before
4115c4f8d80SVincenzo Maffione  * registering the port, or to read the actual configuration after
4125c4f8d80SVincenzo Maffione  * registration.
4135c4f8d80SVincenzo Maffione  */
4145c4f8d80SVincenzo Maffione struct nmreq_pools_info* nmport_extmem_getinfo(struct nmport_d *d);
4155c4f8d80SVincenzo Maffione 
4165c4f8d80SVincenzo Maffione 
417f8113f0aSVincenzo Maffione /* nmport_offset - use offsets for this port
418f8113f0aSVincenzo Maffione  * @initial	the initial offset for all the slots
419f8113f0aSVincenzo Maffione  * @maxoff	the maximum offset
420f8113f0aSVincenzo Maffione  * @bits	the number of bits of slot->ptr to use for the offsets
421*45c67e8fSVincenzo Maffione  * @mingap	the minimum gap between offsets (in shared buffers)
422f8113f0aSVincenzo Maffione  *
423f8113f0aSVincenzo Maffione  * With this option the lower @bits bits of the ptr field in the netmap_slot
424f8113f0aSVincenzo Maffione  * can be used to specify an offset into the buffer.  All offsets will be set
425f8113f0aSVincenzo Maffione  * to the @initial value by netmap.
426f8113f0aSVincenzo Maffione  *
427f8113f0aSVincenzo Maffione  * The offset field can be read and updated using the bitmask found in
428f8113f0aSVincenzo Maffione  * ring->offset_mask after a successful register.  netmap_user.h contains
429f8113f0aSVincenzo Maffione  * some helper macros (NETMAP_ROFFSET, NETMAP_WOFFSET and NETMAP_BUF_OFFSET).
430f8113f0aSVincenzo Maffione  *
431f8113f0aSVincenzo Maffione  * For RX rings, the user writes the offset o in an empty slot before passing
432f8113f0aSVincenzo Maffione  * it to netmap; then, netmap will write the incoming packet at an offset o' >=
433f8113f0aSVincenzo Maffione  * o in the buffer. o' may be larger than o because of, e.g., alignment
434f8113f0aSVincenzo Maffione  * constrains.  If o' > o netmap will also update the offset field in the slot.
435f8113f0aSVincenzo Maffione  * Note that large offsets may cause the port to split the packet over several
436f8113f0aSVincenzo Maffione  * slots, setting the NS_MOREFRAG flag accordingly.
437f8113f0aSVincenzo Maffione  *
438f8113f0aSVincenzo Maffione  * For TX rings, the user may prepare the packet to send at an offset o into
439f8113f0aSVincenzo Maffione  * the buffer and write o in the offset field. Netmap will send the packets
440f8113f0aSVincenzo Maffione  * starting o bytes in the buffer. Note that the address of the packet must
441f8113f0aSVincenzo Maffione  * comply with any alignment constraints that the port may have, or the result
442f8113f0aSVincenzo Maffione  * will be undefined. The user may read the alignment constraint in the new
443*45c67e8fSVincenzo Maffione  * ring->buf_align field.  It is also possible that empty slots already come
444f8113f0aSVincenzo Maffione  * with a non-zero offset o specified in the offset field. In this case, the
445f8113f0aSVincenzo Maffione  * user will have to write the packet at an offset o' >= o.
446f8113f0aSVincenzo Maffione  *
447f8113f0aSVincenzo Maffione  * The user must also declare the @maxoff offset that she is going to use. Any
448f8113f0aSVincenzo Maffione  * offset larger than this will be truncated.
449f8113f0aSVincenzo Maffione  *
450f8113f0aSVincenzo Maffione  * The user may also declare a @mingap (ignored if zero) if she plans to use
451f8113f0aSVincenzo Maffione  * offsets to share the same buffer among several slots. Netmap will guarantee
452f8113f0aSVincenzo Maffione  * that it will never write more than @mingap bytes for each slot, irrespective
453f8113f0aSVincenzo Maffione  * of the buffer length.
454f8113f0aSVincenzo Maffione  */
455f8113f0aSVincenzo Maffione int nmport_offset(struct nmport_d *d, uint64_t initial, uint64_t maxoff,
456f8113f0aSVincenzo Maffione 		uint64_t bits, uint64_t mingap);
457f8113f0aSVincenzo Maffione 
4585c4f8d80SVincenzo Maffione /* enable/disable options
4595c4f8d80SVincenzo Maffione  *
4605c4f8d80SVincenzo Maffione  * These functions can be used to disable options that the application cannot
4615c4f8d80SVincenzo Maffione  * or doesn't want to handle, or to enable options that require special support
4625c4f8d80SVincenzo Maffione  * from the application and are, therefore, disabled by default. Disabled
4635c4f8d80SVincenzo Maffione  * options will cause an error if encountered during option parsing.
4645c4f8d80SVincenzo Maffione  *
4655c4f8d80SVincenzo Maffione  * If the option is unknown, nmport_disable_option is a NOP, while
4665c4f8d80SVincenzo Maffione  * nmport_enable_option returns -1 and sets errno to EOPNOTSUPP.
4675c4f8d80SVincenzo Maffione  *
4685c4f8d80SVincenzo Maffione  * These functions are not threadsafe and are meant to be used at the beginning
4695c4f8d80SVincenzo Maffione  * of the program.
4705c4f8d80SVincenzo Maffione  */
4715c4f8d80SVincenzo Maffione void nmport_disable_option(const char *opt);
4725c4f8d80SVincenzo Maffione int nmport_enable_option(const char *opt);
4735c4f8d80SVincenzo Maffione 
4745c4f8d80SVincenzo Maffione /* nmreq manipulation
4755c4f8d80SVincenzo Maffione  *
4765c4f8d80SVincenzo Maffione  * nmreq_header_init - initialize an nmreq_header
4775c4f8d80SVincenzo Maffione  * @hdr		the nmreq_header to initialize
4785c4f8d80SVincenzo Maffione  * @reqtype	the kind of netmap request
4795c4f8d80SVincenzo Maffione  * @body	the body of the request
4805c4f8d80SVincenzo Maffione  *
4815c4f8d80SVincenzo Maffione  * Initialize the nr_version, nr_reqtype and nr_body fields of *@hdr.
4825c4f8d80SVincenzo Maffione  * The other fields are set to zero.
4835c4f8d80SVincenzo Maffione  */
4845c4f8d80SVincenzo Maffione void nmreq_header_init(struct nmreq_header *hdr, uint16_t reqtype, void *body);
4855c4f8d80SVincenzo Maffione 
4865c4f8d80SVincenzo Maffione /*
4875c4f8d80SVincenzo Maffione  * These functions allow for finer grained parsing of portspecs.  They are used
4885c4f8d80SVincenzo Maffione  * internally by nmport_parse().
4895c4f8d80SVincenzo Maffione  */
4905c4f8d80SVincenzo Maffione 
4915c4f8d80SVincenzo Maffione /* nmreq_header_decode - initialize an nmreq_header
4925c4f8d80SVincenzo Maffione  * @ppspec:	(in/out) pointer to a pointer to the portspec
4935c4f8d80SVincenzo Maffione  * @hdr:	pointer to the nmreq_header to be initialized
4945c4f8d80SVincenzo Maffione  * @ctx:	pointer to the nmctx to use (for errors)
4955c4f8d80SVincenzo Maffione  *
4965c4f8d80SVincenzo Maffione  * This function fills the @hdr the nr_name field with the port name extracted
4975c4f8d80SVincenzo Maffione  * from *@pifname.  The other fields of *@hdr are unchanged. The @pifname is
4985c4f8d80SVincenzo Maffione  * updated to point at the first char past the port name.
4995c4f8d80SVincenzo Maffione  *
5005c4f8d80SVincenzo Maffione  * Returns 0 on success.  In case of error, -1 is returned with errno set to
5015c4f8d80SVincenzo Maffione  * EINVAL, @pifname is unchanged, *@hdr is also unchanged, and an error message
5025c4f8d80SVincenzo Maffione  * is sent through @ctx->error().
5035c4f8d80SVincenzo Maffione  */
5045c4f8d80SVincenzo Maffione int nmreq_header_decode(const char **ppspec, struct nmreq_header *hdr,
5055c4f8d80SVincenzo Maffione 		struct nmctx *ctx);
5065c4f8d80SVincenzo Maffione 
5075c4f8d80SVincenzo Maffione /* nmreq_regiter_decode - initialize an nmreq_register
5085c4f8d80SVincenzo Maffione  * @pmode:	(in/out) pointer to a pointer to an opening mode
5095c4f8d80SVincenzo Maffione  * @reg:	pointer to the nmreq_register to be initialized
5105c4f8d80SVincenzo Maffione  * @ctx:	pointer to the nmctx to use (for errors)
5115c4f8d80SVincenzo Maffione  *
5125c4f8d80SVincenzo Maffione  * This function fills the nr_mode, nr_ringid, nr_flags and nr_mem_id fields of
5135c4f8d80SVincenzo Maffione  * the structure pointed by @reg, according to the opening mode specified by
5145c4f8d80SVincenzo Maffione  * *@pmode. The other fields of *@reg are unchanged.  The @pmode is updated to
5155c4f8d80SVincenzo Maffione  * point at the first char past the opening mode.
5165c4f8d80SVincenzo Maffione  *
5175c4f8d80SVincenzo Maffione  * If a '@' is encountered followed by something which is not a number, parsing
5185c4f8d80SVincenzo Maffione  * stops (without error) and @pmode is left pointing at the '@' char. The
5195c4f8d80SVincenzo Maffione  * nr_mode, nr_ringid and nr_flags fields are still updated, but nr_mem_id is
5205c4f8d80SVincenzo Maffione  * not touched and the interpretation of the '@' field is left to the caller.
5215c4f8d80SVincenzo Maffione  *
5225c4f8d80SVincenzo Maffione  * Returns 0 on success.  In case of error, -1 is returned with errno set to
5235c4f8d80SVincenzo Maffione  * EINVAL, @pmode is unchanged, *@reg is also unchanged, and an error message
5245c4f8d80SVincenzo Maffione  * is sent through @ctx->error().
5255c4f8d80SVincenzo Maffione  */
5265c4f8d80SVincenzo Maffione int nmreq_register_decode(const char **pmode, struct nmreq_register *reg,
5275c4f8d80SVincenzo Maffione 		struct nmctx *ctx);
5285c4f8d80SVincenzo Maffione 
5295c4f8d80SVincenzo Maffione /* nmreq_options_decode - parse the "options" part of the portspec
5305c4f8d80SVincenzo Maffione  * @opt:	pointer to the option list
5315c4f8d80SVincenzo Maffione  * @parsers:	list of option parsers
5325c4f8d80SVincenzo Maffione  * @token:	token to pass to each parser
5335c4f8d80SVincenzo Maffione  * @ctx:	pointer to the nmctx to use (for errors and malloc/free)
5345c4f8d80SVincenzo Maffione  *
5355c4f8d80SVincenzo Maffione  * This function parses each option in @opt. Each option is matched (based on
5365c4f8d80SVincenzo Maffione  * the "option" prefix) to a corresponding parser in @parsers. The function
5375c4f8d80SVincenzo Maffione  * checks that the syntax is appropriate for the parser and it assigns all the
5385c4f8d80SVincenzo Maffione  * keys mentioned in the option. It then passes control to the parser, to
5395c4f8d80SVincenzo Maffione  * interpret the keys values.
5405c4f8d80SVincenzo Maffione  *
5415c4f8d80SVincenzo Maffione  * Returns 0 on success. In case of error, -1 is returned, errno is set to an
5425c4f8d80SVincenzo Maffione  * error value and a message is sent to @ctx->error(). The effects of partially
5435c4f8d80SVincenzo Maffione  * interpreted options may not be undone.
5445c4f8d80SVincenzo Maffione  */
5455c4f8d80SVincenzo Maffione struct nmreq_opt_parser;
5465c4f8d80SVincenzo Maffione int nmreq_options_decode(const char *opt, struct nmreq_opt_parser *parsers,
5475c4f8d80SVincenzo Maffione 		void *token, struct nmctx *ctx);
5485c4f8d80SVincenzo Maffione 
5495c4f8d80SVincenzo Maffione struct nmreq_parse_ctx;
5505c4f8d80SVincenzo Maffione /* type of the option-parsers callbacks */
5515c4f8d80SVincenzo Maffione typedef int (*nmreq_opt_parser_cb)(struct nmreq_parse_ctx *);
5525c4f8d80SVincenzo Maffione 
5535c4f8d80SVincenzo Maffione #define NMREQ_OPT_MAXKEYS 16	/* max nr of recognized keys per option */
5545c4f8d80SVincenzo Maffione 
5555c4f8d80SVincenzo Maffione /* struct nmreq_opt_key - describes an option key */
5565c4f8d80SVincenzo Maffione struct nmreq_opt_key {
5575c4f8d80SVincenzo Maffione 	const char *key;	/* the key name */
5585c4f8d80SVincenzo Maffione 	int id;			/* its position in the parse context */
5595c4f8d80SVincenzo Maffione 	unsigned int flags;
5605c4f8d80SVincenzo Maffione #define NMREQ_OPTK_ALLOWEMPTY 	(1U << 0) /* =value may be omitted */
5615c4f8d80SVincenzo Maffione #define NMREQ_OPTK_MUSTSET	(1U << 1) /* the key is mandatory */
5625c4f8d80SVincenzo Maffione #define NMREQ_OPTK_DEFAULT	(1U << 2) /* this is the default key */
5635c4f8d80SVincenzo Maffione };
5645c4f8d80SVincenzo Maffione 
5655c4f8d80SVincenzo Maffione /* struct nmreq_opt_parser - describes an option parser */
5665c4f8d80SVincenzo Maffione struct nmreq_opt_parser {
5675c4f8d80SVincenzo Maffione 	const char *prefix;	/* matches one option prefix */
5685c4f8d80SVincenzo Maffione 	nmreq_opt_parser_cb parse;	/* the parse callback */
5695c4f8d80SVincenzo Maffione 	int default_key;	/* which option is the default if the
5705c4f8d80SVincenzo Maffione 				   parser is multi-key (-1 if none) */
5715c4f8d80SVincenzo Maffione 	int nr_keys;
5725c4f8d80SVincenzo Maffione 	unsigned int flags;
5735c4f8d80SVincenzo Maffione #define NMREQ_OPTF_DISABLED     (1U << 0)
5745c4f8d80SVincenzo Maffione #define NMREQ_OPTF_ALLOWEMPTY	(1U << 1)	/* =value can be omitted */
5755c4f8d80SVincenzo Maffione 
5765c4f8d80SVincenzo Maffione 	struct nmreq_opt_parser *next;	/* list of options */
5775c4f8d80SVincenzo Maffione 
5785c4f8d80SVincenzo Maffione 	/* recognized keys */
5795c4f8d80SVincenzo Maffione 	struct nmreq_opt_key keys[NMREQ_OPT_MAXKEYS];
5805c4f8d80SVincenzo Maffione } __attribute__((aligned(16)));
5815c4f8d80SVincenzo Maffione 
5825c4f8d80SVincenzo Maffione /* struct nmreq_parse_ctx - the parse context received by the parse callback */
5835c4f8d80SVincenzo Maffione struct nmreq_parse_ctx {
5845c4f8d80SVincenzo Maffione 	struct nmctx *ctx;	/* the nmctx for errors and malloc/free */
5855c4f8d80SVincenzo Maffione 	void *token;		/* the token passed to nmreq_options_parse */
5865c4f8d80SVincenzo Maffione 
5875c4f8d80SVincenzo Maffione 	/* the value (i.e., the part after the = sign) of each recognized key
5885c4f8d80SVincenzo Maffione 	 * is assigned to the corresponding entry in this array, based on the
5895c4f8d80SVincenzo Maffione 	 * key id. Unassigned keys are left at NULL.
5905c4f8d80SVincenzo Maffione 	 */
5915c4f8d80SVincenzo Maffione 	const char *keys[NMREQ_OPT_MAXKEYS];
5925c4f8d80SVincenzo Maffione };
5935c4f8d80SVincenzo Maffione 
5945c4f8d80SVincenzo Maffione /* nmreq_get_mem_id - get the mem_id of the given port
5955c4f8d80SVincenzo Maffione  * @portname	pointer to a pointer to the portname
5965c4f8d80SVincenzo Maffione  * @ctx		pointer to the nmctx to use (for errors)
5975c4f8d80SVincenzo Maffione  *
5985c4f8d80SVincenzo Maffione  * *@portname must point to a substem:vpname porname, possibly followed by
5995c4f8d80SVincenzo Maffione  * something else.
6005c4f8d80SVincenzo Maffione  *
6015c4f8d80SVincenzo Maffione  * If successful, returns the mem_id of *@portname and moves @portname past the
6025c4f8d80SVincenzo Maffione  * subsystem:vpname part of the input. In case of error it returns -1, sets
6035c4f8d80SVincenzo Maffione  * errno to an error value and sends an error message to ctx->error().
6045c4f8d80SVincenzo Maffione  */
6055c4f8d80SVincenzo Maffione int32_t nmreq_get_mem_id(const char **portname, struct nmctx *ctx);
6065c4f8d80SVincenzo Maffione 
6075c4f8d80SVincenzo Maffione /* option list manipulation */
6085c4f8d80SVincenzo Maffione void nmreq_push_option(struct nmreq_header *, struct nmreq_option *);
6095c4f8d80SVincenzo Maffione void nmreq_remove_option(struct nmreq_header *, struct nmreq_option *);
6105c4f8d80SVincenzo Maffione struct nmreq_option *nmreq_find_option(struct nmreq_header *, uint32_t);
6115c4f8d80SVincenzo Maffione void nmreq_free_options(struct nmreq_header *);
6125c4f8d80SVincenzo Maffione const char* nmreq_option_name(uint32_t);
6135c4f8d80SVincenzo Maffione #define nmreq_foreach_option(h_, o_) \
61492c5d82cSVincenzo Maffione 	for ((o_) = (struct nmreq_option *)((uintptr_t)((h_)->nr_options));\
6155c4f8d80SVincenzo Maffione 	     (o_) != NULL;\
61692c5d82cSVincenzo Maffione 	     (o_) = (struct nmreq_option *)((uintptr_t)((o_)->nro_next)))
6175c4f8d80SVincenzo Maffione 
6185c4f8d80SVincenzo Maffione /* nmctx manipulation */
6195c4f8d80SVincenzo Maffione 
6205c4f8d80SVincenzo Maffione /* the nmctx serves a few purposes:
6215c4f8d80SVincenzo Maffione  *
6225c4f8d80SVincenzo Maffione  * - maintain a list of all memory regions open by the program, so that two
6235c4f8d80SVincenzo Maffione  *   ports that are using the same region (as identified by the mem_id) will
6245c4f8d80SVincenzo Maffione  *   point to the same nmem_d instance.
6255c4f8d80SVincenzo Maffione  *
6265c4f8d80SVincenzo Maffione  * - allow the user to specify how to lock accesses to the above list, if
6275c4f8d80SVincenzo Maffione  *   needed (lock() callback)
6285c4f8d80SVincenzo Maffione  *
6295c4f8d80SVincenzo Maffione  * - allow the user to specify how error messages should be delivered (error()
6305c4f8d80SVincenzo Maffione  *   callback)
6315c4f8d80SVincenzo Maffione  *
6325c4f8d80SVincenzo Maffione  * - select the verbosity of the library (verbose field); if verbose==0, no
6335c4f8d80SVincenzo Maffione  *   errors are sent to the error() callback
6345c4f8d80SVincenzo Maffione  *
6355c4f8d80SVincenzo Maffione  * - allow the user to override the malloc/free functions used by the library
6365c4f8d80SVincenzo Maffione  *   (malloc() and free() callbacks)
6375c4f8d80SVincenzo Maffione  *
6385c4f8d80SVincenzo Maffione  */
6395c4f8d80SVincenzo Maffione typedef void  (*nmctx_error_cb)(struct nmctx *, const char *);
6405c4f8d80SVincenzo Maffione typedef void *(*nmctx_malloc_cb)(struct nmctx *,size_t);
6415c4f8d80SVincenzo Maffione typedef void  (*nmctx_free_cb)(struct nmctx *,void *);
6425c4f8d80SVincenzo Maffione typedef void  (*nmctx_lock_cb)(struct nmctx *, int);
6435c4f8d80SVincenzo Maffione 
6445c4f8d80SVincenzo Maffione struct nmctx {
6455c4f8d80SVincenzo Maffione 	int verbose;
6465c4f8d80SVincenzo Maffione 	nmctx_error_cb 	error;
6475c4f8d80SVincenzo Maffione 	nmctx_malloc_cb	malloc;
6485c4f8d80SVincenzo Maffione 	nmctx_free_cb	free;
6495c4f8d80SVincenzo Maffione 	nmctx_lock_cb	lock;
6505c4f8d80SVincenzo Maffione 
6515c4f8d80SVincenzo Maffione 	struct nmem_d  *mem_descs;
6525c4f8d80SVincenzo Maffione };
6535c4f8d80SVincenzo Maffione 
6545c4f8d80SVincenzo Maffione /* nmctx_get - obtain a pointer to the current default context */
6555c4f8d80SVincenzo Maffione struct nmctx *nmctx_get(void);
6565c4f8d80SVincenzo Maffione 
6575c4f8d80SVincenzo Maffione /* nmctx_set_default - change the default context
6585c4f8d80SVincenzo Maffione  * @ctx		pointer to the new context
6595c4f8d80SVincenzo Maffione  *
6605c4f8d80SVincenzo Maffione  * Returns a pointer to the previous default context.
6615c4f8d80SVincenzo Maffione  */
6625c4f8d80SVincenzo Maffione struct nmctx *nmctx_set_default(struct nmctx *ctx);
6635c4f8d80SVincenzo Maffione 
6645c4f8d80SVincenzo Maffione /* internal functions and data structures */
6655c4f8d80SVincenzo Maffione 
6665c4f8d80SVincenzo Maffione /* struct nmem_d - describes a memory region currently used */
6675c4f8d80SVincenzo Maffione struct nmem_d {
6685c4f8d80SVincenzo Maffione 	uint16_t mem_id;	/* the region netmap identifier */
6695c4f8d80SVincenzo Maffione 	int refcount;		/* how many nmport_d's point here */
6705c4f8d80SVincenzo Maffione 	void *mem;		/* memory region base address */
6715c4f8d80SVincenzo Maffione 	size_t size;		/* memory region size */
6725c4f8d80SVincenzo Maffione 	int is_extmem;		/* was it obtained via extmem? */
6735c4f8d80SVincenzo Maffione 
6745c4f8d80SVincenzo Maffione 	/* pointers for the circular list implementation.
6755c4f8d80SVincenzo Maffione 	 * The list head is the mem_descs filed in the nmctx
6765c4f8d80SVincenzo Maffione 	 */
6775c4f8d80SVincenzo Maffione 	struct nmem_d *next;
6785c4f8d80SVincenzo Maffione 	struct nmem_d *prev;
6795c4f8d80SVincenzo Maffione };
6805c4f8d80SVincenzo Maffione 
6815c4f8d80SVincenzo Maffione /* a trick to force the inclusion of libpthread only if requested. If
6825c4f8d80SVincenzo Maffione  * LIBNETMAP_NOTHREADSAFE is defined, no pthread symbol is imported.
6835c4f8d80SVincenzo Maffione  *
6845c4f8d80SVincenzo Maffione  * There is no need to actually call this function: the ((used)) attribute is
6855c4f8d80SVincenzo Maffione  * sufficient to include it in the image.
6865c4f8d80SVincenzo Maffione  */
6875c4f8d80SVincenzo Maffione static  __attribute__((used)) void libnetmap_init(void)
6885c4f8d80SVincenzo Maffione {
6895c4f8d80SVincenzo Maffione #ifndef LIBNETMAP_NOTHREADSAFE
6905c4f8d80SVincenzo Maffione 	extern int nmctx_threadsafe;
6915c4f8d80SVincenzo Maffione 	/* dummy assignment to link-in the nmctx-pthread.o object.  The proper
6925c4f8d80SVincenzo Maffione 	 * inizialization is performed only once in the library constructor
6935c4f8d80SVincenzo Maffione 	 * defined there.
6945c4f8d80SVincenzo Maffione 	 */
6955c4f8d80SVincenzo Maffione 	nmctx_threadsafe = 1;
6965c4f8d80SVincenzo Maffione #endif /* LIBNETMAP_NOTHREADSAFE */
6975c4f8d80SVincenzo Maffione }
6985c4f8d80SVincenzo Maffione 
6995c4f8d80SVincenzo Maffione /* nmctx_set_threadsafe - install a threadsafe default context
7005c4f8d80SVincenzo Maffione  *
7015c4f8d80SVincenzo Maffione  * called by the constructor in nmctx-pthread.o to initialize a lock and install
7025c4f8d80SVincenzo Maffione  * the lock() callback in the default context.
7035c4f8d80SVincenzo Maffione  */
7045c4f8d80SVincenzo Maffione void nmctx_set_threadsafe(void);
7055c4f8d80SVincenzo Maffione 
7065c4f8d80SVincenzo Maffione /* nmctx_ferror - format and send an error message */
7075c4f8d80SVincenzo Maffione void nmctx_ferror(struct nmctx *, const char *, ...);
7085c4f8d80SVincenzo Maffione /* nmctx_malloc - allocate memory */
7095c4f8d80SVincenzo Maffione void *nmctx_malloc(struct nmctx *, size_t);
7105c4f8d80SVincenzo Maffione /* nmctx_free - free memory allocated via nmctx_malloc */
7115c4f8d80SVincenzo Maffione void nmctx_free(struct nmctx *, void *);
7125c4f8d80SVincenzo Maffione /* nmctx_lock - lock the list of nmem_d */
7135c4f8d80SVincenzo Maffione void nmctx_lock(struct nmctx *);
7145c4f8d80SVincenzo Maffione /* nmctx_unlock - unlock the list of nmem_d */
7155c4f8d80SVincenzo Maffione void nmctx_unlock(struct nmctx *);
7165c4f8d80SVincenzo Maffione 
7175c4f8d80SVincenzo Maffione #endif /* LIBNETMAP_H_ */
718