/* * 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); }
/* * 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_udbp_connect(hook_p hook) { /* probably not at splnet, force outward queueing */ NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook)); /* be really amiable and just say "YUP that's OK by me! " */ return (0); }
static int ng_ubt_connect(hook_p hook) { struct ubt_softc *sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook)); UBT_NG_LOCK(sc); ubt_task_schedule(sc, UBT_FLAG_T_START_ALL); UBT_NG_UNLOCK(sc); return (0); } /* ng_ubt_connect */
static int ng_bt3c_connect(hook_p hook) { bt3c_softc_p sc = (bt3c_softc_p) NG_NODE_PRIVATE(NG_HOOK_NODE(hook)); if (hook != sc->hook) { sc->hook = NULL; return (EINVAL); } /* set the hook into queueing mode (for incoming (from wire) packets) */ NG_HOOK_FORCE_QUEUE(NG_HOOK_PEER(hook)); return (0); } /* ng_bt3c_connect */
/* * Give our OK for a hook to be added. The hook name is of the * form "<family>/<type>/<proto>" where the three components may * be decimal numbers or else aliases from the above lists. * * Connecting a hook amounts to opening the socket. Disconnecting * the hook closes the socket and destroys the node as well. */ static int ng_ksocket_newhook(node_p node, hook_p hook, const char *name0) { struct thread *td = curthread; /* XXX broken */ const priv_p priv = NG_NODE_PRIVATE(node); char *s1, *s2, name[NG_HOOKSIZ]; int family, type, protocol, error; /* Check if we're already connected */ if (priv->hook != NULL) return (EISCONN); if (priv->flags & KSF_CLONED) { if (priv->flags & KSF_EMBRYONIC) { /* Remove ourselves from our parent's embryo list */ LIST_REMOVE(priv, siblings); priv->flags &= ~KSF_EMBRYONIC; } } else { /* Extract family, type, and protocol from hook name */ snprintf(name, sizeof(name), "%s", name0); s1 = name; if ((s2 = index(s1, '/')) == NULL) return (EINVAL); *s2++ = '\0'; family = ng_ksocket_parse(ng_ksocket_families, s1, 0); if (family == -1) return (EINVAL); s1 = s2; if ((s2 = index(s1, '/')) == NULL) return (EINVAL); *s2++ = '\0'; type = ng_ksocket_parse(ng_ksocket_types, s1, 0); if (type == -1) return (EINVAL); s1 = s2; protocol = ng_ksocket_parse(ng_ksocket_protos, s1, family); if (protocol == -1) return (EINVAL); /* Create the socket */ error = socreate(family, &priv->so, type, protocol, td->td_ucred, td); if (error != 0) return (error); /* XXX call soreserve() ? */ } /* OK */ priv->hook = hook; /* * In case of misconfigured routing a packet may reenter * ksocket node recursively. Decouple stack to avoid possible * panics about sleeping with locks held. */ NG_HOOK_FORCE_QUEUE(hook); return(0); }