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.4 2004/03/19 17:00:04 dillon Exp $
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>
44 #include <net/netisr.h>
45 #include <net/netmsg.h>
47 static int netmsg_pru_dispatcher(struct netmsg *msg);
50 so_pru_abort(struct socket *so)
53 struct netmsg_pru_abort msg;
56 if (!so->so_proto->pr_mport)
57 return ((*so->so_proto->pr_usrreqs->pru_abort)(so));
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;
64 error = lwkt_domsg(port, &msg.nm_lmsg);
69 so_pru_accept(struct socket *so, struct sockaddr **nam)
72 struct netmsg_pru_accept msg;
75 if (!so->so_proto->pr_mport)
76 return ((*so->so_proto->pr_usrreqs->pru_accept)(so, nam));
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;
84 error = lwkt_domsg(port, &msg.nm_lmsg);
89 so_pru_attach(struct socket *so, int proto, struct pru_attach_info *ai)
92 struct netmsg_pru_attach msg;
95 if (!so->so_proto->pr_mport)
96 return ((*so->so_proto->pr_usrreqs->pru_attach)(so, proto, ai));
98 port = so->so_proto->pr_mport(NULL, NULL);
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;
104 msg.nm_proto = proto;
106 error = lwkt_domsg(port, &msg.nm_lmsg);
111 so_pru_bind(struct socket *so, struct sockaddr *nam, struct thread *td)
114 struct netmsg_pru_bind msg;
117 if (!so->so_proto->pr_mport)
118 return ((*so->so_proto->pr_usrreqs->pru_bind)(so, nam, td));
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;
127 msg.nm_td = td; /* used only for prison_ip() XXX JH */
128 error = lwkt_domsg(port, &msg.nm_lmsg);
133 so_pru_connect(struct socket *so, struct sockaddr *nam, struct thread *td)
136 struct netmsg_pru_connect msg;
139 if (!so->so_proto->pr_mport)
140 return ((*so->so_proto->pr_usrreqs->pru_connect)(so, nam, td));
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;
149 error = lwkt_domsg(port, &msg.nm_lmsg);
154 so_pru_connect2(struct socket *so1, struct socket *so2)
157 struct netmsg_pru_connect2 msg;
160 if (!so1->so_proto->pr_mport)
161 return ((*so1->so_proto->pr_usrreqs->pru_connect2)(so1, so2));
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.
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;
175 error = lwkt_domsg(port, &msg.nm_lmsg);
180 so_pru_control(struct socket *so, u_long cmd, caddr_t data, struct ifnet *ifp,
184 struct netmsg_pru_control msg;
187 if (!so->so_proto->pr_mport)
188 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data,
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;
200 error = lwkt_domsg(port, &msg.nm_lmsg);
205 so_pru_detach(struct socket *so)
208 struct netmsg_pru_detach msg;
211 if (!so->so_proto->pr_mport)
212 return ((*so->so_proto->pr_usrreqs->pru_detach)(so));
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;
219 error = lwkt_domsg(port, &msg.nm_lmsg);
224 so_pru_disconnect(struct socket *so)
227 struct netmsg_pru_disconnect msg;
230 if (!so->so_proto->pr_mport)
231 return ((*so->so_proto->pr_usrreqs->pru_disconnect)(so));
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;
238 error = lwkt_domsg(port, &msg.nm_lmsg);
243 so_pru_listen(struct socket *so, struct thread *td)
246 struct netmsg_pru_listen msg;
249 if (!so->so_proto->pr_mport)
250 return ((*so->so_proto->pr_usrreqs->pru_listen)(so, td));
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;
257 msg.nm_td = td; /* used only for prison_ip() XXX JH */
258 error = lwkt_domsg(port, &msg.nm_lmsg);
263 so_pru_peeraddr(struct socket *so, struct sockaddr **nam)
266 struct netmsg_pru_peeraddr msg;
269 if (!so->so_proto->pr_mport)
270 return ((*so->so_proto->pr_usrreqs->pru_peeraddr)(so, nam));
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;
278 error = lwkt_domsg(port, &msg.nm_lmsg);
283 so_pru_rcvd(struct socket *so, int flags)
286 struct netmsg_pru_rcvd msg;
289 if (!so->so_proto->pr_mport)
290 return ((*so->so_proto->pr_usrreqs->pru_rcvd)(so, flags));
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;
297 msg.nm_flags = flags;
298 error = lwkt_domsg(port, &msg.nm_lmsg);
303 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
306 struct netmsg_pru_rcvoob msg;
309 if (!so->so_proto->pr_mport)
310 return ((*so->so_proto->pr_usrreqs->pru_rcvoob)(so, m, flags));
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;
318 msg.nm_flags = flags;
319 error = lwkt_domsg(port, &msg.nm_lmsg);
324 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
325 struct mbuf *control, struct thread *td)
328 struct netmsg_pru_send msg;
331 if (!so->so_proto->pr_mport)
332 return ((*so->so_proto->pr_usrreqs->pru_send)(so, flags, m,
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;
340 msg.nm_flags = flags;
343 msg.nm_control = control;
345 error = lwkt_domsg(port, &msg.nm_lmsg);
350 so_pru_sense(struct socket *so, struct stat *sb)
353 struct netmsg_pru_sense msg;
356 if (!so->so_proto->pr_mport)
357 return ((*so->so_proto->pr_usrreqs->pru_sense)(so, sb));
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;
365 error = lwkt_domsg(port, &msg.nm_lmsg);
370 so_pru_shutdown(struct socket *so)
373 struct netmsg_pru_shutdown msg;
376 if (!so->so_proto->pr_mport)
377 return ((*so->so_proto->pr_usrreqs->pru_shutdown)(so));
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;
384 error = lwkt_domsg(port, &msg.nm_lmsg);
389 so_pru_sockaddr(struct socket *so, struct sockaddr **nam)
392 struct netmsg_pru_sockaddr msg;
395 if (!so->so_proto->pr_mport)
396 return ((*so->so_proto->pr_usrreqs->pru_sockaddr)(so, nam));
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;
404 error = lwkt_domsg(port, &msg.nm_lmsg);
409 so_pru_sopoll(struct socket *so, int events, struct ucred *cred,
413 struct netmsg_pru_sopoll msg;
416 if (!so->so_proto->pr_mport)
417 return ((*so->so_proto->pr_usrreqs->pru_sopoll)(so, events,
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;
425 msg.nm_events = events;
428 error = lwkt_domsg(port, &msg.nm_lmsg);
433 so_pr_ctloutput(struct socket *so, struct sockopt *sopt)
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;
441 if (!so->so_proto->pr_mport)
442 return ((*so->so_proto->pr_ctloutput)(so, sopt));
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;
450 error = lwkt_domsg(port, &msg.nm_lmsg);
456 * If we convert all the pru_usrreq functions for all the protocols
457 * to take a message directly, this layer can go away.
460 netmsg_pru_dispatcher(struct netmsg *msg)
464 switch (msg->nm_lmsg.ms_cmd) {
465 case CMD_NETMSG_PRU_ABORT:
467 struct netmsg_pru_abort *nm = (struct netmsg_pru_abort *)msg;
469 error = nm->nm_prufn(nm->nm_so);
472 case CMD_NETMSG_PRU_ACCEPT:
474 struct netmsg_pru_accept *nm = (struct netmsg_pru_accept *)msg;
476 error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
479 case CMD_NETMSG_PRU_ATTACH:
481 struct netmsg_pru_attach *nm = (struct netmsg_pru_attach *)msg;
483 error = nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai);
486 case CMD_NETMSG_PRU_BIND:
488 struct netmsg_pru_bind *nm = (struct netmsg_pru_bind *)msg;
490 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
493 case CMD_NETMSG_PRU_CONNECT:
495 struct netmsg_pru_connect *nm =
496 (struct netmsg_pru_connect *)msg;
498 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
501 case CMD_NETMSG_PRU_CONNECT2:
503 struct netmsg_pru_connect2 *nm =
504 (struct netmsg_pru_connect2 *)msg;
506 error = nm->nm_prufn(nm->nm_so1, nm->nm_so2);
509 case CMD_NETMSG_PRU_CONTROL:
511 struct netmsg_pru_control *nm =
512 (struct netmsg_pru_control *)msg;
514 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data,
515 nm->nm_ifp, nm->nm_td);
518 case CMD_NETMSG_PRU_DETACH:
520 struct netmsg_pru_detach *nm = (struct netmsg_pru_detach *)msg;
522 error = nm->nm_prufn(nm->nm_so);
525 case CMD_NETMSG_PRU_DISCONNECT:
527 struct netmsg_pru_disconnect *nm =
528 (struct netmsg_pru_disconnect *)msg;
530 error = nm->nm_prufn(nm->nm_so);
533 case CMD_NETMSG_PRU_LISTEN:
535 struct netmsg_pru_listen *nm = (struct netmsg_pru_listen *)msg;
537 error = nm->nm_prufn(nm->nm_so, nm->nm_td);
540 case CMD_NETMSG_PRU_PEERADDR:
542 struct netmsg_pru_peeraddr *nm =
543 (struct netmsg_pru_peeraddr *)msg;
545 error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
548 case CMD_NETMSG_PRU_RCVD:
550 struct netmsg_pru_rcvd *nm = (struct netmsg_pru_rcvd *)msg;
552 error = nm->nm_prufn(nm->nm_so, nm->nm_flags);
555 case CMD_NETMSG_PRU_RCVOOB:
557 struct netmsg_pru_rcvoob *nm = (struct netmsg_pru_rcvoob *)msg;
559 error = nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags);
562 case CMD_NETMSG_PRU_SEND:
564 struct netmsg_pru_send *nm = (struct netmsg_pru_send *)msg;
566 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m,
567 nm->nm_addr, nm->nm_control, nm->nm_td);
570 case CMD_NETMSG_PRU_SENSE:
572 struct netmsg_pru_sense *nm = (struct netmsg_pru_sense *)msg;
574 error = nm->nm_prufn(nm->nm_so, nm->nm_stat);
577 case CMD_NETMSG_PRU_SHUTDOWN:
579 struct netmsg_pru_shutdown *nm =
580 (struct netmsg_pru_shutdown *)msg;
582 error = nm->nm_prufn(nm->nm_so);
585 case CMD_NETMSG_PRU_SOCKADDR:
587 struct netmsg_pru_sockaddr *nm =
588 (struct netmsg_pru_sockaddr *)msg;
590 error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
593 case CMD_NETMSG_PRU_SOPOLL:
595 struct netmsg_pru_sopoll *nm =
596 (struct netmsg_pru_sopoll *)msg;
598 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred,
603 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);
610 * If we convert all the protosw pr_ functions for all the protocols
611 * to take a message directly, this layer can go away.
614 netmsg_pr_dispatcher(struct netmsg *msg)
618 switch (msg->nm_lmsg.ms_cmd) {
619 case CMD_NETMSG_PR_CTLOUTPUT:
621 struct netmsg_pr_ctloutput *nm =
622 (struct netmsg_pr_ctloutput *)msg;
624 error = nm->nm_prfn(nm->nm_so, nm->nm_sopt);
627 case CMD_NETMSG_PR_TIMEOUT:
629 struct netmsg_pr_timeout *nm = (struct netmsg_pr_timeout *)msg;
635 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);