53#include <sys/domain.h>
55#include <sys/kernel.h>
56#include <sys/linker.h>
58#include <sys/malloc.h>
64#include <sys/protosw.h>
66#include <sys/socket.h>
67#include <sys/socketvar.h>
68#include <sys/syscallsubr.h>
69#include <sys/sysctl.h>
78#ifdef NG_SEPARATE_MALLOC
82#define M_NETGRAPH_PATH M_NETGRAPH
83#define M_NETGRAPH_SOCK M_NETGRAPH
129static int ng_bind(
struct sockaddr *nam,
struct ngpcb *pcbp);
156 &
ngpdg_recvspace , 0,
"Maximum space for incoming Netgraph datagrams");
161static struct mtx ngsocketlist_mtx;
163#define sotongpcb(so) ((struct ngpcb *)(so)->so_pcb)
171 LIST_ENTRY(hookpriv) next;
189#define NGS_FLAG_NOLINGER 1
201 error = priv_check(td, PRIV_NETGRAPH_CONTROL);
214 KASSERT(pcbp != NULL, (
"ngc_detach: pcbp == NULL"));
219ngc_send(
struct socket *so,
int flags,
struct mbuf *m,
struct sockaddr *addr,
220 struct mbuf *
control,
struct thread *td)
239 error = EDESTADDRREQ;
254 bcopy(sap->
sg_data, path, len);
261 for (len = 0, m0 = m; m0 != NULL; m0 = m0->m_next)
268 msg = malloc(len + 1, M_NETGRAPH_MSG, M_WAITOK);
269 m_copydata(m, 0, len, (
char *)msg);
272 free(msg, M_NETGRAPH_MSG);
292 snprintf(filename,
sizeof(filename),
"ng_%s",
294 error = kern_kldload(curthread, filename, &fileid);
296 free(msg, M_NETGRAPH_MSG);
302 free(msg, M_NETGRAPH_MSG);
303 (void)kern_kldunload(curthread, fileid,
304 LINKER_UNLOAD_NORMAL);
315 printf(
"ng_address_path: errx=%d\n", error);
321 printf(
"[%x]:<---------[socket]: c=<%d>cmd=%x(%s) f=%x #%d (%s)\n",
339 bzero(&apply,
sizeof(apply));
342 item->
apply = &apply;
347 mtx_lock(&
priv->mtx);
348 if (
priv->error == -1)
349 msleep(
priv, &
priv->mtx, 0,
"ngsock", 0);
350 mtx_unlock(&
priv->mtx);
351 KASSERT(
priv->error != -1,
352 (
"ng_socket: priv->error wasn't updated"));
366ngc_bind(
struct socket *so,
struct sockaddr *nam,
struct thread *td)
376ngc_connect(
struct socket *so,
struct sockaddr *nam,
struct thread *td)
382 printf(
"program tried to connect control socket to remote node\n");
405 KASSERT(pcbp != NULL, (
"ngd_detach: pcbp == NULL"));
410ngd_send(
struct socket *so,
int flags,
struct mbuf *m,
struct sockaddr *addr,
411 struct mbuf *
control,
struct thread *td)
413 struct epoch_tracker et;
421 if ((pcbp == NULL) || (
control != NULL)) {
445 if ((sap == NULL) || (len <= 0) || (*sap->
sg_data ==
'\0')) {
447 error = EDESTADDRREQ;
465 bcopy(sap->
sg_data, hookname, len);
466 hookname[len] =
'\0';
471 error = EHOSTUNREACH;
492ngd_connect(
struct socket *so,
struct sockaddr *nam,
struct thread *td)
513 if ((pcbp == NULL) || (pcbp->
sockdata == NULL))
519 sg = malloc(
sg_len, M_SONAME, M_WAITOK | M_ZERO);
532 *addr = (
struct sockaddr *)sg;
577 mtx_init(&
priv->mtx,
"ng_socket", NULL, MTX_DEF);
580 priv->ctlsock = pcbp;
616 pcbp = malloc(
sizeof(
struct ngpcb), M_PCB, M_WAITOK | M_ZERO);
620 so->so_pcb = (caddr_t)pcbp;
624 mtx_lock(&ngsocketlist_mtx);
625 LIST_INSERT_HEAD(&ngsocklist, pcbp, socks);
626 mtx_unlock(&ngsocketlist_mtx);
642 mtx_lock(&
priv->mtx);
646 priv->ctlsock = NULL;
649 priv->datasock = NULL;
652 panic(
"%s", __func__);
661 mtx_lock(&ngsocketlist_mtx);
662 LIST_REMOVE(pcbp, socks);
663 mtx_unlock(&ngsocketlist_mtx);
673 mtx_assert(&
priv->mtx, MA_OWNED);
677 if (
priv->refs == 0) {
678 mtx_destroy(&
priv->mtx);
684 if ((
priv->refs == 1) && (
priv->node != NULL)) {
688 mtx_unlock(&
priv->mtx);
692 mtx_unlock(&
priv->mtx);
735 if (
priv->datasock != NULL) {
744 mtx_lock(&
priv->mtx);
745 priv->datasock = pcbp;
749 mtx_unlock(&
priv->mtx);
804 LIST_FOREACH(hook, &node->nd_hooks, hk_hooks) {
807 LIST_REMOVE(hp, next);
810 LIST_INSERT_HEAD(&
new[h], hp, next);
835 h = hash32_str(
name, HASHINIT) &
priv->hmask;
836 LIST_INSERT_HEAD(&
priv->hash[h], hp, next);
851 if ((
priv->datasock) && (
priv->datasock->ng_socket)) {
853 priv->datasock->ng_socket->so_state |= SS_ISCONNECTED;
855 priv->datasock->ng_socket->so_state &= ~SS_ISCONNECTED;
875 hook = LIST_FIRST(&node->nd_hooks);
883 h = hash32_str(
name, HASHINIT) &
priv->hmask;
885 LIST_FOREACH(hp, &
priv->hash[h], next)
916 mtx_lock(&
priv->mtx);
917 pcbp =
priv->ctlsock;
924 mtx_unlock(&
priv->mtx);
930 SOCKBUF_LOCK(&so->so_rcv);
933 mtx_unlock(&
priv->mtx);
936 printf(
"[%x]:---------->[socket]: c=<%d>cmd=%x(%s) f=%x #%d\n",
951 priv->flags &= ~NGS_FLAG_NOLINGER;
956 SOCKBUF_UNLOCK(&so->so_rcv);
964 bzero(&addr,
sizeof(addr));
965 addr.
sg_len =
sizeof(addr);
969 if (addrlen < 0 || addrlen >
sizeof(addr.
sg_data)) {
970 SOCKBUF_UNLOCK(&so->so_rcv);
971 printf(
"%s: snprintf([%x]) failed - %d\n", __func__, retaddr,
988 SOCKBUF_UNLOCK(&so->so_rcv);
994 if (sbappendaddr_locked(&so->so_rcv, (
struct sockaddr *)&addr, m,
996 soroverflow_locked(so);
1003 sorwakeup_locked(so);
1015 struct ngpcb *
const pcbp =
priv->datasock;
1035 addr->
sg_len = addrlen + 3;
1038 addr->
sg_data[addrlen] =
'\0';
1041 SOCKBUF_LOCK(&so->so_rcv);
1042 if (sbappendaddr_locked(&so->so_rcv, (
struct sockaddr *)addr, m,
1044 SOCKBUF_UNLOCK(&so->so_rcv);
1051 sorwakeup_locked(so);
1068 LIST_REMOVE(hp, next);
1071 if ((
priv->datasock) && (
priv->datasock->ng_socket)) {
1073 priv->datasock->ng_socket->so_state |= SS_ISCONNECTED;
1075 priv->datasock->ng_socket->so_state &= ~SS_ISCONNECTED;
1094 struct ngpcb *dpcbp, *pcbp;
1096 mtx_lock(&
priv->mtx);
1097 dpcbp =
priv->datasock;
1098 pcbp =
priv->ctlsock;
1119 mtx_lock(&
priv->mtx);
1122 mtx_unlock(&
priv->mtx);
1144 .pru_peeraddr = NULL,
1146 .pru_shutdown = NULL,
1158 .pru_peeraddr = NULL,
1160 .pru_shutdown = NULL,
1173 .pr_type = SOCK_DGRAM,
1176 .pr_flags = PR_ATOMIC | PR_ADDR ,
1180 .pr_type = SOCK_DGRAM,
1183 .pr_flags = PR_ATOMIC | PR_ADDR,
1189 .dom_family = AF_NETGRAPH,
1190 .dom_name =
"netgraph",
1191 .dom_protosw =
ngsw,
1192 .dom_protoswNPROTOSW = &
ngsw[nitems(
ngsw)]
1206 mtx_init(&ngsocketlist_mtx,
"ng_socketlist", NULL, MTX_DEF);
1210 if (!LIST_EMPTY(&ngsocklist)) {
1228SYSCTL_INT(_net_graph, OID_AUTO, family, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, AF_NETGRAPH,
"");
int ng_connect_t(hook_p hook)
struct ng_type * ng_findtype(const char *type)
#define NG_HOOK_NODE(hook)
hook_p ng_findhook_t(node_p node, const char *name)
int ng_rcvmsg_t(node_p node, item_p item, hook_p lasthook)
#define NG_FWD_ITEM_HOOK(error, item, hook)
int ng_disconnect_t(hook_p hook)
#define NG_NODE_SET_PRIVATE(node, val)
#define NG_NODE_IS_VALID(node)
#define NG_NODE_HAS_NAME(node)
#define NG_NODE_UNREF(node)
#define NG_NODE_NAME(node)
#define NG_HOOK_SET_PRIVATE(hook, val)
int ng_rmnode_self(node_p here)
item_p ng_package_data(struct mbuf *m, int flags)
int ng_address_path(node_p here, item_p item, const char *address, ng_ID_t raddr)
int ng_rcvdata_t(hook_p hook, item_p item)
int ng_shutdown_t(node_p node)
#define NG_HOOK_NAME(hook)
#define NG_FREE_ITEM(item)
int ng_snd_item(item_p item, int queue)
int ng_make_node_common(struct ng_type *typep, node_p *nodep)
int ng_name_node(node_p node, const char *name)
int ng_constructor_t(node_p node)
item_p ng_package_msg(struct ng_mesg *msg, int flags)
#define NG_NODE_NUMHOOKS(node)
#define NGI_GET_MSG(i, m)
#define NG_NODE_REF(node)
#define NG_NODE_PRIVATE(node)
int ng_newhook_t(node_p node, hook_p hook, const char *name)
hook_p ng_findhook(node_p node, const char *name)
#define NG_HOOK_PRIVATE(hook)
MALLOC_DEFINE(M_NG_CCATM, "ng_ccatm", "netgraph uni api node")
#define NGM_GENERIC_COOKIE
static void ng_socket_item_applied(void *context, int error)
#define NGS_FLAG_NOLINGER
static ng_connect_t ngs_connect
static int ngd_attach(struct socket *so, int proto, struct thread *td)
static int ng_attach_common(struct socket *so, int type)
static u_long ngpdg_recvspace
static ng_newhook_t ngs_newhook
static int ng_bind(struct sockaddr *nam, struct ngpcb *pcbp)
static void ngs_rehash(node_p node)
static int ngc_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
static void ngd_detach(struct socket *so)
static ng_rcvdata_t ngs_rcvdata
static SYSCTL_NODE(_net_graph, OID_AUTO, data, CTLFLAG_RW|CTLFLAG_MPSAFE, 0, "DATA")
SYSCTL_INT(_net_graph, OID_AUTO, family, CTLFLAG_RD, SYSCTL_NULL_INT_PTR, AF_NETGRAPH, "")
static ng_shutdown_t ngs_shutdown
static int dummy_disconnect(struct socket *so)
static int ngc_attach(struct socket *so, int proto, struct thread *td)
static int ngc_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
static int ngc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, struct mbuf *control, struct thread *td)
static int ng_attach_cntl(struct socket *so)
static struct ng_type typestruct
static struct protosw ngsw[]
static ng_constructor_t ngs_constructor
static int ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp)
static int ng_getsockaddr(struct socket *so, struct sockaddr **addr)
static ng_findhook_t ngs_findhook
NETGRAPH_INIT_ORDERED(socket, &typestruct, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY)
static void ng_socket_free_priv(struct ngsock *priv)
static void ng_detach_common(struct ngpcb *pcbp, int type)
static ng_disconnect_t ngs_disconnect
static int ngs_mod_event(module_t mod, int event, void *data)
static int ngd_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr, struct mbuf *control, struct thread *td)
SYSCTL_ULONG(_net_graph, OID_AUTO, maxdgram, CTLFLAG_RW, &ngpdg_sendspace, 0, "Maximum outgoing Netgraph datagram size")
static u_long ngpdg_sendspace
static struct pr_usrreqs ngd_usrreqs
static void ngc_detach(struct socket *so)
static struct pr_usrreqs ngc_usrreqs
static int ngd_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
static ng_rcvmsg_t ngs_rcvmsg
static int ng_attach_data(struct socket *so)
#define NG_SOCKET_NODE_TYPE
#define NGM_SOCKET_COOKIE
struct ng_apply_info * apply
u_char cmdstr[NG_CMDSTRSIZ]
struct ng_mesg::ng_msghdr header
struct socket * ng_socket