FreeBSD/sys/dev/netmap/netmap_vale.c
/* nm_bdg_ctl callback for the bwrap.
 * Called on bridge-attach and detach, as an effect of vale-ctl -[ahd].
 * On attach, it needs to provide a fake netmap_priv_d structure and
 * perform a netmap_do_regif() on the bwrap. This will put both the
 * bwrap and the hwna in netmap mode, with the netmap rings shared
 * and cross linked. Moroever, it will start intercepting interrupts
 * directed to hwna.
 */
nm_bdg_ctl callback for the bwrap.
Called on bridge-attach and detach, as an effect of vale-ctl -[ahd].
On attach, it needs to provide a fake netmap_priv_d structure and
perform a netmap_do_regif() on the bwrap. This will put both the
bwrap and the hwna in netmap mode, with the netmap rings shared
and cross linked. Moroever, it will start intercepting interrupts
directed to hwna.
nm_bdg_ctl callback for the bwrap . Called on bridge - attach and detach as an effect of vale - ctl - [ ahd ] . On attach it needs to provide a fake netmap_priv_d structure and perform a netmap_do_regif () on the bwrap . This will put both the bwrap and the hwna in netmap mode with the netmap rings shared and cross linked . Moroever it will start intercepting interrupts directed to hwna .
static int
netmap_bwrap_bdg_ctl(struct netmap_adapter *na, struct nmreq *nmr, int attach)
{
	struct netmap_priv_d *npriv;
	struct netmap_bwrap_adapter *bna = (struct netmap_bwrap_adapter*)na;
	int error = 0;
	if (attach) {
		if (NETMAP_OWNED_BY_ANY(na)) {
			return EBUSY;
		}
		if (bna->na_kpriv) {
			return 0;
		}
		npriv = malloc(sizeof(*npriv), M_DEVBUF, M_NOWAIT|M_ZERO);
		if (npriv == NULL)
			return ENOMEM;
		error = netmap_do_regif(npriv, na, nmr->nr_ringid, nmr->nr_flags);
		if (error) {
			bzero(npriv, sizeof(*npriv));
			free(npriv, M_DEVBUF);
			return error;
		}
		bna->na_kpriv = npriv;
		na->na_flags |= NAF_BUSY;
	} else {
		int last_instance;
		if (na->active_fds == 0) 
			return EINVAL;
		last_instance = netmap_dtor_locked(bna->na_kpriv);
		if (!last_instance) {
			D("--- error, trying to detach an entry with active mmaps");
			error = EINVAL;
		} else {
			struct nm_bridge *b = bna->up.na_bdg,
				*bh = bna->host.na_bdg;
			npriv = bna->na_kpriv;
			bna->na_kpriv = NULL;
			D("deleting priv");
			bzero(npriv, sizeof(*npriv));
			free(npriv, M_DEVBUF);
			if (b) {
				netmap_bdg_detach_common(b, bna->up.bdg_port,
				    (bh ? bna->host.bdg_port : -1));
			}
			na->na_flags &= ~NAF_BUSY;
		}
	}
	return error;
}
static int netmap_bwrap_bdg_ctl ( struct netmap_adapter * na , struct nmreq * nmr , int attach ) { struct netmap_priv_d * npriv ; struct netmap_bwrap_adapter * bna = ( struct netmap_bwrap_adapter * ) na ; int error = 0 ; if ( attach ) { if ( NETMAP_OWNED_BY_ANY ( na ) ) { return EBUSY ; } if ( bna -> na_kpriv ) { return 0 ; } npriv = malloc ( sizeof ( * npriv ) , M_DEVBUF , M_NOWAIT | M_ZERO ) ; if ( npriv == NULL ) return ENOMEM ; error = netmap_do_regif ( npriv , na , nmr -> nr_ringid , nmr -> nr_flags ) ; if ( error ) { bzero ( npriv , sizeof ( * npriv ) ) ; free ( npriv , M_DEVBUF ) ; return error ; } bna -> na_kpriv = npriv ; na -> na_flags |= NAF_BUSY ; } else { int last_instance ; if ( na -> active_fds == 0 ) return EINVAL ; last_instance = netmap_dtor_locked ( bna -> na_kpriv ) ; if ( ! last_instance ) { D ( " " ) ; error = EINVAL ; } else { struct nm_bridge * b = bna -> up . na_bdg , * bh = bna -> host . na_bdg ; npriv = bna -> na_kpriv ; bna -> na_kpriv = NULL ; D ( " " ) ; bzero ( npriv , sizeof ( * npriv ) ) ; free ( npriv , M_DEVBUF ) ; if ( b ) { netmap_bdg_detach_common ( b , bna -> up . bdg_port , ( bh ? bna -> host . bdg_port : -1 ) ) ; } na -> na_flags &= ~ NAF_BUSY ; } } return error ; }
nm_bdg_ctl callback for the bwrap.
nm_bdg_ctl callback for the bwrap .
/* nothing to do */ /* not registered */ /* XXX the bwrap dtor should take care
				 * of this (2014-06-16)
				 */