2 * Copyright (c) 2003, 2004 Jeffrey Hsu.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
30 * $DragonFly: src/sys/kern/uipc_msg.c,v 1.3 2004/03/06 23:19:01 dillon Exp $
33 #if defined(SMP) || defined(ALWAYS_MSG)
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>
46 #include <net/netisr.h>
47 #include <net/netmsg.h>
49 static int netmsg_pru_dispatcher(struct netmsg *msg);
52 so_pru_abort(struct socket *so)
55 struct netmsg_pru_abort msg;
58 if (!so->so_proto->pr_mport)
59 return ((*so->so_proto->pr_usrreqs->pru_abort)(so));
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;
66 error = lwkt_domsg(port, &msg.nm_lmsg);
71 so_pru_accept(struct socket *so, struct sockaddr **nam)
74 struct netmsg_pru_accept msg;
77 if (!so->so_proto->pr_mport)
78 return ((*so->so_proto->pr_usrreqs->pru_accept)(so, nam));
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;
86 error = lwkt_domsg(port, &msg.nm_lmsg);
91 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai)
94 struct netmsg_pru_attach msg;
97 if (!so->so_proto->pr_mport)
98 return ((*so->so_proto->pr_usrreqs->pru_attach)(so, proto, ai));
100 port = so->so_proto->pr_mport(NULL, NULL);
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;
106 msg.nm_proto = proto;
108 error = lwkt_domsg(port, &msg.nm_lmsg);
113 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
116 struct netmsg_pru_bind msg;
119 if (!so->so_proto->pr_mport)
120 return ((*so->so_proto->pr_usrreqs->pru_bind)(so, nam, td));
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;
129 msg.nm_td = td; /* used only for prison_ip() XXX JH */
130 error = lwkt_domsg(port, &msg.nm_lmsg);
135 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
138 struct netmsg_pru_connect msg;
141 if (!so->so_proto->pr_mport)
142 return ((*so->so_proto->pr_usrreqs->pru_connect)(so, nam, td));
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;
151 error = lwkt_domsg(port, &msg.nm_lmsg);
156 so_pru_connect2(struct socket *so1, struct socket *so2)
159 struct netmsg_pru_connect2 msg;
162 if (!so1->so_proto->pr_mport)
163 return ((*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2));
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.
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;
177 error = lwkt_domsg(port, &msg.nm_lmsg);
182 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
186 struct netmsg_pru_control msg;
189 if (!so->so_proto->pr_mport)
190 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data,
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;
202 error = lwkt_domsg(port, &msg.nm_lmsg);
207 so_pru_detach(struct socket *so)
210 struct netmsg_pru_detach msg;
213 if (!so->so_proto->pr_mport)
214 return ((*so->so_proto->pr_usrreqs->pru_detach)(so));
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;
221 error = lwkt_domsg(port, &msg.nm_lmsg);
226 so_pru_disconnect(struct socket *so)
229 struct netmsg_pru_disconnect msg;
232 if (!so->so_proto->pr_mport)
233 return ((*so->so_proto->pr_usrreqs->pru_disconnect)(so));
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;
240 error = lwkt_domsg(port, &msg.nm_lmsg);
245 so_pru_listen(struct socket *so, struct thread *td)
248 struct netmsg_pru_listen msg;
251 if (!so->so_proto->pr_mport)
252 return ((*so->so_proto->pr_usrreqs->pru_listen)(so, td));
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;
259 msg.nm_td = td; /* used only for prison_ip() XXX JH */
260 error = lwkt_domsg(port, &msg.nm_lmsg);
265 so_pru_peeraddr(struct socket *so, struct sockaddr **nam)
268 struct netmsg_pru_peeraddr msg;
271 if (!so->so_proto->pr_mport)
272 return ((*so->so_proto->pr_usrreqs->pru_peeraddr)(so, nam));
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;
280 error = lwkt_domsg(port, &msg.nm_lmsg);
285 so_pru_rcvd(struct socket *so, int flags)
288 struct netmsg_pru_rcvd msg;
291 if (!so->so_proto->pr_mport)
292 return ((*so->so_proto->pr_usrreqs->pru_rcvd)(so, flags));
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;
299 msg.nm_flags = flags;
300 error = lwkt_domsg(port, &msg.nm_lmsg);
305 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
308 struct netmsg_pru_rcvoob msg;
311 if (!so->so_proto->pr_mport)
312 return ((*so->so_proto->pr_usrreqs->pru_rcvoob)(so, m, flags));
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;
320 msg.nm_flags = flags;
321 error = lwkt_domsg(port, &msg.nm_lmsg);
326 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
327 struct mbuf *control, struct thread *td)
330 struct netmsg_pru_send msg;
333 if (!so->so_proto->pr_mport)
334 return ((*so->so_proto->pr_usrreqs->pru_send)(so, flags, m,
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;
342 msg.nm_flags = flags;
345 msg.nm_control = control;
347 error = lwkt_domsg(port, &msg.nm_lmsg);
352 so_pru_sense(struct socket *so, struct stat *sb)
355 struct netmsg_pru_sense msg;
358 if (!so->so_proto->pr_mport)
359 return ((*so->so_proto->pr_usrreqs->pru_sense)(so, sb));
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;
367 error = lwkt_domsg(port, &msg.nm_lmsg);
372 so_pru_shutdown(struct socket *so)
375 struct netmsg_pru_shutdown msg;
378 if (!so->so_proto->pr_mport)
379 return ((*so->so_proto->pr_usrreqs->pru_shutdown)(so));
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;
386 error = lwkt_domsg(port, &msg.nm_lmsg);
391 so_pru_sockaddr(struct socket *so, struct sockaddr **nam)
394 struct netmsg_pru_sockaddr msg;
397 if (!so->so_proto->pr_mport)
398 return ((*so->so_proto->pr_usrreqs->pru_sockaddr)(so, nam));
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;
406 error = lwkt_domsg(port, &msg.nm_lmsg);
411 so_pru_sopoll(struct socket *so, int events, struct ucred *cred,
415 struct netmsg_pru_sopoll msg;
418 if (!so->so_proto->pr_mport)
419 return ((*so->so_proto->pr_usrreqs->pru_sopoll)(so, events,
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;
427 msg.nm_events = events;
430 error = lwkt_domsg(port, &msg.nm_lmsg);
435 so_pr_ctloutput(struct socket *so, struct sockopt *sopt)
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;
443 if (!so->so_proto->pr_mport)
444 return ((*so->so_proto->pr_ctloutput)(so, sopt));
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;
452 error = lwkt_domsg(port, &msg.nm_lmsg);
458 * If we convert all the pru_usrreq functions for all the protocols
459 * to take a message directly, this layer can go away.
462 netmsg_pru_dispatcher(struct netmsg *msg)
466 switch (msg->nm_lmsg.ms_cmd) {
467 case CMD_NETMSG_PRU_ABORT:
469 struct netmsg_pru_abort *nm = (struct netmsg_pru_abort *)msg;
471 error = nm->nm_prufn(nm->nm_so);
474 case CMD_NETMSG_PRU_ACCEPT:
476 struct netmsg_pru_accept *nm = (struct netmsg_pru_accept *)msg;
478 error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
481 case CMD_NETMSG_PRU_ATTACH:
483 struct netmsg_pru_attach *nm = (struct netmsg_pru_attach *)msg;
485 error = nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai);
488 case CMD_NETMSG_PRU_BIND:
490 struct netmsg_pru_bind *nm = (struct netmsg_pru_bind *)msg;
492 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
495 case CMD_NETMSG_PRU_CONNECT:
497 struct netmsg_pru_connect *nm =
498 (struct netmsg_pru_connect *)msg;
500 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
503 case CMD_NETMSG_PRU_CONNECT2:
505 struct netmsg_pru_connect2 *nm =
506 (struct netmsg_pru_connect2 *)msg;
508 error = nm->nm_prufn(nm->nm_so1, nm->nm_so2);
511 case CMD_NETMSG_PRU_CONTROL:
513 struct netmsg_pru_control *nm =
514 (struct netmsg_pru_control *)msg;
516 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data,
517 nm->nm_ifp, nm->nm_td);
520 case CMD_NETMSG_PRU_DETACH:
522 struct netmsg_pru_detach *nm = (struct netmsg_pru_detach *)msg;
524 error = nm->nm_prufn(nm->nm_so);
527 case CMD_NETMSG_PRU_DISCONNECT:
529 struct netmsg_pru_disconnect *nm =
530 (struct netmsg_pru_disconnect *)msg;
532 error = nm->nm_prufn(nm->nm_so);
535 case CMD_NETMSG_PRU_LISTEN:
537 struct netmsg_pru_listen *nm = (struct netmsg_pru_listen *)msg;
539 error = nm->nm_prufn(nm->nm_so, nm->nm_td);
542 case CMD_NETMSG_PRU_PEERADDR:
544 struct netmsg_pru_peeraddr *nm =
545 (struct netmsg_pru_peeraddr *)msg;
547 error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
550 case CMD_NETMSG_PRU_RCVD:
552 struct netmsg_pru_rcvd *nm = (struct netmsg_pru_rcvd *)msg;
554 error = nm->nm_prufn(nm->nm_so, nm->nm_flags);
557 case CMD_NETMSG_PRU_RCVOOB:
559 struct netmsg_pru_rcvoob *nm = (struct netmsg_pru_rcvoob *)msg;
561 error = nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags);
564 case CMD_NETMSG_PRU_SEND:
566 struct netmsg_pru_send *nm = (struct netmsg_pru_send *)msg;
568 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m,
569 nm->nm_addr, nm->nm_control, nm->nm_td);
572 case CMD_NETMSG_PRU_SENSE:
574 struct netmsg_pru_sense *nm = (struct netmsg_pru_sense *)msg;
576 error = nm->nm_prufn(nm->nm_so, nm->nm_stat);
579 case CMD_NETMSG_PRU_SHUTDOWN:
581 struct netmsg_pru_shutdown *nm =
582 (struct netmsg_pru_shutdown *)msg;
584 error = nm->nm_prufn(nm->nm_so);
587 case CMD_NETMSG_PRU_SOCKADDR:
589 struct netmsg_pru_sockaddr *nm =
590 (struct netmsg_pru_sockaddr *)msg;
592 error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
595 case CMD_NETMSG_PRU_SOPOLL:
597 struct netmsg_pru_sopoll *nm =
598 (struct netmsg_pru_sopoll *)msg;
600 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred,
605 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);
612 * If we convert all the protosw pr_ functions for all the protocols
613 * to take a message directly, this layer can go away.
616 netmsg_pr_dispatcher(struct netmsg *msg)
620 switch (msg->nm_lmsg.ms_cmd) {
621 case CMD_NETMSG_PR_CTLOUTPUT:
623 struct netmsg_pr_ctloutput *nm =
624 (struct netmsg_pr_ctloutput *)msg;
626 error = nm->nm_prfn(nm->nm_so, nm->nm_sopt);
629 case CMD_NETMSG_PR_TIMEOUT:
631 struct netmsg_pr_timeout *nm = (struct netmsg_pr_timeout *)msg;
637 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);