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.5 2004/03/24 21:58:44 hsu 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,
183 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp,
185 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */
187 struct netmsg_pru_control msg;
190 if (!so->so_proto->pr_mport)
191 return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data,
194 port = so->so_proto->pr_mport(so, NULL);
195 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_CONTROL);
196 msg.nm_handler = netmsg_pru_dispatcher;
197 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_control;
203 error = lwkt_domsg(port, &msg.nm_lmsg);
209 so_pru_detach(struct socket *so)
212 struct netmsg_pru_detach msg;
215 if (!so->so_proto->pr_mport)
216 return ((*so->so_proto->pr_usrreqs->pru_detach)(so));
218 port = so->so_proto->pr_mport(so, NULL);
219 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_DETACH);
220 msg.nm_handler = netmsg_pru_dispatcher;
221 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_detach;
223 error = lwkt_domsg(port, &msg.nm_lmsg);
228 so_pru_disconnect(struct socket *so)
231 struct netmsg_pru_disconnect msg;
234 if (!so->so_proto->pr_mport)
235 return ((*so->so_proto->pr_usrreqs->pru_disconnect)(so));
237 port = so->so_proto->pr_mport(so, NULL);
238 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_DISCONNECT);
239 msg.nm_handler = netmsg_pru_dispatcher;
240 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_disconnect;
242 error = lwkt_domsg(port, &msg.nm_lmsg);
247 so_pru_listen(struct socket *so, struct thread *td)
250 struct netmsg_pru_listen msg;
253 if (!so->so_proto->pr_mport)
254 return ((*so->so_proto->pr_usrreqs->pru_listen)(so, td));
256 port = so->so_proto->pr_mport(so, NULL);
257 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_LISTEN);
258 msg.nm_handler = netmsg_pru_dispatcher;
259 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_listen;
261 msg.nm_td = td; /* used only for prison_ip() XXX JH */
262 error = lwkt_domsg(port, &msg.nm_lmsg);
267 so_pru_peeraddr(struct socket *so, struct sockaddr **nam)
270 struct netmsg_pru_peeraddr msg;
273 if (!so->so_proto->pr_mport)
274 return ((*so->so_proto->pr_usrreqs->pru_peeraddr)(so, nam));
276 port = so->so_proto->pr_mport(so, NULL);
277 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_PEERADDR);
278 msg.nm_handler = netmsg_pru_dispatcher;
279 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_peeraddr;
282 error = lwkt_domsg(port, &msg.nm_lmsg);
287 so_pru_rcvd(struct socket *so, int flags)
290 struct netmsg_pru_rcvd msg;
293 if (!so->so_proto->pr_mport)
294 return ((*so->so_proto->pr_usrreqs->pru_rcvd)(so, flags));
296 port = so->so_proto->pr_mport(so, NULL);
297 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_RCVD);
298 msg.nm_handler = netmsg_pru_dispatcher;
299 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvd;
301 msg.nm_flags = flags;
302 error = lwkt_domsg(port, &msg.nm_lmsg);
307 so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
310 struct netmsg_pru_rcvoob msg;
313 if (!so->so_proto->pr_mport)
314 return ((*so->so_proto->pr_usrreqs->pru_rcvoob)(so, m, flags));
316 port = so->so_proto->pr_mport(so, NULL);
317 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_RCVOOB);
318 msg.nm_handler = netmsg_pru_dispatcher;
319 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_rcvoob;
322 msg.nm_flags = flags;
323 error = lwkt_domsg(port, &msg.nm_lmsg);
328 so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
329 struct mbuf *control, struct thread *td)
332 struct netmsg_pru_send msg;
335 if (!so->so_proto->pr_mport)
336 return ((*so->so_proto->pr_usrreqs->pru_send)(so, flags, m,
339 port = so->so_proto->pr_mport(so, NULL);
340 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SEND);
341 msg.nm_handler = netmsg_pru_dispatcher;
342 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_send;
344 msg.nm_flags = flags;
347 msg.nm_control = control;
349 error = lwkt_domsg(port, &msg.nm_lmsg);
354 so_pru_sense(struct socket *so, struct stat *sb)
357 struct netmsg_pru_sense msg;
360 if (!so->so_proto->pr_mport)
361 return ((*so->so_proto->pr_usrreqs->pru_sense)(so, sb));
363 port = so->so_proto->pr_mport(so, NULL);
364 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SENSE);
365 msg.nm_handler = netmsg_pru_dispatcher;
366 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sense;
369 error = lwkt_domsg(port, &msg.nm_lmsg);
374 so_pru_shutdown(struct socket *so)
377 struct netmsg_pru_shutdown msg;
380 if (!so->so_proto->pr_mport)
381 return ((*so->so_proto->pr_usrreqs->pru_shutdown)(so));
383 port = so->so_proto->pr_mport(so, NULL);
384 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SHUTDOWN);
385 msg.nm_handler = netmsg_pru_dispatcher;
386 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_shutdown;
388 error = lwkt_domsg(port, &msg.nm_lmsg);
393 so_pru_sockaddr(struct socket *so, struct sockaddr **nam)
396 struct netmsg_pru_sockaddr msg;
399 if (!so->so_proto->pr_mport)
400 return ((*so->so_proto->pr_usrreqs->pru_sockaddr)(so, nam));
402 port = so->so_proto->pr_mport(so, NULL);
403 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SOCKADDR);
404 msg.nm_handler = netmsg_pru_dispatcher;
405 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sockaddr;
408 error = lwkt_domsg(port, &msg.nm_lmsg);
413 so_pru_sopoll(struct socket *so, int events, struct ucred *cred,
417 struct netmsg_pru_sopoll msg;
420 if (!so->so_proto->pr_mport)
421 return ((*so->so_proto->pr_usrreqs->pru_sopoll)(so, events,
424 port = so->so_proto->pr_mport(so, NULL);
425 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PRU_SOPOLL);
426 msg.nm_handler = netmsg_pru_dispatcher;
427 msg.nm_prufn = so->so_proto->pr_usrreqs->pru_sopoll;
429 msg.nm_events = events;
432 error = lwkt_domsg(port, &msg.nm_lmsg);
437 so_pr_ctloutput(struct socket *so, struct sockopt *sopt)
439 return ((*so->so_proto->pr_ctloutput)(so, sopt));
440 #ifdef gag /* does copyin and copyout deep inside stack XXX JH */
441 struct netmsg_pr_ctloutput msg;
445 if (!so->so_proto->pr_mport)
446 return ((*so->so_proto->pr_ctloutput)(so, sopt));
448 port = so->so_proto->pr_mport(so, NULL);
449 lwkt_initmsg(&msg.nm_lmsg, CMD_NETMSG_PR_CTLOUTPUT);
450 msg.nm_handler = netmsg_pr_dispatcher;
451 msg.nm_prfn = so->so_proto->pr_ctloutput;
454 error = lwkt_domsg(port, &msg.nm_lmsg);
460 * If we convert all the pru_usrreq functions for all the protocols
461 * to take a message directly, this layer can go away.
464 netmsg_pru_dispatcher(struct netmsg *msg)
468 switch (msg->nm_lmsg.ms_cmd) {
469 case CMD_NETMSG_PRU_ABORT:
471 struct netmsg_pru_abort *nm = (struct netmsg_pru_abort *)msg;
473 error = nm->nm_prufn(nm->nm_so);
476 case CMD_NETMSG_PRU_ACCEPT:
478 struct netmsg_pru_accept *nm = (struct netmsg_pru_accept *)msg;
480 error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
483 case CMD_NETMSG_PRU_ATTACH:
485 struct netmsg_pru_attach *nm = (struct netmsg_pru_attach *)msg;
487 error = nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai);
490 case CMD_NETMSG_PRU_BIND:
492 struct netmsg_pru_bind *nm = (struct netmsg_pru_bind *)msg;
494 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
497 case CMD_NETMSG_PRU_CONNECT:
499 struct netmsg_pru_connect *nm =
500 (struct netmsg_pru_connect *)msg;
502 error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
505 case CMD_NETMSG_PRU_CONNECT2:
507 struct netmsg_pru_connect2 *nm =
508 (struct netmsg_pru_connect2 *)msg;
510 error = nm->nm_prufn(nm->nm_so1, nm->nm_so2);
513 case CMD_NETMSG_PRU_CONTROL:
515 struct netmsg_pru_control *nm =
516 (struct netmsg_pru_control *)msg;
518 error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data,
519 nm->nm_ifp, nm->nm_td);
522 case CMD_NETMSG_PRU_DETACH:
524 struct netmsg_pru_detach *nm = (struct netmsg_pru_detach *)msg;
526 error = nm->nm_prufn(nm->nm_so);
529 case CMD_NETMSG_PRU_DISCONNECT:
531 struct netmsg_pru_disconnect *nm =
532 (struct netmsg_pru_disconnect *)msg;
534 error = nm->nm_prufn(nm->nm_so);
537 case CMD_NETMSG_PRU_LISTEN:
539 struct netmsg_pru_listen *nm = (struct netmsg_pru_listen *)msg;
541 error = nm->nm_prufn(nm->nm_so, nm->nm_td);
544 case CMD_NETMSG_PRU_PEERADDR:
546 struct netmsg_pru_peeraddr *nm =
547 (struct netmsg_pru_peeraddr *)msg;
549 error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
552 case CMD_NETMSG_PRU_RCVD:
554 struct netmsg_pru_rcvd *nm = (struct netmsg_pru_rcvd *)msg;
556 error = nm->nm_prufn(nm->nm_so, nm->nm_flags);
559 case CMD_NETMSG_PRU_RCVOOB:
561 struct netmsg_pru_rcvoob *nm = (struct netmsg_pru_rcvoob *)msg;
563 error = nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags);
566 case CMD_NETMSG_PRU_SEND:
568 struct netmsg_pru_send *nm = (struct netmsg_pru_send *)msg;
570 error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m,
571 nm->nm_addr, nm->nm_control, nm->nm_td);
574 case CMD_NETMSG_PRU_SENSE:
576 struct netmsg_pru_sense *nm = (struct netmsg_pru_sense *)msg;
578 error = nm->nm_prufn(nm->nm_so, nm->nm_stat);
581 case CMD_NETMSG_PRU_SHUTDOWN:
583 struct netmsg_pru_shutdown *nm =
584 (struct netmsg_pru_shutdown *)msg;
586 error = nm->nm_prufn(nm->nm_so);
589 case CMD_NETMSG_PRU_SOCKADDR:
591 struct netmsg_pru_sockaddr *nm =
592 (struct netmsg_pru_sockaddr *)msg;
594 error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
597 case CMD_NETMSG_PRU_SOPOLL:
599 struct netmsg_pru_sopoll *nm =
600 (struct netmsg_pru_sopoll *)msg;
602 error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred,
607 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);
614 * If we convert all the protosw pr_ functions for all the protocols
615 * to take a message directly, this layer can go away.
618 netmsg_pr_dispatcher(struct netmsg *msg)
622 switch (msg->nm_lmsg.ms_cmd) {
623 case CMD_NETMSG_PR_CTLOUTPUT:
625 struct netmsg_pr_ctloutput *nm =
626 (struct netmsg_pr_ctloutput *)msg;
628 error = nm->nm_prfn(nm->nm_so, nm->nm_sopt);
631 case CMD_NETMSG_PR_TIMEOUT:
633 struct netmsg_pr_timeout *nm = (struct netmsg_pr_timeout *)msg;
639 panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);