File:  [DragonFly] / src / sys / kern / uipc_msg.c
Revision 1.8: download - view: text, annotated - select for diffs
Sat Apr 10 00:48:06 2004 UTC (10 years, 6 months ago) by hsu
Branches: MAIN
CVS tags: HEAD
Add predicate message facility.

    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.8 2004/04/10 00:48:06 hsu 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 void 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, nam);
  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: 	return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data, ifp,
  184: 	    td));
  185: #ifdef gag	/* does copyin and copyout deep inside stack XXX JH */
  186: 	int error;
  187: 	struct netmsg_pru_control msg;
  188: 	lwkt_port_t port;
  189: 
  190: 	if (!so->so_proto->pr_mport)
  191: 		return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd, data,
  192: 		    ifp, td));
  193: 
  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;
  198: 	msg.nm_so = so;
  199: 	msg.nm_cmd = cmd;
  200: 	msg.nm_data = data;
  201: 	msg.nm_ifp = ifp;
  202: 	msg.nm_td = td;
  203: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  204: 	return (error);
  205: #endif
  206: }
  207: 
  208: int
  209: so_pru_detach(struct socket *so)
  210: {
  211: 	int error;
  212: 	struct netmsg_pru_detach msg;
  213: 	lwkt_port_t port;
  214: 
  215: 	if (!so->so_proto->pr_mport)
  216: 		return ((*so->so_proto->pr_usrreqs->pru_detach)(so));
  217: 
  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;
  222: 	msg.nm_so = so;
  223: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  224: 	return (error);
  225: }
  226: 
  227: int
  228: so_pru_disconnect(struct socket *so)
  229: {
  230: 	int error;
  231: 	struct netmsg_pru_disconnect msg;
  232: 	lwkt_port_t port;
  233: 
  234: 	if (!so->so_proto->pr_mport)
  235: 		return ((*so->so_proto->pr_usrreqs->pru_disconnect)(so));
  236: 
  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;
  241: 	msg.nm_so = so;
  242: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  243: 	return (error);
  244: }
  245: 
  246: int
  247: so_pru_listen(struct socket *so, struct thread *td)
  248: {
  249: 	int error;
  250: 	struct netmsg_pru_listen msg;
  251: 	lwkt_port_t port;
  252: 
  253: 	if (!so->so_proto->pr_mport)
  254: 		return ((*so->so_proto->pr_usrreqs->pru_listen)(so, td));
  255: 
  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;
  260: 	msg.nm_so = so;
  261: 	msg.nm_td = td;		/* used only for prison_ip() XXX JH */
  262: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  263: 	return (error);
  264: }
  265: 
  266: int
  267: so_pru_peeraddr(struct socket *so, struct sockaddr **nam)
  268: {
  269: 	int error;
  270: 	struct netmsg_pru_peeraddr msg;
  271: 	lwkt_port_t port;
  272: 
  273: 	if (!so->so_proto->pr_mport)
  274: 		return ((*so->so_proto->pr_usrreqs->pru_peeraddr)(so, nam));
  275: 
  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;
  280: 	msg.nm_so = so;
  281: 	msg.nm_nam = nam;
  282: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  283: 	return (error);
  284: }
  285: 
  286: int
  287: so_pru_rcvd(struct socket *so, int flags)
  288: {
  289: 	int error;
  290: 	struct netmsg_pru_rcvd msg;
  291: 	lwkt_port_t port;
  292: 
  293: 	if (!so->so_proto->pr_mport)
  294: 		return ((*so->so_proto->pr_usrreqs->pru_rcvd)(so, flags));
  295: 
  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;
  300: 	msg.nm_so = so;
  301: 	msg.nm_flags = flags;
  302: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  303: 	return (error);
  304: }
  305: 
  306: int
  307: so_pru_rcvoob(struct socket *so, struct mbuf *m, int flags)
  308: {
  309: 	int error;
  310: 	struct netmsg_pru_rcvoob msg;
  311: 	lwkt_port_t port;
  312: 
  313: 	if (!so->so_proto->pr_mport)
  314: 		return ((*so->so_proto->pr_usrreqs->pru_rcvoob)(so, m, flags));
  315: 
  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;
  320: 	msg.nm_so = so;
  321: 	msg.nm_m = m;
  322: 	msg.nm_flags = flags;
  323: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  324: 	return (error);
  325: }
  326: 
  327: int
  328: so_pru_send(struct socket *so, int flags, struct mbuf *m, struct sockaddr *addr,
  329:     struct mbuf *control, struct thread *td)
  330: {
  331: 	int error;
  332: 	struct netmsg_pru_send msg;
  333: 	lwkt_port_t port;
  334: 
  335: 	if (!so->so_proto->pr_mport)
  336: 		return ((*so->so_proto->pr_usrreqs->pru_send)(so, flags, m,
  337: 		    addr, control, td));
  338: 
  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;
  343: 	msg.nm_so = so;
  344: 	msg.nm_flags = flags;
  345: 	msg.nm_m = m;
  346: 	msg.nm_addr = addr;
  347: 	msg.nm_control = control;
  348: 	msg.nm_td = td;
  349: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  350: 	return (error);
  351: }
  352: 
  353: int
  354: so_pru_sense(struct socket *so, struct stat *sb)
  355: {
  356: 	int error;
  357: 	struct netmsg_pru_sense msg;
  358: 	lwkt_port_t port;
  359: 
  360: 	if (!so->so_proto->pr_mport)
  361: 		return ((*so->so_proto->pr_usrreqs->pru_sense)(so, sb));
  362: 
  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;
  367: 	msg.nm_so = so;
  368: 	msg.nm_stat = sb;
  369: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  370: 	return (error);
  371: }
  372: 
  373: int
  374: so_pru_shutdown(struct socket *so)
  375: {
  376: 	int error;
  377: 	struct netmsg_pru_shutdown msg;
  378: 	lwkt_port_t port;
  379: 
  380: 	if (!so->so_proto->pr_mport)
  381: 		return ((*so->so_proto->pr_usrreqs->pru_shutdown)(so));
  382: 
  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;
  387: 	msg.nm_so = so;
  388: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  389: 	return (error);
  390: }
  391: 
  392: int
  393: so_pru_sockaddr(struct socket *so, struct sockaddr **nam)
  394: {
  395: 	int error;
  396: 	struct netmsg_pru_sockaddr msg;
  397: 	lwkt_port_t port;
  398: 
  399: 	if (!so->so_proto->pr_mport)
  400: 		return ((*so->so_proto->pr_usrreqs->pru_sockaddr)(so, nam));
  401: 
  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;
  406: 	msg.nm_so = so;
  407: 	msg.nm_nam = nam;
  408: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  409: 	return (error);
  410: }
  411: 
  412: int
  413: so_pru_sopoll(struct socket *so, int events, struct ucred *cred,
  414:     struct thread *td)
  415: {
  416: 	int error;
  417: 	struct netmsg_pru_sopoll msg;
  418: 	lwkt_port_t port;
  419: 
  420: 	if (!so->so_proto->pr_mport)
  421: 		return ((*so->so_proto->pr_usrreqs->pru_sopoll)(so, events,
  422: 		    cred, td));
  423: 
  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;
  428: 	msg.nm_so = so;
  429: 	msg.nm_events = events;
  430: 	msg.nm_cred = cred;
  431: 	msg.nm_td = td;
  432: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  433: 	return (error);
  434: }
  435: 
  436: int
  437: so_pr_ctloutput(struct socket *so, struct sockopt *sopt)
  438: {
  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;
  442: 	lwkt_port_t port;
  443: 	int error;
  444: 
  445: 	if (!so->so_proto->pr_mport)
  446: 		return ((*so->so_proto->pr_ctloutput)(so, sopt));
  447: 
  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;
  452: 	msg.nm_so = so;
  453: 	msg.nm_sopt = sopt;
  454: 	error = lwkt_domsg(port, &msg.nm_lmsg);
  455: 	return (error);
  456: #endif
  457: }
  458: 
  459: /*
  460:  * If we convert all the pru_usrreq functions for all the protocols
  461:  * to take a message directly, this layer can go away.
  462:  */
  463: static void
  464: netmsg_pru_dispatcher(struct netmsg *msg)
  465: {
  466: 	int error;
  467: 
  468: 	switch (msg->nm_lmsg.ms_cmd) {
  469: 	case CMD_NETMSG_PRU_ABORT:
  470: 	{
  471: 		struct netmsg_pru_abort *nm = (struct netmsg_pru_abort *)msg;
  472: 
  473: 		error = nm->nm_prufn(nm->nm_so);
  474: 		break;
  475: 	}
  476: 	case CMD_NETMSG_PRU_ACCEPT:
  477: 	{
  478: 		struct netmsg_pru_accept *nm = (struct netmsg_pru_accept *)msg;
  479: 
  480: 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
  481: 		break;
  482: 	}
  483: 	case CMD_NETMSG_PRU_ATTACH:
  484: 	{
  485: 		struct netmsg_pru_attach *nm = (struct netmsg_pru_attach *)msg;
  486: 
  487: 		error = nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai);
  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: 		break;
  496: 	}
  497: 	case CMD_NETMSG_PRU_CONNECT:
  498: 	{
  499: 		struct netmsg_pru_connect *nm =
  500: 		    (struct netmsg_pru_connect *)msg;
  501: 
  502: 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
  503: 		break;
  504: 	}
  505: 	case CMD_NETMSG_PRU_CONNECT2:
  506: 	{
  507: 		struct netmsg_pru_connect2 *nm =
  508: 		    (struct netmsg_pru_connect2 *)msg;
  509: 
  510: 		error = nm->nm_prufn(nm->nm_so1, nm->nm_so2);
  511: 		break;
  512: 	}
  513: 	case CMD_NETMSG_PRU_CONTROL:
  514: 	{
  515: 		struct netmsg_pru_control *nm =
  516: 		    (struct netmsg_pru_control *)msg;
  517: 
  518: 		error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data,
  519: 		    nm->nm_ifp, nm->nm_td);
  520: 		break;
  521: 	}
  522: 	case CMD_NETMSG_PRU_DETACH:
  523: 	{
  524: 		struct netmsg_pru_detach *nm = (struct netmsg_pru_detach *)msg;
  525: 
  526: 		error = nm->nm_prufn(nm->nm_so);
  527: 		break;
  528: 	}
  529: 	case CMD_NETMSG_PRU_DISCONNECT:
  530: 	{
  531: 		struct netmsg_pru_disconnect *nm =
  532: 		    (struct netmsg_pru_disconnect *)msg;
  533: 
  534: 		error = nm->nm_prufn(nm->nm_so);
  535: 		break;
  536: 	}
  537: 	case CMD_NETMSG_PRU_LISTEN:
  538: 	{
  539: 		struct netmsg_pru_listen *nm = (struct netmsg_pru_listen *)msg;
  540: 
  541: 		error = nm->nm_prufn(nm->nm_so, nm->nm_td);
  542: 		break;
  543: 	}
  544: 	case CMD_NETMSG_PRU_PEERADDR:
  545: 	{
  546: 		struct netmsg_pru_peeraddr *nm =
  547: 		    (struct netmsg_pru_peeraddr *)msg;
  548: 
  549: 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
  550: 		break;
  551: 	}
  552: 	case CMD_NETMSG_PRU_RCVD:
  553: 	{
  554: 		struct netmsg_pru_rcvd *nm = (struct netmsg_pru_rcvd *)msg;
  555: 
  556: 		error = nm->nm_prufn(nm->nm_so, nm->nm_flags);
  557: 		break;
  558: 	}
  559: 	case CMD_NETMSG_PRU_RCVOOB:
  560: 	{
  561: 		struct netmsg_pru_rcvoob *nm = (struct netmsg_pru_rcvoob *)msg;
  562: 
  563: 		error = nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags);
  564: 		break;
  565: 	}
  566: 	case CMD_NETMSG_PRU_SEND:
  567: 	{
  568: 		struct netmsg_pru_send *nm = (struct netmsg_pru_send *)msg;
  569: 
  570: 		error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m,
  571: 		    nm->nm_addr, nm->nm_control, nm->nm_td);
  572: 		break;
  573: 	}
  574: 	case CMD_NETMSG_PRU_SENSE:
  575: 	{
  576: 		struct netmsg_pru_sense *nm = (struct netmsg_pru_sense *)msg;
  577: 
  578: 		error = nm->nm_prufn(nm->nm_so, nm->nm_stat);
  579: 		break;
  580: 	}
  581: 	case CMD_NETMSG_PRU_SHUTDOWN:
  582: 	{
  583: 		struct netmsg_pru_shutdown *nm =
  584: 		    (struct netmsg_pru_shutdown *)msg;
  585: 
  586: 		error = nm->nm_prufn(nm->nm_so);
  587: 		break;
  588: 	}
  589: 	case CMD_NETMSG_PRU_SOCKADDR:
  590: 	{
  591: 		struct netmsg_pru_sockaddr *nm =
  592: 		    (struct netmsg_pru_sockaddr *)msg;
  593: 
  594: 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
  595: 		break;
  596: 	}
  597: 	case CMD_NETMSG_PRU_SOPOLL:
  598: 	{
  599: 		struct netmsg_pru_sopoll *nm =
  600: 		    (struct netmsg_pru_sopoll *)msg;
  601: 
  602: 		error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred,
  603: 		    nm->nm_td);
  604: 		break;
  605: 	}
  606: 	default:
  607: 		panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);
  608: 		break;
  609: 	}
  610: 	lwkt_replymsg(&msg->nm_lmsg, error);
  611: }
  612: 
  613: /*
  614:  * If we convert all the protosw pr_ functions for all the protocols
  615:  * to take a message directly, this layer can go away.
  616:  */
  617: void
  618: netmsg_pr_dispatcher(struct netmsg *msg)
  619: {
  620: 	int error = 0;
  621: 
  622: 	switch (msg->nm_lmsg.ms_cmd) {
  623: 	case CMD_NETMSG_PR_CTLOUTPUT:
  624: 	{
  625: 		struct netmsg_pr_ctloutput *nm =
  626: 		    (struct netmsg_pr_ctloutput *)msg;
  627: 
  628: 		error = nm->nm_prfn(nm->nm_so, nm->nm_sopt);
  629: 		break;
  630: 	}
  631: 	case CMD_NETMSG_PR_TIMEOUT:
  632: 	{
  633: 		struct netmsg_pr_timeout *nm = (struct netmsg_pr_timeout *)msg;
  634: 
  635: 		nm->nm_prfn();
  636: 		break;
  637: 	}
  638: 	default:
  639: 		panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);
  640: 		break;
  641: 	}
  642: 	lwkt_replymsg(&msg->nm_lmsg, error);
  643: }
  644: 
  645: void
  646: msg_notify_handler(struct netmsg *msg0)
  647: {
  648: 	struct netmsg_so_notify *msg = (struct netmsg_so_notify *)msg0;
  649: 	struct sockbuf *sb;
  650: 
  651: 	/* Check if event occurred. */
  652: 	if (msg->nm_predicate(msg0)) {
  653: 		lwkt_replymsg(&msg->nm_lmsg, msg->nm_lmsg.ms_error);
  654: 		return;
  655: 	}
  656: 
  657: 	/* If not, queue the predicate check. */
  658: 	sb = (msg->nm_etype & NM_REVENT) ?
  659: 			&msg->nm_so->so_rcv :
  660: 			&msg->nm_so->so_snd;
  661: 
  662: 	TAILQ_INSERT_TAIL(&sb->sb_sel.si_mlist, msg, nm_list);
  663: 	sb->sb_flags |= SB_MEVENT;
  664: }