xref: /dragonfly/sys/net/netmap/netmap_vale.c (revision cd1c6085)
1 /*
2  * Copyright (C) 2013 Universita` di Pisa. 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
6  * are met:
7  *   1. Redistributions of source code must retain the above copyright
8  *      notice, this list of conditions and the following disclaimer.
9  *   2. Redistributions in binary form must reproduce the above copyright
10  *      notice, this list of conditions and the following disclaimer in the
11  *      documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
14  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
16  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
17  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
18  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
19  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
20  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
21  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
22  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
23  * SUCH DAMAGE.
24  */
25 
26 
27 /*
28  * This module implements the VALE switch for netmap
29 
30 --- VALE SWITCH ---
31 
32 NMG_LOCK() serializes all modifications to switches and ports.
33 A switch cannot be deleted until all ports are gone.
34 
35 For each switch, an SX lock (RWlock on linux) protects
36 deletion of ports. When configuring or deleting a new port, the
37 lock is acquired in exclusive mode (after holding NMG_LOCK).
38 When forwarding, the lock is acquired in shared mode (without NMG_LOCK).
39 The lock is held throughout the entire forwarding cycle,
40 during which the thread may incur in a page fault.
41 Hence it is important that sleepable shared locks are used.
42 
43 On the rx ring, the per-port lock is grabbed initially to reserve
44 a number of slot in the ring, then the lock is released,
45 packets are copied from source to destination, and then
46 the lock is acquired again and the receive ring is updated.
47 (A similar thing is done on the tx ring for NIC and host stack
48 ports attached to the switch)
49 
50  */
51 
52 /*
53  * OS-specific code that is used only within this file.
54  * Other OS-specific code that must be accessed by drivers
55  * is present in netmap_kern.h
56  */
57 
58 #include <sys/cdefs.h> /* prerequisite */
59 __FBSDID("$FreeBSD: head/sys/dev/netmap/netmap.c 257176 2013-10-26 17:58:36Z glebius $");
60 
61 #include <sys/types.h>
62 #include <sys/errno.h>
63 #include <sys/param.h>	/* defines used in kernel.h */
64 #include <sys/kernel.h>	/* types used in module initialization */
65 #include <sys/conf.h>	/* cdevsw struct, UID, GID */
66 #include <sys/sockio.h>
67 #include <sys/socketvar.h>	/* struct socket */
68 #include <sys/malloc.h>
69 #include <sys/poll.h>
70 #include <sys/lock.h>
71 #include <sys/socket.h> /* sockaddrs */
72 #include <sys/sysctl.h>
73 #include <net/if.h>
74 #include <net/if_var.h>
75 #include <net/bpf.h>		/* BIOCIMMEDIATE */
76 #include <sys/bus.h>	/* bus_dmamap_* */
77 #include <sys/endian.h>
78 #include <sys/refcount.h>
79 
80 
81 #define BDG_RWLOCK_T		struct lock
82 
83 #define	BDG_RWINIT(b)		\
84 	lockinit(&(b)->bdg_lock, "bdg lock", 0, LK_CANRECURSE)
85 #define BDG_WLOCK(b)		lockmgr(&(b)->bdg_lock, LK_EXCLUSIVE)
86 #define BDG_WUNLOCK(b)		lockmgr(&(b)->bdg_lock, LK_RELEASE)
87 #define BDG_RLOCK(b)		lockmgr(&(b)->bdg_lock, LK_SHARED)
88 #define BDG_RTRYLOCK(b)		lockmgr(&(b)->bdg_lock, LK_SHARED|LK_NOWAIT)
89 #define BDG_RUNLOCK(b)		lockmgr(&(b)->bdg_lock, LK_RELEASE)
90 #define BDG_RWDESTROY(b)	lockuninit(&(b)->bdg_lock)
91 
92 /*
93  * common headers
94  */
95 
96 #include <net/netmap.h>
97 #include <net/netmap/netmap_kern.h>
98 #include <net/netmap/netmap_mem2.h>
99 
100 #ifdef WITH_VALE
101 
102 /*
103  * system parameters (most of them in netmap_kern.h)
104  * NM_NAME	prefix for switch port names, default "vale"
105  * NM_BDG_MAXPORTS	number of ports
106  * NM_BRIDGES	max number of switches in the system.
107  *	XXX should become a sysctl or tunable
108  *
109  * Switch ports are named valeX:Y where X is the switch name and Y
110  * is the port. If Y matches a physical interface name, the port is
111  * connected to a physical device.
112  *
113  * Unlike physical interfaces, switch ports use their own memory region
114  * for rings and buffers.
115  * The virtual interfaces use per-queue lock instead of core lock.
116  * In the tx loop, we aggregate traffic in batches to make all operations
117  * faster. The batch size is bridge_batch.
118  */
119 #define NM_BDG_MAXRINGS		16	/* XXX unclear how many. */
120 #define NM_BDG_MAXSLOTS		4096	/* XXX same as above */
121 #define NM_BRIDGE_RINGSIZE	1024	/* in the device */
122 #define NM_BDG_HASH		1024	/* forwarding table entries */
123 #define NM_BDG_BATCH		1024	/* entries in the forwarding buffer */
124 #define NM_MULTISEG		64	/* max size of a chain of bufs */
125 /* actual size of the tables */
126 #define NM_BDG_BATCH_MAX	(NM_BDG_BATCH + NM_MULTISEG)
127 /* NM_FT_NULL terminates a list of slots in the ft */
128 #define NM_FT_NULL		NM_BDG_BATCH_MAX
129 #define	NM_BRIDGES		8	/* number of bridges */
130 
131 
132 /*
133  * bridge_batch is set via sysctl to the max batch size to be
134  * used in the bridge. The actual value may be larger as the
135  * last packet in the block may overflow the size.
136  */
137 int bridge_batch = NM_BDG_BATCH; /* bridge batch size */
138 SYSCTL_DECL(_dev_netmap);
139 SYSCTL_INT(_dev_netmap, OID_AUTO, bridge_batch, CTLFLAG_RW, &bridge_batch, 0 , "");
140 
141 
142 static int bdg_netmap_attach(struct netmap_adapter *);
143 static int bdg_netmap_reg(struct netmap_adapter *na, int onoff);
144 static int netmap_bwrap_attach(struct ifnet *, struct ifnet *);
145 static int netmap_bwrap_register(struct netmap_adapter *, int onoff);
146 int kern_netmap_regif(struct nmreq *nmr);
147 
148 /*
149  * Each transmit queue accumulates a batch of packets into
150  * a structure before forwarding. Packets to the same
151  * destination are put in a list using ft_next as a link field.
152  * ft_frags and ft_next are valid only on the first fragment.
153  */
154 struct nm_bdg_fwd {	/* forwarding entry for a bridge */
155 	void *ft_buf;		/* netmap or indirect buffer */
156 	uint8_t ft_frags;	/* how many fragments (only on 1st frag) */
157 	uint8_t _ft_port;	/* dst port (unused) */
158 	uint16_t ft_flags;	/* flags, e.g. indirect */
159 	uint16_t ft_len;	/* src fragment len */
160 	uint16_t ft_next;	/* next packet to same destination */
161 };
162 
163 /*
164  * For each output interface, nm_bdg_q is used to construct a list.
165  * bq_len is the number of output buffers (we can have coalescing
166  * during the copy).
167  */
168 struct nm_bdg_q {
169 	uint16_t bq_head;
170 	uint16_t bq_tail;
171 	uint32_t bq_len;	/* number of buffers */
172 };
173 
174 /* XXX revise this */
175 struct nm_hash_ent {
176 	uint64_t	mac;	/* the top 2 bytes are the epoch */
177 	uint64_t	ports;
178 };
179 
180 /*
181  * nm_bridge is a descriptor for a VALE switch.
182  * Interfaces for a bridge are all in bdg_ports[].
183  * The array has fixed size, an empty entry does not terminate
184  * the search, but lookups only occur on attach/detach so we
185  * don't mind if they are slow.
186  *
187  * The bridge is non blocking on the transmit ports: excess
188  * packets are dropped if there is no room on the output port.
189  *
190  * bdg_lock protects accesses to the bdg_ports array.
191  * This is a rw lock (or equivalent).
192  */
193 struct nm_bridge {
194 	/* XXX what is the proper alignment/layout ? */
195 	BDG_RWLOCK_T	bdg_lock;	/* protects bdg_ports */
196 	int		bdg_namelen;
197 	uint32_t	bdg_active_ports; /* 0 means free */
198 	char		bdg_basename[IFNAMSIZ];
199 
200 	/* Indexes of active ports (up to active_ports)
201 	 * and all other remaining ports.
202 	 */
203 	uint8_t		bdg_port_index[NM_BDG_MAXPORTS];
204 
205 	struct netmap_vp_adapter *bdg_ports[NM_BDG_MAXPORTS];
206 
207 
208 	/*
209 	 * The function to decide the destination port.
210 	 * It returns either of an index of the destination port,
211 	 * NM_BDG_BROADCAST to broadcast this packet, or NM_BDG_NOPORT not to
212 	 * forward this packet.  ring_nr is the source ring index, and the
213 	 * function may overwrite this value to forward this packet to a
214 	 * different ring index.
215 	 * This function must be set by netmap_bdgctl().
216 	 */
217 	bdg_lookup_fn_t nm_bdg_lookup;
218 
219 	/* the forwarding table, MAC+ports.
220 	 * XXX should be changed to an argument to be passed to
221 	 * the lookup function, and allocated on attach
222 	 */
223 	struct nm_hash_ent ht[NM_BDG_HASH];
224 };
225 
226 
227 /*
228  * XXX in principle nm_bridges could be created dynamically
229  * Right now we have a static array and deletions are protected
230  * by an exclusive lock.
231  */
232 struct nm_bridge nm_bridges[NM_BRIDGES];
233 
234 
235 /*
236  * A few function to tell which kind of port are we using.
237  * XXX should we hold a lock ?
238  *
239  * nma_is_vp()		virtual port
240  * nma_is_host()	port connected to the host stack
241  * nma_is_hw()		port connected to a NIC
242  * nma_is_generic()	generic netmap adapter XXX stop this madness
243  */
244 static __inline int
245 nma_is_vp(struct netmap_adapter *na)
246 {
247 	return na->nm_register == bdg_netmap_reg;
248 }
249 
250 
251 static __inline int
252 nma_is_host(struct netmap_adapter *na)
253 {
254 	return na->nm_register == NULL;
255 }
256 
257 
258 static __inline int
259 nma_is_hw(struct netmap_adapter *na)
260 {
261 	/* In case of sw adapter, nm_register is NULL */
262 	return !nma_is_vp(na) && !nma_is_host(na) && !nma_is_generic(na);
263 }
264 
265 static __inline int
266 nma_is_bwrap(struct netmap_adapter *na)
267 {
268 	return na->nm_register == netmap_bwrap_register;
269 }
270 
271 
272 
273 /*
274  * this is a slightly optimized copy routine which rounds
275  * to multiple of 64 bytes and is often faster than dealing
276  * with other odd sizes. We assume there is enough room
277  * in the source and destination buffers.
278  *
279  * XXX only for multiples of 64 bytes, non overlapped.
280  */
281 static inline void
282 pkt_copy(void *_src, void *_dst, int l)
283 {
284         uint64_t *src = _src;
285         uint64_t *dst = _dst;
286         if (unlikely(l >= 1024)) {
287                 memcpy(dst, src, l);
288                 return;
289         }
290         for (; likely(l > 0); l-=64) {
291                 *dst++ = *src++;
292                 *dst++ = *src++;
293                 *dst++ = *src++;
294                 *dst++ = *src++;
295                 *dst++ = *src++;
296                 *dst++ = *src++;
297                 *dst++ = *src++;
298                 *dst++ = *src++;
299         }
300 }
301 
302 
303 
304 /*
305  * locate a bridge among the existing ones.
306  * MUST BE CALLED WITH NMG_LOCK()
307  *
308  * a ':' in the name terminates the bridge name. Otherwise, just NM_NAME.
309  * We assume that this is called with a name of at least NM_NAME chars.
310  */
311 static struct nm_bridge *
312 nm_find_bridge(const char *name, int create)
313 {
314 	int i, l, namelen;
315 	struct nm_bridge *b = NULL;
316 
317 	NMG_LOCK_ASSERT();
318 
319 	namelen = strlen(NM_NAME);	/* base length */
320 	l = name ? strlen(name) : 0;		/* actual length */
321 	if (l < namelen) {
322 		D("invalid bridge name %s", name ? name : NULL);
323 		return NULL;
324 	}
325 	for (i = namelen + 1; i < l; i++) {
326 		if (name[i] == ':') {
327 			namelen = i;
328 			break;
329 		}
330 	}
331 	if (namelen >= IFNAMSIZ)
332 		namelen = IFNAMSIZ;
333 	ND("--- prefix is '%.*s' ---", namelen, name);
334 
335 	/* lookup the name, remember empty slot if there is one */
336 	for (i = 0; i < NM_BRIDGES; i++) {
337 		struct nm_bridge *x = nm_bridges + i;
338 
339 		if (x->bdg_active_ports == 0) {
340 			if (create && b == NULL)
341 				b = x;	/* record empty slot */
342 		} else if (x->bdg_namelen != namelen) {
343 			continue;
344 		} else if (strncmp(name, x->bdg_basename, namelen) == 0) {
345 			ND("found '%.*s' at %d", namelen, name, i);
346 			b = x;
347 			break;
348 		}
349 	}
350 	if (i == NM_BRIDGES && b) { /* name not found, can create entry */
351 		/* initialize the bridge */
352 		strncpy(b->bdg_basename, name, namelen);
353 		ND("create new bridge %s with ports %d", b->bdg_basename,
354 			b->bdg_active_ports);
355 		b->bdg_namelen = namelen;
356 		b->bdg_active_ports = 0;
357 		for (i = 0; i < NM_BDG_MAXPORTS; i++)
358 			b->bdg_port_index[i] = i;
359 		/* set the default function */
360 		b->nm_bdg_lookup = netmap_bdg_learning;
361 		/* reset the MAC address table */
362 		bzero(b->ht, sizeof(struct nm_hash_ent) * NM_BDG_HASH);
363 	}
364 	return b;
365 }
366 
367 
368 /*
369  * Free the forwarding tables for rings attached to switch ports.
370  */
371 static void
372 nm_free_bdgfwd(struct netmap_adapter *na)
373 {
374 	int nrings, i;
375 	struct netmap_kring *kring;
376 
377 	NMG_LOCK_ASSERT();
378 	nrings = nma_is_vp(na) ? na->num_tx_rings : na->num_rx_rings;
379 	kring = nma_is_vp(na) ? na->tx_rings : na->rx_rings;
380 	for (i = 0; i < nrings; i++) {
381 		if (kring[i].nkr_ft) {
382 			kfree(kring[i].nkr_ft, M_DEVBUF);
383 			kring[i].nkr_ft = NULL; /* protect from freeing twice */
384 		}
385 	}
386 }
387 
388 
389 /*
390  * Allocate the forwarding tables for the rings attached to the bridge ports.
391  */
392 static int
393 nm_alloc_bdgfwd(struct netmap_adapter *na)
394 {
395 	int nrings, l, i, num_dstq;
396 	struct netmap_kring *kring;
397 
398 	NMG_LOCK_ASSERT();
399 	/* all port:rings + broadcast */
400 	num_dstq = NM_BDG_MAXPORTS * NM_BDG_MAXRINGS + 1;
401 	l = sizeof(struct nm_bdg_fwd) * NM_BDG_BATCH_MAX;
402 	l += sizeof(struct nm_bdg_q) * num_dstq;
403 	l += sizeof(uint16_t) * NM_BDG_BATCH_MAX;
404 
405 	nrings = na->num_tx_rings + 1;
406 	kring = na->tx_rings;
407 	for (i = 0; i < nrings; i++) {
408 		struct nm_bdg_fwd *ft;
409 		struct nm_bdg_q *dstq;
410 		int j;
411 
412 		ft = kmalloc(l, M_DEVBUF, M_NOWAIT | M_ZERO);
413 		if (!ft) {
414 			nm_free_bdgfwd(na);
415 			return ENOMEM;
416 		}
417 		dstq = (struct nm_bdg_q *)(ft + NM_BDG_BATCH_MAX);
418 		for (j = 0; j < num_dstq; j++) {
419 			dstq[j].bq_head = dstq[j].bq_tail = NM_FT_NULL;
420 			dstq[j].bq_len = 0;
421 		}
422 		kring[i].nkr_ft = ft;
423 	}
424 	return 0;
425 }
426 
427 
428 static void
429 netmap_bdg_detach_common(struct nm_bridge *b, int hw, int sw)
430 {
431 	int s_hw = hw, s_sw = sw;
432 	int i, lim =b->bdg_active_ports;
433 	uint8_t tmp[NM_BDG_MAXPORTS];
434 
435 	/*
436 	New algorithm:
437 	make a copy of bdg_port_index;
438 	lookup NA(ifp)->bdg_port and SWNA(ifp)->bdg_port
439 	in the array of bdg_port_index, replacing them with
440 	entries from the bottom of the array;
441 	decrement bdg_active_ports;
442 	acquire BDG_WLOCK() and copy back the array.
443 	 */
444 
445 	D("detach %d and %d (lim %d)", hw, sw, lim);
446 	/* make a copy of the list of active ports, update it,
447 	 * and then copy back within BDG_WLOCK().
448 	 */
449 	memcpy(tmp, b->bdg_port_index, sizeof(tmp));
450 	for (i = 0; (hw >= 0 || sw >= 0) && i < lim; ) {
451 		if (hw >= 0 && tmp[i] == hw) {
452 			ND("detach hw %d at %d", hw, i);
453 			lim--; /* point to last active port */
454 			tmp[i] = tmp[lim]; /* swap with i */
455 			tmp[lim] = hw;	/* now this is inactive */
456 			hw = -1;
457 		} else if (sw >= 0 && tmp[i] == sw) {
458 			ND("detach sw %d at %d", sw, i);
459 			lim--;
460 			tmp[i] = tmp[lim];
461 			tmp[lim] = sw;
462 			sw = -1;
463 		} else {
464 			i++;
465 		}
466 	}
467 	if (hw >= 0 || sw >= 0) {
468 		D("XXX delete failed hw %d sw %d, should panic...", hw, sw);
469 	}
470 
471 	BDG_WLOCK(b);
472 	b->bdg_ports[s_hw] = NULL;
473 	if (s_sw >= 0) {
474 		b->bdg_ports[s_sw] = NULL;
475 	}
476 	memcpy(b->bdg_port_index, tmp, sizeof(tmp));
477 	b->bdg_active_ports = lim;
478 	BDG_WUNLOCK(b);
479 
480 	ND("now %d active ports", lim);
481 	if (lim == 0) {
482 		ND("marking bridge %s as free", b->bdg_basename);
483 		b->nm_bdg_lookup = NULL;
484 	}
485 }
486 
487 static void
488 netmap_adapter_vp_dtor(struct netmap_adapter *na)
489 {
490 	struct netmap_vp_adapter *vpna = (struct netmap_vp_adapter*)na;
491 	struct nm_bridge *b = vpna->na_bdg;
492 	struct ifnet *ifp = na->ifp;
493 
494 	ND("%s has %d references", NM_IFPNAME(ifp), na->na_refcount);
495 
496 	if (b) {
497 		netmap_bdg_detach_common(b, vpna->bdg_port, -1);
498 	}
499 
500 	bzero(ifp, sizeof(*ifp));
501 	kfree(ifp, M_DEVBUF);
502 	na->ifp = NULL;
503 }
504 
505 int
506 netmap_get_bdg_na(struct nmreq *nmr, struct netmap_adapter **na, int create)
507 {
508 	const char *name = nmr->nr_name;
509 	struct ifnet *ifp;
510 	int error = 0;
511 	struct netmap_adapter *ret;
512 	struct netmap_vp_adapter *vpna;
513 	struct nm_bridge *b;
514 	int i, j, cand = -1, cand2 = -1;
515 	int needed;
516 
517 	*na = NULL;     /* default return value */
518 
519 	/* first try to see if this is a bridge port. */
520 	NMG_LOCK_ASSERT();
521 	if (strncmp(name, NM_NAME, sizeof(NM_NAME) - 1)) {
522 		return 0;  /* no error, but no VALE prefix */
523 	}
524 
525 	b = nm_find_bridge(name, create);
526 	if (b == NULL) {
527 		D("no bridges available for '%s'", name);
528 		return (ENXIO);
529 	}
530 
531 	/* Now we are sure that name starts with the bridge's name,
532 	 * lookup the port in the bridge. We need to scan the entire
533 	 * list. It is not important to hold a WLOCK on the bridge
534 	 * during the search because NMG_LOCK already guarantees
535 	 * that there are no other possible writers.
536 	 */
537 
538 	/* lookup in the local list of ports */
539 	for (j = 0; j < b->bdg_active_ports; j++) {
540 		i = b->bdg_port_index[j];
541 		vpna = b->bdg_ports[i];
542 		// KASSERT(na != NULL);
543 		ifp = vpna->up.ifp;
544 		/* XXX make sure the name only contains one : */
545 		if (!strcmp(NM_IFPNAME(ifp), name)) {
546 			netmap_adapter_get(&vpna->up);
547 			ND("found existing if %s refs %d", name,
548 				vpna->na_bdg_refcount);
549 			*na = (struct netmap_adapter *)vpna;
550 			return 0;
551 		}
552 	}
553 	/* not found, should we create it? */
554 	if (!create)
555 		return ENXIO;
556 	/* yes we should, see if we have space to attach entries */
557 	needed = 2; /* in some cases we only need 1 */
558 	if (b->bdg_active_ports + needed >= NM_BDG_MAXPORTS) {
559 		D("bridge full %d, cannot create new port", b->bdg_active_ports);
560 		return EINVAL;
561 	}
562 	/* record the next two ports available, but do not allocate yet */
563 	cand = b->bdg_port_index[b->bdg_active_ports];
564 	cand2 = b->bdg_port_index[b->bdg_active_ports + 1];
565 	ND("+++ bridge %s port %s used %d avail %d %d",
566 		b->bdg_basename, name, b->bdg_active_ports, cand, cand2);
567 
568 	/*
569 	 * try see if there is a matching NIC with this name
570 	 * (after the bridge's name)
571 	 */
572 	ifnet_lock();
573 	ifp = ifunit(name + b->bdg_namelen + 1);
574 	if (!ifp) { /* this is a virtual port */
575 		/* Create a temporary NA with arguments, then
576 		 * bdg_netmap_attach() will allocate the real one
577 		 * and attach it to the ifp
578 		 */
579 		struct netmap_adapter tmp_na;
580 
581 		ifnet_unlock();
582 
583 		if (nmr->nr_cmd) {
584 			/* nr_cmd must be 0 for a virtual port */
585 			return EINVAL;
586 		}
587 		bzero(&tmp_na, sizeof(tmp_na));
588 		/* bound checking */
589 		tmp_na.num_tx_rings = nmr->nr_tx_rings;
590 		nm_bound_var(&tmp_na.num_tx_rings, 1, 1, NM_BDG_MAXRINGS, NULL);
591 		nmr->nr_tx_rings = tmp_na.num_tx_rings; // write back
592 		tmp_na.num_rx_rings = nmr->nr_rx_rings;
593 		nm_bound_var(&tmp_na.num_rx_rings, 1, 1, NM_BDG_MAXRINGS, NULL);
594 		nmr->nr_rx_rings = tmp_na.num_rx_rings; // write back
595 		nm_bound_var(&nmr->nr_tx_slots, NM_BRIDGE_RINGSIZE,
596 				1, NM_BDG_MAXSLOTS, NULL);
597 		tmp_na.num_tx_desc = nmr->nr_tx_slots;
598 		nm_bound_var(&nmr->nr_rx_slots, NM_BRIDGE_RINGSIZE,
599 				1, NM_BDG_MAXSLOTS, NULL);
600 		tmp_na.num_rx_desc = nmr->nr_rx_slots;
601 
602 	 	/* create a struct ifnet for the new port.
603 		 * need M_NOWAIT as we are under nma_lock
604 		 */
605 		ifp = kmalloc(sizeof(*ifp), M_DEVBUF, M_NOWAIT | M_ZERO);
606 		if (!ifp)
607 			return ENOMEM;
608 
609 		strcpy(ifp->if_xname, name);
610 		tmp_na.ifp = ifp;
611 		/* bdg_netmap_attach creates a struct netmap_adapter */
612 		error = bdg_netmap_attach(&tmp_na);
613 		if (error) {
614 			D("error %d", error);
615 			kfree(ifp, M_DEVBUF);
616 			return error;
617 		}
618 		ret = NA(ifp);
619 		cand2 = -1;	/* only need one port */
620 	} else {  /* this is a NIC */
621 		struct ifnet *fake_ifp;
622 
623 		error = netmap_get_hw_na(ifp, &ret);
624 		if (error || ret == NULL)
625 			goto out;
626 
627 		/* make sure the NIC is not already in use */
628 		if (NETMAP_OWNED_BY_ANY(ret)) {
629 			D("NIC %s busy, cannot attach to bridge",
630 				NM_IFPNAME(ifp));
631 			error = EINVAL;
632 			goto out;
633 		}
634 		/* create a fake interface */
635 		fake_ifp = kmalloc(sizeof(*ifp), M_DEVBUF, M_NOWAIT | M_ZERO);
636 		if (!fake_ifp) {
637 			error = ENOMEM;
638 			goto out;
639 		}
640 		strcpy(fake_ifp->if_xname, name);
641 		error = netmap_bwrap_attach(fake_ifp, ifp);
642 		if (error) {
643 			kfree(fake_ifp, M_DEVBUF);
644 			goto out;
645 		}
646 		ret = NA(fake_ifp);
647 		if (nmr->nr_arg1 != NETMAP_BDG_HOST)
648 			cand2 = -1; /* only need one port */
649 
650 		ifnet_unlock();
651 	}
652 	vpna = (struct netmap_vp_adapter *)ret;
653 
654 	BDG_WLOCK(b);
655 	vpna->bdg_port = cand;
656 	ND("NIC  %p to bridge port %d", vpna, cand);
657 	/* bind the port to the bridge (virtual ports are not active) */
658 	b->bdg_ports[cand] = vpna;
659 	vpna->na_bdg = b;
660 	b->bdg_active_ports++;
661 	if (cand2 >= 0) {
662 		struct netmap_vp_adapter *hostna = vpna + 1;
663 		/* also bind the host stack to the bridge */
664 		b->bdg_ports[cand2] = hostna;
665 		hostna->bdg_port = cand2;
666 		hostna->na_bdg = b;
667 		b->bdg_active_ports++;
668 		ND("host %p to bridge port %d", hostna, cand2);
669 	}
670 	ND("if %s refs %d", name, vpna->up.na_refcount);
671 	BDG_WUNLOCK(b);
672 	*na = ret;
673 	netmap_adapter_get(ret);
674 	return 0;
675 
676 out:
677 	ifnet_unlock();
678 	return error;
679 }
680 
681 
682 /* Process NETMAP_BDG_ATTACH and NETMAP_BDG_DETACH */
683 static int
684 nm_bdg_attach(struct nmreq *nmr)
685 {
686 	struct netmap_adapter *na;
687 	struct netmap_if *nifp;
688 	struct netmap_priv_d *npriv;
689 	struct netmap_bwrap_adapter *bna;
690 	int error;
691 
692 	npriv = kmalloc(sizeof(*npriv), M_DEVBUF, M_NOWAIT|M_ZERO);
693 	if (npriv == NULL)
694 		return ENOMEM;
695 	NMG_LOCK();
696 	/* XXX probably netmap_get_bdg_na() */
697 	error = netmap_get_na(nmr, &na, 1 /* create if not exists */);
698 	if (error) /* no device, or another bridge or user owns the device */
699 		goto unlock_exit;
700 	/* netmap_get_na() sets na_bdg if this is a physical interface
701 	 * that we can attach to a switch.
702 	 */
703 	if (!nma_is_bwrap(na)) {
704 		/* got reference to a virtual port or direct access to a NIC.
705 		 * perhaps specified no bridge prefix or wrong NIC name
706 		 */
707 		error = EINVAL;
708 		goto unref_exit;
709 	}
710 
711 	if (na->active_fds > 0) { /* already registered */
712 		error = EBUSY;
713 		goto unref_exit;
714 	}
715 
716 	nifp = netmap_do_regif(npriv, na, nmr->nr_ringid, &error);
717 	if (!nifp) {
718 		goto unref_exit;
719 	}
720 
721 	bna = (struct netmap_bwrap_adapter*)na;
722 	bna->na_kpriv = npriv;
723 	NMG_UNLOCK();
724 	ND("registered %s to netmap-mode", NM_IFPNAME(na->ifp));
725 	return 0;
726 
727 unref_exit:
728 	netmap_adapter_put(na);
729 unlock_exit:
730 	NMG_UNLOCK();
731 	bzero(npriv, sizeof(*npriv));
732 	kfree(npriv, M_DEVBUF);
733 	return error;
734 }
735 
736 static int
737 nm_bdg_detach(struct nmreq *nmr)
738 {
739 	struct netmap_adapter *na;
740 	int error;
741 	struct netmap_bwrap_adapter *bna;
742 	int last_instance;
743 
744 	NMG_LOCK();
745 	error = netmap_get_na(nmr, &na, 0 /* don't create */);
746 	if (error) { /* no device, or another bridge or user owns the device */
747 		goto unlock_exit;
748 	}
749 	if (!nma_is_bwrap(na)) {
750 		/* got reference to a virtual port or direct access to a NIC.
751 		 * perhaps specified no bridge's prefix or wrong NIC's name
752 		 */
753 		error = EINVAL;
754 		goto unref_exit;
755 	}
756 	bna = (struct netmap_bwrap_adapter *)na;
757 
758 	if (na->active_fds == 0) { /* not registered */
759 		error = EINVAL;
760 		goto unref_exit;
761 	}
762 
763 	last_instance = netmap_dtor_locked(bna->na_kpriv); /* unregister */
764 	if (!last_instance) {
765 		D("--- error, trying to detach an entry with active mmaps");
766 		error = EINVAL;
767 	} else {
768 		struct netmap_priv_d *npriv = bna->na_kpriv;
769 
770 		bna->na_kpriv = NULL;
771 		D("deleting priv");
772 
773 		bzero(npriv, sizeof(*npriv));
774 		kfree(npriv, M_DEVBUF);
775 	}
776 
777 unref_exit:
778 	netmap_adapter_put(na);
779 unlock_exit:
780 	NMG_UNLOCK();
781 	return error;
782 
783 }
784 
785 
786 /* exported to kernel callers, e.g. OVS ?
787  * Entry point.
788  * Called without NMG_LOCK.
789  */
790 int
791 netmap_bdg_ctl(struct nmreq *nmr, bdg_lookup_fn_t func)
792 {
793 	struct nm_bridge *b;
794 	struct netmap_vp_adapter *na;
795 	struct ifnet *iter;
796 	char *name = nmr->nr_name;
797 	int cmd = nmr->nr_cmd, namelen = strlen(name);
798 	int error = 0, i, j;
799 
800 	switch (cmd) {
801 	case NETMAP_BDG_ATTACH:
802 		error = nm_bdg_attach(nmr);
803 		break;
804 
805 	case NETMAP_BDG_DETACH:
806 		error = nm_bdg_detach(nmr);
807 		break;
808 
809 	case NETMAP_BDG_LIST:
810 		/* this is used to enumerate bridges and ports */
811 		if (namelen) { /* look up indexes of bridge and port */
812 			if (strncmp(name, NM_NAME, strlen(NM_NAME))) {
813 				error = EINVAL;
814 				break;
815 			}
816 			NMG_LOCK();
817 			b = nm_find_bridge(name, 0 /* don't create */);
818 			if (!b) {
819 				error = ENOENT;
820 				NMG_UNLOCK();
821 				break;
822 			}
823 
824 			error = ENOENT;
825 			for (j = 0; j < b->bdg_active_ports; j++) {
826 				i = b->bdg_port_index[j];
827 				na = b->bdg_ports[i];
828 				if (na == NULL) {
829 					D("---AAAAAAAAARGH-------");
830 					continue;
831 				}
832 				iter = na->up.ifp;
833 				/* the former and the latter identify a
834 				 * virtual port and a NIC, respectively
835 				 */
836 				if (!strcmp(iter->if_xname, name)) {
837 					/* bridge index */
838 					nmr->nr_arg1 = b - nm_bridges;
839 					nmr->nr_arg2 = i; /* port index */
840 					error = 0;
841 					break;
842 				}
843 			}
844 			NMG_UNLOCK();
845 		} else {
846 			/* return the first non-empty entry starting from
847 			 * bridge nr_arg1 and port nr_arg2.
848 			 *
849 			 * Users can detect the end of the same bridge by
850 			 * seeing the new and old value of nr_arg1, and can
851 			 * detect the end of all the bridge by error != 0
852 			 */
853 			i = nmr->nr_arg1;
854 			j = nmr->nr_arg2;
855 
856 			NMG_LOCK();
857 			for (error = ENOENT; i < NM_BRIDGES; i++) {
858 				b = nm_bridges + i;
859 				if (j >= b->bdg_active_ports) {
860 					j = 0; /* following bridges scan from 0 */
861 					continue;
862 				}
863 				nmr->nr_arg1 = i;
864 				nmr->nr_arg2 = j;
865 				j = b->bdg_port_index[j];
866 				na = b->bdg_ports[j];
867 				iter = na->up.ifp;
868 				strncpy(name, iter->if_xname, (size_t)IFNAMSIZ);
869 				error = 0;
870 				break;
871 			}
872 			NMG_UNLOCK();
873 		}
874 		break;
875 
876 	case NETMAP_BDG_LOOKUP_REG:
877 		/* register a lookup function to the given bridge.
878 		 * nmr->nr_name may be just bridge's name (including ':'
879 		 * if it is not just NM_NAME).
880 		 */
881 		if (!func) {
882 			error = EINVAL;
883 			break;
884 		}
885 		NMG_LOCK();
886 		b = nm_find_bridge(name, 0 /* don't create */);
887 		if (!b) {
888 			error = EINVAL;
889 		} else {
890 			b->nm_bdg_lookup = func;
891 		}
892 		NMG_UNLOCK();
893 		break;
894 
895 	default:
896 		D("invalid cmd (nmr->nr_cmd) (0x%x)", cmd);
897 		error = EINVAL;
898 		break;
899 	}
900 	return error;
901 }
902 
903 
904 static int
905 netmap_vp_krings_create(struct netmap_adapter *na)
906 {
907 	u_int ntx, nrx, tailroom;
908 	int error, i;
909 	uint32_t *leases;
910 
911 	/* XXX vps do not need host rings,
912 	 * but we crash if we don't have one
913 	 */
914 	ntx = na->num_tx_rings + 1;
915 	nrx = na->num_rx_rings + 1;
916 
917 	/*
918 	 * Leases are attached to RX rings on vale ports
919 	 */
920 	tailroom = sizeof(uint32_t) * na->num_rx_desc * nrx;
921 
922 	error = netmap_krings_create(na, ntx, nrx, tailroom);
923 	if (error)
924 		return error;
925 
926 	leases = na->tailroom;
927 
928 	for (i = 0; i < nrx; i++) { /* Receive rings */
929 		na->rx_rings[i].nkr_leases = leases;
930 		leases += na->num_rx_desc;
931 	}
932 
933 	error = nm_alloc_bdgfwd(na);
934 	if (error) {
935 		netmap_krings_delete(na);
936 		return error;
937 	}
938 
939 	return 0;
940 }
941 
942 static void
943 netmap_vp_krings_delete(struct netmap_adapter *na)
944 {
945 	nm_free_bdgfwd(na);
946 	netmap_krings_delete(na);
947 }
948 
949 
950 static int
951 nm_bdg_flush(struct nm_bdg_fwd *ft, u_int n,
952 	struct netmap_vp_adapter *na, u_int ring_nr);
953 
954 
955 /*
956  * Grab packets from a kring, move them into the ft structure
957  * associated to the tx (input) port. Max one instance per port,
958  * filtered on input (ioctl, poll or XXX).
959  * Returns the next position in the ring.
960  */
961 static int
962 nm_bdg_preflush(struct netmap_vp_adapter *na, u_int ring_nr,
963 	struct netmap_kring *kring, u_int end)
964 {
965 	struct netmap_ring *ring = kring->ring;
966 	struct nm_bdg_fwd *ft;
967 	u_int j = kring->nr_hwcur, lim = kring->nkr_num_slots - 1;
968 	u_int ft_i = 0;	/* start from 0 */
969 	u_int frags = 1; /* how many frags ? */
970 	struct nm_bridge *b = na->na_bdg;
971 
972 	/* To protect against modifications to the bridge we acquire a
973 	 * shared lock, waiting if we can sleep (if the source port is
974 	 * attached to a user process) or with a trylock otherwise (NICs).
975 	 */
976 	ND("wait rlock for %d packets", ((j > end ? lim+1 : 0) + end) - j);
977 	if (na->up.na_flags & NAF_BDG_MAYSLEEP)
978 		BDG_RLOCK(b);
979 	else if (!BDG_RTRYLOCK(b))
980 		return 0;
981 	ND(5, "rlock acquired for %d packets", ((j > end ? lim+1 : 0) + end) - j);
982 	ft = kring->nkr_ft;
983 
984 	for (; likely(j != end); j = nm_next(j, lim)) {
985 		struct netmap_slot *slot = &ring->slot[j];
986 		char *buf;
987 
988 		ft[ft_i].ft_len = slot->len;
989 		ft[ft_i].ft_flags = slot->flags;
990 
991 		ND("flags is 0x%x", slot->flags);
992 		/* this slot goes into a list so initialize the link field */
993 		ft[ft_i].ft_next = NM_FT_NULL;
994 		buf = ft[ft_i].ft_buf = (slot->flags & NS_INDIRECT) ?
995 			(void *)(uintptr_t)slot->ptr : BDG_NMB(&na->up, slot);
996 		prefetch(buf);
997 		++ft_i;
998 		if (slot->flags & NS_MOREFRAG) {
999 			frags++;
1000 			continue;
1001 		}
1002 		if (unlikely(netmap_verbose && frags > 1))
1003 			RD(5, "%d frags at %d", frags, ft_i - frags);
1004 		ft[ft_i - frags].ft_frags = frags;
1005 		frags = 1;
1006 		if (unlikely((int)ft_i >= bridge_batch))
1007 			ft_i = nm_bdg_flush(ft, ft_i, na, ring_nr);
1008 	}
1009 	if (frags > 1) {
1010 		D("truncate incomplete fragment at %d (%d frags)", ft_i, frags);
1011 		// ft_i > 0, ft[ft_i-1].flags has NS_MOREFRAG
1012 		ft[ft_i - 1].ft_frags &= ~NS_MOREFRAG;
1013 		ft[ft_i - frags].ft_frags = frags - 1;
1014 	}
1015 	if (ft_i)
1016 		ft_i = nm_bdg_flush(ft, ft_i, na, ring_nr);
1017 	BDG_RUNLOCK(b);
1018 	return j;
1019 }
1020 
1021 
1022 /*
1023  *---- support for virtual bridge -----
1024  */
1025 
1026 /* ----- FreeBSD if_bridge hash function ------- */
1027 
1028 /*
1029  * The following hash function is adapted from "Hash Functions" by Bob Jenkins
1030  * ("Algorithm Alley", Dr. Dobbs Journal, September 1997).
1031  *
1032  * http://www.burtleburtle.net/bob/hash/spooky.html
1033  */
1034 #define mix(a, b, c)                                                    \
1035 do {                                                                    \
1036         a -= b; a -= c; a ^= (c >> 13);                                 \
1037         b -= c; b -= a; b ^= (a << 8);                                  \
1038         c -= a; c -= b; c ^= (b >> 13);                                 \
1039         a -= b; a -= c; a ^= (c >> 12);                                 \
1040         b -= c; b -= a; b ^= (a << 16);                                 \
1041         c -= a; c -= b; c ^= (b >> 5);                                  \
1042         a -= b; a -= c; a ^= (c >> 3);                                  \
1043         b -= c; b -= a; b ^= (a << 10);                                 \
1044         c -= a; c -= b; c ^= (b >> 15);                                 \
1045 } while (/*CONSTCOND*/0)
1046 
1047 static __inline uint32_t
1048 nm_bridge_rthash(const uint8_t *addr)
1049 {
1050         uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = 0; // hask key
1051 
1052         b += addr[5] << 8;
1053         b += addr[4];
1054         a += addr[3] << 24;
1055         a += addr[2] << 16;
1056         a += addr[1] << 8;
1057         a += addr[0];
1058 
1059         mix(a, b, c);
1060 #define BRIDGE_RTHASH_MASK	(NM_BDG_HASH-1)
1061         return (c & BRIDGE_RTHASH_MASK);
1062 }
1063 
1064 #undef mix
1065 
1066 
1067 static int
1068 bdg_netmap_reg(struct netmap_adapter *na, int onoff)
1069 {
1070 	struct netmap_vp_adapter *vpna =
1071 		(struct netmap_vp_adapter*)na;
1072 	struct ifnet *ifp = na->ifp;
1073 
1074 	/* the interface is already attached to the bridge,
1075 	 * so we only need to toggle IFCAP_NETMAP.
1076 	 */
1077 	BDG_WLOCK(vpna->na_bdg);
1078 	if (onoff) {
1079 		ifp->if_capenable |= IFCAP_NETMAP;
1080 	} else {
1081 		ifp->if_capenable &= ~IFCAP_NETMAP;
1082 	}
1083 	BDG_WUNLOCK(vpna->na_bdg);
1084 	return 0;
1085 }
1086 
1087 
1088 /*
1089  * Lookup function for a learning bridge.
1090  * Update the hash table with the source address,
1091  * and then returns the destination port index, and the
1092  * ring in *dst_ring (at the moment, always use ring 0)
1093  */
1094 u_int
1095 netmap_bdg_learning(char *buf, u_int buf_len, uint8_t *dst_ring,
1096 		struct netmap_vp_adapter *na)
1097 {
1098 	struct nm_hash_ent *ht = na->na_bdg->ht;
1099 	uint32_t sh, dh;
1100 	u_int dst, mysrc = na->bdg_port;
1101 	uint64_t smac, dmac;
1102 
1103 	if (buf_len < 14) {
1104 		D("invalid buf length %d", buf_len);
1105 		return NM_BDG_NOPORT;
1106 	}
1107 	dmac = le64toh(*(uint64_t *)(buf)) & 0xffffffffffff;
1108 	smac = le64toh(*(uint64_t *)(buf + 4));
1109 	smac >>= 16;
1110 
1111 	/*
1112 	 * The hash is somewhat expensive, there might be some
1113 	 * worthwhile optimizations here.
1114 	 */
1115 	if ((buf[6] & 1) == 0) { /* valid src */
1116 		uint8_t *s = buf+6;
1117 		sh = nm_bridge_rthash(s); // XXX hash of source
1118 		/* update source port forwarding entry */
1119 		ht[sh].mac = smac;	/* XXX expire ? */
1120 		ht[sh].ports = mysrc;
1121 		if (netmap_verbose)
1122 		    D("src %02x:%02x:%02x:%02x:%02x:%02x on port %d",
1123 			s[0], s[1], s[2], s[3], s[4], s[5], mysrc);
1124 	}
1125 	dst = NM_BDG_BROADCAST;
1126 	if ((buf[0] & 1) == 0) { /* unicast */
1127 		dh = nm_bridge_rthash(buf); // XXX hash of dst
1128 		if (ht[dh].mac == dmac) {	/* found dst */
1129 			dst = ht[dh].ports;
1130 		}
1131 		/* XXX otherwise return NM_BDG_UNKNOWN ? */
1132 	}
1133 	*dst_ring = 0;
1134 	return dst;
1135 }
1136 
1137 
1138 /*
1139  * This flush routine supports only unicast and broadcast but a large
1140  * number of ports, and lets us replace the learn and dispatch functions.
1141  */
1142 int
1143 nm_bdg_flush(struct nm_bdg_fwd *ft, u_int n, struct netmap_vp_adapter *na,
1144 		u_int ring_nr)
1145 {
1146 	struct nm_bdg_q *dst_ents, *brddst;
1147 	uint16_t num_dsts = 0, *dsts;
1148 	struct nm_bridge *b = na->na_bdg;
1149 	u_int i, j, me = na->bdg_port;
1150 
1151 	/*
1152 	 * The work area (pointed by ft) is followed by an array of
1153 	 * pointers to queues , dst_ents; there are NM_BDG_MAXRINGS
1154 	 * queues per port plus one for the broadcast traffic.
1155 	 * Then we have an array of destination indexes.
1156 	 */
1157 	dst_ents = (struct nm_bdg_q *)(ft + NM_BDG_BATCH_MAX);
1158 	dsts = (uint16_t *)(dst_ents + NM_BDG_MAXPORTS * NM_BDG_MAXRINGS + 1);
1159 
1160 	/* first pass: find a destination for each packet in the batch */
1161 	for (i = 0; likely(i < n); i += ft[i].ft_frags) {
1162 		uint8_t dst_ring = ring_nr; /* default, same ring as origin */
1163 		uint16_t dst_port, d_i;
1164 		struct nm_bdg_q *d;
1165 
1166 		ND("slot %d frags %d", i, ft[i].ft_frags);
1167 		dst_port = b->nm_bdg_lookup(ft[i].ft_buf, ft[i].ft_len,
1168 			&dst_ring, na);
1169 		if (netmap_verbose > 255)
1170 			RD(5, "slot %d port %d -> %d", i, me, dst_port);
1171 		if (dst_port == NM_BDG_NOPORT)
1172 			continue; /* this packet is identified to be dropped */
1173 		else if (unlikely(dst_port > NM_BDG_MAXPORTS))
1174 			continue;
1175 		else if (dst_port == NM_BDG_BROADCAST)
1176 			dst_ring = 0; /* broadcasts always go to ring 0 */
1177 		else if (unlikely(dst_port == me ||
1178 		    !b->bdg_ports[dst_port]))
1179 			continue;
1180 
1181 		/* get a position in the scratch pad */
1182 		d_i = dst_port * NM_BDG_MAXRINGS + dst_ring;
1183 		d = dst_ents + d_i;
1184 
1185 		/* append the first fragment to the list */
1186 		if (d->bq_head == NM_FT_NULL) { /* new destination */
1187 			d->bq_head = d->bq_tail = i;
1188 			/* remember this position to be scanned later */
1189 			if (dst_port != NM_BDG_BROADCAST)
1190 				dsts[num_dsts++] = d_i;
1191 		} else {
1192 			ft[d->bq_tail].ft_next = i;
1193 			d->bq_tail = i;
1194 		}
1195 		d->bq_len += ft[i].ft_frags;
1196 	}
1197 
1198 	/*
1199 	 * Broadcast traffic goes to ring 0 on all destinations.
1200 	 * So we need to add these rings to the list of ports to scan.
1201 	 * XXX at the moment we scan all NM_BDG_MAXPORTS ports, which is
1202 	 * expensive. We should keep a compact list of active destinations
1203 	 * so we could shorten this loop.
1204 	 */
1205 	brddst = dst_ents + NM_BDG_BROADCAST * NM_BDG_MAXRINGS;
1206 	if (brddst->bq_head != NM_FT_NULL) {
1207 		for (j = 0; likely(j < b->bdg_active_ports); j++) {
1208 			uint16_t d_i;
1209 			i = b->bdg_port_index[j];
1210 			if (unlikely(i == me))
1211 				continue;
1212 			d_i = i * NM_BDG_MAXRINGS;
1213 			if (dst_ents[d_i].bq_head == NM_FT_NULL)
1214 				dsts[num_dsts++] = d_i;
1215 		}
1216 	}
1217 
1218 	ND(5, "pass 1 done %d pkts %d dsts", n, num_dsts);
1219 	/* second pass: scan destinations (XXX will be modular somehow) */
1220 	for (i = 0; i < num_dsts; i++) {
1221 		struct ifnet *dst_ifp;
1222 		struct netmap_vp_adapter *dst_na;
1223 		struct netmap_kring *kring;
1224 		struct netmap_ring *ring;
1225 		u_int dst_nr, lim, j, sent = 0, d_i, next, brd_next;
1226 		u_int needed, howmany;
1227 		int retry = netmap_txsync_retry;
1228 		struct nm_bdg_q *d;
1229 		uint32_t my_start = 0, lease_idx = 0;
1230 		int nrings;
1231 
1232 		d_i = dsts[i];
1233 		ND("second pass %d port %d", i, d_i);
1234 		d = dst_ents + d_i;
1235 		// XXX fix the division
1236 		dst_na = b->bdg_ports[d_i/NM_BDG_MAXRINGS];
1237 		/* protect from the lookup function returning an inactive
1238 		 * destination port
1239 		 */
1240 		if (unlikely(dst_na == NULL))
1241 			goto cleanup;
1242 		if (dst_na->up.na_flags & NAF_SW_ONLY)
1243 			goto cleanup;
1244 		dst_ifp = dst_na->up.ifp;
1245 		/*
1246 		 * The interface may be in !netmap mode in two cases:
1247 		 * - when na is attached but not activated yet;
1248 		 * - when na is being deactivated but is still attached.
1249 		 */
1250 		if (unlikely(!(dst_ifp->if_capenable & IFCAP_NETMAP))) {
1251 			ND("not in netmap mode!");
1252 			goto cleanup;
1253 		}
1254 
1255 		/* there is at least one either unicast or broadcast packet */
1256 		brd_next = brddst->bq_head;
1257 		next = d->bq_head;
1258 		/* we need to reserve this many slots. If fewer are
1259 		 * available, some packets will be dropped.
1260 		 * Packets may have multiple fragments, so we may not use
1261 		 * there is a chance that we may not use all of the slots
1262 		 * we have claimed, so we will need to handle the leftover
1263 		 * ones when we regain the lock.
1264 		 */
1265 		needed = d->bq_len + brddst->bq_len;
1266 
1267 		ND(5, "pass 2 dst %d is %x %s",
1268 			i, d_i, is_vp ? "virtual" : "nic/host");
1269 		dst_nr = d_i & (NM_BDG_MAXRINGS-1);
1270 		nrings = dst_na->up.num_rx_rings;
1271 		if (dst_nr >= nrings)
1272 			dst_nr = dst_nr % nrings;
1273 		kring = &dst_na->up.rx_rings[dst_nr];
1274 		ring = kring->ring;
1275 		lim = kring->nkr_num_slots - 1;
1276 
1277 retry:
1278 
1279 		/* reserve the buffers in the queue and an entry
1280 		 * to report completion, and drop lock.
1281 		 * XXX this might become a helper function.
1282 		 */
1283 		lockmgr(&kring->q_lock, LK_EXCLUSIVE);
1284 		if (kring->nkr_stopped) {
1285 			lockmgr(&kring->q_lock, LK_RELEASE);
1286 			goto cleanup;
1287 		}
1288 		if (dst_na->retry) {
1289 			dst_na->up.nm_notify(&dst_na->up, dst_nr, NR_RX, 0);
1290 		}
1291 		my_start = j = kring->nkr_hwlease;
1292 		howmany = nm_kr_space(kring, 1);
1293 		if (needed < howmany)
1294 			howmany = needed;
1295 		lease_idx = nm_kr_lease(kring, howmany, 1);
1296 		lockmgr(&kring->q_lock, LK_RELEASE);
1297 
1298 		/* only retry if we need more than available slots */
1299 		if (retry && needed <= howmany)
1300 			retry = 0;
1301 
1302 		/* copy to the destination queue */
1303 		while (howmany > 0) {
1304 			struct netmap_slot *slot;
1305 			struct nm_bdg_fwd *ft_p, *ft_end;
1306 			u_int cnt;
1307 
1308 			/* find the queue from which we pick next packet.
1309 			 * NM_FT_NULL is always higher than valid indexes
1310 			 * so we never dereference it if the other list
1311 			 * has packets (and if both are empty we never
1312 			 * get here).
1313 			 */
1314 			if (next < brd_next) {
1315 				ft_p = ft + next;
1316 				next = ft_p->ft_next;
1317 			} else { /* insert broadcast */
1318 				ft_p = ft + brd_next;
1319 				brd_next = ft_p->ft_next;
1320 			}
1321 			cnt = ft_p->ft_frags; // cnt > 0
1322 			if (unlikely(cnt > howmany))
1323 			    break; /* no more space */
1324 			howmany -= cnt;
1325 			if (netmap_verbose && cnt > 1)
1326 				RD(5, "rx %d frags to %d", cnt, j);
1327 			ft_end = ft_p + cnt;
1328 			do {
1329 			    void *dst, *src = ft_p->ft_buf;
1330 			    size_t len = (ft_p->ft_len + 63) & ~63;
1331 
1332 			    slot = &ring->slot[j];
1333 			    dst = BDG_NMB(&dst_na->up, slot);
1334 			    /* round to a multiple of 64 */
1335 
1336 			    ND("send %d %d bytes at %s:%d",
1337 				i, ft_p->ft_len, NM_IFPNAME(dst_ifp), j);
1338 			    if (ft_p->ft_flags & NS_INDIRECT) {
1339 				if (copyin(src, dst, len)) {
1340 					// invalid user pointer, pretend len is 0
1341 					ft_p->ft_len = 0;
1342 				}
1343 			    } else {
1344 				//memcpy(dst, src, len);
1345 				pkt_copy(src, dst, (int)len);
1346 			    }
1347 			    slot->len = ft_p->ft_len;
1348 			    slot->flags = (cnt << 8)| NS_MOREFRAG;
1349 			    j = nm_next(j, lim);
1350 			    ft_p++;
1351 			    sent++;
1352 			} while (ft_p != ft_end);
1353 			slot->flags = (cnt << 8); /* clear flag on last entry */
1354 			/* are we done ? */
1355 			if (next == NM_FT_NULL && brd_next == NM_FT_NULL)
1356 				break;
1357 		}
1358 		{
1359 		    /* current position */
1360 		    uint32_t *p = kring->nkr_leases; /* shorthand */
1361 		    uint32_t update_pos;
1362 		    int still_locked = 1;
1363 
1364 		    lockmgr(&kring->q_lock, LK_EXCLUSIVE);
1365 		    if (unlikely(howmany > 0)) {
1366 			/* not used all bufs. If i am the last one
1367 			 * i can recover the slots, otherwise must
1368 			 * fill them with 0 to mark empty packets.
1369 			 */
1370 			ND("leftover %d bufs", howmany);
1371 			if (nm_next(lease_idx, lim) == kring->nkr_lease_idx) {
1372 			    /* yes i am the last one */
1373 			    ND("roll back nkr_hwlease to %d", j);
1374 			    kring->nkr_hwlease = j;
1375 			} else {
1376 			    while (howmany-- > 0) {
1377 				ring->slot[j].len = 0;
1378 				ring->slot[j].flags = 0;
1379 				j = nm_next(j, lim);
1380 			    }
1381 			}
1382 		    }
1383 		    p[lease_idx] = j; /* report I am done */
1384 
1385 		    update_pos = nm_kr_rxpos(kring);
1386 
1387 		    if (my_start == update_pos) {
1388 			/* all slots before my_start have been reported,
1389 			 * so scan subsequent leases to see if other ranges
1390 			 * have been completed, and to a selwakeup or txsync.
1391 		         */
1392 			while (lease_idx != kring->nkr_lease_idx &&
1393 				p[lease_idx] != NR_NOSLOT) {
1394 			    j = p[lease_idx];
1395 			    p[lease_idx] = NR_NOSLOT;
1396 			    lease_idx = nm_next(lease_idx, lim);
1397 			}
1398 			/* j is the new 'write' position. j != my_start
1399 			 * means there are new buffers to report
1400 			 */
1401 			if (likely(j != my_start)) {
1402 				uint32_t old_avail = kring->nr_hwavail;
1403 
1404 				kring->nr_hwavail = (j >= kring->nr_hwcur) ?
1405 					j - kring->nr_hwcur :
1406 					j + lim + 1 - kring->nr_hwcur;
1407 				if (kring->nr_hwavail < old_avail) {
1408 					D("avail shrink %d -> %d",
1409 						old_avail, kring->nr_hwavail);
1410 				}
1411 				dst_na->up.nm_notify(&dst_na->up, dst_nr, NR_RX, 0);
1412 				still_locked = 0;
1413 				lockmgr(&kring->q_lock, LK_RELEASE);
1414 				if (dst_na->retry && retry--)
1415 					goto retry;
1416 			}
1417 		    }
1418 		    if (still_locked)
1419 			lockmgr(&kring->q_lock, LK_RELEASE);
1420 		}
1421 cleanup:
1422 		d->bq_head = d->bq_tail = NM_FT_NULL; /* cleanup */
1423 		d->bq_len = 0;
1424 	}
1425 	brddst->bq_head = brddst->bq_tail = NM_FT_NULL; /* cleanup */
1426 	brddst->bq_len = 0;
1427 	return 0;
1428 }
1429 
1430 static int
1431 netmap_vp_txsync(struct netmap_vp_adapter *na, u_int ring_nr, int flags)
1432 {
1433 	struct netmap_kring *kring = &na->up.tx_rings[ring_nr];
1434 	struct netmap_ring *ring = kring->ring;
1435 	u_int j, k, lim = kring->nkr_num_slots - 1;
1436 
1437 	k = ring->cur;
1438 	if (k > lim)
1439 		return netmap_ring_reinit(kring);
1440 
1441 	if (bridge_batch <= 0) { /* testing only */
1442 		j = k; // used all
1443 		goto done;
1444 	}
1445 	if (bridge_batch > NM_BDG_BATCH)
1446 		bridge_batch = NM_BDG_BATCH;
1447 
1448 	j = nm_bdg_preflush(na, ring_nr, kring, k);
1449 	if (j != k)
1450 		D("early break at %d/ %d, avail %d", j, k, kring->nr_hwavail);
1451 	/* k-j modulo ring size is the number of slots processed */
1452 	if (k < j)
1453 		k += kring->nkr_num_slots;
1454 	kring->nr_hwavail = lim - (k - j);
1455 
1456 done:
1457 	kring->nr_hwcur = j;
1458 	ring->avail = kring->nr_hwavail;
1459 	if (netmap_verbose)
1460 		D("%s ring %d flags %d", NM_IFPNAME(na->up.ifp), ring_nr, flags);
1461 	return 0;
1462 }
1463 
1464 
1465 /*
1466  * main dispatch routine for the bridge.
1467  * We already know that only one thread is running this.
1468  * we must run nm_bdg_preflush without lock.
1469  */
1470 static int
1471 bdg_netmap_txsync(struct netmap_adapter *na, u_int ring_nr, int flags)
1472 {
1473 	struct netmap_vp_adapter *vpna = (struct netmap_vp_adapter*)na;
1474 	return netmap_vp_txsync(vpna, ring_nr, flags);
1475 }
1476 
1477 
1478 /*
1479  * user process reading from a VALE switch.
1480  * Already protected against concurrent calls from userspace,
1481  * but we must acquire the queue's lock to protect against
1482  * writers on the same queue.
1483  */
1484 static int
1485 bdg_netmap_rxsync(struct netmap_adapter *na, u_int ring_nr, int flags)
1486 {
1487 	struct netmap_kring *kring = &na->rx_rings[ring_nr];
1488 	struct netmap_ring *ring = kring->ring;
1489 	u_int j, lim = kring->nkr_num_slots - 1;
1490 	u_int k = ring->cur, resvd = ring->reserved;
1491 	int n;
1492 
1493 	lockmgr(&kring->q_lock, LK_EXCLUSIVE);
1494 	if (k > lim) {
1495 		D("ouch dangerous reset!!!");
1496 		n = netmap_ring_reinit(kring);
1497 		goto done;
1498 	}
1499 
1500 	/* skip past packets that userspace has released */
1501 	j = kring->nr_hwcur;    /* netmap ring index */
1502 	if (resvd > 0) {
1503 		if (resvd + ring->avail >= lim + 1) {
1504 			D("XXX invalid reserve/avail %d %d", resvd, ring->avail);
1505 			ring->reserved = resvd = 0; // XXX panic...
1506 		}
1507 		k = (k >= resvd) ? k - resvd : k + lim + 1 - resvd;
1508 	}
1509 
1510 	if (j != k) { /* userspace has released some packets. */
1511 		n = k - j;
1512 		if (n < 0)
1513 			n += kring->nkr_num_slots;
1514 		ND("userspace releases %d packets", n);
1515 		for (n = 0; likely(j != k); n++) {
1516 			struct netmap_slot *slot = &ring->slot[j];
1517 			void *addr = BDG_NMB(na, slot);
1518 
1519 			if (addr == netmap_buffer_base) { /* bad buf */
1520 				D("bad buffer index %d, ignore ?",
1521 					slot->buf_idx);
1522 			}
1523 			slot->flags &= ~NS_BUF_CHANGED;
1524 			j = nm_next(j, lim);
1525 		}
1526 		kring->nr_hwavail -= n;
1527 		kring->nr_hwcur = k;
1528 	}
1529 	/* tell userspace that there are new packets */
1530 	ring->avail = kring->nr_hwavail - resvd;
1531 	n = 0;
1532 done:
1533 	lockmgr(&kring->q_lock, LK_RELEASE);
1534 	return n;
1535 }
1536 
1537 static int
1538 bdg_netmap_attach(struct netmap_adapter *arg)
1539 {
1540 	struct netmap_vp_adapter *vpna;
1541 	struct netmap_adapter *na;
1542 	int error;
1543 
1544 	vpna = kmalloc(sizeof(*vpna), M_DEVBUF, M_NOWAIT | M_ZERO);
1545 	if (vpna == NULL)
1546 		return ENOMEM;
1547 	na = &vpna->up;
1548 	*na = *arg;
1549 	na->na_flags |= NAF_BDG_MAYSLEEP | NAF_MEM_OWNER;
1550 	na->nm_txsync = bdg_netmap_txsync;
1551 	na->nm_rxsync = bdg_netmap_rxsync;
1552 	na->nm_register = bdg_netmap_reg;
1553 	na->nm_dtor = netmap_adapter_vp_dtor;
1554 	na->nm_krings_create = netmap_vp_krings_create;
1555 	na->nm_krings_delete = netmap_vp_krings_delete;
1556 	na->nm_mem = netmap_mem_private_new(NM_IFPNAME(arg->ifp),
1557 			na->num_tx_rings, na->num_tx_desc,
1558 			na->num_rx_rings, na->num_rx_desc);
1559 	/* other nmd fields are set in the common routine */
1560 	error = netmap_attach_common(na);
1561 	if (error) {
1562 		kfree(vpna, M_DEVBUF);
1563 		return error;
1564 	}
1565 	return 0;
1566 }
1567 
1568 static void
1569 netmap_bwrap_dtor(struct netmap_adapter *na)
1570 {
1571 	struct netmap_bwrap_adapter *bna = (struct netmap_bwrap_adapter*)na;
1572 	struct netmap_adapter *hwna = bna->hwna;
1573 	struct nm_bridge *b = bna->up.na_bdg,
1574 		*bh = bna->host.na_bdg;
1575 	struct ifnet *ifp = na->ifp;
1576 
1577 	ND("na %p", na);
1578 
1579 	if (b) {
1580 		netmap_bdg_detach_common(b, bna->up.bdg_port,
1581 			(bh ? bna->host.bdg_port : -1));
1582 	}
1583 
1584 	hwna->na_private = NULL;
1585 	netmap_adapter_put(hwna);
1586 
1587 	bzero(ifp, sizeof(*ifp));
1588 	kfree(ifp, M_DEVBUF);
1589 	na->ifp = NULL;
1590 
1591 }
1592 
1593 /*
1594  * Pass packets from nic to the bridge.
1595  * XXX TODO check locking: this is called from the interrupt
1596  * handler so we should make sure that the interface is not
1597  * disconnected while passing down an interrupt.
1598  *
1599  * Note, no user process can access this NIC so we can ignore
1600  * the info in the 'ring'.
1601  */
1602 /* callback that overwrites the hwna notify callback.
1603  * Packets come from the outside or from the host stack and are put on an hwna rx ring.
1604  * The bridge wrapper then sends the packets through the bridge.
1605  */
1606 static int
1607 netmap_bwrap_intr_notify(struct netmap_adapter *na, u_int ring_nr, enum txrx tx, int flags)
1608 {
1609 	struct ifnet *ifp = na->ifp;
1610 	struct netmap_bwrap_adapter *bna = na->na_private;
1611 	struct netmap_vp_adapter *hostna = &bna->host;
1612 	struct netmap_kring *kring, *bkring;
1613 	struct netmap_ring *ring;
1614 	int is_host_ring = ring_nr == na->num_rx_rings;
1615 	struct netmap_vp_adapter *vpna = &bna->up;
1616 	int error = 0;
1617 
1618 	ND("%s[%d] %s %x", NM_IFPNAME(ifp), ring_nr, (tx == NR_TX ? "TX" : "RX"), flags);
1619 
1620 	if (flags & NAF_DISABLE_NOTIFY) {
1621 		kring = tx == NR_TX ? na->tx_rings : na->rx_rings;
1622 		bkring = tx == NR_TX ? vpna->up.rx_rings : vpna->up.tx_rings;
1623 		if (kring->nkr_stopped)
1624 			netmap_disable_ring(bkring);
1625 		else
1626 			bkring->nkr_stopped = 0;
1627 		return 0;
1628 	}
1629 
1630 	if (ifp == NULL || !(ifp->if_capenable & IFCAP_NETMAP))
1631 		return 0;
1632 
1633 	if (tx == NR_TX)
1634 		return 0;
1635 
1636 	kring = &na->rx_rings[ring_nr];
1637 	ring = kring->ring;
1638 
1639 	/* make sure the ring is not disabled */
1640 	if (nm_kr_tryget(kring))
1641 		return 0;
1642 
1643 	if (is_host_ring && hostna->na_bdg == NULL) {
1644 		error = bna->save_notify(na, ring_nr, tx, flags);
1645 		goto put_out;
1646 	}
1647 
1648 	if (is_host_ring) {
1649 		vpna = hostna;
1650 		ring_nr = 0;
1651 	} else {
1652 		/* fetch packets that have arrived.
1653 		 * XXX maybe do this in a loop ?
1654 		 */
1655 		error = na->nm_rxsync(na, ring_nr, 0);
1656 		if (error)
1657 			goto put_out;
1658 	}
1659 	if (kring->nr_hwavail == 0 && netmap_verbose) {
1660 		D("how strange, interrupt with no packets on %s",
1661 			NM_IFPNAME(ifp));
1662 		goto put_out;
1663 	}
1664 	/* XXX avail ? */
1665 	ring->cur = nm_kr_rxpos(kring);
1666 	netmap_vp_txsync(vpna, ring_nr, flags);
1667 
1668 	if (!is_host_ring)
1669 		error = na->nm_rxsync(na, ring_nr, 0);
1670 
1671 put_out:
1672 	nm_kr_put(kring);
1673 	return error;
1674 }
1675 
1676 static int
1677 netmap_bwrap_register(struct netmap_adapter *na, int onoff)
1678 {
1679 	struct netmap_bwrap_adapter *bna =
1680 		(struct netmap_bwrap_adapter *)na;
1681 	struct netmap_adapter *hwna = bna->hwna;
1682 	struct netmap_vp_adapter *hostna = &bna->host;
1683 	int error;
1684 
1685 	ND("%s %d", NM_IFPNAME(ifp), onoff);
1686 
1687 	if (onoff) {
1688 		int i;
1689 
1690 		hwna->na_lut = na->na_lut;
1691 		hwna->na_lut_objtotal = na->na_lut_objtotal;
1692 
1693 		if (hostna->na_bdg) {
1694 			hostna->up.na_lut = na->na_lut;
1695 			hostna->up.na_lut_objtotal = na->na_lut_objtotal;
1696 		}
1697 
1698 		/* cross-link the netmap rings */
1699 		for (i = 0; i <= na->num_tx_rings; i++) {
1700 			hwna->tx_rings[i].nkr_num_slots = na->rx_rings[i].nkr_num_slots;
1701 			hwna->tx_rings[i].ring = na->rx_rings[i].ring;
1702 		}
1703 		for (i = 0; i <= na->num_rx_rings; i++) {
1704 			hwna->rx_rings[i].nkr_num_slots = na->tx_rings[i].nkr_num_slots;
1705 			hwna->rx_rings[i].ring = na->tx_rings[i].ring;
1706 		}
1707 	}
1708 
1709 	if (hwna->ifp) {
1710 		error = hwna->nm_register(hwna, onoff);
1711 		if (error)
1712 			return error;
1713 	}
1714 
1715 	bdg_netmap_reg(na, onoff);
1716 
1717 	if (onoff) {
1718 		bna->save_notify = hwna->nm_notify;
1719 		hwna->nm_notify = netmap_bwrap_intr_notify;
1720 	} else {
1721 		hwna->nm_notify = bna->save_notify;
1722 		hwna->na_lut = NULL;
1723 		hwna->na_lut_objtotal = 0;
1724 	}
1725 
1726 	return 0;
1727 }
1728 
1729 static int
1730 netmap_bwrap_config(struct netmap_adapter *na, u_int *txr, u_int *txd,
1731 				    u_int *rxr, u_int *rxd)
1732 {
1733 	struct netmap_bwrap_adapter *bna =
1734 		(struct netmap_bwrap_adapter *)na;
1735 	struct netmap_adapter *hwna = bna->hwna;
1736 
1737 	/* forward the request */
1738 	netmap_update_config(hwna);
1739 	/* swap the results */
1740 	*txr = hwna->num_rx_rings;
1741 	*txd = hwna->num_rx_desc;
1742 	*rxr = hwna->num_tx_rings;
1743 	*rxd = hwna->num_rx_desc;
1744 
1745 	return 0;
1746 }
1747 
1748 static int
1749 netmap_bwrap_krings_create(struct netmap_adapter *na)
1750 {
1751 	struct netmap_bwrap_adapter *bna =
1752 		(struct netmap_bwrap_adapter *)na;
1753 	struct netmap_adapter *hwna = bna->hwna;
1754 	struct netmap_adapter *hostna = &bna->host.up;
1755 	int error;
1756 
1757 	ND("%s", NM_IFPNAME(na->ifp));
1758 
1759 	error = netmap_vp_krings_create(na);
1760 	if (error)
1761 		return error;
1762 
1763 	error = hwna->nm_krings_create(hwna);
1764 	if (error) {
1765 		netmap_vp_krings_delete(na);
1766 		return error;
1767 	}
1768 
1769 	hostna->tx_rings = na->tx_rings + na->num_tx_rings;
1770 	hostna->rx_rings = na->rx_rings + na->num_rx_rings;
1771 
1772 	return 0;
1773 }
1774 
1775 static void
1776 netmap_bwrap_krings_delete(struct netmap_adapter *na)
1777 {
1778 	struct netmap_bwrap_adapter *bna =
1779 		(struct netmap_bwrap_adapter *)na;
1780 	struct netmap_adapter *hwna = bna->hwna;
1781 
1782 	ND("%s", NM_IFPNAME(na->ifp));
1783 
1784 	hwna->nm_krings_delete(hwna);
1785 	netmap_vp_krings_delete(na);
1786 }
1787 
1788 /* notify method for the bridge-->hwna direction */
1789 static int
1790 netmap_bwrap_notify(struct netmap_adapter *na, u_int ring_n, enum txrx tx, int flags)
1791 {
1792 	struct netmap_bwrap_adapter *bna =
1793 		(struct netmap_bwrap_adapter *)na;
1794 	struct netmap_adapter *hwna = bna->hwna;
1795 	struct netmap_kring *kring, *hw_kring;
1796 	struct netmap_ring *ring;
1797 	u_int lim, k;
1798 	int error = 0;
1799 
1800 	if (tx == NR_TX)
1801 	        return ENXIO;
1802 
1803 	kring = &na->rx_rings[ring_n];
1804 	hw_kring = &hwna->tx_rings[ring_n];
1805 	ring = kring->ring;
1806 
1807 	lim = kring->nkr_num_slots - 1;
1808 	k = nm_kr_rxpos(kring);
1809 
1810 	if (hwna->ifp == NULL || !(hwna->ifp->if_capenable & IFCAP_NETMAP))
1811 		return 0;
1812 	ring->cur = k;
1813 	ND("%s[%d] PRE rx(%d, %d, %d, %d) ring(%d, %d, %d) tx(%d, %d)",
1814 		NM_IFPNAME(na->ifp), ring_n,
1815 		kring->nr_hwcur, kring->nr_hwavail, kring->nkr_hwlease, kring->nr_hwreserved,
1816 		ring->cur, ring->avail, ring->reserved,
1817 		hw_kring->nr_hwcur, hw_kring->nr_hwavail);
1818 	if (ring_n == na->num_rx_rings) {
1819 		netmap_txsync_to_host(hwna);
1820 	} else {
1821 		error = hwna->nm_txsync(hwna, ring_n, flags);
1822 	}
1823 	kring->nr_hwcur = ring->cur;
1824 	kring->nr_hwavail = 0;
1825 	kring->nr_hwreserved = lim - ring->avail;
1826 	ND("%s[%d] PST rx(%d, %d, %d, %d) ring(%d, %d, %d) tx(%d, %d)",
1827 		NM_IFPNAME(na->ifp), ring_n,
1828 		kring->nr_hwcur, kring->nr_hwavail, kring->nkr_hwlease, kring->nr_hwreserved,
1829 		ring->cur, ring->avail, ring->reserved,
1830 		hw_kring->nr_hwcur, hw_kring->nr_hwavail);
1831 
1832 	return error;
1833 }
1834 
1835 static int
1836 netmap_bwrap_host_notify(struct netmap_adapter *na, u_int ring_n, enum txrx tx, int flags)
1837 {
1838 	struct netmap_bwrap_adapter *bna = na->na_private;
1839 	struct netmap_adapter *port_na = &bna->up.up;
1840 	if (tx == NR_TX || ring_n != 0)
1841 		return ENXIO;
1842 	return netmap_bwrap_notify(port_na, port_na->num_rx_rings, NR_RX, flags);
1843 }
1844 
1845 /* attach a bridge wrapper to the 'real' device */
1846 static int
1847 netmap_bwrap_attach(struct ifnet *fake, struct ifnet *real)
1848 {
1849 	struct netmap_bwrap_adapter *bna;
1850 	struct netmap_adapter *na;
1851 	struct netmap_adapter *hwna = NA(real);
1852 	struct netmap_adapter *hostna;
1853 	int error;
1854 
1855 
1856 	bna = kmalloc(sizeof(*bna), M_DEVBUF, M_NOWAIT | M_ZERO);
1857 	if (bna == NULL)
1858 		return ENOMEM;
1859 
1860 	na = &bna->up.up;
1861 	na->ifp = fake;
1862 	/* fill the ring data for the bwrap adapter with rx/tx meanings
1863 	 * swapped. The real cross-linking will be done during register,
1864 	 * when all the krings will have been created.
1865 	 */
1866 	na->num_rx_rings = hwna->num_tx_rings;
1867 	na->num_tx_rings = hwna->num_rx_rings;
1868 	na->num_tx_desc = hwna->num_rx_desc;
1869 	na->num_rx_desc = hwna->num_tx_desc;
1870 	na->nm_dtor = netmap_bwrap_dtor;
1871 	na->nm_register = netmap_bwrap_register;
1872 	// na->nm_txsync = netmap_bwrap_txsync;
1873 	// na->nm_rxsync = netmap_bwrap_rxsync;
1874 	na->nm_config = netmap_bwrap_config;
1875 	na->nm_krings_create = netmap_bwrap_krings_create;
1876 	na->nm_krings_delete = netmap_bwrap_krings_delete;
1877 	na->nm_notify = netmap_bwrap_notify;
1878 	na->nm_mem = hwna->nm_mem;
1879 	na->na_private = na; /* prevent NIOCREGIF */
1880 	bna->up.retry = 1; /* XXX maybe this should depend on the hwna */
1881 
1882 	bna->hwna = hwna;
1883 	netmap_adapter_get(hwna);
1884 	hwna->na_private = bna; /* weak reference */
1885 
1886 	hostna = &bna->host.up;
1887 	hostna->ifp = hwna->ifp;
1888 	hostna->num_tx_rings = 1;
1889 	hostna->num_tx_desc = hwna->num_rx_desc;
1890 	hostna->num_rx_rings = 1;
1891 	hostna->num_rx_desc = hwna->num_tx_desc;
1892 	// hostna->nm_txsync = netmap_bwrap_host_txsync;
1893 	// hostna->nm_rxsync = netmap_bwrap_host_rxsync;
1894 	hostna->nm_notify = netmap_bwrap_host_notify;
1895 	hostna->nm_mem = na->nm_mem;
1896 	hostna->na_private = bna;
1897 
1898 	D("%s<->%s txr %d txd %d rxr %d rxd %d", fake->if_xname, real->if_xname,
1899 		na->num_tx_rings, na->num_tx_desc,
1900 		na->num_rx_rings, na->num_rx_desc);
1901 
1902 	error = netmap_attach_common(na);
1903 	if (error) {
1904 		netmap_adapter_put(hwna);
1905 		kfree(bna, M_DEVBUF);
1906 		return error;
1907 	}
1908 	return 0;
1909 }
1910 
1911 void
1912 netmap_init_bridges(void)
1913 {
1914 	int i;
1915 	bzero(nm_bridges, sizeof(struct nm_bridge) * NM_BRIDGES); /* safety */
1916 	for (i = 0; i < NM_BRIDGES; i++)
1917 		BDG_RWINIT(&nm_bridges[i]);
1918 }
1919 #endif /* WITH_VALE */
1920