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