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