Make ALWAYS_MSG the default. This introduces an extra procedural call
[dragonfly.git] / sys / kern / uipc_msg.c
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