File:  [DragonFly] / src / sys / kern / uipc_msg.c
Revision 1.2: download - view: text, annotated - select for diffs
Sat Mar 6 19:40:28 2004 UTC (10 years, 1 month ago) by dillon
Branches: MAIN
CVS tags: HEAD
Simplify LWKT message initialization semantics to reduce API confusion.

Cleanup netisr messaging to provide more uniform error handling and to use
lwkt_replymsg() unconditionally for both async/auto-free and sync messages
as the abstraction intended.  This also fixes a reply/free race.

    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.2 2004/03/06 19:40:28 dillon 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 int 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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, 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 int
  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: 		break;
  472: 	}
  473: 	case CMD_NETMSG_PRU_ACCEPT:
  474: 	{
  475: 		struct netmsg_pru_accept *nm = (struct netmsg_pru_accept *)msg;
  476: 
  477: 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
  478: 		break;
  479: 	}
  480: 	case CMD_NETMSG_PRU_ATTACH:
  481: 	{
  482: 		struct netmsg_pru_attach *nm = (struct netmsg_pru_attach *)msg;
  483: 
  484: 		error = nm->nm_prufn(nm->nm_so, nm->nm_proto, nm->nm_ai);
  485: 		break;
  486: 	}
  487: 	case CMD_NETMSG_PRU_BIND:
  488: 	{
  489: 		struct netmsg_pru_bind *nm = (struct netmsg_pru_bind *)msg;
  490: 
  491: 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
  492: 		break;
  493: 	}
  494: 	case CMD_NETMSG_PRU_CONNECT:
  495: 	{
  496: 		struct netmsg_pru_connect *nm =
  497: 		    (struct netmsg_pru_connect *)msg;
  498: 
  499: 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam, nm->nm_td);
  500: 		break;
  501: 	}
  502: 	case CMD_NETMSG_PRU_CONNECT2:
  503: 	{
  504: 		struct netmsg_pru_connect2 *nm =
  505: 		    (struct netmsg_pru_connect2 *)msg;
  506: 
  507: 		error = nm->nm_prufn(nm->nm_so1, nm->nm_so2);
  508: 		break;
  509: 	}
  510: 	case CMD_NETMSG_PRU_CONTROL:
  511: 	{
  512: 		struct netmsg_pru_control *nm =
  513: 		    (struct netmsg_pru_control *)msg;
  514: 
  515: 		error = nm->nm_prufn(nm->nm_so, nm->nm_cmd, nm->nm_data,
  516: 		    nm->nm_ifp, nm->nm_td);
  517: 		break;
  518: 	}
  519: 	case CMD_NETMSG_PRU_DETACH:
  520: 	{
  521: 		struct netmsg_pru_detach *nm = (struct netmsg_pru_detach *)msg;
  522: 
  523: 		error = nm->nm_prufn(nm->nm_so);
  524: 		break;
  525: 	}
  526: 	case CMD_NETMSG_PRU_DISCONNECT:
  527: 	{
  528: 		struct netmsg_pru_disconnect *nm =
  529: 		    (struct netmsg_pru_disconnect *)msg;
  530: 
  531: 		error = nm->nm_prufn(nm->nm_so);
  532: 		break;
  533: 	}
  534: 	case CMD_NETMSG_PRU_LISTEN:
  535: 	{
  536: 		struct netmsg_pru_listen *nm = (struct netmsg_pru_listen *)msg;
  537: 
  538: 		error = nm->nm_prufn(nm->nm_so, nm->nm_td);
  539: 		break;
  540: 	}
  541: 	case CMD_NETMSG_PRU_PEERADDR:
  542: 	{
  543: 		struct netmsg_pru_peeraddr *nm =
  544: 		    (struct netmsg_pru_peeraddr *)msg;
  545: 
  546: 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
  547: 		break;
  548: 	}
  549: 	case CMD_NETMSG_PRU_RCVD:
  550: 	{
  551: 		struct netmsg_pru_rcvd *nm = (struct netmsg_pru_rcvd *)msg;
  552: 
  553: 		error = nm->nm_prufn(nm->nm_so, nm->nm_flags);
  554: 		break;
  555: 	}
  556: 	case CMD_NETMSG_PRU_RCVOOB:
  557: 	{
  558: 		struct netmsg_pru_rcvoob *nm = (struct netmsg_pru_rcvoob *)msg;
  559: 
  560: 		error = nm->nm_prufn(nm->nm_so, nm->nm_m, nm->nm_flags);
  561: 		break;
  562: 	}
  563: 	case CMD_NETMSG_PRU_SEND:
  564: 	{
  565: 		struct netmsg_pru_send *nm = (struct netmsg_pru_send *)msg;
  566: 
  567: 		error = nm->nm_prufn(nm->nm_so, nm->nm_flags, nm->nm_m,
  568: 		    nm->nm_addr, nm->nm_control, nm->nm_td);
  569: 		break;
  570: 	}
  571: 	case CMD_NETMSG_PRU_SENSE:
  572: 	{
  573: 		struct netmsg_pru_sense *nm = (struct netmsg_pru_sense *)msg;
  574: 
  575: 		error = nm->nm_prufn(nm->nm_so, nm->nm_stat);
  576: 		break;
  577: 	}
  578: 	case CMD_NETMSG_PRU_SHUTDOWN:
  579: 	{
  580: 		struct netmsg_pru_shutdown *nm =
  581: 		    (struct netmsg_pru_shutdown *)msg;
  582: 
  583: 		error = nm->nm_prufn(nm->nm_so);
  584: 		break;
  585: 	}
  586: 	case CMD_NETMSG_PRU_SOCKADDR:
  587: 	{
  588: 		struct netmsg_pru_sockaddr *nm =
  589: 		    (struct netmsg_pru_sockaddr *)msg;
  590: 
  591: 		error = nm->nm_prufn(nm->nm_so, nm->nm_nam);
  592: 		break;
  593: 	}
  594: 	case CMD_NETMSG_PRU_SOPOLL:
  595: 	{
  596: 		struct netmsg_pru_sopoll *nm =
  597: 		    (struct netmsg_pru_sopoll *)msg;
  598: 
  599: 		error = nm->nm_prufn(nm->nm_so, nm->nm_events, nm->nm_cred,
  600: 		    nm->nm_td);
  601: 		break;
  602: 	}
  603: 	default:
  604: 		panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);
  605: 		break;
  606: 	}
  607: 	return(error);
  608: }
  609: 
  610: /*
  611:  * If we convert all the protosw pr_ functions for all the protocols
  612:  * to take a message directly, this layer can go away.
  613:  */
  614: int
  615: netmsg_pr_dispatcher(struct netmsg *msg)
  616: {
  617: 	int error = 0;
  618: 
  619: 	switch (msg->nm_lmsg.ms_cmd) {
  620: 	case CMD_NETMSG_PR_CTLOUTPUT:
  621: 	{
  622: 		struct netmsg_pr_ctloutput *nm =
  623: 		    (struct netmsg_pr_ctloutput *)msg;
  624: 
  625: 		error = nm->nm_prfn(nm->nm_so, nm->nm_sopt);
  626: 		break;
  627: 	}
  628: 	case CMD_NETMSG_PR_TIMEOUT:
  629: 	{
  630: 		struct netmsg_pr_timeout *nm = (struct netmsg_pr_timeout *)msg;
  631: 
  632: 		nm->nm_prfn();
  633: 		break;
  634: 	}
  635: 	default:
  636: 		panic("unknown netmsg %d", msg->nm_lmsg.ms_cmd);
  637: 		break;
  638: 	}
  639: 	return(error);
  640: }
  641: 
  642: #endif