FreeBSD/sys/net/if_clone.c
/*
 * Destroy a clone network interface.
 */
Destroy a clone network interface.
Destroy a clone network interface .
int
if_clone_destroyif(struct if_clone *ifc, struct ifnet *ifp)
{
	int err;
	struct ifnet *ifcifp;
	if (ifc->ifc_type == ADVANCED && ifc->ifc_destroy == NULL)
		return(EOPNOTSUPP);
	CURVNET_SET_QUIET(ifp->if_vnet);
	IF_CLONE_LOCK(ifc);
	LIST_FOREACH(ifcifp, &ifc->ifc_iflist, if_clones) {
		if (ifcifp == ifp) {
			IFC_IFLIST_REMOVE(ifc, ifp);
			break;
		}
	}
	IF_CLONE_UNLOCK(ifc);
	if (ifcifp == NULL) {
		CURVNET_RESTORE();
		return (ENXIO);		
	}
	if_delgroup(ifp, ifc->ifc_name);
	if (ifc->ifc_type == SIMPLE)
		err = ifc_simple_destroy(ifc, ifp);
	else
		err = (*ifc->ifc_destroy)(ifc, ifp);
	if (err != 0) {
		if_addgroup(ifp, ifc->ifc_name);
		IF_CLONE_LOCK(ifc);
		IFC_IFLIST_INSERT(ifc, ifp);
		IF_CLONE_UNLOCK(ifc);
	}
	CURVNET_RESTORE();
	return (err);
}
int if_clone_destroyif ( struct if_clone * ifc , struct ifnet * ifp ) { int err ; struct ifnet * ifcifp ; if ( ifc -> ifc_type == ADVANCED && ifc -> ifc_destroy == NULL ) return ( EOPNOTSUPP ) ; CURVNET_SET_QUIET ( ifp -> if_vnet ) ; IF_CLONE_LOCK ( ifc ) ; LIST_FOREACH ( ifcifp , & ifc -> ifc_iflist , if_clones ) { if ( ifcifp == ifp ) { IFC_IFLIST_REMOVE ( ifc , ifp ) ; break ; } } IF_CLONE_UNLOCK ( ifc ) ; if ( ifcifp == NULL ) { CURVNET_RESTORE ( ) ; return ( ENXIO ) ; } if_delgroup ( ifp , ifc -> ifc_name ) ; if ( ifc -> ifc_type == SIMPLE ) err = ifc_simple_destroy ( ifc , ifp ) ; else err = ( * ifc -> ifc_destroy ) ( ifc , ifp ) ; if ( err != 0 ) { if_addgroup ( ifp , ifc -> ifc_name ) ; IF_CLONE_LOCK ( ifc ) ; IFC_IFLIST_INSERT ( ifc , ifp ) ; IF_CLONE_UNLOCK ( ifc ) ; } CURVNET_RESTORE ( ) ; return ( err ) ; }
Destroy a clone network interface.
Destroy a clone network interface .
/*
	 * Given that the cloned ifnet might be attached to a different
	 * vnet from where its cloner was registered, we have to
	 * switch to the vnet context of the target vnet.
	 */ /* ifp is not on the list. */