FreeBSD/sys/dev/netmap/netmap_vale.c
/* remove from bridge b the ports in slots hw and sw
 * (sw can be -1 if not needed)
 */
remove from bridge b the ports in slots hw and sw
(sw can be -1 if not needed)
remove from bridge b the ports in slots hw and sw ( sw can be - 1 if not needed )
static void
netmap_bdg_detach_common(struct nm_bridge *b, int hw, int sw)
{
	int s_hw = hw, s_sw = sw;
	int i, lim =b->bdg_active_ports;
	uint8_t tmp[NM_BDG_MAXPORTS];
	if (netmap_verbose)
		D("detach %d and %d (lim %d)", hw, sw, lim);
	memcpy(tmp, b->bdg_port_index, sizeof(tmp));
	for (i = 0; (hw >= 0 || sw >= 0) && i < lim; ) {
		if (hw >= 0 && tmp[i] == hw) {
			ND("detach hw %d at %d", hw, i);
			lim--; 
			tmp[i] = tmp[lim]; 
			tmp[lim] = hw;	
			hw = -1;
		} else if (sw >= 0 && tmp[i] == sw) {
			ND("detach sw %d at %d", sw, i);
			lim--;
			tmp[i] = tmp[lim];
			tmp[lim] = sw;
			sw = -1;
		} else {
			i++;
		}
	}
	if (hw >= 0 || sw >= 0) {
		D("XXX delete failed hw %d sw %d, should panic...", hw, sw);
	}
	BDG_WLOCK(b);
	if (b->bdg_ops.dtor)
		b->bdg_ops.dtor(b->bdg_ports[s_hw]);
	b->bdg_ports[s_hw] = NULL;
	if (s_sw >= 0) {
		b->bdg_ports[s_sw] = NULL;
	}
	memcpy(b->bdg_port_index, tmp, sizeof(tmp));
	b->bdg_active_ports = lim;
	BDG_WUNLOCK(b);
	ND("now %d active ports", lim);
	if (lim == 0) {
		ND("marking bridge %s as free", b->bdg_basename);
		bzero(&b->bdg_ops, sizeof(b->bdg_ops));
		NM_BNS_PUT(b);
	}
}
static void netmap_bdg_detach_common ( struct nm_bridge * b , int hw , int sw ) { int s_hw = hw , s_sw = sw ; int i , lim = b -> bdg_active_ports ; uint8_t tmp [ NM_BDG_MAXPORTS ] ; if ( netmap_verbose ) D ( " " , hw , sw , lim ) ; memcpy ( tmp , b -> bdg_port_index , sizeof ( tmp ) ) ; for ( i = 0 ; ( hw >= 0 || sw >= 0 ) && i < lim ; ) { if ( hw >= 0 && tmp [ i ] == hw ) { ND ( " " , hw , i ) ; lim -- ; tmp [ i ] = tmp [ lim ] ; tmp [ lim ] = hw ; hw = -1 ; } else if ( sw >= 0 && tmp [ i ] == sw ) { ND ( " " , sw , i ) ; lim -- ; tmp [ i ] = tmp [ lim ] ; tmp [ lim ] = sw ; sw = -1 ; } else { i ++ ; } } if ( hw >= 0 || sw >= 0 ) { D ( " " , hw , sw ) ; } BDG_WLOCK ( b ) ; if ( b -> bdg_ops . dtor ) b -> bdg_ops . dtor ( b -> bdg_ports [ s_hw ] ) ; b -> bdg_ports [ s_hw ] = NULL ; if ( s_sw >= 0 ) { b -> bdg_ports [ s_sw ] = NULL ; } memcpy ( b -> bdg_port_index , tmp , sizeof ( tmp ) ) ; b -> bdg_active_ports = lim ; BDG_WUNLOCK ( b ) ; ND ( " " , lim ) ; if ( lim == 0 ) { ND ( " " , b -> bdg_basename ) ; bzero ( & b -> bdg_ops , sizeof ( b -> bdg_ops ) ) ; NM_BNS_PUT ( b ) ; } }
remove from bridge b the ports in slots hw and sw
 (sw can be -1 if not needed)
remove from bridge b the ports in slots hw and sw ( sw can be - 1 if not needed )
/*
	New algorithm:
	make a copy of bdg_port_index;
	lookup NA(ifp)->bdg_port and SWNA(ifp)->bdg_port
	in the array of bdg_port_index, replacing them with
	entries from the bottom of the array;
	decrement bdg_active_ports;
	acquire BDG_WLOCK() and copy back the array.
	 */ /* make a copy of the list of active ports, update it,
	 * and then copy back within BDG_WLOCK().
	 */ /* point to last active port */ /* swap with i */ /* now this is inactive */