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