xref: /dragonfly/sys/netgraph7/socket/ng_socket.c (revision 37de577a)
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  *
40  * $FreeBSD: src/sys/netgraph/ng_socket.c,v 1.85 2008/03/11 21:58:48 mav Exp $
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/domain.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/msgport2.h>
59 /*
60 #include <sys/mutex.h>
61 */
62 #include <sys/param.h>
63 #include <sys/priv.h>
64 #include <sys/proc.h>
65 #include <sys/protosw.h>
66 #include <sys/queue.h>
67 #include <sys/socket.h>
68 #include <sys/socketvar.h>
69 #include <sys/socketvar2.h>
70 /*
71 #include <sys/syscallsubr.h>
72 */
73 #include <sys/sysctl.h>
74 #include <sys/vnode.h>
75 
76 #include <netgraph7/ng_message.h>
77 #include <netgraph7/netgraph.h>
78 #include "ng_socketvar.h"
79 #include "ng_socket.h"
80 
81 #ifdef NG_SEPARATE_MALLOC
82 MALLOC_DEFINE(M_NETGRAPH_PATH, "netgraph_path", "netgraph path info ");
83 MALLOC_DEFINE(M_NETGRAPH_SOCK, "netgraph_sock", "netgraph socket info ");
84 #else
85 #define M_NETGRAPH_PATH M_NETGRAPH
86 #define M_NETGRAPH_SOCK M_NETGRAPH
87 #endif
88 
89 /*
90  * It's Ascii-art time!
91  *   +-------------+   +-------------+
92  *   |socket  (ctl)|   |socket (data)|
93  *   +-------------+   +-------------+
94  *          ^                 ^
95  *          |                 |
96  *          v                 v
97  *    +-----------+     +-----------+
98  *    |pcb   (ctl)|     |pcb  (data)|
99  *    +-----------+     +-----------+
100  *          ^                 ^
101  *          |                 |
102  *          v                 v
103  *      +--------------------------+
104  *      |   Socket type private    |
105  *      |       data               |
106  *      +--------------------------+
107  *                   ^
108  *                   |
109  *                   v
110  *           +----------------+
111  *           | struct ng_node |
112  *           +----------------+
113  */
114 
115 /* Netgraph node methods */
116 static ng_constructor_t	ngs_constructor;
117 static ng_rcvmsg_t	ngs_rcvmsg;
118 static ng_shutdown_t	ngs_shutdown;
119 static ng_newhook_t	ngs_newhook;
120 static ng_connect_t	ngs_connect;
121 static ng_rcvdata_t	ngs_rcvdata;
122 static ng_disconnect_t	ngs_disconnect;
123 
124 /* Internal methods */
125 static int	ng_attach_data(struct socket *so);
126 static int	ng_attach_cntl(struct socket *so);
127 static int	ng_attach_common(struct socket *so, int type);
128 static void	ng_detach_common(struct ngpcb *pcbp, int type);
129 static void	ng_socket_free_priv(struct ngsock *priv);
130 #ifdef NOTYET
131 static int	ng_internalize(struct mbuf *m, struct thread *p);
132 #endif
133 static int	ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp);
134 static int	ng_bind(struct sockaddr *nam, struct ngpcb *pcbp);
135 
136 static int	ngs_mod_event(module_t mod, int event, void *data);
137 static void	ng_socket_item_applied(void *context, int error);
138 static int	linker_api_available(void);
139 
140 /* Netgraph type descriptor */
141 static struct ng_type typestruct = {
142 	.version =	NG_ABI_VERSION,
143 	.name =		NG_SOCKET_NODE_TYPE,
144 	.mod_event =	ngs_mod_event,
145 	.constructor =	ngs_constructor,
146 	.rcvmsg =	ngs_rcvmsg,
147 	.shutdown =	ngs_shutdown,
148 	.newhook =	ngs_newhook,
149 	.connect =	ngs_connect,
150 	.rcvdata =	ngs_rcvdata,
151 	.disconnect =	ngs_disconnect,
152 };
153 NETGRAPH_INIT_ORDERED(socket, &typestruct, SI_SUB_PROTO_DOMAIN, SI_ORDER_ANY);
154 
155 /* Buffer space */
156 static u_long ngpdg_sendspace = 20 * 1024;	/* really max datagram size */
157 SYSCTL_INT(_net_graph, OID_AUTO, maxdgram, CTLFLAG_RW,
158     &ngpdg_sendspace , 0, "Maximum outgoing Netgraph datagram size");
159 static u_long ngpdg_recvspace = 20 * 1024;
160 SYSCTL_INT(_net_graph, OID_AUTO, recvspace, CTLFLAG_RW,
161     &ngpdg_recvspace , 0, "Maximum space for incoming Netgraph datagrams");
162 
163 #define sotongpcb(so) ((struct ngpcb *)(so)->so_pcb)
164 
165 /* If getting unexplained errors returned, set this to "kdb_enter("X"); */
166 #ifndef TRAP_ERROR
167 #define TRAP_ERROR
168 #endif
169 
170 /***************************************************************
171 	Control sockets
172 ***************************************************************/
173 
174 static void
175 ngc_attach(netmsg_t msg)
176 {
177 	struct socket *so = msg->attach.base.nm_so;
178 	struct pru_attach_info *ai = msg->attach.nm_ai;
179 	struct ngpcb *const pcbp = sotongpcb(so);
180 	int error;
181 
182 	if (priv_check_cred(ai->p_ucred, PRIV_ROOT, NULL_CRED_OKAY) != 0)
183 		error = EPERM;
184 	else if (pcbp != NULL)
185 		error = EISCONN;
186 	else
187 		error = ng_attach_cntl(so);
188 	lwkt_replymsg(&msg->attach.base.lmsg, error);
189 }
190 
191 static void
192 ngc_detach(netmsg_t msg)
193 {
194 	struct socket *so = msg->detach.base.nm_so;
195 	struct ngpcb *const pcbp = sotongpcb(so);
196 
197 	KASSERT(pcbp != NULL, ("ngc_detach: pcbp == NULL"));
198 	ng_detach_common(pcbp, NG_CONTROL);
199 	lwkt_replymsg(&msg->detach.base.lmsg, 0);
200 }
201 
202 static void
203 ngc_send(netmsg_t netmsg)
204 {
205 	struct socket *so = netmsg->send.base.nm_so;
206 	struct mbuf *m = netmsg->send.nm_m;
207 	struct sockaddr *addr = netmsg->send.nm_addr;
208 	struct mbuf *control = netmsg->send.nm_control;
209 	struct ngpcb *const pcbp = sotongpcb(so);
210 	struct sockaddr_ng *const sap = (struct sockaddr_ng *) addr;
211 	struct ng_mesg *msg;
212 	struct mbuf *m0;
213 	item_p item;
214 	char *path = NULL;
215 	int len, error = 0;
216 	struct ng_apply_info *apply;
217 
218 #ifdef	NOTYET
219 	if (control && (error = ng_internalize(control, td))) {
220 		if (pcbp->sockdata == NULL) {
221 			error = ENOTCONN;
222 			goto release;
223 		}
224 	}
225 #else	/* NOTYET */
226 	if (control) {
227 		error = EINVAL;
228 		goto release;
229 	}
230 #endif	/* NOTYET */
231 
232 	/* Require destination as there may be >= 1 hooks on this node. */
233 	if (addr == NULL) {
234 		error = EDESTADDRREQ;
235 		goto release;
236 	}
237 
238 	/*
239 	 * Allocate an expendable buffer for the path, chop off
240 	 * the sockaddr header, and make sure it's NUL terminated.
241 	 */
242 	len = sap->sg_len - 2;
243 	path = kmalloc(len + 1, M_NETGRAPH_PATH, M_WAITOK);
244 	bcopy(sap->sg_data, path, len);
245 	path[len] = '\0';
246 
247 	/*
248 	 * Move the actual message out of mbufs into a linear buffer.
249 	 * Start by adding up the size of the data. (could use mh_len?)
250 	 */
251 	for (len = 0, m0 = m; m0 != NULL; m0 = m0->m_next)
252 		len += m0->m_len;
253 
254 	/*
255 	 * Move the data into a linear buffer as well.
256 	 * Messages are not delivered in mbufs.
257 	 */
258 	msg = kmalloc(len + 1, M_NETGRAPH_MSG, M_WAITOK);
259 	m_copydata(m, 0, len, (char *)msg);
260 
261 	if (msg->header.version != NG_VERSION) {
262 		kfree(msg, M_NETGRAPH_MSG);
263 		error = EINVAL;
264 		goto release;
265 	}
266 
267 	/*
268 	 * Hack alert!
269 	 * We look into the message and if it mkpeers a node of unknown type, we
270 	 * try to load it. We need to do this now, in syscall thread, because if
271 	 * message gets queued and applied later we will get panic.
272 	 */
273 	if (msg->header.typecookie == NGM_GENERIC_COOKIE &&
274 	    msg->header.cmd == NGM_MKPEER) {
275 		struct ngm_mkpeer *const mkp = (struct ngm_mkpeer *) msg->data;
276 		struct ng_type *type;
277 
278 		if ((type = ng_findtype(mkp->type)) == NULL) {
279 			char filename[NG_TYPESIZ + 3];
280 			linker_file_t fileid;
281 
282 			if (!linker_api_available()) {
283 				error = ENXIO;
284 				goto done;
285 			}
286 
287 			/* Not found, try to load it as a loadable module. */
288 			ksnprintf(filename, sizeof(filename), "ng_%s.ko",
289 			    mkp->type);
290 			error = linker_load_file(filename, &fileid);
291 			if (error != 0) {
292 				kfree(msg, M_NETGRAPH_MSG);
293 				goto release;
294 			}
295 
296 			/* See if type has been loaded successfully. */
297 			if ((type = ng_findtype(mkp->type)) == NULL) {
298 				kfree(msg, M_NETGRAPH_MSG);
299 				(void)linker_file_unload(fileid);
300 				error =  ENXIO;
301 				goto release;
302 			}
303 		}
304 	}
305 
306 	item = ng_package_msg(msg, NG_WAITOK);
307 	if ((error = ng_address_path((pcbp->sockdata->node), item, path, 0))
308 	    != 0) {
309 #ifdef TRACE_MESSAGES
310 		kprintf("ng_address_path: errx=%d\n", error);
311 #endif
312 		goto release;
313 	}
314 
315 #ifdef TRACE_MESSAGES
316 	kprintf("[%x]:<---------[socket]: c=<%d>cmd=%x(%s) f=%x #%d (%s)\n",
317 		item->el_dest->nd_ID,
318 		msg->header.typecookie,
319 		msg->header.cmd,
320 		msg->header.cmdstr,
321 		msg->header.flags,
322 		msg->header.token,
323 		item->el_dest->nd_type->name);
324 #endif
325 	SAVE_LINE(item);
326 
327 	/*
328 	 * We do not want the user thread to return from syscall until the
329 	 * item is processed by destination node.  We register callback
330 	 * on the item, which will reply to the user thread when item
331 	 * was applied.
332 	 */
333 	apply = ng_alloc_apply();
334 	bzero(apply, sizeof(*apply));
335 	apply->apply = ng_socket_item_applied;
336 	apply->context = &netmsg->send.base.lmsg;
337 	item->apply = apply;
338 
339 	error = ng_snd_item(item, NG_PROGRESS);
340 
341 release:
342 	if (path != NULL)
343 		kfree(path, M_NETGRAPH_PATH);
344 	if (control != NULL)
345 		m_freem(control);
346 	if (m != NULL)
347 		m_freem(m);
348 done:
349 	if (error != EINPROGRESS)
350 		lwkt_replymsg(&netmsg->send.base.lmsg, error);
351 }
352 
353 static void
354 ngc_bind(netmsg_t msg)
355 {
356 	struct socket *so = msg->connect.base.nm_so;
357 	struct sockaddr *nam = msg->connect.nm_nam;
358 	struct ngpcb *const pcbp = sotongpcb(so);
359 	int error;
360 
361 	if (pcbp == NULL)
362 		error = EINVAL;
363 	else
364 		error = ng_bind(nam, pcbp);
365 	lwkt_replymsg(&msg->connect.base.lmsg, error);
366 }
367 
368 static void
369 ngc_connect(netmsg_t msg)
370 {
371 	/*
372 	 * At this time refuse to do this.. it used to
373 	 * do something but it was undocumented and not used.
374 	 */
375 	kprintf("program tried to connect control socket to remote node\n");
376 	lwkt_replymsg(&msg->connect.base.lmsg, EINVAL);
377 }
378 
379 /***************************************************************
380 	Data sockets
381 ***************************************************************/
382 
383 static void
384 ngd_attach(netmsg_t msg)
385 {
386 	struct socket *so = msg->attach.base.nm_so;
387 	struct ngpcb *const pcbp = sotongpcb(so);
388 	int error;
389 
390 	if (pcbp != NULL)
391 		error =  EISCONN;
392 	else
393 		error = ng_attach_data(so);
394 	lwkt_replymsg(&msg->connect.base.lmsg, error);
395 }
396 
397 static void
398 ngd_detach(netmsg_t msg)
399 {
400 	struct socket *so = msg->detach.base.nm_so;
401 	struct ngpcb *const pcbp = sotongpcb(so);
402 
403 	KASSERT(pcbp != NULL, ("ngd_detach: pcbp == NULL"));
404 	ng_detach_common(pcbp, NG_DATA);
405 	lwkt_replymsg(&msg->detach.base.lmsg, 0);
406 }
407 
408 static void
409 ngd_send(netmsg_t msg)
410 {
411 	struct socket *so = msg->send.base.nm_so;
412 	struct mbuf *m = msg->send.nm_m;
413 	struct sockaddr *addr = msg->send.nm_addr;
414 	struct mbuf *control = msg->send.nm_control;
415 	struct ngpcb *const pcbp = sotongpcb(so);
416 	struct sockaddr_ng *const sap = (struct sockaddr_ng *) addr;
417 	int	len, error;
418 	hook_p  hook = NULL;
419 	char	hookname[NG_HOOKSIZ];
420 
421 	if ((pcbp == NULL) || (control != NULL)) {
422 		error = EINVAL;
423 		goto release;
424 	}
425 	if (pcbp->sockdata == NULL) {
426 		error = ENOTCONN;
427 		goto release;
428 	}
429 
430 	if (sap == NULL)
431 		len = 0;		/* Make compiler happy. */
432 	else
433 		len = sap->sg_len - 2;
434 
435 	/*
436 	 * If the user used any of these ways to not specify an address
437 	 * then handle specially.
438 	 */
439 	if ((sap == NULL) || (len <= 0) || (*sap->sg_data == '\0')) {
440 		if (NG_NODE_NUMHOOKS(pcbp->sockdata->node) != 1) {
441 			error = EDESTADDRREQ;
442 			goto release;
443 		}
444 		/*
445 		 * If exactly one hook exists, just use it.
446 		 * Special case to allow write(2) to work on an ng_socket.
447 		 */
448 		hook = LIST_FIRST(&pcbp->sockdata->node->nd_hooks);
449 	} else {
450 		if (len >= NG_HOOKSIZ) {
451 			error = EINVAL;
452 			goto release;
453 		}
454 
455 		/*
456 		 * chop off the sockaddr header, and make sure it's NUL
457 		 * terminated
458 		 */
459 		bcopy(sap->sg_data, hookname, len);
460 		hookname[len] = '\0';
461 
462 		/* Find the correct hook from 'hookname' */
463 		hook = ng_findhook(pcbp->sockdata->node, hookname);
464 		if (hook == NULL) {
465 			error = EHOSTUNREACH;
466 			goto release;
467 		}
468 	}
469 
470 	/* Send data. */
471 	NG_SEND_DATA_FLAGS(error, hook, m, NG_WAITOK);
472 
473 release:
474 	if (control != NULL)
475 		m_freem(control);
476 	if (m != NULL)
477 		m_freem(m);
478 	lwkt_replymsg(&msg->send.base.lmsg, error);
479 }
480 
481 static void
482 ngd_connect(netmsg_t msg)
483 {
484 	struct socket *so = msg->connect.base.nm_so;
485 	struct sockaddr *nam = msg->connect.nm_nam;
486 	struct ngpcb *const pcbp = sotongpcb(so);
487 	int error;
488 
489 	if (pcbp == NULL)
490 		error = EINVAL;
491 	else
492 		error = ng_connect_data(nam, pcbp);
493 	lwkt_replymsg(&msg->connect.base.lmsg, error);
494 }
495 
496 /*
497  * Used for both data and control sockets
498  */
499 static void
500 ng_getsockaddr(netmsg_t msg)
501 {
502 	struct socket *so = msg->sockaddr.base.nm_so;
503 	struct sockaddr **addr = msg->sockaddr.nm_nam;
504 	struct ngpcb *pcbp;
505 	struct sockaddr_ng *sg;
506 	int sg_len;
507 	int error = 0;
508 
509 	/* Why isn't sg_data a `char[1]' ? :-( */
510 	sg_len = sizeof(struct sockaddr_ng) - sizeof(sg->sg_data) + 1;
511 
512 	pcbp = sotongpcb(so);
513 	if ((pcbp == NULL) || (pcbp->sockdata == NULL)) {
514 		/* XXXGL: can this still happen? */
515 		error = EINVAL;
516 		goto replymsg;
517 	}
518 
519 	mtx_lock(&pcbp->sockdata->mtx);
520 	if (pcbp->sockdata->node != NULL) {
521 		node_p node = pcbp->sockdata->node;
522 		int namelen = 0;	/* silence compiler! */
523 
524 		if (NG_NODE_HAS_NAME(node))
525 			sg_len += namelen = strlen(NG_NODE_NAME(node));
526 
527 		sg = kmalloc(sg_len, M_SONAME, M_WAITOK | M_ZERO);
528 
529 		if (NG_NODE_HAS_NAME(node))
530 			bcopy(NG_NODE_NAME(node), sg->sg_data, namelen);
531 
532 		sg->sg_len = sg_len;
533 		sg->sg_family = AF_NETGRAPH;
534 		*addr = (struct sockaddr *)sg;
535 		mtx_unlock(&pcbp->sockdata->mtx);
536 	} else {
537 		mtx_unlock(&pcbp->sockdata->mtx);
538 		error = EINVAL;
539 	}
540 
541 replymsg:
542 	lwkt_replymsg(&msg->sockaddr.base.lmsg, error);
543 }
544 
545 /*
546  * Attach a socket to it's protocol specific partner.
547  * For a control socket, actually create a netgraph node and attach
548  * to it as well.
549  */
550 
551 static int
552 ng_attach_cntl(struct socket *so)
553 {
554 	struct ngsock *priv;
555 	struct ngpcb *pcbp;
556 	int error;
557 
558 	/* Allocate node private info */
559 	priv = kmalloc(sizeof(*priv), M_NETGRAPH_SOCK, M_WAITOK | M_ZERO);
560 
561 	/* Setup protocol control block */
562 	if ((error = ng_attach_common(so, NG_CONTROL)) != 0) {
563 		kfree(priv, M_NETGRAPH_SOCK);
564 		return (error);
565 	}
566 	pcbp = sotongpcb(so);
567 
568 	/* Link the pcb the private data. */
569 	priv->ctlsock = pcbp;
570 	pcbp->sockdata = priv;
571 	priv->refs++;
572 
573 	/* Initialize mutex. */
574 	mtx_init(&priv->mtx, "ng_socket");
575 
576 	/* Make the generic node components */
577 	if ((error = ng_make_node_common(&typestruct, &priv->node)) != 0) {
578 		kfree(priv, M_NETGRAPH_SOCK);
579 		ng_detach_common(pcbp, NG_CONTROL);
580 		return (error);
581 	}
582 
583 	/* Link the node and the private data. */
584 	NG_NODE_SET_PRIVATE(priv->node, priv);
585 	NG_NODE_REF(priv->node);
586 	priv->refs++;
587 
588 	return (0);
589 }
590 
591 static int
592 ng_attach_data(struct socket *so)
593 {
594 	return (ng_attach_common(so, NG_DATA));
595 }
596 
597 /*
598  * Set up a socket protocol control block.
599  * This code is shared between control and data sockets.
600  */
601 static int
602 ng_attach_common(struct socket *so, int type)
603 {
604 	struct ngpcb *pcbp;
605 	int error;
606 
607 	/* Standard socket setup stuff. */
608 	error = soreserve(so, ngpdg_sendspace, ngpdg_recvspace, NULL);
609 	if (error)
610 		return (error);
611 
612 	/* Allocate the pcb. */
613 	pcbp = kmalloc(sizeof(struct ngpcb), M_PCB, M_WAITOK | M_ZERO);
614 	pcbp->type = type;
615 
616 	/* Link the pcb and the socket. */
617 	so->so_pcb = (caddr_t)pcbp;
618 	pcbp->ng_socket = so;
619 
620 	return (0);
621 }
622 
623 /*
624  * Disassociate the socket from it's protocol specific
625  * partner. If it's attached to a node's private data structure,
626  * then unlink from that too. If we were the last socket attached to it,
627  * then shut down the entire node. Shared code for control and data sockets.
628  */
629 static void
630 ng_detach_common(struct ngpcb *pcbp, int which)
631 {
632 	struct ngsock *priv = pcbp->sockdata;
633 
634 	if (priv != NULL) {
635 		mtx_lock(&priv->mtx);
636 
637 		switch (which) {
638 		case NG_CONTROL:
639 			priv->ctlsock = NULL;
640 			break;
641 		case NG_DATA:
642 			priv->datasock = NULL;
643 			break;
644 		default:
645 			panic(__func__);
646 		}
647 		pcbp->sockdata = NULL;
648 
649 		ng_socket_free_priv(priv);
650 	}
651 
652 	pcbp->ng_socket->so_pcb = NULL;
653 	kfree(pcbp, M_PCB);
654 }
655 
656 /*
657  * Remove a reference from node private data.
658  */
659 static void
660 ng_socket_free_priv(struct ngsock *priv)
661 {
662 	KKASSERT(mtx_owned(&priv->mtx));
663 
664 	priv->refs--;
665 
666 	if (priv->refs == 0) {
667 		mtx_uninit(&priv->mtx);
668 		kfree(priv, M_NETGRAPH_SOCK);
669 		return;
670 	}
671 
672 	if ((priv->refs == 1) && (priv->node != NULL)) {
673 		node_p node = priv->node;
674 
675 		priv->node = NULL;
676 		mtx_unlock(&priv->mtx);
677 		NG_NODE_UNREF(node);
678 		ng_rmnode_self(node);
679 	} else
680 		mtx_unlock(&priv->mtx);
681 }
682 
683 #ifdef NOTYET
684 /*
685  * File descriptors can be passed into an AF_NETGRAPH socket.
686  * Note, that file descriptors cannot be passed OUT.
687  * Only character device descriptors are accepted.
688  * Character devices are useful to connect a graph to a device,
689  * which after all is the purpose of this whole system.
690  */
691 static int
692 ng_internalize(struct mbuf *control, struct thread *td)
693 {
694 	const struct cmsghdr *cm = mtod(control, const struct cmsghdr *);
695 	struct file *fp;
696 	struct vnode *vn;
697 	int oldfds;
698 	int fd;
699 
700 	if (cm->cmsg_type != SCM_RIGHTS || cm->cmsg_level != SOL_SOCKET ||
701 	    cm->cmsg_len != control->m_len) {
702 		TRAP_ERROR;
703 		return (EINVAL);
704 	}
705 
706 	/* Check there is only one FD. XXX what would more than one signify? */
707 	oldfds = ((caddr_t)cm + cm->cmsg_len - (caddr_t)data) / sizeof (int);
708 	if (oldfds != 1) {
709 		TRAP_ERROR;
710 		return (EINVAL);
711 	}
712 
713 	/* Check that the FD given is legit. and change it to a pointer to a
714 	 * struct file. */
715 	fd = CMSG_DATA(cm);
716 	if ((error = fget(td, fd, &fp)) != 0)
717 		return (error);
718 
719 	/* Depending on what kind of resource it is, act differently. For
720 	 * devices, we treat it as a file. For an AF_NETGRAPH socket,
721 	 * shortcut straight to the node. */
722 	switch (fp->f_type) {
723 	case DTYPE_VNODE:
724 		vn = fp->f_data;
725 		if (vn && (vn->v_type == VCHR)) {
726 			/* for a VCHR, actually reference the FILE */
727 			fhold(fp);
728 			/* XXX then what :) */
729 			/* how to pass on to other modules? */
730 		} else {
731 			fdrop(fp, td);
732 			TRAP_ERROR;
733 			return (EINVAL);
734 		}
735 		break;
736 	default:
737 		fdrop(fp, td);
738 		TRAP_ERROR;
739 		return (EINVAL);
740 	}
741 	fdrop(fp, td);
742 	return (0);
743 }
744 #endif	/* NOTYET */
745 
746 /*
747  * Connect the data socket to a named control socket node.
748  */
749 static int
750 ng_connect_data(struct sockaddr *nam, struct ngpcb *pcbp)
751 {
752 	struct sockaddr_ng *sap;
753 	node_p farnode;
754 	struct ngsock *priv;
755 	int error;
756 	item_p item;
757 
758 	/* If we are already connected, don't do it again. */
759 	if (pcbp->sockdata != NULL)
760 		return (EISCONN);
761 
762 	/*
763 	 * Find the target (victim) and check it doesn't already have
764 	 * a data socket. Also check it is a 'socket' type node.
765 	 * Use ng_package_data() and ng_address_path() to do this.
766 	 */
767 
768 	sap = (struct sockaddr_ng *) nam;
769 	/* The item will hold the node reference. */
770 	item = ng_package_data(NULL, NG_WAITOK);
771 
772 	if ((error = ng_address_path(NULL, item,  sap->sg_data, 0))) {
773 		ng_free_item(item);
774 		return (error);
775 	}
776 
777 	/*
778 	 * Extract node from item and free item. Remember we now have
779 	 * a reference on the node. The item holds it for us.
780 	 * when we free the item we release the reference.
781 	 */
782 	farnode = item->el_dest; /* shortcut */
783 	if (strcmp(farnode->nd_type->name, NG_SOCKET_NODE_TYPE) != 0) {
784 		ng_free_item(item); /* drop the reference to the node */
785 		return (EINVAL);
786 	}
787 	priv = NG_NODE_PRIVATE(farnode);
788 	if (priv->datasock != NULL) {
789 		ng_free_item(item);	/* drop the reference to the node */
790 		return (EADDRINUSE);
791 	}
792 
793 	/*
794 	 * Link the PCB and the private data struct. and note the extra
795 	 * reference. Drop the extra reference on the node.
796 	 */
797 	mtx_lock(&priv->mtx);
798 	priv->datasock = pcbp;
799 	pcbp->sockdata = priv;
800 	priv->refs++;
801 	mtx_unlock(&priv->mtx);
802 	ng_free_item(item);	/* drop the reference to the node */
803 	return (0);
804 }
805 
806 /*
807  * Binding a socket means giving the corresponding node a name
808  */
809 static int
810 ng_bind(struct sockaddr *nam, struct ngpcb *pcbp)
811 {
812 	struct ngsock *const priv = pcbp->sockdata;
813 	struct sockaddr_ng *const sap = (struct sockaddr_ng *) nam;
814 
815 	if (priv == NULL) {
816 		TRAP_ERROR;
817 		return (EINVAL);
818 	}
819 	if ((sap->sg_len < 4) || (sap->sg_len > (NG_NODESIZ + 2)) ||
820 	    (sap->sg_data[0] == '\0') ||
821 	    (sap->sg_data[sap->sg_len - 3] != '\0')) {
822 		TRAP_ERROR;
823 		return (EINVAL);
824 	}
825 	return (ng_name_node(priv->node, sap->sg_data));
826 }
827 
828 /***************************************************************
829 	Netgraph node
830 ***************************************************************/
831 
832 /*
833  * You can only create new nodes from the socket end of things.
834  */
835 static int
836 ngs_constructor(node_p nodep)
837 {
838 	return (EINVAL);
839 }
840 
841 /*
842  * We allow any hook to be connected to the node.
843  * There is no per-hook private information though.
844  */
845 static int
846 ngs_newhook(node_p node, hook_p hook, const char *name)
847 {
848 	NG_HOOK_SET_PRIVATE(hook, NG_NODE_PRIVATE(node));
849 	return (0);
850 }
851 
852 /*
853  * If only one hook, allow read(2) and write(2) to work.
854  */
855 static int
856 ngs_connect(hook_p hook)
857 {
858 	node_p node = NG_HOOK_NODE(hook);
859 	struct ngsock *priv = NG_NODE_PRIVATE(node);
860 
861 	if ((priv->datasock) && (priv->datasock->ng_socket)) {
862 		if (NG_NODE_NUMHOOKS(node) == 1)
863 			sosetstate(priv->datasock->ng_socket, SS_ISCONNECTED);
864 		else
865 			soclrstate(priv->datasock->ng_socket, SS_ISCONNECTED);
866 	}
867 	return (0);
868 }
869 
870 /*
871  * Incoming messages get passed up to the control socket.
872  * Unless they are for us specifically (socket_type)
873  */
874 static int
875 ngs_rcvmsg(node_p node, item_p item, hook_p lasthook)
876 {
877 	struct ngsock *const priv = NG_NODE_PRIVATE(node);
878 	struct ngpcb *const pcbp = priv->ctlsock;
879 	struct socket *so;
880 	struct sockaddr_ng addr;
881 	struct ng_mesg *msg;
882 	struct mbuf *m;
883 	ng_ID_t	retaddr = NGI_RETADDR(item);
884 	int addrlen;
885 	int error = 0;
886 
887 	NGI_GET_MSG(item, msg);
888 	NG_FREE_ITEM(item);
889 
890 	/*
891 	 * Only allow mesgs to be passed if we have the control socket.
892 	 * Data sockets can only support the generic messages.
893 	 */
894 	if (pcbp == NULL) {
895 		TRAP_ERROR;
896 		NG_FREE_MSG(msg);
897 		return (EINVAL);
898 	}
899 	so = pcbp->ng_socket;
900 
901 #ifdef TRACE_MESSAGES
902 	kprintf("[%x]:---------->[socket]: c=<%d>cmd=%x(%s) f=%x #%d\n",
903 		retaddr,
904 		msg->header.typecookie,
905 		msg->header.cmd,
906 		msg->header.cmdstr,
907 		msg->header.flags,
908 		msg->header.token);
909 #endif
910 
911 	if (msg->header.typecookie == NGM_SOCKET_COOKIE) {
912 		switch (msg->header.cmd) {
913 		case NGM_SOCK_CMD_NOLINGER:
914 			priv->flags |= NGS_FLAG_NOLINGER;
915 			break;
916 		case NGM_SOCK_CMD_LINGER:
917 			priv->flags &= ~NGS_FLAG_NOLINGER;
918 			break;
919 		default:
920 			error = EINVAL;		/* unknown command */
921 		}
922 		/* Free the message and return. */
923 		NG_FREE_MSG(msg);
924 		return (error);
925 	}
926 
927 	/* Get the return address into a sockaddr. */
928 	bzero(&addr, sizeof(addr));
929 	addr.sg_len = sizeof(addr);
930 	addr.sg_family = AF_NETGRAPH;
931 	addrlen = ksnprintf((char *)&addr.sg_data, sizeof(addr.sg_data),
932 	    "[%x]:", retaddr);
933 	if (addrlen < 0 || addrlen > sizeof(addr.sg_data)) {
934 		kprintf("%s: ksnprintf([%x]) failed - %d\n", __func__, retaddr,
935 		    addrlen);
936 		NG_FREE_MSG(msg);
937 		return (EINVAL);
938 	}
939 
940 	/* Copy the message itself into an mbuf chain. */
941 	m = m_devget((caddr_t)msg, sizeof(struct ng_mesg) + msg->header.arglen,
942 		     0, NULL);
943 
944 	/*
945 	 * Here we free the message. We need to do that
946 	 * regardless of whether we got mbufs.
947 	 */
948 	NG_FREE_MSG(msg);
949 
950 	if (m == NULL) {
951 		TRAP_ERROR;
952 		return (ENOBUFS);
953 	}
954 
955 	/* Send it up to the socket. */
956 	lwkt_gettoken(&so->so_rcv.ssb_token);
957 	if (sbappendaddr((struct sockbuf *)&so->so_rcv, (struct sockaddr *)&addr, m, NULL) == 0) {
958 		lwkt_reltoken(&so->so_rcv.ssb_token);
959 		TRAP_ERROR;
960 		m_freem(m);
961 		return (ENOBUFS);
962 	}
963 	lwkt_reltoken(&so->so_rcv.ssb_token);
964 	sorwakeup(so);
965 
966 	return (error);
967 }
968 
969 /*
970  * Receive data on a hook
971  */
972 static int
973 ngs_rcvdata(hook_p hook, item_p item)
974 {
975 	struct ngsock *const priv = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
976 	struct ngpcb *const pcbp = priv->datasock;
977 	struct socket *so;
978 	struct sockaddr_ng *addr;
979 	char *addrbuf[NG_HOOKSIZ + 4];
980 	int addrlen;
981 	struct mbuf *m;
982 
983 	NGI_GET_M(item, m);
984 	NG_FREE_ITEM(item);
985 
986 	/* If there is no data socket, black-hole it. */
987 	if (pcbp == NULL) {
988 		NG_FREE_M(m);
989 		return (0);
990 	}
991 	so = pcbp->ng_socket;
992 
993 	/* Get the return address into a sockaddr. */
994 	addrlen = strlen(NG_HOOK_NAME(hook));	/* <= NG_HOOKSIZ - 1 */
995 	addr = (struct sockaddr_ng *) addrbuf;
996 	addr->sg_len = addrlen + 3;
997 	addr->sg_family = AF_NETGRAPH;
998 	bcopy(NG_HOOK_NAME(hook), addr->sg_data, addrlen);
999 	addr->sg_data[addrlen] = '\0';
1000 
1001 	/* Try to tell the socket which hook it came in on. */
1002 	lwkt_gettoken(&so->so_rcv.ssb_token);
1003 	if (sbappendaddr((struct sockbuf *)&so->so_rcv, (struct sockaddr *)addr, m, NULL) == 0) {
1004 		lwkt_reltoken(&so->so_rcv.ssb_token);
1005 		m_freem(m);
1006 		TRAP_ERROR;
1007 		return (ENOBUFS);
1008 	}
1009 	lwkt_reltoken(&so->so_rcv.ssb_token);
1010 	sorwakeup(so);
1011 	return (0);
1012 }
1013 
1014 /*
1015  * Hook disconnection
1016  *
1017  * For this type, removal of the last link destroys the node
1018  * if the NOLINGER flag is set.
1019  */
1020 static int
1021 ngs_disconnect(hook_p hook)
1022 {
1023 	node_p node = NG_HOOK_NODE(hook);
1024 	struct ngsock *const priv = NG_NODE_PRIVATE(node);
1025 
1026 	if ((priv->datasock) && (priv->datasock->ng_socket)) {
1027 		if (NG_NODE_NUMHOOKS(node) == 1)
1028 			sosetstate(priv->datasock->ng_socket, SS_ISCONNECTED);
1029 		else
1030 			soclrstate(priv->datasock->ng_socket, SS_ISCONNECTED);
1031 	}
1032 
1033 	if ((priv->flags & NGS_FLAG_NOLINGER) &&
1034 	    (NG_NODE_NUMHOOKS(node) == 0) && (NG_NODE_IS_VALID(node)))
1035 		ng_rmnode_self(node);
1036 
1037 	return (0);
1038 }
1039 
1040 /*
1041  * Do local shutdown processing.
1042  * In this case, that involves making sure the socket
1043  * knows we should be shutting down.
1044  */
1045 static int
1046 ngs_shutdown(node_p node)
1047 {
1048 	struct ngsock *const priv = NG_NODE_PRIVATE(node);
1049 	struct ngpcb *const dpcbp = priv->datasock;
1050 	struct ngpcb *const pcbp = priv->ctlsock;
1051 
1052 	if (dpcbp != NULL)
1053 		soisdisconnected(dpcbp->ng_socket);
1054 
1055 	if (pcbp != NULL)
1056 		soisdisconnected(pcbp->ng_socket);
1057 
1058 	mtx_lock(&priv->mtx);
1059 	priv->node = NULL;
1060 	NG_NODE_SET_PRIVATE(node, NULL);
1061 	ng_socket_free_priv(priv);
1062 
1063 	NG_NODE_UNREF(node);
1064 	return (0);
1065 }
1066 
1067 static void
1068 ng_socket_item_applied(void *context, int error)
1069 {
1070 	lwkt_msg *msg = context;
1071 
1072 	lwkt_replymsg(msg, error);
1073 }
1074 
1075 /*
1076  * Control and data socket type descriptors
1077  *
1078  * XXXRW: Perhaps _close should do something?
1079  */
1080 
1081 static struct pr_usrreqs ngc_usrreqs = {
1082 	.pru_abort =		NULL,
1083 	.pru_attach =		ngc_attach,
1084 	.pru_bind =		ngc_bind,
1085 	.pru_connect =		ngc_connect,
1086 	.pru_detach =		ngc_detach,
1087 	.pru_disconnect =	NULL,
1088 	.pru_peeraddr =		NULL,
1089 	.pru_send =		ngc_send,
1090 	.pru_shutdown =		NULL,
1091 	.pru_sockaddr =		ng_getsockaddr,
1092 	.pru_sosend =		sosend,
1093 	.pru_soreceive =	soreceive,
1094 	/* .pru_close =		NULL, */
1095 };
1096 
1097 static struct pr_usrreqs ngd_usrreqs = {
1098 	.pru_abort =		NULL,
1099 	.pru_attach =		ngd_attach,
1100 	.pru_bind =		NULL,
1101 	.pru_connect =		ngd_connect,
1102 	.pru_detach =		ngd_detach,
1103 	.pru_disconnect =	NULL,
1104 	.pru_peeraddr =		NULL,
1105 	.pru_send =		ngd_send,
1106 	.pru_shutdown =		NULL,
1107 	.pru_sockaddr =		ng_getsockaddr,
1108 	.pru_sosend =		sosend,
1109 	.pru_soreceive =	soreceive,
1110 	/* .pru_close =		NULL, */
1111 };
1112 
1113 /*
1114  * Definitions of protocols supported in the NETGRAPH domain.
1115  */
1116 
1117 extern struct domain ngdomain;		/* stop compiler warnings */
1118 
1119 static struct protosw ngsw[] = {
1120 {
1121 	.pr_type =		SOCK_DGRAM,
1122 	.pr_domain =		&ngdomain,
1123 	.pr_protocol =		NG_CONTROL,
1124 	.pr_flags =		PR_ATOMIC | PR_ADDR /* | PR_RIGHTS */,
1125 	.pr_usrreqs =		&ngc_usrreqs
1126 },
1127 {
1128 	.pr_type =		SOCK_DGRAM,
1129 	.pr_domain =		&ngdomain,
1130 	.pr_protocol =		NG_DATA,
1131 	.pr_flags =		PR_ATOMIC | PR_ADDR,
1132 	.pr_usrreqs =		&ngd_usrreqs
1133 }
1134 };
1135 
1136 struct domain ngdomain = {
1137 	.dom_family =		AF_NETGRAPH,
1138 	.dom_name =		"netgraph",
1139 	.dom_protosw =		ngsw,
1140 	.dom_protoswNPROTOSW =	&ngsw[NELEM(ngsw)]
1141 };
1142 
1143 /*
1144  * Handle loading and unloading for this node type.
1145  * This is to handle auxiliary linkages (e.g protocol domain addition).
1146  */
1147 static int
1148 ngs_mod_event(module_t mod, int event, void *data)
1149 {
1150 	int error = 0;
1151 
1152 	switch (event) {
1153 	case MOD_LOAD:
1154 		/* Register protocol domain. */
1155 		net_add_domain(&ngdomain);
1156 		break;
1157 	case MOD_UNLOAD:
1158 #ifdef NOTYET
1159 		/* Unregister protocol domain XXX can't do this yet.. */
1160 		if ((error = net_rm_domain(&ngdomain)) != 0)
1161 			break;
1162 		else
1163 #endif
1164 			error = EBUSY;
1165 		break;
1166 	default:
1167 		error = EOPNOTSUPP;
1168 		break;
1169 	}
1170 	return (error);
1171 }
1172 
1173 static int
1174 linker_api_available(void)
1175 {
1176 	/* linker_* API won't work without a process context */
1177 	if (curproc == NULL)
1178 		return 0;
1179 	/*
1180 	 * nlookup_init() relies on namei_oc to be initialized,
1181 	 * but it's not when the netgraph module is loaded during boot.
1182 	 */
1183 	if (namei_oc == NULL)
1184 		return 0;
1185 	return 1;
1186 }
1187 
1188 SYSCTL_INT(_net_graph, OID_AUTO, family, CTLFLAG_RD, 0, AF_NETGRAPH, "");
1189 SYSCTL_NODE(_net_graph, OID_AUTO, data, CTLFLAG_RW, 0, "DATA");
1190 SYSCTL_INT(_net_graph_data, OID_AUTO, proto, CTLFLAG_RD, 0, NG_DATA, "");
1191 SYSCTL_NODE(_net_graph, OID_AUTO, control, CTLFLAG_RW, 0, "CONTROL");
1192 SYSCTL_INT(_net_graph_control, OID_AUTO, proto, CTLFLAG_RD, 0, NG_CONTROL, "");
1193 
1194