* Give our OK for a hook to be added. The hook name is of the * form " / / " 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. */
| 537 | * the hook closes the socket and destroys the node as well. |
| 538 | */ |
| 539 | static int |
| 540 | ng_ksocket_newhook(node_p node, hook_p hook, const char *name0) |
| 541 | { |
| 542 | struct thread *td = curthread; /* XXX broken */ |
| 543 | const priv_p priv = NG_NODE_PRIVATE(node); |
| 544 | char *s1, *s2, name[NG_HOOKSIZ]; |
| 545 | int family, type, protocol, error; |
| 546 | |
| 547 | /* Check if we're already connected */ |
| 548 | if (priv->hook != NULL) |
| 549 | return (EISCONN); |
| 550 | |
| 551 | if (priv->flags & KSF_CLONED) { |
| 552 | if (priv->flags & KSF_EMBRYONIC) { |
| 553 | /* Remove ourselves from our parent's embryo list */ |
| 554 | LIST_REMOVE(priv, siblings); |
| 555 | priv->flags &= ~KSF_EMBRYONIC; |
| 556 | } |
| 557 | } else { |
| 558 | /* Extract family, type, and protocol from hook name */ |
| 559 | snprintf(name, sizeof(name), "%s", name0); |
| 560 | s1 = name; |
| 561 | if ((s2 = strchr(s1, '/')) == NULL) |
| 562 | return (EINVAL); |
| 563 | *s2++ = '\0'; |
| 564 | family = ng_ksocket_parse(ng_ksocket_families, s1, 0); |
| 565 | if (family == -1) |
| 566 | return (EINVAL); |
| 567 | s1 = s2; |
| 568 | if ((s2 = strchr(s1, '/')) == NULL) |
| 569 | return (EINVAL); |
| 570 | *s2++ = '\0'; |
| 571 | type = ng_ksocket_parse(ng_ksocket_types, s1, 0); |
| 572 | if (type == -1) |
| 573 | return (EINVAL); |
| 574 | s1 = s2; |
| 575 | protocol = ng_ksocket_parse(ng_ksocket_protos, s1, family); |
| 576 | if (protocol == -1) |
| 577 | return (EINVAL); |
| 578 | |
| 579 | /* Create the socket */ |
| 580 | error = socreate(family, &priv->so, type, protocol, |
| 581 | td->td_ucred, td); |
| 582 | if (error != 0) |
| 583 | return (error); |
| 584 | |
| 585 | /* XXX call soreserve() ? */ |
| 586 | } |
| 587 | |
| 588 | /* OK */ |
| 589 | priv->hook = hook; |
| 590 | |
| 591 | /* |
| 592 | * In case of misconfigured routing a packet may reenter |
| 593 | * ksocket node recursively. Decouple stack to avoid possible |
| 594 | * panics about sleeping with locks held. |
| 595 | */ |
| 596 | NG_HOOK_FORCE_QUEUE(hook); |
nothing calls this directly
no test coverage detected