xref: /dragonfly/sys/kern/uipc_msg.c (revision 9bb2a92d)
1 /*
2  * Copyright (c) 2003, 2004 Jeffrey Hsu.
3  * All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions
7  * are met:
8  * 1. Redistributions of source code must retain the above copyright
9  *    notice, this list of conditions and the following disclaimer.
10  * 2. Redistributions in binary form must reproduce the above copyright
11  *    notice, this list of conditions and the following disclaimer in the
12  *    documentation and/or other materials provided with the distribution.
13  * 3. All advertising materials mentioning features or use of this software
14  *    must display the following acknowledgement:
15  *	This product includes software developed by Jeffrey M. Hsu.
16  * 4. The name of the author may not be used to endorse or promote products
17  *    derived from this software without specific prior written permission.
18  *
19  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
20  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
21  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
22  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
23  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
24  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
28  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  *
30  * $DragonFly: src/sys/kern/uipc_msg.c,v 1.3 2004/03/06 23:19:01 dillon Exp $
31  */
32 
33 #if defined(SMP) || defined(ALWAYS_MSG)
34 
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/msgport.h>
38 #include <sys/protosw.h>
39 #include <sys/socket.h>
40 #include <sys/socketvar.h>
41 #include <sys/socketops.h>
42 #include <sys/thread.h>
43 #include <sys/thread2.h>
44 #include <sys/msgport2.h>
45 
46 #include <net/netisr.h>
47 #include <net/netmsg.h>
48 
49 static int netmsg_pru_dispatcher(struct netmsg *msg);
50 
51 int
52 so_pru_abort(struct socket *so)
53 {
54 	int error;
55 	struct netmsg_pru_abort msg;
56 	lwkt_port_t port;
57 
58 	if (!so->so_proto->pr_mport)
59 		return ((*so->so_proto->pr_usrreqs->pru_abort)(so));
60 
61 	port = so->so_proto->pr_mport(so, NULL);
62 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_ABORT);
63 	msg.nm_handler = netmsg_pru_dispatcher;
64 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_abort;
65 	msg.nm_so = so;
66 	error = lwkt_domsg(port, &msg.nm_lmsg);
67 	return (error);
68 }
69 
70 int
71 so_pru_accept(struct socket *so, struct sockaddr **nam)
72 {
73 	int error;
74 	struct netmsg_pru_accept msg;
75 	lwkt_port_t port;
76 
77 	if (!so->so_proto->pr_mport)
78 		return ((*so->so_proto->pr_usrreqs->pru_accept)(so, nam));
79 
80 	port = so->so_proto->pr_mport(so, NULL);
81 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_ACCEPT);
82 	msg.nm_handler = netmsg_pru_dispatcher;
83 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_accept;
84 	msg.nm_so = so;
85 	msg.nm_nam = nam;
86 	error = lwkt_domsg(port, &msg.nm_lmsg);
87 	return (error);
88 }
89 
90 int
91 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai)
92 {
93 	int error;
94 	struct netmsg_pru_attach msg;
95 	lwkt_port_t port;
96 
97 	if (!so->so_proto->pr_mport)
98 		return ((*so->so_proto->pr_usrreqs->pru_attach)(so, proto, ai));
99 
100 	port = so->so_proto->pr_mport(NULL, NULL);
101 
102 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_ATTACH);
103 	msg.nm_handler = netmsg_pru_dispatcher;
104 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_attach;
105 	msg.nm_so = so;
106 	msg.nm_proto = proto;
107 	msg.nm_ai = ai;
108 	error = lwkt_domsg(port, &msg.nm_lmsg);
109 	return (error);
110 }
111 
112 int
113 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
114 {
115 	int error;
116 	struct netmsg_pru_bind msg;
117 	lwkt_port_t port;
118 
119 	if (!so->so_proto->pr_mport)
120 		return ((*so->so_proto->pr_usrreqs->pru_bind)(so, nam, td));
121 
122 	/* Send mesg to thread for new address. */
123 	port = so->so_proto->pr_mport(NULL, nam);
124 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_BIND);
125 	msg.nm_handler = netmsg_pru_dispatcher;
126 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_bind;
127 	msg.nm_so = so;
128 	msg.nm_nam = nam;
129 	msg.nm_td = td;		/* used only for prison_ip() XXX JH */
130 	error = lwkt_domsg(port, &msg.nm_lmsg);
131 	return (error);
132 }
133 
134 int
135 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
136 {
137 	int error;
138 	struct netmsg_pru_connect msg;
139 	lwkt_port_t port;
140 
141 	if (!so->so_proto->pr_mport)
142 		return ((*so->so_proto->pr_usrreqs->pru_connect)(so, nam, td));
143 
144 	port = so->so_proto->pr_mport(so, NULL);
145 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_CONNECT);
146 	msg.nm_handler = netmsg_pru_dispatcher;
147 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_connect;
148 	msg.nm_so = so;
149 	msg.nm_nam = nam;
150 	msg.nm_td = td;
151 	error = lwkt_domsg(port, &msg.nm_lmsg);
152 	return (error);
153 }
154 
155 int
156 so_pru_connect2(struct socket *so1, struct socket *so2)
157 {
158 	int error;
159 	struct netmsg_pru_connect2 msg;
160 	lwkt_port_t port;
161 
162 	if (!so1->so_proto->pr_mport)
163 		return ((*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2));
164 
165 	/*
166 	 * Actually, connect2() is only called for Unix domain sockets
167 	 * and we currently short-circuit that above, so the following
168 	 * code is never reached.
169 	 */
170 	panic("connect2 on socket type %d", so1->so_type);
171 	port = so1->so_proto->pr_mport(so1, NULL);
172 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_CONNECT2);
173 	msg.nm_handler = netmsg_pru_dispatcher;
174 	msg.nm_prufn = so1->so_proto->pr_usrreqs->pru_connect2;
175 	msg.nm_so1 = so1;
176 	msg.nm_so2 = so2;
177 	error = lwkt_domsg(port, &msg.nm_lmsg);
178 	return (error);
179 }
180 
181 int
182 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
183     struct thread *td)
184 {
185 	int error;
186 	struct netmsg_pru_control msg;
187 	lwkt_port_t port;
188 
189 	if (!so->so_proto->pr_mport)
190 		return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data,
191 		    ifp, td));
192 
193 	port = so->so_proto->pr_mport(so, NULL);
194 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_CONTROL);
195 	msg.nm_handler = netmsg_pru_dispatcher;
196 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control;
197 	msg.nm_so = so;
198 	msg.nm_cmd = cmd;
199 	msg.nm_data = data;
200 	msg.nm_ifp = ifp;
201 	msg.nm_td = td;
202 	error = lwkt_domsg(port, &msg.nm_lmsg);
203 	return (error);
204 }
205 
206 int
207 so_pru_detach(struct socket *so)
208 {
209 	int error;
210 	struct netmsg_pru_detach msg;
211 	lwkt_port_t port;
212 
213 	if (!so->so_proto->pr_mport)
214 		return ((*so->so_proto->pr_usrreqs->pru_detach)(so));
215 
216 	port = so->so_proto->pr_mport(so, NULL);
217 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_DETACH);
218 	msg.nm_handler = netmsg_pru_dispatcher;
219 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach;
220 	msg.nm_so = so;
221 	error = lwkt_domsg(port, &msg.nm_lmsg);
222 	return (error);
223 }
224 
225 int
226 so_pru_disconnect(struct socket *so)
227 {
228 	int error;
229 	struct netmsg_pru_disconnect msg;
230 	lwkt_port_t port;
231 
232 	if (!so->so_proto->pr_mport)
233 		return ((*so->so_proto->pr_usrreqs->pru_disconnect)(so));
234 
235 	port = so->so_proto->pr_mport(so, NULL);
236 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_DISCONNECT);
237 	msg.nm_handler = netmsg_pru_dispatcher;
238 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect;
239 	msg.nm_so = so;
240 	error = lwkt_domsg(port, &msg.nm_lmsg);
241 	return (error);
242 }
243 
244 int
245 so_pru_listen(struct socket *so, struct thread *td)
246 {
247 	int error;
248 	struct netmsg_pru_listen msg;
249 	lwkt_port_t port;
250 
251 	if (!so->so_proto->pr_mport)
252 		return ((*so->so_proto->pr_usrreqs->pru_listen)(so, td));
253 
254 	port = so->so_proto->pr_mport(so, NULL);
255 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_LISTEN);
256 	msg.nm_handler = netmsg_pru_dispatcher;
257 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen;
258 	msg.nm_so = so;
259 	msg.nm_td = td;		/* used only for prison_ip() XXX JH */
260 	error = lwkt_domsg(port, &msg.nm_lmsg);
261 	return (error);
262 }
263 
264 int
265 so_pru_peeraddr(struct socket *so, struct sockaddr **nam)
266 {
267 	int error;
268 	struct netmsg_pru_peeraddr msg;
269 	lwkt_port_t port;
270 
271 	if (!so->so_proto->pr_mport)
272 		return ((*so->so_proto->pr_usrreqs->pru_peeraddr)(so, nam));
273 
274 	port = so->so_proto->pr_mport(so, NULL);
275 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_PEERADDR);
276 	msg.nm_handler = netmsg_pru_dispatcher;
277 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr;
278 	msg.nm_so = so;
279 	msg.nm_nam = nam;
280 	error = lwkt_domsg(port, &msg.nm_lmsg);
281 	return (error);
282 }
283 
284 int
285 so_pru_rcvd(struct socket *so, int flags)
286 {
287 	int error;
288 	struct netmsg_pru_rcvd msg;
289 	lwkt_port_t port;
290 
291 	if (!so->so_proto->pr_mport)
292 		return ((*so->so_proto->pr_usrreqs->pru_rcvd)(so, flags));
293 
294 	port = so->so_proto->pr_mport(so, NULL);
295 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_RCVD);
296 	msg.nm_handler = netmsg_pru_dispatcher;
297 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd;
298 	msg.nm_so = so;
299 	msg.nm_flags = flags;
300 	error = lwkt_domsg(port, &msg.nm_lmsg);
301 	return (error);
302 }
303 
304 int
305 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
306 {
307 	int error;
308 	struct netmsg_pru_rcvoob msg;
309 	lwkt_port_t port;
310 
311 	if (!so->so_proto->pr_mport)
312 		return ((*so->so_proto->pr_usrreqs->pru_rcvoob)(so, m, flags));
313 
314 	port = so->so_proto->pr_mport(so, NULL);
315 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_RCVOOB);
316 	msg.nm_handler = netmsg_pru_dispatcher;
317 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob;
318 	msg.nm_so = so;
319 	msg.nm_m = m;
320 	msg.nm_flags = flags;
321 	error = lwkt_domsg(port, &msg.nm_lmsg);
322 	return (error);
323 }
324 
325 int
326 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
327     struct mbuf *control, struct thread *td)
328 {
329 	int error;
330 	struct netmsg_pru_send msg;
331 	lwkt_port_t port;
332 
333 	if (!so->so_proto->pr_mport)
334 		return ((*so->so_proto->pr_usrreqs->pru_send)(so, flags, m,
335 		    addr, control, td));
336 
337 	port = so->so_proto->pr_mport(so, NULL);
338 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SEND);
339 	msg.nm_handler = netmsg_pru_dispatcher;
340 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send;
341 	msg.nm_so = so;
342 	msg.nm_flags = flags;
343 	msg.nm_m = m;
344 	msg.nm_addr = addr;
345 	msg.nm_control = control;
346 	msg.nm_td = td;
347 	error = lwkt_domsg(port, &msg.nm_lmsg);
348 	return (error);
349 }
350 
351 int
352 so_pru_sense(struct socket *so, struct stat *sb)
353 {
354 	int error;
355 	struct netmsg_pru_sense msg;
356 	lwkt_port_t port;
357 
358 	if (!so->so_proto->pr_mport)
359 		return ((*so->so_proto->pr_usrreqs->pru_sense)(so, sb));
360 
361 	port = so->so_proto->pr_mport(so, NULL);
362 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SENSE);
363 	msg.nm_handler = netmsg_pru_dispatcher;
364 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense;
365 	msg.nm_so = so;
366 	msg.nm_stat = sb;
367 	error = lwkt_domsg(port, &msg.nm_lmsg);
368 	return (error);
369 }
370 
371 int
372 so_pru_shutdown(struct socket *so)
373 {
374 	int error;
375 	struct netmsg_pru_shutdown msg;
376 	lwkt_port_t port;
377 
378 	if (!so->so_proto->pr_mport)
379 		return ((*so->so_proto->pr_usrreqs->pru_shutdown)(so));
380 
381 	port = so->so_proto->pr_mport(so, NULL);
382 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SHUTDOWN);
383 	msg.nm_handler = netmsg_pru_dispatcher;
384 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown;
385 	msg.nm_so = so;
386 	error = lwkt_domsg(port, &msg.nm_lmsg);
387 	return (error);
388 }
389 
390 int
391 so_pru_sockaddr(struct socket *so, struct sockaddr **nam)
392 {
393 	int error;
394 	struct netmsg_pru_sockaddr msg;
395 	lwkt_port_t port;
396 
397 	if (!so->so_proto->pr_mport)
398 		return ((*so->so_proto->pr_usrreqs->pru_sockaddr)(so, nam));
399 
400 	port = so->so_proto->pr_mport(so, NULL);
401 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SOCKADDR);
402 	msg.nm_handler = netmsg_pru_dispatcher;
403 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr;
404 	msg.nm_so = so;
405 	msg.nm_nam = nam;
406 	error = lwkt_domsg(port, &msg.nm_lmsg);
407 	return (error);
408 }
409 
410 int
411 so_pru_sopoll(struct socket *so, int events, struct ucred *cred,
412     struct thread *td)
413 {
414 	int error;
415 	struct netmsg_pru_sopoll msg;
416 	lwkt_port_t port;
417 
418 	if (!so->so_proto->pr_mport)
419 		return ((*so->so_proto->pr_usrreqs->pru_sopoll)(so, events,
420 		    cred, td));
421 
422 	port = so->so_proto->pr_mport(so, NULL);
423 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SOPOLL);
424 	msg.nm_handler = netmsg_pru_dispatcher;
425 	msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll;
426 	msg.nm_so = so;
427 	msg.nm_events = events;
428 	msg.nm_cred = cred;
429 	msg.nm_td = td;
430 	error = lwkt_domsg(port, &msg.nm_lmsg);
431 	return (error);
432 }
433 
434 int
435 so_pr_ctloutput(struct socket *so, struct sockopt *sopt)
436 {
437 	return ((*so->so_proto->pr_ctloutput)(so, sopt));
438 #ifdef gag	/* does copyin and copyout deep inside stack XXX JH */
439 	struct netmsg_pr_ctloutput msg;
440 	lwkt_port_t port;
441 	int error;
442 
443 	if (!so->so_proto->pr_mport)
444 		return ((*so->so_proto->pr_ctloutput)(so, sopt));
445 
446 	port = so->so_proto->pr_mport(so, NULL);
447 	lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PR_CTLOUTPUT);
448 	msg.nm_handler = netmsg_pr_dispatcher;
449 	msg.nm_prfn = so->so_proto->pr_ctloutput;
450 	msg.nm_so = so;
451 	msg.nm_sopt = sopt;
452 	error = lwkt_domsg(port, &msg.nm_lmsg);
453 	return (error);
454 #endif
455 }
456 
457 /*
458  * If we convert all the pru_usrreq functions for all the protocols
459  * to take a message directly, this layer can go away.
460  */
461 static int
462 netmsg_pru_dispatcher(struct netmsg *msg)
463 {
464 	int error;
465 
466 	switch (msg->nm_lmsg.ms_cmd) {
467 	case CMD_NETMSG_PRU_ABORT:
468 	{
469 		struct netmsg_pru_abort *nm = (struct netmsg_pru_abort *)msg;
470 
471 		error = nm->nm_prufn(nm->nm_so);
472 		break;
473 	}
474 	case CMD_NETMSG_PRU_ACCEPT:
475 	{
476 		struct netmsg_pru_accept *nm = (struct netmsg_pru_accept *)msg;
477 
478 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
479 		break;
480 	}
481 	case CMD_NETMSG_PRU_ATTACH:
482 	{
483 		struct netmsg_pru_attach *nm = (struct netmsg_pru_attach *)msg;
484 
485 		error = nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai);
486 		break;
487 	}
488 	case CMD_NETMSG_PRU_BIND:
489 	{
490 		struct netmsg_pru_bind *nm = (struct netmsg_pru_bind *)msg;
491 
492 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
493 		break;
494 	}
495 	case CMD_NETMSG_PRU_CONNECT:
496 	{
497 		struct netmsg_pru_connect *nm =
498 		    (struct netmsg_pru_connect *)msg;
499 
500 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
501 		break;
502 	}
503 	case CMD_NETMSG_PRU_CONNECT2:
504 	{
505 		struct netmsg_pru_connect2 *nm =
506 		    (struct netmsg_pru_connect2 *)msg;
507 
508 		error = nm->nm_prufn(nm->nm_so1, nm->nm_so2);
509 		break;
510 	}
511 	case CMD_NETMSG_PRU_CONTROL:
512 	{
513 		struct netmsg_pru_control *nm =
514 		    (struct netmsg_pru_control *)msg;
515 
516 		error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data,
517 		    nm->nm_ifp, nm->nm_td);
518 		break;
519 	}
520 	case CMD_NETMSG_PRU_DETACH:
521 	{
522 		struct netmsg_pru_detach *nm = (struct netmsg_pru_detach *)msg;
523 
524 		error = nm->nm_prufn(nm->nm_so);
525 		break;
526 	}
527 	case CMD_NETMSG_PRU_DISCONNECT:
528 	{
529 		struct netmsg_pru_disconnect *nm =
530 		    (struct netmsg_pru_disconnect *)msg;
531 
532 		error = nm->nm_prufn(nm->nm_so);
533 		break;
534 	}
535 	case CMD_NETMSG_PRU_LISTEN:
536 	{
537 		struct netmsg_pru_listen *nm = (struct netmsg_pru_listen *)msg;
538 
539 		error = nm->nm_prufn(nm->nm_so, nm->nm_td);
540 		break;
541 	}
542 	case CMD_NETMSG_PRU_PEERADDR:
543 	{
544 		struct netmsg_pru_peeraddr *nm =
545 		    (struct netmsg_pru_peeraddr *)msg;
546 
547 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
548 		break;
549 	}
550 	case CMD_NETMSG_PRU_RCVD:
551 	{
552 		struct netmsg_pru_rcvd *nm = (struct netmsg_pru_rcvd *)msg;
553 
554 		error = nm->nm_prufn(nm->nm_so, nm->nm_flags);
555 		break;
556 	}
557 	case CMD_NETMSG_PRU_RCVOOB:
558 	{
559 		struct netmsg_pru_rcvoob *nm = (struct netmsg_pru_rcvoob *)msg;
560 
561 		error = nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags);
562 		break;
563 	}
564 	case CMD_NETMSG_PRU_SEND:
565 	{
566 		struct netmsg_pru_send *nm = (struct netmsg_pru_send *)msg;
567 
568 		error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m,
569 		    nm->nm_addr, nm->nm_control, nm->nm_td);
570 		break;
571 	}
572 	case CMD_NETMSG_PRU_SENSE:
573 	{
574 		struct netmsg_pru_sense *nm = (struct netmsg_pru_sense *)msg;
575 
576 		error = nm->nm_prufn(nm->nm_so, nm->nm_stat);
577 		break;
578 	}
579 	case CMD_NETMSG_PRU_SHUTDOWN:
580 	{
581 		struct netmsg_pru_shutdown *nm =
582 		    (struct netmsg_pru_shutdown *)msg;
583 
584 		error = nm->nm_prufn(nm->nm_so);
585 		break;
586 	}
587 	case CMD_NETMSG_PRU_SOCKADDR:
588 	{
589 		struct netmsg_pru_sockaddr *nm =
590 		    (struct netmsg_pru_sockaddr *)msg;
591 
592 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
593 		break;
594 	}
595 	case CMD_NETMSG_PRU_SOPOLL:
596 	{
597 		struct netmsg_pru_sopoll *nm =
598 		    (struct netmsg_pru_sopoll *)msg;
599 
600 		error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred,
601 		    nm->nm_td);
602 		break;
603 	}
604 	default:
605 		panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);
606 		break;
607 	}
608 	return(error);
609 }
610 
611 /*
612  * If we convert all the protosw pr_ functions for all the protocols
613  * to take a message directly, this layer can go away.
614  */
615 int
616 netmsg_pr_dispatcher(struct netmsg *msg)
617 {
618 	int error = 0;
619 
620 	switch (msg->nm_lmsg.ms_cmd) {
621 	case CMD_NETMSG_PR_CTLOUTPUT:
622 	{
623 		struct netmsg_pr_ctloutput *nm =
624 		    (struct netmsg_pr_ctloutput *)msg;
625 
626 		error = nm->nm_prfn(nm->nm_so, nm->nm_sopt);
627 		break;
628 	}
629 	case CMD_NETMSG_PR_TIMEOUT:
630 	{
631 		struct netmsg_pr_timeout *nm = (struct netmsg_pr_timeout *)msg;
632 
633 		nm->nm_prfn();
634 		break;
635 	}
636 	default:
637 		panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);
638 		break;
639 	}
640 	return(error);
641 }
642 
643 #endif
644