xref: /freebsd-14.2/sys/netgraph/ng_socket.c (revision 4b2b8a37)
1 /*
2  * ng_socket.c
3  */
4 
5 /*-
6  * Copyright (c) 1996-1999 Whistle Communications, Inc.
7  * All rights reserved.
8  *
9  * Subject to the following obligations and disclaimer of warranty, use and
10  * redistribution of this software, in source or object code forms, with or
11  * without modifications are expressly permitted by Whistle Communications;
12  * provided, however, that:
13  * 1. Any and all reproductions of the source or object code must include the
14  *    copyright notice above and the following disclaimer of warranties; and
15  * 2. No rights are granted, in any manner or form, to use Whistle
16  *    Communications, Inc. trademarks, including the mark "WHISTLE
17  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
18  *    such appears in the above copyright notice or in the software.
19  *
20  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
21  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
22  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
23  * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
25  * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
26  * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
27  * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
28  * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
29  * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
30  * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31  * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
32  * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36  * OF SUCH DAMAGE.
37  *
38  * Author: Julian Elischer <[email protected]>
39  *
40  * $FreeBSD$
41  * $Whistle: ng_socket.c,v 1.28 1999/11/01 09:24:52 julian Exp $
42  */
43 
44 /*
45  * Netgraph socket nodes
46  *
47  * There are two types of netgraph sockets, control and data.
48  * Control sockets have a netgraph node, but data sockets are
49  * parasitic on control sockets, and have no node of their own.
50  */
51 
52 #include <sys/param.h>
53 #include <sys/domain.h>
54 #include <sys/kernel.h>
55 #include <sys/linker.h>
56 #include <sys/lock.h>
57 #include <sys/malloc.h>
58 #include <sys/mbuf.h>
59 #include <sys/mutex.h>
60 #include <sys/priv.h>
61 #include <sys/protosw.h>
62 #include <sys/queue.h>
63 #include <sys/socket.h>
64 #include <sys/socketvar.h>
65 #include <sys/syscallsubr.h>
66 #include <sys/sysctl.h>
67 
68 #include <net/vnet.h>
69 
70 #include <netgraph/ng_message.h>
71 #include <netgraph/netgraph.h>
72 #include <netgraph/ng_socketvar.h>
73 #include <netgraph/ng_socket.h>
74 
75 #ifdef NG_SEPARATE_MALLOC
76 static MALLOC_DEFINE(M_NETGRAPH_PATH, "netgraph_path", "netgraph path info");
77 static MALLOC_DEFINE(M_NETGRAPH_SOCK, "netgraph_sock", "netgraph socket info");
78 #else
79 #define M_NETGRAPH_PATH M_NETGRAPH
80 #define M_NETGRAPH_SOCK M_NETGRAPH
81 #endif
82 
83 /*
84  * It's Ascii-art time!
85  *   +-------------+   +-------------+
86  *   |socket  (ctl)|   |socket (data)|
87  *   +-------------+   +-------------+
88  *          ^                 ^
89  *          |                 |
90  *          v                 v
91  *    +-----------+     +-----------+
92  *    |pcb   (ctl)|     |pcb  (data)|
93  *    +-----------+     +-----------+
94  *          ^                 ^
95  *          |                 |
96  *          v                 v
97  *      +--------------------------+
98  *      |   Socket type private    |
99  *      |       data               |
100  *      +--------------------------+
101  *                   ^
102  *                   |
103  *                   v
104  *           +----------------+
105  *           | struct ng_node |
106  *           +----------------+
107  */
108 
109 /* Netgraph node methods */
110 static ng_constructor_t	ngs_constructor;
111 static ng_rcvmsg_t	ngs_rcvmsg;
112 static ng_shutdown_t	ngs_shutdown;
113 static ng_newhook_t	ngs_newhook;
114 static ng_connect_t	ngs_connect;
115 static ng_rcvdata_t	ngs_rcvdata;
116 static ng_disconnect_t	ngs_disconnect;
117 
118 /* Internal methods */
119 static int	ng_attach_data(struct socket *so);
120 static int	ng_attach_cntl(struct socket *so);
121 static int	ng_attach_common(struct socket *so, int type);
122 static void	ng_detach_common(struct ngpcb *pcbp, int type);
123 static void	ng_socket_free_priv(struct ngsock *priv);
124 static int	ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp);
125 static int	ng_bind(struct sockaddr *nam, struct ngpcb *pcbp);
126 
127 static int	ngs_mod_event(module_t mod, int event, void *data);
128 static void	ng_socket_item_applied(void *context, int error);
129 
130 /* Netgraph type descriptor */
131 static struct ng_type typestruct = {
132 	.version =	NG_ABI_VERSION,
133 	.name =		NG_SOCKET_NODE_TYPE,
134 	.mod_event =	ngs_mod_event,
135 	.constructor =	ngs_constructor,
136 	.rcvmsg =	ngs_rcvmsg,
137 	.shutdown =	ngs_shutdown,
138 	.newhook =	ngs_newhook,
139 	.connect =	ngs_connect,
140 	.rcvdata =	ngs_rcvdata,
141 	.disconnect =	ngs_disconnect,
142 };
143 NETGRAPH_INIT_ORDERED(socket, &typestruct, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
144 
145 /* Buffer space */
146 static u_long ngpdg_sendspace = 20 * 1024;	/* really max datagram size */
147 SYSCTL_ULONG(_net_graph, OID_AUTO, maxdgram, CTLFLAG_RW,
148     &ngpdg_sendspace , 0, "Maximum outgoing Netgraph datagram size");
149 static u_long ngpdg_recvspace = 20 * 1024;
150 SYSCTL_ULONG(_net_graph, OID_AUTO, recvspace, CTLFLAG_RW,
151     &ngpdg_recvspace , 0, "Maximum space for incoming Netgraph datagrams");
152 
153 /* List of all sockets (for netstat -f netgraph) */
154 static LIST_HEAD(, ngpcb) ngsocklist;
155 
156 static struct mtx	ngsocketlist_mtx;
157 
158 #define sotongpcb(so) ((struct ngpcb *)(so)->so_pcb)
159 
160 /* If getting unexplained errors returned, set this to "kdb_enter("X"); */
161 #ifndef TRAP_ERROR
162 #define TRAP_ERROR
163 #endif
164 
165 /* Per-node private data */
166 struct ngsock {
167 	struct ng_node	*node;		/* the associated netgraph node */
168 	struct ngpcb	*datasock;	/* optional data socket */
169 	struct ngpcb	*ctlsock;	/* optional control socket */
170 	int	flags;
171 	int	refs;
172 	struct mtx	mtx;		/* mtx to wait on */
173 	int		error;		/* place to store error */
174 };
175 
176 #define	NGS_FLAG_NOLINGER	1	/* close with last hook */
177 
178 /***************************************************************
179 	Control sockets
180 ***************************************************************/
181 
182 static int
183 ngc_attach(struct socket *so, int proto, struct thread *td)
184 {
185 	struct ngpcb *const pcbp = sotongpcb(so);
186 	int error;
187 
188 	error = priv_check(td, PRIV_NETGRAPH_CONTROL);
189 	if (error)
190 		return (error);
191 	if (pcbp != NULL)
192 		return (EISCONN);
193 	return (ng_attach_cntl(so));
194 }
195 
196 static void
197 ngc_detach(struct socket *so)
198 {
199 	struct ngpcb *const pcbp = sotongpcb(so);
200 
201 	KASSERT(pcbp != NULL, ("ngc_detach: pcbp == NULL"));
202 	ng_detach_common(pcbp, NG_CONTROL);
203 }
204 
205 static int
206 ngc_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
207 	 struct mbuf *control, struct thread *td)
208 {
209 	struct ngpcb *const pcbp = sotongpcb(so);
210 	struct ngsock *const priv = NG_NODE_PRIVATE(pcbp->sockdata->node);
211 	struct sockaddr_ng *const sap = (struct sockaddr_ng *) addr;
212 	struct ng_mesg *msg;
213 	struct mbuf *m0;
214 	item_p item;
215 	char *path = NULL;
216 	int len, error = 0;
217 	struct ng_apply_info apply;
218 
219 	if (control) {
220 		error = EINVAL;
221 		goto release;
222 	}
223 
224 	/* Require destination as there may be >= 1 hooks on this node. */
225 	if (addr == NULL) {
226 		error = EDESTADDRREQ;
227 		goto release;
228 	}
229 
230 	/*
231 	 * Allocate an expendable buffer for the path, chop off
232 	 * the sockaddr header, and make sure it's NUL terminated.
233 	 */
234 	len = sap->sg_len - 2;
235 	path = malloc(len + 1, M_NETGRAPH_PATH, M_WAITOK);
236 	bcopy(sap->sg_data, path, len);
237 	path[len] = '\0';
238 
239 	/*
240 	 * Move the actual message out of mbufs into a linear buffer.
241 	 * Start by adding up the size of the data. (could use mh_len?)
242 	 */
243 	for (len = 0, m0 = m; m0 != NULL; m0 = m0->m_next)
244 		len += m0->m_len;
245 
246 	/*
247 	 * Move the data into a linear buffer as well.
248 	 * Messages are not delivered in mbufs.
249 	 */
250 	msg = malloc(len + 1, M_NETGRAPH_MSG, M_WAITOK);
251 	m_copydata(m, 0, len, (char *)msg);
252 
253 	if (msg->header.version != NG_VERSION) {
254 		free(msg, M_NETGRAPH_MSG);
255 		error = EINVAL;
256 		goto release;
257 	}
258 
259 	/*
260 	 * Hack alert!
261 	 * We look into the message and if it mkpeers a node of unknown type, we
262 	 * try to load it. We need to do this now, in syscall thread, because if
263 	 * message gets queued and applied later we will get panic.
264 	 */
265 	if (msg->header.typecookie == NGM_GENERIC_COOKIE &&
266 	    msg->header.cmd == NGM_MKPEER) {
267 		struct ngm_mkpeer *const mkp = (struct ngm_mkpeer *) msg->data;
268 
269 		if (ng_findtype(mkp->type) == NULL) {
270 			char filename[NG_TYPESIZ + 3];
271 			int fileid;
272 
273 			/* Not found, try to load it as a loadable module. */
274 			snprintf(filename, sizeof(filename), "ng_%s",
275 			    mkp->type);
276 			error = kern_kldload(curthread, filename, &fileid);
277 			if (error != 0) {
278 				free(msg, M_NETGRAPH_MSG);
279 				goto release;
280 			}
281 
282 			/* See if type has been loaded successfully. */
283 			if (ng_findtype(mkp->type) == NULL) {
284 				free(msg, M_NETGRAPH_MSG);
285 				(void)kern_kldunload(curthread, fileid,
286 				    LINKER_UNLOAD_NORMAL);
287 				error =  ENXIO;
288 				goto release;
289 			}
290 		}
291 	}
292 
293 	item = ng_package_msg(msg, M_WAITOK);
294 	if ((error = ng_address_path((pcbp->sockdata->node), item, path, 0))
295 	    != 0) {
296 #ifdef TRACE_MESSAGES
297 		printf("ng_address_path: errx=%d\n", error);
298 #endif
299 		goto release;
300 	}
301 
302 #ifdef TRACE_MESSAGES
303 	printf("[%x]:<---------[socket]: c=<%d>cmd=%x(%s) f=%x #%d (%s)\n",
304 		item->el_dest->nd_ID,
305 		msg->header.typecookie,
306 		msg->header.cmd,
307 		msg->header.cmdstr,
308 		msg->header.flags,
309 		msg->header.token,
310 		item->el_dest->nd_type->name);
311 #endif
312 	SAVE_LINE(item);
313 	/*
314 	 * We do not want to return from syscall until the item
315 	 * is processed by destination node. We register callback
316 	 * on the item, which will update priv->error when item
317 	 * was applied.
318 	 * If ng_snd_item() has queued item, we sleep until
319 	 * callback wakes us up.
320 	 */
321 	bzero(&apply, sizeof(apply));
322 	apply.apply = ng_socket_item_applied;
323 	apply.context = priv;
324 	item->apply = &apply;
325 	priv->error = -1;
326 
327 	error = ng_snd_item(item, 0);
328 
329 	mtx_lock(&priv->mtx);
330 	if (priv->error == -1)
331 		msleep(priv, &priv->mtx, 0, "ngsock", 0);
332 	mtx_unlock(&priv->mtx);
333 	KASSERT(priv->error != -1,
334 	    ("ng_socket: priv->error wasn't updated"));
335 	error = priv->error;
336 
337 release:
338 	if (path != NULL)
339 		free(path, M_NETGRAPH_PATH);
340 	if (control != NULL)
341 		m_freem(control);
342 	if (m != NULL)
343 		m_freem(m);
344 	return (error);
345 }
346 
347 static int
348 ngc_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
349 {
350 	struct ngpcb *const pcbp = sotongpcb(so);
351 
352 	if (pcbp == 0)
353 		return (EINVAL);
354 	return (ng_bind(nam, pcbp));
355 }
356 
357 static int
358 ngc_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
359 {
360 	/*
361 	 * At this time refuse to do this.. it used to
362 	 * do something but it was undocumented and not used.
363 	 */
364 	printf("program tried to connect control socket to remote node\n");
365 	return (EINVAL);
366 }
367 
368 /***************************************************************
369 	Data sockets
370 ***************************************************************/
371 
372 static int
373 ngd_attach(struct socket *so, int proto, struct thread *td)
374 {
375 	struct ngpcb *const pcbp = sotongpcb(so);
376 
377 	if (pcbp != NULL)
378 		return (EISCONN);
379 	return (ng_attach_data(so));
380 }
381 
382 static void
383 ngd_detach(struct socket *so)
384 {
385 	struct ngpcb *const pcbp = sotongpcb(so);
386 
387 	KASSERT(pcbp != NULL, ("ngd_detach: pcbp == NULL"));
388 	ng_detach_common(pcbp, NG_DATA);
389 }
390 
391 static int
392 ngd_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
393 	 struct mbuf *control, struct thread *td)
394 {
395 	struct ngpcb *const pcbp = sotongpcb(so);
396 	struct sockaddr_ng *const sap = (struct sockaddr_ng *) addr;
397 	int	len, error;
398 	hook_p  hook = NULL;
399 	char	hookname[NG_HOOKSIZ];
400 
401 	if ((pcbp == NULL) || (control != NULL)) {
402 		error = EINVAL;
403 		goto release;
404 	}
405 	if (pcbp->sockdata == NULL) {
406 		error = ENOTCONN;
407 		goto release;
408 	}
409 
410 	if (sap == NULL)
411 		len = 0;		/* Make compiler happy. */
412 	else
413 		len = sap->sg_len - 2;
414 
415 	/*
416 	 * If the user used any of these ways to not specify an address
417 	 * then handle specially.
418 	 */
419 	if ((sap == NULL) || (len <= 0) || (*sap->sg_data == '\0')) {
420 		if (NG_NODE_NUMHOOKS(pcbp->sockdata->node) != 1) {
421 			error = EDESTADDRREQ;
422 			goto release;
423 		}
424 		/*
425 		 * If exactly one hook exists, just use it.
426 		 * Special case to allow write(2) to work on an ng_socket.
427 		 */
428 		hook = LIST_FIRST(&pcbp->sockdata->node->nd_hooks);
429 	} else {
430 		if (len >= NG_HOOKSIZ) {
431 			error = EINVAL;
432 			goto release;
433 		}
434 
435 		/*
436 		 * chop off the sockaddr header, and make sure it's NUL
437 		 * terminated
438 		 */
439 		bcopy(sap->sg_data, hookname, len);
440 		hookname[len] = '\0';
441 
442 		/* Find the correct hook from 'hookname' */
443 		hook = ng_findhook(pcbp->sockdata->node, hookname);
444 		if (hook == NULL) {
445 			error = EHOSTUNREACH;
446 			goto release;
447 		}
448 	}
449 
450 	/* Send data. */
451 	NG_SEND_DATA_FLAGS(error, hook, m, NG_WAITOK);
452 
453 release:
454 	if (control != NULL)
455 		m_freem(control);
456 	if (m != NULL)
457 		m_freem(m);
458 	return (error);
459 }
460 
461 static int
462 ngd_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
463 {
464 	struct ngpcb *const pcbp = sotongpcb(so);
465 
466 	if (pcbp == 0)
467 		return (EINVAL);
468 	return (ng_connect_data(nam, pcbp));
469 }
470 
471 /*
472  * Used for both data and control sockets
473  */
474 static int
475 ng_getsockaddr(struct socket *so, struct sockaddr **addr)
476 {
477 	struct ngpcb *pcbp;
478 	struct sockaddr_ng *sg;
479 	int sg_len;
480 	int error = 0;
481 
482 	/* Why isn't sg_data a `char[1]' ? :-( */
483 	sg_len = sizeof(struct sockaddr_ng) - sizeof(sg->sg_data) + 1;
484 
485 	pcbp = sotongpcb(so);
486 	if ((pcbp == NULL) || (pcbp->sockdata == NULL))
487 		/* XXXGL: can this still happen? */
488 		return (EINVAL);
489 
490 	mtx_lock(&pcbp->sockdata->mtx);
491 	if (pcbp->sockdata->node != NULL) {
492 		node_p node = pcbp->sockdata->node;
493 		int namelen = 0;	/* silence compiler! */
494 
495 		if (NG_NODE_HAS_NAME(node))
496 			sg_len += namelen = strlen(NG_NODE_NAME(node));
497 
498 		sg = malloc(sg_len, M_SONAME, M_WAITOK | M_ZERO);
499 
500 		if (NG_NODE_HAS_NAME(node))
501 			bcopy(NG_NODE_NAME(node), sg->sg_data, namelen);
502 
503 		sg->sg_len = sg_len;
504 		sg->sg_family = AF_NETGRAPH;
505 		*addr = (struct sockaddr *)sg;
506 		mtx_unlock(&pcbp->sockdata->mtx);
507 	} else {
508 		mtx_unlock(&pcbp->sockdata->mtx);
509 		error = EINVAL;
510 	}
511 
512 	return (error);
513 }
514 
515 /*
516  * Attach a socket to it's protocol specific partner.
517  * For a control socket, actually create a netgraph node and attach
518  * to it as well.
519  */
520 
521 static int
522 ng_attach_cntl(struct socket *so)
523 {
524 	struct ngsock *priv;
525 	struct ngpcb *pcbp;
526 	node_p node;
527 	int error;
528 
529 	/* Setup protocol control block */
530 	if ((error = ng_attach_common(so, NG_CONTROL)) != 0)
531 		return (error);
532 	pcbp = sotongpcb(so);
533 
534 	/* Make the generic node components */
535 	if ((error = ng_make_node_common(&typestruct, &node)) != 0) {
536 		ng_detach_common(pcbp, NG_CONTROL);
537 		return (error);
538 	}
539 
540 	/* Allocate node private info */
541 	priv = malloc(sizeof(*priv), M_NETGRAPH_SOCK, M_WAITOK | M_ZERO);
542 
543 	/* Initialize mutex. */
544 	mtx_init(&priv->mtx, "ng_socket", NULL, MTX_DEF);
545 
546 	/* Link the pcb the private data. */
547 	priv->ctlsock = pcbp;
548 	pcbp->sockdata = priv;
549 	priv->refs++;
550 	priv->node = node;
551 	pcbp->node_id = node->nd_ID;	/* hint for netstat(1) */
552 
553 	/* Link the node and the private data. */
554 	NG_NODE_SET_PRIVATE(priv->node, priv);
555 	NG_NODE_REF(priv->node);
556 	priv->refs++;
557 
558 	return (0);
559 }
560 
561 static int
562 ng_attach_data(struct socket *so)
563 {
564 	return (ng_attach_common(so, NG_DATA));
565 }
566 
567 /*
568  * Set up a socket protocol control block.
569  * This code is shared between control and data sockets.
570  */
571 static int
572 ng_attach_common(struct socket *so, int type)
573 {
574 	struct ngpcb *pcbp;
575 	int error;
576 
577 	/* Standard socket setup stuff. */
578 	error = soreserve(so, ngpdg_sendspace, ngpdg_recvspace);
579 	if (error)
580 		return (error);
581 
582 	/* Allocate the pcb. */
583 	pcbp = malloc(sizeof(struct ngpcb), M_PCB, M_WAITOK | M_ZERO);
584 	pcbp->type = type;
585 
586 	/* Link the pcb and the socket. */
587 	so->so_pcb = (caddr_t)pcbp;
588 	pcbp->ng_socket = so;
589 
590 	/* Add the socket to linked list */
591 	mtx_lock(&ngsocketlist_mtx);
592 	LIST_INSERT_HEAD(&ngsocklist, pcbp, socks);
593 	mtx_unlock(&ngsocketlist_mtx);
594 	return (0);
595 }
596 
597 /*
598  * Disassociate the socket from it's protocol specific
599  * partner. If it's attached to a node's private data structure,
600  * then unlink from that too. If we were the last socket attached to it,
601  * then shut down the entire node. Shared code for control and data sockets.
602  */
603 static void
604 ng_detach_common(struct ngpcb *pcbp, int which)
605 {
606 	struct ngsock *priv = pcbp->sockdata;
607 
608 	if (priv != NULL) {
609 		mtx_lock(&priv->mtx);
610 
611 		switch (which) {
612 		case NG_CONTROL:
613 			priv->ctlsock = NULL;
614 			break;
615 		case NG_DATA:
616 			priv->datasock = NULL;
617 			break;
618 		default:
619 			panic("%s", __func__);
620 		}
621 		pcbp->sockdata = NULL;
622 		pcbp->node_id = 0;
623 
624 		ng_socket_free_priv(priv);
625 	}
626 
627 	pcbp->ng_socket->so_pcb = NULL;
628 	mtx_lock(&ngsocketlist_mtx);
629 	LIST_REMOVE(pcbp, socks);
630 	mtx_unlock(&ngsocketlist_mtx);
631 	free(pcbp, M_PCB);
632 }
633 
634 /*
635  * Remove a reference from node private data.
636  */
637 static void
638 ng_socket_free_priv(struct ngsock *priv)
639 {
640 	mtx_assert(&priv->mtx, MA_OWNED);
641 
642 	priv->refs--;
643 
644 	if (priv->refs == 0) {
645 		mtx_destroy(&priv->mtx);
646 		free(priv, M_NETGRAPH_SOCK);
647 		return;
648 	}
649 
650 	if ((priv->refs == 1) && (priv->node != NULL)) {
651 		node_p node = priv->node;
652 
653 		priv->node = NULL;
654 		mtx_unlock(&priv->mtx);
655 		NG_NODE_UNREF(node);
656 		ng_rmnode_self(node);
657 	} else
658 		mtx_unlock(&priv->mtx);
659 }
660 
661 /*
662  * Connect the data socket to a named control socket node.
663  */
664 static int
665 ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp)
666 {
667 	struct sockaddr_ng *sap;
668 	node_p farnode;
669 	struct ngsock *priv;
670 	int error;
671 	item_p item;
672 
673 	/* If we are already connected, don't do it again. */
674 	if (pcbp->sockdata != NULL)
675 		return (EISCONN);
676 
677 	/*
678 	 * Find the target (victim) and check it doesn't already have
679 	 * a data socket. Also check it is a 'socket' type node.
680 	 * Use ng_package_data() and ng_address_path() to do this.
681 	 */
682 
683 	sap = (struct sockaddr_ng *) nam;
684 	/* The item will hold the node reference. */
685 	item = ng_package_data(NULL, NG_WAITOK);
686 
687 	if ((error = ng_address_path(NULL, item,  sap->sg_data, 0)))
688 		return (error); /* item is freed on failure */
689 
690 	/*
691 	 * Extract node from item and free item. Remember we now have
692 	 * a reference on the node. The item holds it for us.
693 	 * when we free the item we release the reference.
694 	 */
695 	farnode = item->el_dest; /* shortcut */
696 	if (strcmp(farnode->nd_type->name, NG_SOCKET_NODE_TYPE) != 0) {
697 		NG_FREE_ITEM(item); /* drop the reference to the node */
698 		return (EINVAL);
699 	}
700 	priv = NG_NODE_PRIVATE(farnode);
701 	if (priv->datasock != NULL) {
702 		NG_FREE_ITEM(item);	/* drop the reference to the node */
703 		return (EADDRINUSE);
704 	}
705 
706 	/*
707 	 * Link the PCB and the private data struct. and note the extra
708 	 * reference. Drop the extra reference on the node.
709 	 */
710 	mtx_lock(&priv->mtx);
711 	priv->datasock = pcbp;
712 	pcbp->sockdata = priv;
713 	pcbp->node_id = priv->node->nd_ID;	/* hint for netstat(1) */
714 	priv->refs++;
715 	mtx_unlock(&priv->mtx);
716 	NG_FREE_ITEM(item);	/* drop the reference to the node */
717 	return (0);
718 }
719 
720 /*
721  * Binding a socket means giving the corresponding node a name
722  */
723 static int
724 ng_bind(struct sockaddr *nam, struct ngpcb *pcbp)
725 {
726 	struct ngsock *const priv = pcbp->sockdata;
727 	struct sockaddr_ng *const sap = (struct sockaddr_ng *) nam;
728 
729 	if (priv == NULL) {
730 		TRAP_ERROR;
731 		return (EINVAL);
732 	}
733 	if ((sap->sg_len < 4) || (sap->sg_len > (NG_NODESIZ + 2)) ||
734 	    (sap->sg_data[0] == '\0') ||
735 	    (sap->sg_data[sap->sg_len - 3] != '\0')) {
736 		TRAP_ERROR;
737 		return (EINVAL);
738 	}
739 	return (ng_name_node(priv->node, sap->sg_data));
740 }
741 
742 /***************************************************************
743 	Netgraph node
744 ***************************************************************/
745 
746 /*
747  * You can only create new nodes from the socket end of things.
748  */
749 static int
750 ngs_constructor(node_p nodep)
751 {
752 	return (EINVAL);
753 }
754 
755 /*
756  * We allow any hook to be connected to the node.
757  * There is no per-hook private information though.
758  */
759 static int
760 ngs_newhook(node_p node, hook_p hook, const char *name)
761 {
762 	NG_HOOK_SET_PRIVATE(hook, NG_NODE_PRIVATE(node));
763 	return (0);
764 }
765 
766 /*
767  * If only one hook, allow read(2) and write(2) to work.
768  */
769 static int
770 ngs_connect(hook_p hook)
771 {
772 	node_p node = NG_HOOK_NODE(hook);
773 	struct ngsock *priv = NG_NODE_PRIVATE(node);
774 
775 	if ((priv->datasock) && (priv->datasock->ng_socket)) {
776 		if (NG_NODE_NUMHOOKS(node) == 1)
777 			priv->datasock->ng_socket->so_state |= SS_ISCONNECTED;
778 		else
779 			priv->datasock->ng_socket->so_state &= ~SS_ISCONNECTED;
780 	}
781 	return (0);
782 }
783 
784 /*
785  * Incoming messages get passed up to the control socket.
786  * Unless they are for us specifically (socket_type)
787  */
788 static int
789 ngs_rcvmsg(node_p node, item_p item, hook_p lasthook)
790 {
791 	struct ngsock *const priv = NG_NODE_PRIVATE(node);
792 	struct ngpcb *pcbp;
793 	struct socket *so;
794 	struct sockaddr_ng addr;
795 	struct ng_mesg *msg;
796 	struct mbuf *m;
797 	ng_ID_t	retaddr = NGI_RETADDR(item);
798 	int addrlen;
799 	int error = 0;
800 
801 	NGI_GET_MSG(item, msg);
802 	NG_FREE_ITEM(item);
803 
804 	/*
805 	 * Grab priv->mtx here to prevent destroying of control socket
806 	 * after checking that priv->ctlsock is not NULL.
807 	 */
808 	mtx_lock(&priv->mtx);
809 	pcbp = priv->ctlsock;
810 
811 	/*
812 	 * Only allow mesgs to be passed if we have the control socket.
813 	 * Data sockets can only support the generic messages.
814 	 */
815 	if (pcbp == NULL) {
816 		mtx_unlock(&priv->mtx);
817 		TRAP_ERROR;
818 		NG_FREE_MSG(msg);
819 		return (EINVAL);
820 	}
821 	so = pcbp->ng_socket;
822 	SOCKBUF_LOCK(&so->so_rcv);
823 
824 	/* As long as the race is handled, priv->mtx may be unlocked now. */
825 	mtx_unlock(&priv->mtx);
826 
827 #ifdef TRACE_MESSAGES
828 	printf("[%x]:---------->[socket]: c=<%d>cmd=%x(%s) f=%x #%d\n",
829 		retaddr,
830 		msg->header.typecookie,
831 		msg->header.cmd,
832 		msg->header.cmdstr,
833 		msg->header.flags,
834 		msg->header.token);
835 #endif
836 
837 	if (msg->header.typecookie == NGM_SOCKET_COOKIE) {
838 		switch (msg->header.cmd) {
839 		case NGM_SOCK_CMD_NOLINGER:
840 			priv->flags |= NGS_FLAG_NOLINGER;
841 			break;
842 		case NGM_SOCK_CMD_LINGER:
843 			priv->flags &= ~NGS_FLAG_NOLINGER;
844 			break;
845 		default:
846 			error = EINVAL;		/* unknown command */
847 		}
848 		SOCKBUF_UNLOCK(&so->so_rcv);
849 
850 		/* Free the message and return. */
851 		NG_FREE_MSG(msg);
852 		return (error);
853 	}
854 
855 	/* Get the return address into a sockaddr. */
856 	bzero(&addr, sizeof(addr));
857 	addr.sg_len = sizeof(addr);
858 	addr.sg_family = AF_NETGRAPH;
859 	addrlen = snprintf((char *)&addr.sg_data, sizeof(addr.sg_data),
860 	    "[%x]:", retaddr);
861 	if (addrlen < 0 || addrlen > sizeof(addr.sg_data)) {
862 		SOCKBUF_UNLOCK(&so->so_rcv);
863 		printf("%s: snprintf([%x]) failed - %d\n", __func__, retaddr,
864 		    addrlen);
865 		NG_FREE_MSG(msg);
866 		return (EINVAL);
867 	}
868 
869 	/* Copy the message itself into an mbuf chain. */
870 	m = m_devget((caddr_t)msg, sizeof(struct ng_mesg) + msg->header.arglen,
871 	    0, NULL, NULL);
872 
873 	/*
874 	 * Here we free the message. We need to do that
875 	 * regardless of whether we got mbufs.
876 	 */
877 	NG_FREE_MSG(msg);
878 
879 	if (m == NULL) {
880 		SOCKBUF_UNLOCK(&so->so_rcv);
881 		TRAP_ERROR;
882 		return (ENOBUFS);
883 	}
884 
885 	/* Send it up to the socket. */
886 	if (sbappendaddr_locked(&so->so_rcv, (struct sockaddr *)&addr, m,
887 	    NULL) == 0) {
888 		SOCKBUF_UNLOCK(&so->so_rcv);
889 		TRAP_ERROR;
890 		m_freem(m);
891 		return (ENOBUFS);
892 	}
893 	sorwakeup_locked(so);
894 
895 	return (error);
896 }
897 
898 /*
899  * Receive data on a hook
900  */
901 static int
902 ngs_rcvdata(hook_p hook, item_p item)
903 {
904 	struct ngsock *const priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
905 	struct ngpcb *const pcbp = priv->datasock;
906 	struct socket *so;
907 	struct sockaddr_ng *addr;
908 	char *addrbuf[NG_HOOKSIZ + 4];
909 	int addrlen;
910 	struct mbuf *m;
911 
912 	NGI_GET_M(item, m);
913 	NG_FREE_ITEM(item);
914 
915 	/* If there is no data socket, black-hole it. */
916 	if (pcbp == NULL) {
917 		NG_FREE_M(m);
918 		return (0);
919 	}
920 	so = pcbp->ng_socket;
921 
922 	/* Get the return address into a sockaddr. */
923 	addrlen = strlen(NG_HOOK_NAME(hook));	/* <= NG_HOOKSIZ - 1 */
924 	addr = (struct sockaddr_ng *) addrbuf;
925 	addr->sg_len = addrlen + 3;
926 	addr->sg_family = AF_NETGRAPH;
927 	bcopy(NG_HOOK_NAME(hook), addr->sg_data, addrlen);
928 	addr->sg_data[addrlen] = '\0';
929 
930 	/* Try to tell the socket which hook it came in on. */
931 	if (sbappendaddr(&so->so_rcv, (struct sockaddr *)addr, m, NULL) == 0) {
932 		m_freem(m);
933 		TRAP_ERROR;
934 		return (ENOBUFS);
935 	}
936 	sorwakeup(so);
937 	return (0);
938 }
939 
940 /*
941  * Hook disconnection
942  *
943  * For this type, removal of the last link destroys the node
944  * if the NOLINGER flag is set.
945  */
946 static int
947 ngs_disconnect(hook_p hook)
948 {
949 	node_p node = NG_HOOK_NODE(hook);
950 	struct ngsock *const priv = NG_NODE_PRIVATE(node);
951 
952 	if ((priv->datasock) && (priv->datasock->ng_socket)) {
953 		if (NG_NODE_NUMHOOKS(node) == 1)
954 			priv->datasock->ng_socket->so_state |= SS_ISCONNECTED;
955 		else
956 			priv->datasock->ng_socket->so_state &= ~SS_ISCONNECTED;
957 	}
958 
959 	if ((priv->flags & NGS_FLAG_NOLINGER) &&
960 	    (NG_NODE_NUMHOOKS(node) == 0) && (NG_NODE_IS_VALID(node)))
961 		ng_rmnode_self(node);
962 
963 	return (0);
964 }
965 
966 /*
967  * Do local shutdown processing.
968  * In this case, that involves making sure the socket
969  * knows we should be shutting down.
970  */
971 static int
972 ngs_shutdown(node_p node)
973 {
974 	struct ngsock *const priv = NG_NODE_PRIVATE(node);
975 	struct ngpcb *dpcbp, *pcbp;
976 
977 	mtx_lock(&priv->mtx);
978 	dpcbp = priv->datasock;
979 	pcbp = priv->ctlsock;
980 
981 	if (dpcbp != NULL)
982 		soisdisconnected(dpcbp->ng_socket);
983 
984 	if (pcbp != NULL)
985 		soisdisconnected(pcbp->ng_socket);
986 
987 	priv->node = NULL;
988 	NG_NODE_SET_PRIVATE(node, NULL);
989 	ng_socket_free_priv(priv);
990 
991 	NG_NODE_UNREF(node);
992 	return (0);
993 }
994 
995 static void
996 ng_socket_item_applied(void *context, int error)
997 {
998 	struct ngsock *const priv = (struct ngsock *)context;
999 
1000 	mtx_lock(&priv->mtx);
1001 	priv->error = error;
1002 	wakeup(priv);
1003 	mtx_unlock(&priv->mtx);
1004 
1005 }
1006 
1007 static	int
1008 dummy_disconnect(struct socket *so)
1009 {
1010 	return (0);
1011 }
1012 /*
1013  * Control and data socket type descriptors
1014  *
1015  * XXXRW: Perhaps _close should do something?
1016  */
1017 
1018 static struct pr_usrreqs ngc_usrreqs = {
1019 	.pru_abort =		NULL,
1020 	.pru_attach =		ngc_attach,
1021 	.pru_bind =		ngc_bind,
1022 	.pru_connect =		ngc_connect,
1023 	.pru_detach =		ngc_detach,
1024 	.pru_disconnect =	dummy_disconnect,
1025 	.pru_peeraddr =		NULL,
1026 	.pru_send =		ngc_send,
1027 	.pru_shutdown =		NULL,
1028 	.pru_sockaddr =		ng_getsockaddr,
1029 	.pru_close =		NULL,
1030 };
1031 
1032 static struct pr_usrreqs ngd_usrreqs = {
1033 	.pru_abort =		NULL,
1034 	.pru_attach =		ngd_attach,
1035 	.pru_bind =		NULL,
1036 	.pru_connect =		ngd_connect,
1037 	.pru_detach =		ngd_detach,
1038 	.pru_disconnect =	dummy_disconnect,
1039 	.pru_peeraddr =		NULL,
1040 	.pru_send =		ngd_send,
1041 	.pru_shutdown =		NULL,
1042 	.pru_sockaddr =		ng_getsockaddr,
1043 	.pru_close =		NULL,
1044 };
1045 
1046 /*
1047  * Definitions of protocols supported in the NETGRAPH domain.
1048  */
1049 
1050 extern struct domain ngdomain;		/* stop compiler warnings */
1051 
1052 static struct protosw ngsw[] = {
1053 {
1054 	.pr_type =		SOCK_DGRAM,
1055 	.pr_domain =		&ngdomain,
1056 	.pr_protocol =		NG_CONTROL,
1057 	.pr_flags =		PR_ATOMIC | PR_ADDR /* | PR_RIGHTS */,
1058 	.pr_usrreqs =		&ngc_usrreqs
1059 },
1060 {
1061 	.pr_type =		SOCK_DGRAM,
1062 	.pr_domain =		&ngdomain,
1063 	.pr_protocol =		NG_DATA,
1064 	.pr_flags =		PR_ATOMIC | PR_ADDR,
1065 	.pr_usrreqs =		&ngd_usrreqs
1066 }
1067 };
1068 
1069 struct domain ngdomain = {
1070 	.dom_family =		AF_NETGRAPH,
1071 	.dom_name =		"netgraph",
1072 	.dom_protosw =		ngsw,
1073 	.dom_protoswNPROTOSW =	&ngsw[sizeof(ngsw) / sizeof(ngsw[0])]
1074 };
1075 
1076 /*
1077  * Handle loading and unloading for this node type.
1078  * This is to handle auxiliary linkages (e.g protocol domain addition).
1079  */
1080 static int
1081 ngs_mod_event(module_t mod, int event, void *data)
1082 {
1083 	int error = 0;
1084 
1085 	switch (event) {
1086 	case MOD_LOAD:
1087 		mtx_init(&ngsocketlist_mtx, "ng_socketlist", NULL, MTX_DEF);
1088 		break;
1089 	case MOD_UNLOAD:
1090 		/* Ensure there are no open netgraph sockets. */
1091 		if (!LIST_EMPTY(&ngsocklist)) {
1092 			error = EBUSY;
1093 			break;
1094 		}
1095 #ifdef NOTYET
1096 		/* Unregister protocol domain XXX can't do this yet.. */
1097 #endif
1098 		error = EBUSY;
1099 		break;
1100 	default:
1101 		error = EOPNOTSUPP;
1102 		break;
1103 	}
1104 	return (error);
1105 }
1106 
1107 VNET_DOMAIN_SET(ng);
1108 
1109 SYSCTL_INT(_net_graph, OID_AUTO, family, CTLFLAG_RD, 0, AF_NETGRAPH, "");
1110 static SYSCTL_NODE(_net_graph, OID_AUTO, data, CTLFLAG_RW, 0, "DATA");
1111 SYSCTL_INT(_net_graph_data, OID_AUTO, proto, CTLFLAG_RD, 0, NG_DATA, "");
1112 static SYSCTL_NODE(_net_graph, OID_AUTO, control, CTLFLAG_RW, 0, "CONTROL");
1113 SYSCTL_INT(_net_graph_control, OID_AUTO, proto, CTLFLAG_RD, 0, NG_CONTROL, "");
1114 
1115