bool vboxNetFltOsMaybeRediscovered(PVBOXNETFLTINS pThis) { struct ifnet *ifp, *ifp0; ifp = ASMAtomicUoReadPtrT(&pThis->u.s.ifp, struct ifnet *); VBOXCURVNET_SET(ifp->if_vnet); /* * Attempt to check if the interface is still there and re-initialize if * something has changed. */ ifp0 = ifunit(pThis->szName); if (ifp != ifp0) { ASMAtomicUoWriteBool(&pThis->fDisconnectedFromHost, true); ng_rmnode_self(pThis->u.s.node); pThis->u.s.node = NULL; } if (ifp0 != NULL) { vboxNetFltOsDeleteInstance(pThis); vboxNetFltOsInitInstance(pThis, NULL); } VBOXCURVNET_RESTORE(); return !ASMAtomicUoReadBool(&pThis->fDisconnectedFromHost); }
/* * Destroy node */ static int ng_ksocket_shutdown(node_p node) { const priv_p priv = NG_NODE_PRIVATE(node); priv_p embryo; /* Close our socket (if any) */ if (priv->so != NULL) { atomic_clear_int(&priv->so->so_rcv.ssb_flags, SSB_UPCALL); atomic_clear_int(&priv->so->so_snd.ssb_flags, SSB_UPCALL); priv->so->so_upcall = NULL; soclose(priv->so, FNONBLOCK); priv->so = NULL; } /* If we are an embryo, take ourselves out of the parent's list */ if (priv->flags & KSF_EMBRYONIC) { LIST_REMOVE(priv, siblings); priv->flags &= ~KSF_EMBRYONIC; } /* Remove any embryonic children we have */ while (!LIST_EMPTY(&priv->embryos)) { embryo = LIST_FIRST(&priv->embryos); ng_rmnode_self(embryo->node); } /* Take down netgraph node */ bzero(priv, sizeof(*priv)); kfree(priv, M_NETGRAPH); NG_NODE_SET_PRIVATE(node, NULL); NG_NODE_UNREF(node); /* let the node escape */ return (0); }
static int ng_sscop_disconnect(hook_p hook) { node_p node = NG_HOOK_NODE(hook); struct priv *priv = NG_NODE_PRIVATE(node); if(hook == priv->upper) priv->upper = NULL; else if(hook == priv->lower) priv->lower = NULL; else if(hook == priv->manage) priv->manage = NULL; if(NG_NODE_NUMHOOKS(node) == 0) { if(NG_NODE_IS_VALID(node)) ng_rmnode_self(node); } else { /* * Imply a release request, if the upper layer is * disconnected. */ if(priv->upper == NULL && priv->lower != NULL && priv->enabled && sscop_getstate(priv->sscop) != SSCOP_IDLE) { sscop_aasig(priv->sscop, SSCOP_RELEASE_request, NULL, 0); } } return 0; }
int ubt_detach(device_t dev) { struct ubt_softc *sc = device_get_softc(dev); node_p node = sc->sc_node; /* Destroy Netgraph node */ if (node != NULL) { sc->sc_node = NULL; NG_NODE_REALLY_DIE(node); ng_rmnode_self(node); } /* Make sure ubt_task in gone */ taskqueue_drain(taskqueue_swi, &sc->sc_task); /* Free USB transfers, if any */ usbd_transfer_unsetup(sc->sc_xfer, UBT_N_TRANSFER); /* Destroy queues */ UBT_NG_LOCK(sc); NG_BT_MBUFQ_DESTROY(&sc->sc_cmdq); NG_BT_MBUFQ_DESTROY(&sc->sc_aclq); NG_BT_MBUFQ_DESTROY(&sc->sc_scoq); UBT_NG_UNLOCK(sc); mtx_destroy(&sc->sc_if_mtx); mtx_destroy(&sc->sc_ng_mtx); return (0); } /* ubt_detach */
/* * Hook disconnection */ static int ngipi_disconnect(hook_p hook) { if (NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); }
static int bt3c_pccard_detach(device_t dev) { bt3c_softc_p sc = (bt3c_softc_p) device_get_softc(dev); if (sc == NULL) return (0); unregister_swi(sc->ith, SWI_TTY, -1); sc->ith = NULL; bus_teardown_intr(dev, sc->irq, sc->irq_cookie); bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); sc->irq_cookie = NULL; sc->irq = NULL; sc->irq_rid = 0; bus_release_resource(dev, SYS_RES_IOPORT, sc->iobase_rid, sc->iobase); sc->iobase = NULL; sc->iobase_rid = 0; if (sc->node != NULL) { NG_NODE_SET_PRIVATE(sc->node, NULL); ng_rmnode_self(sc->node); sc->node = NULL; } NG_FREE_M(sc->m); IF_DRAIN(&sc->inq); IF_DRAIN(&sc->outq); return (0); } /* bt3c_pccacd_detach */
static int ng_sscfu_disconnect(hook_p hook) { node_p node = NG_HOOK_NODE(hook); struct priv *priv = NG_NODE_PRIVATE(node); if (hook == priv->upper) priv->upper = NULL; else if (hook == priv->lower) priv->lower = NULL; else { log(LOG_ERR, "bogus hook"); return (EINVAL); } if (NG_NODE_NUMHOOKS(node) == 0) { if (NG_NODE_IS_VALID(node)) ng_rmnode_self(node); } else { /* * Because there are no timeouts reset the protocol * if the lower layer is disconnected. */ if (priv->lower == NULL && priv->enabled && sscfu_getstate(priv->sscf) != SSCFU_RELEASED) sscfu_reset(priv->sscf); } return (0); }
/* * Removal of the last link destroys the nodeo */ static int ngee_disconnect(hook_p hook) { if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) { ng_rmnode_self(NG_HOOK_NODE(hook)); } return (0); }
/* * Hook disconnection */ static int ng_ksocket_disconnect(hook_p hook) { KASSERT(NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0, ("%s: numhooks=%d?", __func__, NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)))); if (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); }
/* * Dook disconnection * * For this type, removal of the last link destroys the node */ Static int ng_udbp_disconnect(hook_p hook) { const udbp_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); sc->hook = NULL; if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); }
/* * Hook disconnection */ static int ngt_disconnect(hook_p hook) { struct hookinfo *const hinfo = NG_HOOK_PRIVATE(hook); KASSERT(hinfo != NULL, ("%s: null info", __func__)); hinfo->hook = NULL; if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); }
void vboxNetFltOsDeleteInstance(PVBOXNETFLTINS pThis) { taskqueue_drain(taskqueue_fast, &pThis->u.s.tskin); taskqueue_drain(taskqueue_fast, &pThis->u.s.tskout); mtx_destroy(&pThis->u.s.inq.ifq_mtx); mtx_destroy(&pThis->u.s.outq.ifq_mtx); if (pThis->u.s.node != NULL) ng_rmnode_self(pThis->u.s.node); pThis->u.s.node = NULL; }
/* * Hook disconnection */ static int ng_split_disconnect(hook_p hook) { hook_p *localhook = NG_HOOK_PRIVATE(hook); KASSERT(localhook != NULL, ("%s: null info", __func__)); *localhook = NULL; if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) { ng_rmnode_self(NG_HOOK_NODE(hook)); } return (0); }
/* * This is called once we've already connected a new hook to the other node. * It gives us a chance to balk at the last minute. */ static int ng_xxx_connect(hook_p hook) { #if 0 /* * If we were a driver running at other than splnet then * we should set the QUEUE bit on the edge so that we * will deliver by queing. */ if /*it is the upstream hook */ NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook)); #endif #if 0 /* * If for some reason we want incoming date to be queued * by the NETISR system and delivered later we can set the same bit on * OUR hook. (maybe to allow unwinding of the stack) */ if (NG_HOOK_PRIVATE(hook)) { int dlci; /* * If it's dlci 1023, requeue it so that it's handled * at a lower priority. This is how a node decides to * defer a data message. */ dlci = ((struct XXX_hookinfo *) NG_HOOK_PRIVATE(hook))->dlci; if (dlci == 1023) { NG_HOOK_FORCE_QUEUE(hook); } #endif /* otherwise be really amiable and just say "YUP that's OK by me! " */ return (0); } /* * Hook disconnection * * For this type, removal of the last link destroys the node */ static int ng_xxx_disconnect(hook_p hook) { if (NG_HOOK_PRIVATE(hook)) ((struct XXX_hookinfo *) (NG_HOOK_PRIVATE(hook)))->hook = NULL; if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) /* already shutting down? */ ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); }
/* * Hook disconnection * For this type, removal of any link except "debug" destroys the node. */ static int nglmi_disconnect(hook_p hook) { const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); /* OK to remove debug hook(s) */ if (NG_HOOK_PRIVATE(hook) == NULL) return (0); /* Stop timer if it's currently active */ if (sc->flags & SCF_CONNECTED) ng_uncallout(&sc->handle, sc->node); /* Self-destruct */ if (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))) ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); }
/* * Hook disconnection * * For this type, removal of the last link destroys the node * if the NOLINGER flag is set. */ static int ngs_disconnect(hook_p hook) { node_p node = NG_HOOK_NODE(hook); struct ngsock *const priv = NG_NODE_PRIVATE(node); if ((priv->datasock) && (priv->datasock->ng_socket)) { if (NG_NODE_NUMHOOKS(node) == 1) sosetstate(priv->datasock->ng_socket, SS_ISCONNECTED); else soclrstate(priv->datasock->ng_socket, SS_ISCONNECTED); } if ((priv->flags & NGS_FLAG_NOLINGER) && (NG_NODE_NUMHOOKS(node) == 0) && (NG_NODE_IS_VALID(node))) ng_rmnode_self(node); return (0); }
/* * Hook disconnection * * Invalidate the private data associated with this dlci. * For this type, removal of the last link resets tries to destroy the node. */ static int ngfrm_disconnect(hook_p hook) { const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); struct ctxinfo *const cp = NG_HOOK_PRIVATE(hook); int dlci; /* If it's a regular dlci hook, then free resources etc.. */ if (cp != NULL) { cp->hook = NULL; dlci = cp->dlci; if (dlci != -1) sc->ALT[dlci] = 0; cp->flags = 0; sc->datahooks--; } if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0) && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook)))) ng_rmnode_self(NG_HOOK_NODE(hook)); return (0); }
/* * Remove a reference from node private data. */ static void ng_socket_free_priv(struct ngsock *priv) { mtx_assert(&priv->mtx, MA_OWNED); priv->refs--; if (priv->refs == 0) { mtx_destroy(&priv->mtx); kfree(priv, M_NETGRAPH_SOCK); return; } if ((priv->refs == 1) && (priv->node != NULL)) { node_p node = priv->node; priv->node = NULL; mtx_unlock(&priv->mtx); NG_NODE_UNREF(node); ng_rmnode_self(node); } else mtx_unlock(&priv->mtx); }
/* * Remove a reference from node private data. */ static void ng_socket_free_priv(struct ngsock *priv) { KKASSERT(mtx_owned(&priv->mtx)); priv->refs--; if (priv->refs == 0) { mtx_uninit(&priv->mtx); kfree(priv, M_NETGRAPH_SOCK); return; } if ((priv->refs == 1) && (priv->node != NULL)) { node_p node = priv->node; priv->node = NULL; mtx_unlock(&priv->mtx); NG_NODE_UNREF(node); ng_rmnode_self(node); } else mtx_unlock(&priv->mtx); }
/* * Destroy node */ static int ng_ksocket_shutdown(node_p node) { const priv_p priv = NG_NODE_PRIVATE(node); priv_p embryo; /* Close our socket (if any) */ if (priv->so != NULL) { SOCKBUF_LOCK(&priv->so->so_rcv); soupcall_clear(priv->so, SO_RCV); SOCKBUF_UNLOCK(&priv->so->so_rcv); SOCKBUF_LOCK(&priv->so->so_snd); soupcall_clear(priv->so, SO_SND); SOCKBUF_UNLOCK(&priv->so->so_snd); soclose(priv->so); priv->so = NULL; } /* If we are an embryo, take ourselves out of the parent's list */ if (priv->flags & KSF_EMBRYONIC) { LIST_REMOVE(priv, siblings); priv->flags &= ~KSF_EMBRYONIC; } /* Remove any embryonic children we have */ while (!LIST_EMPTY(&priv->embryos)) { embryo = LIST_FIRST(&priv->embryos); ng_rmnode_self(embryo->node); } /* Take down netgraph node */ bzero(priv, sizeof(*priv)); free(priv, M_NETGRAPH_KSOCKET); NG_NODE_SET_PRIVATE(node, NULL); NG_NODE_UNREF(node); /* let the node escape */ return (0); }