xref: /freebsd/sys/net/netmap.h (revision 5686c6c38a3e1cc78804eaf5f880bda23dcf592f)
1 /*
2  * Copyright (C) 2011 Matteo Landi, Luigi Rizzo. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *   1. Redistributions of source code must retain the above copyright
9  *      notice, this list of conditions and the following disclaimer.
10  *
11  *   2. Redistributions in binary form must reproduce the above copyright
12  *      notice, this list of conditions and the following disclaimer in the
13  *      documentation and/or other materials provided with the
14  *      distribution.
15  *
16  *   3. Neither the name of the authors nor the names of their contributors
17  *      may be used to endorse or promote products derived from this
18  *      software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY MATTEO LANDI AND CONTRIBUTORS "AS IS" AND
21  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL MATTEO LANDI OR CONTRIBUTORS
24  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  */
32 
33 /*
34  * $FreeBSD$
35  *
36  * Definitions of constants and the structures used by the netmap
37  * framework, for the part visible to both kernel and userspace.
38  * Detailed info on netmap is available with "man netmap" or at
39  *
40  *	http://info.iet.unipi.it/~luigi/netmap/
41  */
42 
43 #ifndef _NET_NETMAP_H_
44 #define _NET_NETMAP_H_
45 
46 /*
47  * --- Netmap data structures ---
48  *
49  * The data structures used by netmap are shown below. Those in
50  * capital letters are in an mmapp()ed area shared with userspace,
51  * while others are private to the kernel.
52  * Shared structures do not contain pointers but only memory
53  * offsets, so that addressing is portable between kernel and userspace.
54 
55 
56  softc
57 +----------------+
58 | standard fields|
59 | if_pspare[0] ----------+
60 +----------------+       |
61                          |
62 +----------------+<------+
63 |(netmap_adapter)|
64 |                |                             netmap_kring
65 | tx_rings *--------------------------------->+---------------+
66 |                |       netmap_kring         | ring    *---------.
67 | rx_rings *--------->+---------------+       | nr_hwcur      |   |
68 +----------------+    | ring    *--------.    | nr_hwavail    |   V
69                       | nr_hwcur      |  |    | selinfo       |   |
70                       | nr_hwavail    |  |    +---------------+   .
71                       | selinfo       |  |    |     ...       |   .
72                       +---------------+  |    |(ntx+1 entries)|
73                       |    ....       |  |    |               |
74                       |(nrx+1 entries)|  |    +---------------+
75                       |               |  |
76    KERNEL             +---------------+  |
77                                          |
78   ====================================================================
79                                          |
80    USERSPACE                             |      NETMAP_RING
81                                          +---->+-------------+
82                                              / | cur         |
83    NETMAP_IF  (nifp, one per file desc.)    /  | avail       |
84     +---------------+                      /   | buf_ofs     |
85     | ni_tx_rings   |                     /    +=============+
86     | ni_rx_rings   |                    /     | buf_idx     | slot[0]
87     |               |                   /      | len, flags  |
88     |               |                  /       +-------------+
89     +===============+                 /        | buf_idx     | slot[1]
90     | txring_ofs[0] | (rel.to nifp)--'         | len, flags  |
91     | txring_ofs[1] |                          +-------------+
92   (num_rings+1 entries)                     (nr_num_slots entries)
93     | txring_ofs[n] |                          | buf_idx     | slot[n-1]
94     +---------------+                          | len, flags  |
95     | rxring_ofs[0] |                          +-------------+
96     | rxring_ofs[1] |
97   (num_rings+1 entries)
98     | txring_ofs[n] |
99     +---------------+
100 
101  * The private descriptor ('softc' or 'adapter') of each interface
102  * is extended with a "struct netmap_adapter" containing netmap-related
103  * info (see description in dev/netmap/netmap_kernel.h.
104  * Among other things, tx_rings and rx_rings point to the arrays of
105  * "struct netmap_kring" which in turn reache the various
106  * "struct netmap_ring", shared with userspace.
107 
108  * The NETMAP_RING is the userspace-visible replica of the NIC ring.
109  * Each slot has the index of a buffer, its length and some flags.
110  * In user space, the buffer address is computed as
111  *	(char *)ring + buf_ofs + index*NETMAP_BUF_SIZE
112  * In the kernel, buffers do not necessarily need to be contiguous,
113  * and the virtual and physical addresses are derived through
114  * a lookup table.
115  *
116  * struct netmap_slot:
117  *
118  * buf_idx	is the index of the buffer associated to the slot.
119  * len		is the length of the payload
120  * NS_BUF_CHANGED	must be set whenever userspace wants
121  *		to change buf_idx (it might be necessary to
122  *		reprogram the NIC slot)
123  * NS_REPORT	must be set if we want the NIC to generate an interrupt
124  *		when this slot is used. Leaving it to 0 improves
125  *		performance.
126  * NS_FORWARD	if set on a receive ring, and the device is in
127  *		transparent mode, buffers released with the flag set
128  *		will be forwarded to the 'other' side (host stack
129  *		or NIC, respectively) on the next select() or ioctl()
130  * NS_NO_LEARN	on a VALE switch, do not 'learn' the source port for
131  *		this packet.
132  * NS_PORT_MASK	the high 8 bits of the flag, if not zero, indicate the
133  *		destination port for the VALE switch, overriding
134  *		the lookup table.
135  */
136 
137 struct netmap_slot {
138 	uint32_t buf_idx; /* buffer index */
139 	uint16_t len;	/* packet length, to be copied to/from the hw ring */
140 	uint16_t flags;	/* buf changed, etc. */
141 #define	NS_BUF_CHANGED	0x0001	/* must resync the map, buffer changed */
142 #define	NS_REPORT	0x0002	/* ask the hardware to report results
143 				 * e.g. by generating an interrupt
144 				 */
145 #define	NS_FORWARD	0x0004	/* pass packet to the other endpoint
146 				 * (host stack or device)
147 				 */
148 #define	NS_NO_LEARN	0x0008
149 #define	NS_PORT_SHIFT	8
150 #define	NS_PORT_MASK	(0xff << NS_PORT_SHIFT)
151 };
152 
153 /*
154  * Netmap representation of a TX or RX ring (also known as "queue").
155  * This is a queue implemented as a fixed-size circular array.
156  * At the software level, two fields are important: avail and cur.
157  *
158  * In TX rings:
159  *	avail	indicates the number of slots available for transmission.
160  *		It is updated by the kernel after every netmap system call.
161  *		It MUST BE decremented by the application when it appends a
162  *		packet.
163  *	cur	indicates the slot to use for the next packet
164  *		to send (i.e. the "tail" of the queue).
165  *		It MUST BE incremented by the application before
166  *		netmap system calls to reflect the number of newly
167  *		sent packets.
168  *		It is checked by the kernel on netmap system calls
169  *		(normally unmodified by the kernel unless invalid).
170  *
171  *   The kernel side of netmap uses two additional fields in its own
172  *   private ring structure, netmap_kring:
173  *	nr_hwcur is a copy of nr_cur on an NIOCTXSYNC.
174  *	nr_hwavail is the number of slots known as available by the
175  *		hardware. It is updated on an INTR (inc by the
176  *		number of packets sent) and on a NIOCTXSYNC
177  *		(decrease by nr_cur - nr_hwcur)
178  *		A special case, nr_hwavail is -1 if the transmit
179  *		side is idle (no pending transmits).
180  *
181  * In RX rings:
182  *	avail	is the number of packets available (possibly 0).
183  *		It MUST BE decremented by the application when it consumes
184  *		a packet, and it is updated to nr_hwavail on a NIOCRXSYNC
185  *	cur	indicates the first slot that contains a packet not
186  *		processed yet (the "head" of the queue).
187  *		It MUST BE incremented by the software when it consumes
188  *		a packet.
189  *	reserved	indicates the number of buffers before 'cur'
190  *		that the application has still in use. Normally 0,
191  *		it MUST BE incremented by the application when it
192  *		does not return the buffer immediately, and decremented
193  *		when the buffer is finally freed.
194  *
195  *   The kernel side of netmap uses two additional fields in the kring:
196  *	nr_hwcur is a copy of nr_cur on an NIOCRXSYNC
197  *	nr_hwavail is the number of packets available. It is updated
198  *		on INTR (inc by the number of new packets arrived)
199  *		and on NIOCRXSYNC (decreased by nr_cur - nr_hwcur).
200  *
201  * DATA OWNERSHIP/LOCKING:
202  *	The netmap_ring is owned by the user program and it is only
203  *	accessed or modified in the upper half of the kernel during
204  *	a system call.
205  *
206  *	The netmap_kring is only modified by the upper half of the kernel.
207  *
208  * FLAGS
209  *	NR_TIMESTAMP	updates the 'ts' field on each syscall. This is
210  *			a global timestamp for all packets.
211  *	NR_RX_TSTMP	if set, the last 64 byte in each buffer will
212  *			contain a timestamp for the frame supplied by
213  *			the hardware (if supported)
214  *	NR_FORWARD	if set, the NS_FORWARD flag in each slot of the
215  *			RX ring is checked, and if set the packet is
216  *			passed to the other side (host stack or device,
217  *			respectively). This permits bpf-like behaviour
218  *			or transparency for selected packets.
219  */
220 struct netmap_ring {
221 	/*
222 	 * nr_buf_base_ofs is meant to be used through macros.
223 	 * It contains the offset of the buffer region from this
224 	 * descriptor.
225 	 */
226 	const ssize_t	buf_ofs;
227 	const uint32_t	num_slots;	/* number of slots in the ring. */
228 	uint32_t	avail;		/* number of usable slots */
229 	uint32_t        cur;		/* 'current' r/w position */
230 	uint32_t	reserved;	/* not refilled before current */
231 
232 	const uint16_t	nr_buf_size;
233 	uint16_t	flags;
234 #define	NR_TIMESTAMP	0x0002		/* set timestamp on *sync() */
235 #define	NR_FORWARD	0x0004		/* enable NS_FORWARD for ring */
236 #define	NR_RX_TSTMP	0x0008		/* set rx timestamp in slots */
237 
238 	struct timeval	ts;		/* time of last *sync() */
239 
240 	/* the slots follow. This struct has variable size */
241 	struct netmap_slot slot[0];	/* array of slots. */
242 };
243 
244 
245 /*
246  * Netmap representation of an interface and its queue(s).
247  * There is one netmap_if for each file descriptor on which we want
248  * to select/poll.  We assume that on each interface has the same number
249  * of receive and transmit queues.
250  * select/poll operates on one or all pairs depending on the value of
251  * nmr_queueid passed on the ioctl.
252  */
253 struct netmap_if {
254 	char		ni_name[IFNAMSIZ]; /* name of the interface. */
255 	const u_int	ni_version;	/* API version, currently unused */
256 	const u_int	ni_rx_rings;	/* number of rx rings */
257 	const u_int	ni_tx_rings;	/* if zero, same as ni_rx_rings */
258 	/*
259 	 * The following array contains the offset of each netmap ring
260 	 * from this structure. The first ni_tx_queues+1 entries refer
261 	 * to the tx rings, the next ni_rx_queues+1 refer to the rx rings
262 	 * (the last entry in each block refers to the host stack rings).
263 	 * The area is filled up by the kernel on NIOCREG,
264 	 * and then only read by userspace code.
265 	 */
266 	const ssize_t	ring_ofs[0];
267 };
268 
269 #ifndef NIOCREGIF
270 /*
271  * ioctl names and related fields
272  *
273  * NIOCGINFO takes a struct ifreq, the interface name is the input,
274  *	the outputs are number of queues and number of descriptor
275  *	for each queue (useful to set number of threads etc.).
276  *
277  * NIOCREGIF takes an interface name within a struct ifreq,
278  *	and activates netmap mode on the interface (if possible).
279  *
280  * NIOCUNREGIF unregisters the interface associated to the fd.
281  *
282  * NIOCTXSYNC, NIOCRXSYNC synchronize tx or rx queues,
283  *	whose identity is set in NIOCREGIF through nr_ringid
284  */
285 
286 /*
287  * struct nmreq overlays a struct ifreq
288  */
289 struct nmreq {
290 	char		nr_name[IFNAMSIZ];
291 	uint32_t	nr_version;	/* API version */
292 #define	NETMAP_API	3		/* current version */
293 	uint32_t	nr_offset;	/* nifp offset in the shared region */
294 	uint32_t	nr_memsize;	/* size of the shared region */
295 	uint32_t	nr_tx_slots;	/* slots in tx rings */
296 	uint32_t	nr_rx_slots;	/* slots in rx rings */
297 	uint16_t	nr_tx_rings;	/* number of tx rings */
298 	uint16_t	nr_rx_rings;	/* number of rx rings */
299 	uint16_t	nr_ringid;	/* ring(s) we care about */
300 #define NETMAP_HW_RING	0x4000		/* low bits indicate one hw ring */
301 #define NETMAP_SW_RING	0x2000		/* process the sw ring */
302 #define NETMAP_NO_TX_POLL	0x1000	/* no automatic txsync on poll */
303 #define NETMAP_RING_MASK 0xfff		/* the ring number */
304 	uint16_t	spare1;
305 	uint32_t	spare2[4];
306 };
307 
308 /*
309  * FreeBSD uses the size value embedded in the _IOWR to determine
310  * how much to copy in/out. So we need it to match the actual
311  * data structure we pass. We put some spares in the structure
312  * to ease compatibility with other versions
313  */
314 #define NIOCGINFO	_IOWR('i', 145, struct nmreq) /* return IF info */
315 #define NIOCREGIF	_IOWR('i', 146, struct nmreq) /* interface register */
316 #define NIOCUNREGIF	_IO('i', 147) /* interface unregister */
317 #define NIOCTXSYNC	_IO('i', 148) /* sync tx queues */
318 #define NIOCRXSYNC	_IO('i', 149) /* sync rx queues */
319 #endif /* !NIOCREGIF */
320 
321 #endif /* _NET_NETMAP_H_ */
322