Module Name:    src
Committed By:   rtr
Date:           Tue Aug  5 07:55:32 UTC 2014

Modified Files:
        src/sys/dev: kttcp.c
        src/sys/dev/bluetooth: bthidev.c btmagic.c btsco.c
        src/sys/kern: uipc_socket.c uipc_usrreq.c
        src/sys/net: if_gre.c link_proto.c raw_cb.h raw_usrreq.c rtsock.c
        src/sys/netatalk: ddp_usrreq.c
        src/sys/netbt: hci_socket.c l2cap.h l2cap_lower.c l2cap_socket.c
            l2cap_upper.c rfcomm.h rfcomm_session.c rfcomm_socket.c
            rfcomm_upper.c sco.h sco_socket.c sco_upper.c
        src/sys/netinet: raw_ip.c tcp_usrreq.c udp_usrreq.c
        src/sys/netinet6: raw_ip6.c udp6_usrreq.c
        src/sys/netipsec: keysock.c
        src/sys/netmpls: mpls_proto.c
        src/sys/netnatm: natm.c
        src/sys/nfs: nfs_socket.c
        src/sys/rump/net/lib/libsockin: sockin.c
        src/sys/sys: protosw.h

Log Message:
split PRU_SEND function out of pr_generic() usrreq switches and put into
separate functions

   xxx_send(struct socket *, struct mbuf *, struct mbuf *,
       struct mbuf *, struct lwp *)

  - always KASSERT(solocked(so)) even if not implemented

  - replace calls to pr_generic() with req = PRU_SEND with calls to
    pr_send()

rename existing functions that operate on PCB for consistency (and to
free up their names for xxx_send() PRUs

  - l2cap_send() -> l2cap_send_pcb()
  - sco_send() -> sco_send_pcb()
  - rfcomm_send() -> rfcomm_send_pcb()

patch reviewed by rmind


To generate a diff of this commit:
cvs rdiff -u -r1.35 -r1.36 src/sys/dev/kttcp.c
cvs rdiff -u -r1.28 -r1.29 src/sys/dev/bluetooth/bthidev.c
cvs rdiff -u -r1.10 -r1.11 src/sys/dev/bluetooth/btmagic.c
cvs rdiff -u -r1.32 -r1.33 src/sys/dev/bluetooth/btsco.c
cvs rdiff -u -r1.231 -r1.232 src/sys/kern/uipc_socket.c
cvs rdiff -u -r1.165 -r1.166 src/sys/kern/uipc_usrreq.c
cvs rdiff -u -r1.157 -r1.158 src/sys/net/if_gre.c
cvs rdiff -u -r1.21 -r1.22 src/sys/net/link_proto.c
cvs rdiff -u -r1.22 -r1.23 src/sys/net/raw_cb.h
cvs rdiff -u -r1.49 -r1.50 src/sys/net/raw_usrreq.c
cvs rdiff -u -r1.160 -r1.161 src/sys/net/rtsock.c
cvs rdiff -u -r1.58 -r1.59 src/sys/netatalk/ddp_usrreq.c
cvs rdiff -u -r1.37 -r1.38 src/sys/netbt/hci_socket.c
cvs rdiff -u -r1.17 -r1.18 src/sys/netbt/l2cap.h src/sys/netbt/l2cap_upper.c
cvs rdiff -u -r1.9 -r1.10 src/sys/netbt/l2cap_lower.c
cvs rdiff -u -r1.28 -r1.29 src/sys/netbt/l2cap_socket.c
cvs rdiff -u -r1.16 -r1.17 src/sys/netbt/rfcomm.h
cvs rdiff -u -r1.22 -r1.23 src/sys/netbt/rfcomm_session.c
cvs rdiff -u -r1.30 -r1.31 src/sys/netbt/rfcomm_socket.c \
    src/sys/netbt/sco_socket.c
cvs rdiff -u -r1.19 -r1.20 src/sys/netbt/rfcomm_upper.c
cvs rdiff -u -r1.10 -r1.11 src/sys/netbt/sco.h
cvs rdiff -u -r1.15 -r1.16 src/sys/netbt/sco_upper.c
cvs rdiff -u -r1.142 -r1.143 src/sys/netinet/raw_ip.c
cvs rdiff -u -r1.197 -r1.198 src/sys/netinet/tcp_usrreq.c
cvs rdiff -u -r1.214 -r1.215 src/sys/netinet/udp_usrreq.c
cvs rdiff -u -r1.133 -r1.134 src/sys/netinet6/raw_ip6.c
cvs rdiff -u -r1.112 -r1.113 src/sys/netinet6/udp6_usrreq.c
cvs rdiff -u -r1.40 -r1.41 src/sys/netipsec/keysock.c
cvs rdiff -u -r1.21 -r1.22 src/sys/netmpls/mpls_proto.c
cvs rdiff -u -r1.42 -r1.43 src/sys/netnatm/natm.c
cvs rdiff -u -r1.191 -r1.192 src/sys/nfs/nfs_socket.c
cvs rdiff -u -r1.55 -r1.56 src/sys/rump/net/lib/libsockin/sockin.c
cvs rdiff -u -r1.57 -r1.58 src/sys/sys/protosw.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/dev/kttcp.c
diff -u src/sys/dev/kttcp.c:1.35 src/sys/dev/kttcp.c:1.36
--- src/sys/dev/kttcp.c:1.35	Fri Jul 25 08:10:35 2014
+++ src/sys/dev/kttcp.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: kttcp.c,v 1.35 2014/07/25 08:10:35 dholland Exp $	*/
+/*	$NetBSD: kttcp.c,v 1.36 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*
  * Copyright (c) 2002 Wasabi Systems, Inc.
@@ -42,7 +42,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: kttcp.c,v 1.35 2014/07/25 08:10:35 dholland Exp $");
+__KERNEL_RCSID(0, "$NetBSD: kttcp.c,v 1.36 2014/08/05 07:55:31 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/types.h>
@@ -324,8 +324,8 @@ nopages:
 				error = (*so->so_proto->pr_usrreqs->pr_sendoob)(so,
 				    top, NULL);
 			else
-				error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
-				    PRU_SEND, top, NULL, NULL, l);
+				error = (*so->so_proto->pr_usrreqs->pr_send)(so,
+				    top, NULL, NULL, l);
 			if (dontroute)
 				so->so_options &= ~SO_DONTROUTE;
 			if (resid > 0)

Index: src/sys/dev/bluetooth/bthidev.c
diff -u src/sys/dev/bluetooth/bthidev.c:1.28 src/sys/dev/bluetooth/bthidev.c:1.29
--- src/sys/dev/bluetooth/bthidev.c:1.28	Thu Jul 31 03:39:35 2014
+++ src/sys/dev/bluetooth/bthidev.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: bthidev.c,v 1.28 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: bthidev.c,v 1.29 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.28 2014/07/31 03:39:35 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.29 2014/08/05 07:55:31 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/condvar.h>
@@ -1017,7 +1017,7 @@ bthidev_output(struct bthidev *hidev, ui
 	m->m_pkthdr.len = m->m_len = rlen + 2;
 
 	mutex_enter(bt_lock);
-	err = l2cap_send(sc->sc_int, m);
+	err = l2cap_send_pcb(sc->sc_int, m);
 	mutex_exit(bt_lock);
 
 	return err;

Index: src/sys/dev/bluetooth/btmagic.c
diff -u src/sys/dev/bluetooth/btmagic.c:1.10 src/sys/dev/bluetooth/btmagic.c:1.11
--- src/sys/dev/bluetooth/btmagic.c:1.10	Thu Jul 31 03:39:35 2014
+++ src/sys/dev/bluetooth/btmagic.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: btmagic.c,v 1.10 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: btmagic.c,v 1.11 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -85,7 +85,7 @@
  *****************************************************************************/
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.10 2014/07/31 03:39:35 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.11 2014/08/05 07:55:31 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -723,7 +723,7 @@ btmagic_ctl_send(struct btmagic_softc *s
 
 	memcpy(mtod(m, uint8_t *), data, len);
 	m->m_pkthdr.len = m->m_len = len;
-	return l2cap_send(sc->sc_ctl, m);
+	return l2cap_send_pcb(sc->sc_ctl, m);
 }
 
 /*

Index: src/sys/dev/bluetooth/btsco.c
diff -u src/sys/dev/bluetooth/btsco.c:1.32 src/sys/dev/bluetooth/btsco.c:1.33
--- src/sys/dev/bluetooth/btsco.c:1.32	Thu Jul 31 03:39:35 2014
+++ src/sys/dev/bluetooth/btsco.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: btsco.c,v 1.32 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: btsco.c,v 1.33 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.32 2014/07/31 03:39:35 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.33 2014/08/05 07:55:31 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/audioio.h>
@@ -1123,7 +1123,7 @@ btsco_dev_ioctl(void *hdl, u_long cmd, v
 /*
  * Our transmit interrupt. This is triggered when a new block is to be
  * sent.  We send mtu sized chunks of the block as mbufs with external
- * storage to sco_send()
+ * storage to sco_send_pcb()
  */
 static void
 btsco_intr(void *arg)
@@ -1163,7 +1163,7 @@ btsco_intr(void *arg)
 		m->m_pkthdr.len = m->m_len = mlen;
 		sc->sc_tx_pending++;
 
-		if (sco_send(sc->sc_sco, m) > 0) {
+		if (sco_send_pcb(sc->sc_sco, m) > 0) {
 			sc->sc_tx_pending--;
 			break;
 		}

Index: src/sys/kern/uipc_socket.c
diff -u src/sys/kern/uipc_socket.c:1.231 src/sys/kern/uipc_socket.c:1.232
--- src/sys/kern/uipc_socket.c:1.231	Tue Aug  5 05:24:26 2014
+++ src/sys/kern/uipc_socket.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_socket.c,v 1.231 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: uipc_socket.c,v 1.232 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2002, 2007, 2008, 2009 The NetBSD Foundation, Inc.
@@ -71,7 +71,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.231 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.232 2014/08/05 07:55:31 rtr Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_sock_counters.h"
@@ -1052,8 +1052,8 @@ sosend(struct socket *so, struct mbuf *a
 				error = (*so->so_proto->pr_usrreqs->pr_sendoob)(so,
 				    top, control);
 			else
-				error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
-				    PRU_SEND, top, addr, control, curlwp);
+				error = (*so->so_proto->pr_usrreqs->pr_send)(so,
+				    top, addr, control, l);
 			if (dontroute)
 				so->so_options &= ~SO_DONTROUTE;
 			if (resid > 0)

Index: src/sys/kern/uipc_usrreq.c
diff -u src/sys/kern/uipc_usrreq.c:1.165 src/sys/kern/uipc_usrreq.c:1.166
--- src/sys/kern/uipc_usrreq.c:1.165	Tue Aug  5 05:24:26 2014
+++ src/sys/kern/uipc_usrreq.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_usrreq.c,v 1.165 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: uipc_usrreq.c,v 1.166 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 1998, 2000, 2004, 2008, 2009 The NetBSD Foundation, Inc.
@@ -96,7 +96,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.165 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.166 2014/08/05 07:55:31 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -377,6 +377,134 @@ unp_recvoob(struct socket *so, struct mb
 }
 
 static int
+unp_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct unpcb *unp = sotounpcb(so);
+	int error = 0;
+	u_int newhiwat;
+	struct socket *so2;
+
+	KASSERT(solocked(so));
+	KASSERT(unp != NULL);
+	KASSERT(m != NULL);
+
+	/*
+	 * Note: unp_internalize() rejects any control message
+	 * other than SCM_RIGHTS, and only allows one.  This
+	 * has the side-effect of preventing a caller from
+	 * forging SCM_CREDS.
+	 */
+	if (control) {
+		sounlock(so);
+		error = unp_internalize(&control);
+		solock(so);
+		if (error != 0) {
+			m_freem(control);
+			m_freem(m);
+			return error;
+		}
+	}
+
+	switch (so->so_type) {
+
+	case SOCK_DGRAM: {
+		KASSERT(so->so_lock == uipc_lock);
+		if (nam) {
+			if ((so->so_state & SS_ISCONNECTED) != 0)
+				error = EISCONN;
+			else {
+				/*
+				 * Note: once connected, the
+				 * socket's lock must not be
+				 * dropped until we have sent
+				 * the message and disconnected.
+				 * This is necessary to prevent
+				 * intervening control ops, like
+				 * another connection.
+				 */
+				error = unp_connect(so, nam, l);
+			}
+		} else {
+			if ((so->so_state & SS_ISCONNECTED) == 0)
+				error = ENOTCONN;
+		}
+		if (error) {
+			unp_dispose(control);
+			m_freem(control);
+			m_freem(m);
+			return error;
+		}
+		error = unp_output(m, control, unp);
+		if (nam)
+			unp_disconnect1(unp);
+		break;
+	}
+
+	case SOCK_SEQPACKET: /* FALLTHROUGH */
+	case SOCK_STREAM:
+#define	rcv (&so2->so_rcv)
+#define	snd (&so->so_snd)
+		if (unp->unp_conn == NULL) {
+			error = ENOTCONN;
+			break;
+		}
+		so2 = unp->unp_conn->unp_socket;
+		KASSERT(solocked2(so, so2));
+		if (unp->unp_conn->unp_flags & UNP_WANTCRED) {
+			/*
+			 * Credentials are passed only once on
+			 * SOCK_STREAM and SOCK_SEQPACKET.
+			 */
+			unp->unp_conn->unp_flags &= ~UNP_WANTCRED;
+			control = unp_addsockcred(l, control);
+		}
+		/*
+		 * Send to paired receive port, and then reduce
+		 * send buffer hiwater marks to maintain backpressure.
+		 * Wake up readers.
+		 */
+		if (control) {
+			if (sbappendcontrol(rcv, m, control) != 0)
+				control = NULL;
+		} else {
+			switch(so->so_type) {
+			case SOCK_SEQPACKET:
+				sbappendrecord(rcv, m);
+				break;
+			case SOCK_STREAM:
+				sbappend(rcv, m);
+				break;
+			default:
+				panic("uipc_usrreq");
+				break;
+			}
+		}
+		snd->sb_mbmax -=
+		    rcv->sb_mbcnt - unp->unp_conn->unp_mbcnt;
+		unp->unp_conn->unp_mbcnt = rcv->sb_mbcnt;
+		newhiwat = snd->sb_hiwat -
+		    (rcv->sb_cc - unp->unp_conn->unp_cc);
+		(void)chgsbsize(so->so_uidinfo,
+		    &snd->sb_hiwat, newhiwat, RLIM_INFINITY);
+		unp->unp_conn->unp_cc = rcv->sb_cc;
+		sorwakeup(so2);
+#undef snd
+#undef rcv
+		if (control != NULL) {
+			unp_dispose(control);
+			m_freem(control);
+		}
+		break;
+
+	default:
+		panic("uipc 4");
+	}
+
+	return error;
+}
+
+static int
 unp_sendoob(struct socket *so, struct mbuf *m, struct mbuf * control)
 {
 	KASSERT(solocked(so));
@@ -410,12 +538,13 @@ unp_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	KASSERT(solocked(so));
 	unp = sotounpcb(so);
 
-	KASSERT(!control || req == PRU_SEND);
+	KASSERT(!control);
 	if (unp == NULL) {
 		error = EINVAL;
 		goto release;
@@ -461,120 +590,6 @@ unp_usrreq(struct socket *so, int req, s
 		}
 		break;
 
-	case PRU_SEND:
-		/*
-		 * Note: unp_internalize() rejects any control message
-		 * other than SCM_RIGHTS, and only allows one.  This
-		 * has the side-effect of preventing a caller from
-		 * forging SCM_CREDS.
-		 */
-		if (control) {
-			sounlock(so);
-			error = unp_internalize(&control);
-			solock(so);
-			if (error != 0) {
-				m_freem(control);
-				m_freem(m);
-				break;
-			}
-		}
-		switch (so->so_type) {
-
-		case SOCK_DGRAM: {
-			KASSERT(so->so_lock == uipc_lock);
-			if (nam) {
-				if ((so->so_state & SS_ISCONNECTED) != 0)
-					error = EISCONN;
-				else {
-					/*
-					 * Note: once connected, the
-					 * socket's lock must not be
-					 * dropped until we have sent
-					 * the message and disconnected.
-					 * This is necessary to prevent
-					 * intervening control ops, like
-					 * another connection.
-					 */
-					error = unp_connect(so, nam, l);
-				}
-			} else {
-				if ((so->so_state & SS_ISCONNECTED) == 0)
-					error = ENOTCONN;
-			}
-			if (error) {
-				unp_dispose(control);
-				m_freem(control);
-				m_freem(m);
-				break;
-			}
-			KASSERT(l != NULL);
-			error = unp_output(m, control, unp);
-			if (nam)
-				unp_disconnect1(unp);
-			break;
-		}
-
-		case SOCK_SEQPACKET: /* FALLTHROUGH */
-		case SOCK_STREAM:
-#define	rcv (&so2->so_rcv)
-#define	snd (&so->so_snd)
-			if (unp->unp_conn == NULL) {
-				error = ENOTCONN;
-				break;
-			}
-			so2 = unp->unp_conn->unp_socket;
-			KASSERT(solocked2(so, so2));
-			if (unp->unp_conn->unp_flags & UNP_WANTCRED) {
-				/*
-				 * Credentials are passed only once on
-				 * SOCK_STREAM and SOCK_SEQPACKET.
-				 */
-				unp->unp_conn->unp_flags &= ~UNP_WANTCRED;
-				control = unp_addsockcred(l, control);
-			}
-			/*
-			 * Send to paired receive port, and then reduce
-			 * send buffer hiwater marks to maintain backpressure.
-			 * Wake up readers.
-			 */
-			if (control) {
-				if (sbappendcontrol(rcv, m, control) != 0)
-					control = NULL;
-			} else {
-				switch(so->so_type) {
-				case SOCK_SEQPACKET:
-					sbappendrecord(rcv, m);
-					break;
-				case SOCK_STREAM:
-					sbappend(rcv, m);
-					break;
-				default:
-					panic("uipc_usrreq");
-					break;
-				}
-			}
-			snd->sb_mbmax -=
-			    rcv->sb_mbcnt - unp->unp_conn->unp_mbcnt;
-			unp->unp_conn->unp_mbcnt = rcv->sb_mbcnt;
-			newhiwat = snd->sb_hiwat -
-			    (rcv->sb_cc - unp->unp_conn->unp_cc);
-			(void)chgsbsize(so->so_uidinfo,
-			    &snd->sb_hiwat, newhiwat, RLIM_INFINITY);
-			unp->unp_conn->unp_cc = rcv->sb_cc;
-			sorwakeup(so2);
-#undef snd
-#undef rcv
-			if (control != NULL) {
-				unp_dispose(control);
-				m_freem(control);
-			}
-			break;
-
-		default:
-			panic("uipc 4");
-		}
-		break;
-
 	default:
 		panic("piusrreq");
 	}
@@ -1911,6 +1926,7 @@ const struct pr_usrreqs unp_usrreqs = {
 	.pr_peeraddr	= unp_peeraddr,
 	.pr_sockaddr	= unp_sockaddr,
 	.pr_recvoob	= unp_recvoob,
+	.pr_send	= unp_send,
 	.pr_sendoob	= unp_sendoob,
 	.pr_generic	= unp_usrreq,
 };

Index: src/sys/net/if_gre.c
diff -u src/sys/net/if_gre.c:1.157 src/sys/net/if_gre.c:1.158
--- src/sys/net/if_gre.c:1.157	Wed Jul  9 04:54:03 2014
+++ src/sys/net/if_gre.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: if_gre.c,v 1.157 2014/07/09 04:54:03 rtr Exp $ */
+/*	$NetBSD: if_gre.c,v 1.158 2014/08/05 07:55:31 rtr Exp $ */
 
 /*
  * Copyright (c) 1998, 2008 The NetBSD Foundation, Inc.
@@ -45,7 +45,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.157 2014/07/09 04:54:03 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: if_gre.c,v 1.158 2014/08/05 07:55:31 rtr Exp $");
 
 #include "opt_atalk.h"
 #include "opt_gre.h"
@@ -528,8 +528,8 @@ gre_sosend(struct socket *so, struct mbu
 	 */
 	if (so->so_state & SS_CANTSENDMORE)
 		snderr(EPIPE);
-	error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
-	    PRU_SEND, top, NULL, NULL, l);
+	error = (*so->so_proto->pr_usrreqs->pr_send)(so,
+	    top, NULL, NULL, l);
 	top = NULL;
  release:
 	sbunlock(&so->so_snd);

Index: src/sys/net/link_proto.c
diff -u src/sys/net/link_proto.c:1.21 src/sys/net/link_proto.c:1.22
--- src/sys/net/link_proto.c:1.21	Tue Aug  5 05:24:26 2014
+++ src/sys/net/link_proto.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: link_proto.c,v 1.21 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: link_proto.c,v 1.22 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: link_proto.c,v 1.21 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: link_proto.c,v 1.22 2014/08/05 07:55:31 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -62,6 +62,8 @@ static int link_stat(struct socket *, st
 static int link_peeraddr(struct socket *, struct mbuf *);
 static int link_sockaddr(struct socket *, struct mbuf *);
 static int link_recvoob(struct socket *, struct mbuf *, int);
+static int link_send(struct socket *, struct mbuf *, struct mbuf *,
+    struct mbuf *, struct lwp *);
 static int link_sendoob(struct socket *, struct mbuf *, struct mbuf *);
 static int link_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
     struct mbuf *, struct lwp *);
@@ -88,6 +90,7 @@ static const struct pr_usrreqs link_usrr
 	.pr_peeraddr	= link_peeraddr,
 	.pr_sockaddr	= link_sockaddr,
 	.pr_recvoob	= link_recvoob,
+	.pr_send	= link_send,
 	.pr_sendoob	= link_sendoob,
 	.pr_generic	= link_usrreq,
 };
@@ -351,6 +354,15 @@ link_recvoob(struct socket *so, struct m
 }
 
 static int
+link_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	KASSERT(solocked(so));
+
+	return EOPNOTSUPP;
+}
+
+static int
 link_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -376,6 +388,7 @@ link_usrreq(struct socket *so, int req, 
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	return EOPNOTSUPP;

Index: src/sys/net/raw_cb.h
diff -u src/sys/net/raw_cb.h:1.22 src/sys/net/raw_cb.h:1.23
--- src/sys/net/raw_cb.h:1.22	Wed May 21 20:43:56 2014
+++ src/sys/net/raw_cb.h	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_cb.h,v 1.22 2014/05/21 20:43:56 rmind Exp $	*/
+/*	$NetBSD: raw_cb.h,v 1.23 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -70,6 +70,8 @@ int	raw_usrreq(struct socket *,
 	    int, struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *);
 void	raw_setsockaddr(struct rawcb *, struct mbuf *);
 void	raw_setpeeraddr(struct rawcb *, struct mbuf *);
+int	raw_send(struct socket *,
+	    struct mbuf *, struct mbuf *, struct mbuf *, struct lwp *);
 
 #endif /* _KERNEL */
 

Index: src/sys/net/raw_usrreq.c
diff -u src/sys/net/raw_usrreq.c:1.49 src/sys/net/raw_usrreq.c:1.50
--- src/sys/net/raw_usrreq.c:1.49	Tue Aug  5 05:24:26 2014
+++ src/sys/net/raw_usrreq.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_usrreq.c,v 1.49 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: raw_usrreq.c,v 1.50 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.49 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.50 2014/08/05 07:55:31 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -154,6 +154,48 @@ raw_setpeeraddr(struct rawcb *rp, struct
 }
 
 int
+raw_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct rawcb *rp = sotorawcb(so);
+	int error = 0;
+
+	KASSERT(rp != NULL);
+
+	/*
+	 * Ship a packet out.  The appropriate raw output
+	 * routine handles any massaging necessary.
+	 */
+	if (control && control->m_len) {
+		m_freem(control);
+		m_freem(m);
+		return EINVAL;
+	}
+	if (nam) {
+		if ((so->so_state & SS_ISCONNECTED) != 0) {
+			error = EISCONN;
+			goto die;
+		}
+		error = (*so->so_proto->pr_usrreqs->pr_connect)(so, nam, l);
+		if (error) {
+		die:
+			m_freem(m);
+			return error;
+		}
+	} else {
+		if ((so->so_state & SS_ISCONNECTED) == 0) {
+			error = ENOTCONN;
+			goto die;
+		}
+	}
+	error = (*so->so_proto->pr_output)(m, so);
+	if (nam)
+		raw_disconnect(rp);
+
+	return error;
+}
+
+int
 raw_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
     struct mbuf *control, struct lwp *l)
 {
@@ -174,12 +216,13 @@ raw_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	s = splsoftnet();
 	KERNEL_LOCK(1, NULL);
 
-	KASSERT(!control || req == PRU_SEND);
+	KASSERT(!control);
 	if (rp == NULL) {
 		error = EINVAL;
 		goto release;
@@ -200,39 +243,6 @@ raw_usrreq(struct socket *so, int req, s
 		error = EOPNOTSUPP;
 		break;
 
-	/*
-	 * Ship a packet out.  The appropriate raw output
-	 * routine handles any massaging necessary.
-	 */
-	case PRU_SEND:
-		if (control && control->m_len) {
-			m_freem(control);
-			m_freem(m);
-			error = EINVAL;
-			break;
-		}
-		if (nam) {
-			if ((so->so_state & SS_ISCONNECTED) != 0) {
-				error = EISCONN;
-				goto die;
-			}
-			error = (*so->so_proto->pr_usrreqs->pr_connect)(so, nam, l);
-			if (error) {
-			die:
-				m_freem(m);
-				break;
-			}
-		} else {
-			if ((so->so_state & SS_ISCONNECTED) == 0) {
-				error = ENOTCONN;
-				goto die;
-			}
-		}
-		error = (*so->so_proto->pr_output)(m, so);
-		if (nam)
-			raw_disconnect(rp);
-		break;
-
 	default:
 		panic("raw_usrreq");
 	}

Index: src/sys/net/rtsock.c
diff -u src/sys/net/rtsock.c:1.160 src/sys/net/rtsock.c:1.161
--- src/sys/net/rtsock.c:1.160	Tue Aug  5 05:24:26 2014
+++ src/sys/net/rtsock.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtsock.c,v 1.160 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: rtsock.c,v 1.161 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -61,7 +61,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.160 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.161 2014/08/05 07:55:31 rtr Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -356,6 +356,22 @@ COMPATNAME(route_recvoob)(struct socket 
 }
 
 static int
+COMPATNAME(route_send)(struct socket *so, struct mbuf *m,
+    struct mbuf *nam, struct mbuf *control, struct lwp *l)
+{
+	int error = 0;
+	int s;
+
+	KASSERT(solocked(so));
+
+	s = splsoftnet();
+	error = raw_send(so, m, nam, control, l);
+	splx(s);
+
+	return error;
+}
+
+static int
 COMPATNAME(route_sendoob)(struct socket *so, struct mbuf *m,
     struct mbuf *control)
 {
@@ -387,6 +403,7 @@ COMPATNAME(route_usrreq)(struct socket *
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	s = splsoftnet();
@@ -1496,6 +1513,7 @@ static const struct pr_usrreqs route_usr
 	.pr_peeraddr	= COMPATNAME(route_peeraddr_wrapper),
 	.pr_sockaddr	= COMPATNAME(route_sockaddr_wrapper),
 	.pr_recvoob	= COMPATNAME(route_recvoob_wrapper),
+	.pr_send	= COMPATNAME(route_send_wrapper),
 	.pr_sendoob	= COMPATNAME(route_sendoob_wrapper),
 	.pr_generic	= COMPATNAME(route_usrreq_wrapper),
 };

Index: src/sys/netatalk/ddp_usrreq.c
diff -u src/sys/netatalk/ddp_usrreq.c:1.58 src/sys/netatalk/ddp_usrreq.c:1.59
--- src/sys/netatalk/ddp_usrreq.c:1.58	Tue Aug  5 05:24:26 2014
+++ src/sys/netatalk/ddp_usrreq.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ddp_usrreq.c,v 1.58 2014/08/05 05:24:26 rtr Exp $	 */
+/*	$NetBSD: ddp_usrreq.c,v 1.59 2014/08/05 07:55:31 rtr Exp $	 */
 
 /*
  * Copyright (c) 1990,1991 Regents of The University of Michigan.
@@ -27,7 +27,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.58 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.59 2014/08/05 07:55:31 rtr Exp $");
 
 #include "opt_mbuftrace.h"
 
@@ -96,6 +96,7 @@ ddp_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	ddp = sotoddpcb(so);
@@ -115,36 +116,6 @@ ddp_usrreq(struct socket *so, int req, s
 		goto release;
 	}
 	switch (req) {
-	case PRU_SEND:{
-			int s = 0;
-
-			if (addr) {
-				if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT) {
-					error = EISCONN;
-					break;
-				}
-				s = splnet();
-				error = at_pcbconnect(ddp, addr);
-				if (error) {
-					splx(s);
-					break;
-				}
-			} else {
-				if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT) {
-					error = ENOTCONN;
-					break;
-				}
-			}
-
-			error = ddp_output(m, ddp);
-			m = NULL;
-			if (addr) {
-				at_pcbdisconnect(ddp);
-				splx(s);
-			}
-		}
-		break;
-
 	case PRU_CONNECT2:
 	case PRU_FASTTIMO:
 	case PRU_SLOWTIMO:
@@ -565,6 +536,42 @@ ddp_recvoob(struct socket *so, struct mb
 }
 
 static int
+ddp_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct ddpcb *ddp = sotoddpcb(so);
+	int error = 0;
+	int s;
+
+	KASSERT(solocked(so));
+	KASSERT(ddp != NULL);
+	KASSERT(nam != NULL);
+
+	if (nam) {
+		if (ddp->ddp_fsat.sat_port != ATADDR_ANYPORT)
+			return EISCONN;
+		s = splnet();
+		error = at_pcbconnect(ddp, nam);
+		if (error) {
+			splx(s);
+			return error;
+		}
+	} else {
+		if (ddp->ddp_fsat.sat_port == ATADDR_ANYPORT)
+			return ENOTCONN;
+	}
+
+	error = ddp_output(m, ddp);
+	m = NULL;
+	if (nam) {
+		at_pcbdisconnect(ddp);
+		splx(s);
+	}
+
+	return error;
+}
+
+static int
 ddp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -660,6 +667,7 @@ PR_WRAP_USRREQS(ddp)
 #define	ddp_peeraddr	ddp_peeraddr_wrapper
 #define	ddp_sockaddr	ddp_sockaddr_wrapper
 #define	ddp_recvoob	ddp_recvoob_wrapper
+#define	ddp_send	ddp_send_wrapper
 #define	ddp_sendoob	ddp_sendoob_wrapper
 #define	ddp_usrreq	ddp_usrreq_wrapper
 
@@ -678,6 +686,7 @@ const struct pr_usrreqs ddp_usrreqs = {
 	.pr_peeraddr	= ddp_peeraddr,
 	.pr_sockaddr	= ddp_sockaddr,
 	.pr_recvoob	= ddp_recvoob,
+	.pr_send	= ddp_send,
 	.pr_sendoob	= ddp_sendoob,
 	.pr_generic	= ddp_usrreq,
 };

Index: src/sys/netbt/hci_socket.c
diff -u src/sys/netbt/hci_socket.c:1.37 src/sys/netbt/hci_socket.c:1.38
--- src/sys/netbt/hci_socket.c:1.37	Tue Aug  5 05:24:26 2014
+++ src/sys/netbt/hci_socket.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: hci_socket.c,v 1.37 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: hci_socket.c,v 1.38 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.37 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.38 2014/08/05 07:55:31 rtr Exp $");
 
 /* load symbolic names */
 #ifdef BLUETOOTH_DEBUG
@@ -353,7 +353,7 @@ hci_cmdwait_flush(struct socket *so)
  *     This came from userland, so check it out.
  */
 static int
-hci_send(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr)
+hci_send_pcb(struct hci_pcb *pcb, struct mbuf *m, bdaddr_t *addr)
 {
 	struct hci_unit *unit;
 	struct mbuf *m0;
@@ -655,6 +655,43 @@ hci_recvoob(struct socket *so, struct mb
 }
 
 static int
+hci_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct hci_pcb *pcb = so->so_pcb;
+	struct sockaddr_bt * sa = NULL;
+	int err = 0;
+
+	KASSERT(solocked(so));
+	KASSERT(pcb != NULL);
+
+	if (control) /* have no use for this */
+		m_freem(control);
+
+	if (nam) {
+		sa = mtod(nam, struct sockaddr_bt *);
+
+		if (sa->bt_len != sizeof(struct sockaddr_bt)) {
+			err = EINVAL;
+			goto release;
+		}
+
+		if (sa->bt_family != AF_BLUETOOTH) {
+			err = EAFNOSUPPORT;
+			goto release;
+		}
+	}
+
+	return hci_send_pcb(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr));
+
+release:
+	if (m)
+		m_freem(m);
+
+	return err;
+}
+
+static int
 hci_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -682,7 +719,6 @@ hci_usrreq(struct socket *up, int req, s
 		struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
 {
 	struct hci_pcb *pcb = (struct hci_pcb *)up->so_pcb;
-	struct sockaddr_bt *sa;
 	int err = 0;
 
 	DPRINTFN(2, "%s\n", prurequests[req]);
@@ -700,6 +736,7 @@ hci_usrreq(struct socket *up, int req, s
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	switch(req) {
@@ -714,27 +751,6 @@ hci_usrreq(struct socket *up, int req, s
 	}
 
 	switch(req) {
-	case PRU_SEND:
-		sa = NULL;
-		if (nam) {
-			sa = mtod(nam, struct sockaddr_bt *);
-
-			if (sa->bt_len != sizeof(struct sockaddr_bt)) {
-				err = EINVAL;
-				goto release;
-			}
-
-			if (sa->bt_family != AF_BLUETOOTH) {
-				err = EAFNOSUPPORT;
-				goto release;
-			}
-		}
-
-		if (ctl) /* have no use for this */
-			m_freem(ctl);
-
-		return hci_send(pcb, m, (sa ? &sa->bt_bdaddr : &pcb->hp_raddr));
-
 	case PRU_RCVD:
 		return EOPNOTSUPP;	/* (no release) */
 
@@ -980,6 +996,7 @@ PR_WRAP_USRREQS(hci)
 #define	hci_peeraddr		hci_peeraddr_wrapper
 #define	hci_sockaddr		hci_sockaddr_wrapper
 #define	hci_recvoob		hci_recvoob_wrapper
+#define	hci_send		hci_send_wrapper
 #define	hci_sendoob		hci_sendoob_wrapper
 #define	hci_usrreq		hci_usrreq_wrapper
 
@@ -998,6 +1015,7 @@ const struct pr_usrreqs hci_usrreqs = {
 	.pr_peeraddr	= hci_peeraddr,
 	.pr_sockaddr	= hci_sockaddr,
 	.pr_recvoob	= hci_recvoob,
+	.pr_send	= hci_send,
 	.pr_sendoob	= hci_sendoob,
 	.pr_generic	= hci_usrreq,
 };

Index: src/sys/netbt/l2cap.h
diff -u src/sys/netbt/l2cap.h:1.17 src/sys/netbt/l2cap.h:1.18
--- src/sys/netbt/l2cap.h:1.17	Thu Jul 31 03:39:35 2014
+++ src/sys/netbt/l2cap.h	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: l2cap.h,v 1.17 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: l2cap.h,v 1.18 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -54,7 +54,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: l2cap.h,v 1.17 2014/07/31 03:39:35 rtr Exp $
+ * $Id: l2cap.h,v 1.18 2014/08/05 07:55:31 rtr Exp $
  * $FreeBSD: src/sys/netgraph/bluetooth/include/l2cap.h,v 1.4 2005/08/31 18:13:23 emax Exp $
  */
 
@@ -469,7 +469,7 @@ int l2cap_peeraddr_pcb(struct l2cap_chan
 int l2cap_disconnect_pcb(struct l2cap_channel *, int);
 void l2cap_detach_pcb(struct l2cap_channel **);
 int l2cap_listen_pcb(struct l2cap_channel *);
-int l2cap_send(struct l2cap_channel *, struct mbuf *);
+int l2cap_send_pcb(struct l2cap_channel *, struct mbuf *);
 int l2cap_setopt(struct l2cap_channel *, const struct sockopt *);
 int l2cap_getopt(struct l2cap_channel *, struct sockopt *);
 
Index: src/sys/netbt/l2cap_upper.c
diff -u src/sys/netbt/l2cap_upper.c:1.17 src/sys/netbt/l2cap_upper.c:1.18
--- src/sys/netbt/l2cap_upper.c:1.17	Thu Jul 31 03:39:35 2014
+++ src/sys/netbt/l2cap_upper.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: l2cap_upper.c,v 1.17 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: l2cap_upper.c,v 1.18 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.17 2014/07/31 03:39:35 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.18 2014/08/05 07:55:32 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -372,7 +372,7 @@ l2cap_listen_pcb(struct l2cap_channel *c
 }
 
 /*
- * l2cap_send(l2cap_channel, mbuf)
+ * l2cap_send_pcb(l2cap_channel, mbuf)
  *
  *	Output SDU on channel described by channel. This corresponds
  *	to "Send Data Request" in the L2CAP specification. The upper
@@ -394,7 +394,7 @@ l2cap_listen_pcb(struct l2cap_channel *c
  *	B-Frame header and start sending if we are not already
  */
 int
-l2cap_send(struct l2cap_channel *chan, struct mbuf *m)
+l2cap_send_pcb(struct l2cap_channel *chan, struct mbuf *m)
 {
 	l2cap_hdr_t *hdr;
 	int plen;

Index: src/sys/netbt/l2cap_lower.c
diff -u src/sys/netbt/l2cap_lower.c:1.9 src/sys/netbt/l2cap_lower.c:1.10
--- src/sys/netbt/l2cap_lower.c:1.9	Tue Aug  5 13:08:31 2008
+++ src/sys/netbt/l2cap_lower.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: l2cap_lower.c,v 1.9 2008/08/05 13:08:31 plunky Exp $	*/
+/*	$NetBSD: l2cap_lower.c,v 1.10 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_lower.c,v 1.9 2008/08/05 13:08:31 plunky Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_lower.c,v 1.10 2014/08/05 07:55:31 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -150,7 +150,7 @@ failed:
 }
 
 /*
- * Start another L2CAP packet on its way. This is called from l2cap_send
+ * Start another L2CAP packet on its way. This is called from l2cap_send_pcb
  * (when no PDU is pending) and hci_acl_start (when PDU has been placed on
  * device queue). Thus we can have more than one PDU waiting at the device
  * if space is available but no single channel will hog the link.

Index: src/sys/netbt/l2cap_socket.c
diff -u src/sys/netbt/l2cap_socket.c:1.28 src/sys/netbt/l2cap_socket.c:1.29
--- src/sys/netbt/l2cap_socket.c:1.28	Tue Aug  5 05:24:26 2014
+++ src/sys/netbt/l2cap_socket.c	Tue Aug  5 07:55:31 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: l2cap_socket.c,v 1.28 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: l2cap_socket.c,v 1.29 2014/08/05 07:55:31 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.28 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.29 2014/08/05 07:55:31 rtr Exp $");
 
 /* load symbolic names */
 #ifdef BLUETOOTH_DEBUG
@@ -283,6 +283,49 @@ l2cap_recvoob(struct socket *so, struct 
 }
 
 static int
+l2cap_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct l2cap_channel *pcb = so->so_pcb;
+	struct mbuf *m0;
+	int error = 0;
+
+	KASSERT(solocked(so));
+	KASSERT(m != NULL);
+
+	if (control)
+		m_freem(control);
+
+	if (pcb == NULL) {
+		error = EINVAL;
+		goto release;
+	}
+
+	if (m->m_pkthdr.len == 0)
+		goto release;
+
+	if (m->m_pkthdr.len > pcb->lc_omtu) {
+		error = EMSGSIZE;
+		goto release;
+	}
+
+	m0 = m_copypacket(m, M_DONTWAIT);
+	if (m0 == NULL) {
+		error = ENOMEM;
+		goto release;
+	}
+
+	sbappendrecord(&so->so_snd, m);
+	return l2cap_send_pcb(pcb, m0);
+
+release:
+	if (m)
+		m_freem(m);
+
+	return error;
+}
+
+static int
 l2cap_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -315,7 +358,6 @@ l2cap_usrreq(struct socket *up, int req,
     struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
 {
 	struct l2cap_channel *pcb = up->so_pcb;
-	struct mbuf *m0;
 	int err = 0;
 
 	DPRINTFN(2, "%s\n", prurequests[req]);
@@ -333,6 +375,7 @@ l2cap_usrreq(struct socket *up, int req,
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	switch (req) {
@@ -346,28 +389,6 @@ l2cap_usrreq(struct socket *up, int req,
 	}
 
 	switch(req) {
-	case PRU_SEND:
-		KASSERT(m != NULL);
-		if (m->m_pkthdr.len == 0)
-			break;
-
-		if (m->m_pkthdr.len > pcb->lc_omtu) {
-			err = EMSGSIZE;
-			break;
-		}
-
-		m0 = m_copypacket(m, M_DONTWAIT);
-		if (m0 == NULL) {
-			err = ENOMEM;
-			break;
-		}
-
-		if (ctl)	/* no use for that */
-			m_freem(ctl);
-
-		sbappendrecord(&up->so_snd, m);
-		return l2cap_send(pcb, m0);
-
 	case PRU_RCVD:
 		return EOPNOTSUPP;	/* (no release) */
 
@@ -547,6 +568,7 @@ PR_WRAP_USRREQS(l2cap)
 #define	l2cap_peeraddr		l2cap_peeraddr_wrapper
 #define	l2cap_sockaddr		l2cap_sockaddr_wrapper
 #define	l2cap_recvoob		l2cap_recvoob_wrapper
+#define	l2cap_send		l2cap_send_wrapper
 #define	l2cap_sendoob		l2cap_sendoob_wrapper
 #define	l2cap_usrreq		l2cap_usrreq_wrapper
 
@@ -565,6 +587,7 @@ const struct pr_usrreqs l2cap_usrreqs = 
 	.pr_peeraddr	= l2cap_peeraddr,
 	.pr_sockaddr	= l2cap_sockaddr,
 	.pr_recvoob	= l2cap_recvoob,
+	.pr_send	= l2cap_send,
 	.pr_sendoob	= l2cap_sendoob,
 	.pr_generic	= l2cap_usrreq,
 };

Index: src/sys/netbt/rfcomm.h
diff -u src/sys/netbt/rfcomm.h:1.16 src/sys/netbt/rfcomm.h:1.17
--- src/sys/netbt/rfcomm.h:1.16	Thu Jul 31 03:39:35 2014
+++ src/sys/netbt/rfcomm.h	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rfcomm.h,v 1.16 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: rfcomm.h,v 1.17 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -55,7 +55,7 @@
  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  * SUCH DAMAGE.
  *
- * $Id: rfcomm.h,v 1.16 2014/07/31 03:39:35 rtr Exp $
+ * $Id: rfcomm.h,v 1.17 2014/08/05 07:55:32 rtr Exp $
  * $FreeBSD: src/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h,v 1.4 2005/01/11 01:39:53 emax Exp $
  */
 
@@ -415,7 +415,7 @@ int rfcomm_peeraddr_pcb(struct rfcomm_dl
 int rfcomm_disconnect_pcb(struct rfcomm_dlc *, int);
 void rfcomm_detach_pcb(struct rfcomm_dlc **);
 int rfcomm_listen_pcb(struct rfcomm_dlc *);
-int rfcomm_send(struct rfcomm_dlc *, struct mbuf *);
+int rfcomm_send_pcb(struct rfcomm_dlc *, struct mbuf *);
 int rfcomm_rcvd(struct rfcomm_dlc *, size_t);
 int rfcomm_setopt(struct rfcomm_dlc *, const struct sockopt *);
 int rfcomm_getopt(struct rfcomm_dlc *, struct sockopt *);

Index: src/sys/netbt/rfcomm_session.c
diff -u src/sys/netbt/rfcomm_session.c:1.22 src/sys/netbt/rfcomm_session.c:1.23
--- src/sys/netbt/rfcomm_session.c:1.22	Thu Jul 31 03:39:35 2014
+++ src/sys/netbt/rfcomm_session.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rfcomm_session.c,v 1.22 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: rfcomm_session.c,v 1.23 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.22 2014/07/31 03:39:35 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.23 2014/08/05 07:55:32 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -1510,7 +1510,7 @@ rfcomm_session_send_frame(struct rfcomm_
 	DPRINTFN(5, "dlci %d type %2.2x (%d bytes, fcs=%#2.2x)\n",
 		dlci, type, m->m_pkthdr.len, fcs);
 
-	return l2cap_send(rs->rs_l2cap, m);
+	return l2cap_send_pcb(rs->rs_l2cap, m);
 }
 
 /*
@@ -1610,7 +1610,7 @@ rfcomm_session_send_uih(struct rfcomm_se
 	/*
 	 * UIH frame ready to go..
 	 */
-	err = l2cap_send(rs->rs_l2cap, m0);
+	err = l2cap_send_pcb(rs->rs_l2cap, m0);
 	if (err)
 		goto fail;
 

Index: src/sys/netbt/rfcomm_socket.c
diff -u src/sys/netbt/rfcomm_socket.c:1.30 src/sys/netbt/rfcomm_socket.c:1.31
--- src/sys/netbt/rfcomm_socket.c:1.30	Tue Aug  5 05:24:26 2014
+++ src/sys/netbt/rfcomm_socket.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rfcomm_socket.c,v 1.30 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: rfcomm_socket.c,v 1.31 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.30 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.31 2014/08/05 07:55:32 rtr Exp $");
 
 /* load symbolic names */
 #ifdef BLUETOOTH_DEBUG
@@ -291,6 +291,39 @@ rfcomm_recvoob(struct socket *so, struct
 }
 
 static int
+rfcomm_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct rfcomm_dlc *pcb = so->so_pcb;
+	int err = 0;
+	struct mbuf *m0;
+
+	KASSERT(solocked(so));
+	KASSERT(m != NULL);
+
+	if (control)	/* no use for that */
+		m_freem(control);
+
+	if (pcb == NULL) {
+		err = EINVAL;
+		goto release;
+	}
+
+	m0 = m_copypacket(m, M_DONTWAIT);
+	if (m0 == NULL) {
+		err = ENOMEM;
+		goto release;
+	}
+
+	sbappendstream(&so->so_snd, m);
+	return rfcomm_send_pcb(pcb, m0);
+
+release:
+	m_freem(m);
+	return err;
+}
+
+static int
 rfcomm_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -323,7 +356,6 @@ rfcomm_usrreq(struct socket *up, int req
 		struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
 {
 	struct rfcomm_dlc *pcb = up->so_pcb;
-	struct mbuf *m0;
 	int err = 0;
 
 	DPRINTFN(2, "%s\n", prurequests[req]);
@@ -341,6 +373,7 @@ rfcomm_usrreq(struct socket *up, int req
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	switch (req) {
@@ -353,22 +386,6 @@ rfcomm_usrreq(struct socket *up, int req
 	}
 
 	switch(req) {
-	case PRU_SEND:
-		KASSERT(m != NULL);
-
-		if (ctl)	/* no use for that */
-			m_freem(ctl);
-
-		m0 = m_copypacket(m, M_DONTWAIT);
-		if (m0 == NULL) {
-			err = ENOMEM;
-			goto release;
-		}
-
-		sbappendstream(&up->so_snd, m);
-
-		return rfcomm_send(pcb, m0);
-
 	case PRU_RCVD:
 		return rfcomm_rcvd(pcb, sbspace(&up->so_rcv));
 
@@ -560,6 +577,7 @@ PR_WRAP_USRREQS(rfcomm)
 #define	rfcomm_peeraddr		rfcomm_peeraddr_wrapper
 #define	rfcomm_sockaddr		rfcomm_sockaddr_wrapper
 #define	rfcomm_recvoob		rfcomm_recvoob_wrapper
+#define	rfcomm_send		rfcomm_send_wrapper
 #define	rfcomm_sendoob		rfcomm_sendoob_wrapper
 #define	rfcomm_usrreq		rfcomm_usrreq_wrapper
 
@@ -578,6 +596,7 @@ const struct pr_usrreqs rfcomm_usrreqs =
 	.pr_peeraddr	= rfcomm_peeraddr,
 	.pr_sockaddr	= rfcomm_sockaddr,
 	.pr_recvoob	= rfcomm_recvoob,
+	.pr_send	= rfcomm_send,
 	.pr_sendoob	= rfcomm_sendoob,
 	.pr_generic	= rfcomm_usrreq,
 };
Index: src/sys/netbt/sco_socket.c
diff -u src/sys/netbt/sco_socket.c:1.30 src/sys/netbt/sco_socket.c:1.31
--- src/sys/netbt/sco_socket.c:1.30	Tue Aug  5 05:24:26 2014
+++ src/sys/netbt/sco_socket.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: sco_socket.c,v 1.30 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: sco_socket.c,v 1.31 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.30 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.31 2014/08/05 07:55:32 rtr Exp $");
 
 /* load symbolic names */
 #ifdef BLUETOOTH_DEBUG
@@ -274,6 +274,47 @@ sco_recvoob(struct socket *so, struct mb
 }
 
 static int
+sco_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct sco_pcb *pcb = so->so_pcb;
+	int err = 0;
+	struct mbuf *m0;
+
+	KASSERT(solocked(so));
+	KASSERT(m != NULL);
+
+	if (control) /* no use for that */
+		m_freem(control);
+
+	if (pcb == NULL) {
+		err = EINVAL;
+		goto release;
+	}
+
+	if (m->m_pkthdr.len == 0)
+		goto release;
+
+	if (m->m_pkthdr.len > pcb->sp_mtu) {
+		err = EMSGSIZE;
+		goto release;
+	}
+
+	m0 = m_copypacket(m, M_DONTWAIT);
+	if (m0 == NULL) {
+		err = ENOMEM;
+		goto release;
+	}
+
+	sbappendrecord(&so->so_snd, m);
+	return sco_send_pcb(pcb, m0);
+
+release:
+	m_freem(m);
+	return err;
+}
+
+static int
 sco_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -302,7 +343,6 @@ sco_usrreq(struct socket *up, int req, s
     struct mbuf *nam, struct mbuf *ctl, struct lwp *l)
 {
 	struct sco_pcb *pcb = (struct sco_pcb *)up->so_pcb;
-	struct mbuf *m0;
 	int err = 0;
 
 	DPRINTFN(2, "%s\n", prurequests[req]);
@@ -320,6 +360,7 @@ sco_usrreq(struct socket *up, int req, s
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	switch(req) {
@@ -334,28 +375,6 @@ sco_usrreq(struct socket *up, int req, s
 	}
 
 	switch(req) {
-	case PRU_SEND:
-		KASSERT(m != NULL);
-		if (m->m_pkthdr.len == 0)
-			break;
-
-		if (m->m_pkthdr.len > pcb->sp_mtu) {
-			err = EMSGSIZE;
-			break;
-		}
-
-		m0 = m_copypacket(m, M_DONTWAIT);
-		if (m0 == NULL) {
-			err = ENOMEM;
-			break;
-		}
-
-		if (ctl) /* no use for that */
-			m_freem(ctl);
-
-		sbappendrecord(&up->so_snd, m);
-		return sco_send(pcb, m0);
-
 	case PRU_RCVD:
 		return EOPNOTSUPP;	/* (no release) */
 
@@ -514,6 +533,7 @@ PR_WRAP_USRREQS(sco)
 #define	sco_peeraddr		sco_peeraddr_wrapper
 #define	sco_sockaddr		sco_sockaddr_wrapper
 #define	sco_recvoob		sco_recvoob_wrapper
+#define	sco_send		sco_send_wrapper
 #define	sco_sendoob		sco_sendoob_wrapper
 #define	sco_usrreq		sco_usrreq_wrapper
 
@@ -532,6 +552,7 @@ const struct pr_usrreqs sco_usrreqs = {
 	.pr_peeraddr	= sco_peeraddr,
 	.pr_sockaddr	= sco_sockaddr,
 	.pr_recvoob	= sco_recvoob,
+	.pr_send	= sco_send,
 	.pr_sendoob	= sco_sendoob,
 	.pr_generic	= sco_usrreq,
 };

Index: src/sys/netbt/rfcomm_upper.c
diff -u src/sys/netbt/rfcomm_upper.c:1.19 src/sys/netbt/rfcomm_upper.c:1.20
--- src/sys/netbt/rfcomm_upper.c:1.19	Thu Jul 31 03:39:35 2014
+++ src/sys/netbt/rfcomm_upper.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rfcomm_upper.c,v 1.19 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: rfcomm_upper.c,v 1.20 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_upper.c,v 1.19 2014/07/31 03:39:35 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_upper.c,v 1.20 2014/08/05 07:55:32 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -382,14 +382,14 @@ rfcomm_listen_pcb(struct rfcomm_dlc *dlc
 }
 
 /*
- * rfcomm_send(dlc, mbuf)
+ * rfcomm_send_pcb(dlc, mbuf)
  *
  * Output data on DLC. This is streamed data, so we add it
  * to our buffer and start the DLC, which will assemble
  * packets and send them if it can.
  */
 int
-rfcomm_send(struct rfcomm_dlc *dlc, struct mbuf *m)
+rfcomm_send_pcb(struct rfcomm_dlc *dlc, struct mbuf *m)
 {
 
 	if (dlc->rd_txbuf != NULL) {

Index: src/sys/netbt/sco.h
diff -u src/sys/netbt/sco.h:1.10 src/sys/netbt/sco.h:1.11
--- src/sys/netbt/sco.h:1.10	Thu Jul 31 03:39:35 2014
+++ src/sys/netbt/sco.h	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: sco.h,v 1.10 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: sco.h,v 1.11 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -76,7 +76,7 @@ int sco_peeraddr_pcb(struct sco_pcb *, s
 int sco_disconnect_pcb(struct sco_pcb *, int);
 void sco_detach_pcb(struct sco_pcb **);
 int sco_listen_pcb(struct sco_pcb *);
-int sco_send(struct sco_pcb *, struct mbuf *);
+int sco_send_pcb(struct sco_pcb *, struct mbuf *);
 int sco_setopt(struct sco_pcb *, const struct sockopt *);
 int sco_getopt(struct sco_pcb *, struct sockopt *);
 

Index: src/sys/netbt/sco_upper.c
diff -u src/sys/netbt/sco_upper.c:1.15 src/sys/netbt/sco_upper.c:1.16
--- src/sys/netbt/sco_upper.c:1.15	Thu Jul 31 03:39:35 2014
+++ src/sys/netbt/sco_upper.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: sco_upper.c,v 1.15 2014/07/31 03:39:35 rtr Exp $	*/
+/*	$NetBSD: sco_upper.c,v 1.16 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sco_upper.c,v 1.15 2014/07/31 03:39:35 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sco_upper.c,v 1.16 2014/08/05 07:55:32 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -261,7 +261,7 @@ sco_listen_pcb(struct sco_pcb *pcb)
 }
 
 /*
- * sco_send(pcb, mbuf)
+ * sco_send_pcb(pcb, mbuf)
  *
  *	Send data on SCO pcb.
  *
@@ -271,7 +271,7 @@ sco_listen_pcb(struct sco_pcb *pcb)
  * we can drop a record from the socket buffer.
  */
 int
-sco_send(struct sco_pcb *pcb, struct mbuf *m)
+sco_send_pcb(struct sco_pcb *pcb, struct mbuf *m)
 {
 	hci_scodata_hdr_t *hdr;
 	int plen;

Index: src/sys/netinet/raw_ip.c
diff -u src/sys/netinet/raw_ip.c:1.142 src/sys/netinet/raw_ip.c:1.143
--- src/sys/netinet/raw_ip.c:1.142	Tue Aug  5 05:24:26 2014
+++ src/sys/netinet/raw_ip.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_ip.c,v 1.142 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: raw_ip.c,v 1.143 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -65,7 +65,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.142 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.143 2014/08/05 07:55:32 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -723,6 +723,55 @@ rip_recvoob(struct socket *so, struct mb
 }
 
 static int
+rip_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct inpcb *inp = sotoinpcb(so);
+	int error = 0;
+	int s;
+
+	KASSERT(solocked(so));
+	KASSERT(inp != NULL);
+	KASSERT(m != NULL);
+
+	/*
+	 * Ship a packet out.  The appropriate raw output
+	 * routine handles any massaging necessary.
+	 */
+	if (control && control->m_len) {
+		m_freem(control);
+		m_freem(m);
+		return EINVAL;
+	}
+
+	s = splsoftnet();
+	if (nam) {
+		if ((so->so_state & SS_ISCONNECTED) != 0) {
+			error = EISCONN;
+			goto die;
+		}
+		error = rip_connect_pcb(inp, nam);
+		if (error) {
+		die:
+			m_freem(m);
+			splx(s);
+			return error;
+		}
+	} else {
+		if ((so->so_state & SS_ISCONNECTED) == 0) {
+			error = ENOTCONN;
+			goto die;
+		}
+	}
+	error = rip_output(m, inp);
+	if (nam)
+		rip_disconnect1(inp);
+
+	splx(s);
+	return error;
+}
+
+static int
 rip_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -754,6 +803,7 @@ rip_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	s = splsoftnet();
@@ -770,7 +820,7 @@ rip_usrreq(struct socket *so, int req, s
 	KASSERT(solocked(so));
 	inp = sotoinpcb(so);
 
-	KASSERT(!control || (req == PRU_SEND));
+	KASSERT(!control);
 	if (inp == NULL) {
 		splx(s);
 		return EINVAL;
@@ -786,41 +836,6 @@ rip_usrreq(struct socket *so, int req, s
 		error = EOPNOTSUPP;
 		break;
 
-	/*
-	 * Ship a packet out.  The appropriate raw output
-	 * routine handles any massaging necessary.
-	 */
-	case PRU_SEND:
-		if (control && control->m_len) {
-			m_freem(control);
-			m_freem(m);
-			error = EINVAL;
-			break;
-		}
-	{
-		if (nam) {
-			if ((so->so_state & SS_ISCONNECTED) != 0) {
-				error = EISCONN;
-				goto die;
-			}
-			error = rip_connect_pcb(inp, nam);
-			if (error) {
-			die:
-				m_freem(m);
-				break;
-			}
-		} else {
-			if ((so->so_state & SS_ISCONNECTED) == 0) {
-				error = ENOTCONN;
-				goto die;
-			}
-		}
-		error = rip_output(m, inp);
-		if (nam)
-			rip_disconnect1(inp);
-	}
-		break;
-
 	default:
 		panic("rip_usrreq");
 	}
@@ -844,6 +859,7 @@ PR_WRAP_USRREQS(rip)
 #define	rip_peeraddr	rip_peeraddr_wrapper
 #define	rip_sockaddr	rip_sockaddr_wrapper
 #define	rip_recvoob	rip_recvoob_wrapper
+#define	rip_send	rip_send_wrapper
 #define	rip_sendoob	rip_sendoob_wrapper
 #define	rip_usrreq	rip_usrreq_wrapper
 
@@ -862,6 +878,7 @@ const struct pr_usrreqs rip_usrreqs = {
 	.pr_peeraddr	= rip_peeraddr,
 	.pr_sockaddr	= rip_sockaddr,
 	.pr_recvoob	= rip_recvoob,
+	.pr_send	= rip_send,
 	.pr_sendoob	= rip_sendoob,
 	.pr_generic	= rip_usrreq,
 };

Index: src/sys/netinet/tcp_usrreq.c
diff -u src/sys/netinet/tcp_usrreq.c:1.197 src/sys/netinet/tcp_usrreq.c:1.198
--- src/sys/netinet/tcp_usrreq.c:1.197	Tue Aug  5 07:10:41 2014
+++ src/sys/netinet/tcp_usrreq.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: tcp_usrreq.c,v 1.197 2014/08/05 07:10:41 rtr Exp $	*/
+/*	$NetBSD: tcp_usrreq.c,v 1.198 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -99,7 +99,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.197 2014/08/05 07:10:41 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.198 2014/08/05 07:55:32 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -245,6 +245,7 @@ tcp_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	s = splsoftnet();
@@ -283,7 +284,7 @@ tcp_usrreq(struct socket *so, int req, s
 
 	ostate = tcp_debug_capture(tp, req);
 
-	KASSERT(!control || req == PRU_SEND);
+	KASSERT(!control);
 #ifdef INET6
 	/* XXX: KASSERT((inp != NULL) ^ (in6p != NULL)); */
 #endif
@@ -312,21 +313,6 @@ tcp_usrreq(struct socket *so, int req, s
 			(void) tcp_output(tp);
 		break;
 
-	/*
-	 * Do a send by putting data in output queue and updating urgent
-	 * marker if URG set.  Possibly send more data.
-	 */
-	case PRU_SEND:
-		if (control && control->m_len) {
-			m_freem(control);
-			m_freem(m);
-			error = EINVAL;
-			break;
-		}
-		sbappendstream(&so->so_snd, m);
-		error = tcp_output(tp);
-		break;
-
 	default:
 		panic("tcp_usrreq");
 	}
@@ -1121,6 +1107,43 @@ tcp_recvoob(struct socket *so, struct mb
 }
 
 static int
+tcp_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct inpcb *inp = NULL;
+	struct in6pcb *in6p = NULL;
+	struct tcpcb *tp = NULL;
+	int ostate = 0;
+	int error = 0;
+	int s;
+
+	if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+		return error;
+
+	ostate = tcp_debug_capture(tp, PRU_SEND);
+
+	/*
+	 * Do a send by putting data in output queue and updating urgent
+	 * marker if URG set.  Possibly send more data.
+	 */
+	s = splsoftnet();
+	if (control && control->m_len) {
+		m_freem(control);
+		m_freem(m);
+		tcp_debug_trace(so, tp, ostate, PRU_SEND);
+		splx(s);
+		return EINVAL;
+	}
+
+	sbappendstream(&so->so_snd, m);
+	error = tcp_output(tp);
+	tcp_debug_trace(so, tp, ostate, PRU_SEND);
+	splx(s);
+
+	return error;
+}
+
+static int
 tcp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	struct inpcb *inp = NULL;
@@ -2408,6 +2431,7 @@ PR_WRAP_USRREQS(tcp)
 #define	tcp_peeraddr	tcp_peeraddr_wrapper
 #define	tcp_sockaddr	tcp_sockaddr_wrapper
 #define	tcp_recvoob	tcp_recvoob_wrapper
+#define	tcp_send	tcp_send_wrapper
 #define	tcp_sendoob	tcp_sendoob_wrapper
 #define	tcp_usrreq	tcp_usrreq_wrapper
 
@@ -2426,6 +2450,7 @@ const struct pr_usrreqs tcp_usrreqs = {
 	.pr_peeraddr	= tcp_peeraddr,
 	.pr_sockaddr	= tcp_sockaddr,
 	.pr_recvoob	= tcp_recvoob,
+	.pr_send	= tcp_send,
 	.pr_sendoob	= tcp_sendoob,
 	.pr_generic	= tcp_usrreq,
 };

Index: src/sys/netinet/udp_usrreq.c
diff -u src/sys/netinet/udp_usrreq.c:1.214 src/sys/netinet/udp_usrreq.c:1.215
--- src/sys/netinet/udp_usrreq.c:1.214	Tue Aug  5 05:24:26 2014
+++ src/sys/netinet/udp_usrreq.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: udp_usrreq.c,v 1.214 2014/08/05 05:24:26 rtr Exp $	*/
+/*	$NetBSD: udp_usrreq.c,v 1.215 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -66,7 +66,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.214 2014/08/05 05:24:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.215 2014/08/05 07:55:32 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -1049,6 +1049,58 @@ udp_recvoob(struct socket *so, struct mb
 }
 
 static int
+udp_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct inpcb *inp = sotoinpcb(so);
+	int error = 0;
+	struct in_addr laddr;			/* XXX */
+	int s;
+
+	KASSERT(solocked(so));
+	KASSERT(inp != NULL);
+	KASSERT(m != NULL);
+
+	if (control && control->m_len) {
+		m_freem(control);
+		m_freem(m);
+		return EINVAL;
+	}
+
+	memset(&laddr, 0, sizeof laddr);
+
+	s = splsoftnet();
+	if (nam) {
+		laddr = inp->inp_laddr;		/* XXX */
+		if ((so->so_state & SS_ISCONNECTED) != 0) {
+			error = EISCONN;
+			goto die;
+		}
+		error = in_pcbconnect(inp, nam, l);
+		if (error)
+			goto die;
+	} else {
+		if ((so->so_state & SS_ISCONNECTED) == 0) {
+			error = ENOTCONN;
+			goto die;
+		}
+	}
+	error = udp_output(m, inp);
+	m = NULL;
+	if (nam) {
+		in_pcbdisconnect(inp);
+		inp->inp_laddr = laddr;		/* XXX */
+		in_pcbstate(inp, INP_BOUND);	/* XXX */
+	}
+  die:
+	if (m)
+		m_freem(m);
+
+	splx(s);
+	return error;
+}
+
+static int
 udp_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -1080,6 +1132,7 @@ udp_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	s = splsoftnet();
@@ -1096,7 +1149,7 @@ udp_usrreq(struct socket *so, int req, s
 	KASSERT(solocked(so));
 	inp = sotoinpcb(so);
 
-	KASSERT(!control || req == PRU_SEND);
+	KASSERT(!control);
 	if (inp == NULL) {
 		splx(s);
 		return EINVAL;
@@ -1115,45 +1168,6 @@ udp_usrreq(struct socket *so, int req, s
 		error = EOPNOTSUPP;
 		break;
 
-	case PRU_SEND:
-		if (control && control->m_len) {
-			m_freem(control);
-			m_freem(m);
-			error = EINVAL;
-			break;
-		}
-	{
-		struct in_addr laddr;			/* XXX */
-
-		memset(&laddr, 0, sizeof laddr);
-		if (nam) {
-			laddr = inp->inp_laddr;		/* XXX */
-			if ((so->so_state & SS_ISCONNECTED) != 0) {
-				error = EISCONN;
-				goto die;
-			}
-			error = in_pcbconnect(inp, nam, l);
-			if (error)
-				goto die;
-		} else {
-			if ((so->so_state & SS_ISCONNECTED) == 0) {
-				error = ENOTCONN;
-				goto die;
-			}
-		}
-		error = udp_output(m, inp);
-		m = NULL;
-		if (nam) {
-			in_pcbdisconnect(inp);
-			inp->inp_laddr = laddr;		/* XXX */
-			in_pcbstate(inp, INP_BOUND);	/* XXX */
-		}
-	  die:
-		if (m)
-			m_freem(m);
-	}
-		break;
-
 	default:
 		panic("udp_usrreq");
 	}
@@ -1394,6 +1408,7 @@ PR_WRAP_USRREQS(udp)
 #define	udp_peeraddr	udp_peeraddr_wrapper
 #define	udp_sockaddr	udp_sockaddr_wrapper
 #define	udp_recvoob	udp_recvoob_wrapper
+#define	udp_send	udp_send_wrapper
 #define	udp_sendoob	udp_sendoob_wrapper
 #define	udp_usrreq	udp_usrreq_wrapper
 
@@ -1412,6 +1427,7 @@ const struct pr_usrreqs udp_usrreqs = {
 	.pr_peeraddr	= udp_peeraddr,
 	.pr_sockaddr	= udp_sockaddr,
 	.pr_recvoob	= udp_recvoob,
+	.pr_send	= udp_send,
 	.pr_sendoob	= udp_sendoob,
 	.pr_generic	= udp_usrreq,
 };

Index: src/sys/netinet6/raw_ip6.c
diff -u src/sys/netinet6/raw_ip6.c:1.133 src/sys/netinet6/raw_ip6.c:1.134
--- src/sys/netinet6/raw_ip6.c:1.133	Tue Aug  5 05:24:27 2014
+++ src/sys/netinet6/raw_ip6.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_ip6.c,v 1.133 2014/08/05 05:24:27 rtr Exp $	*/
+/*	$NetBSD: raw_ip6.c,v 1.134 2014/08/05 07:55:32 rtr Exp $	*/
 /*	$KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.133 2014/08/05 05:24:27 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.134 2014/08/05 07:55:32 rtr Exp $");
 
 #include "opt_ipsec.h"
 
@@ -838,6 +838,61 @@ rip6_recvoob(struct socket *so, struct m
 }
 
 static int
+rip6_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct in6pcb *in6p = sotoin6pcb(so);
+	struct sockaddr_in6 tmp;
+	struct sockaddr_in6 *dst;
+	int error = 0;
+
+	KASSERT(solocked(so));
+	KASSERT(in6p != NULL);
+	KASSERT(m != NULL);
+
+	/*
+	 * Ship a packet out. The appropriate raw output
+	 * routine handles any messaging necessary.
+	 */
+
+	/* always copy sockaddr to avoid overwrites */
+	if (so->so_state & SS_ISCONNECTED) {
+		if (nam) {
+			error = EISCONN;
+			goto release;
+		}
+		/* XXX */
+		sockaddr_in6_init(&tmp, &in6p->in6p_faddr, 0, 0, 0);
+		dst = &tmp;
+	} else {
+		if (nam == NULL) {
+			error = ENOTCONN;
+			goto release;
+		}
+		if (nam->m_len != sizeof(tmp)) {
+			error = EINVAL;
+			goto release;
+		}
+
+		tmp = *mtod(nam, struct sockaddr_in6 *);
+		dst = &tmp;
+
+		if (dst->sin6_family != AF_INET6) {
+			error = EAFNOSUPPORT;
+			goto release;
+		}
+	}
+	error = rip6_output(m, so, dst, control);
+	m = NULL;
+
+release:
+	if (m)
+		m_freem(m);
+
+	return error;
+}
+
+static int
 rip6_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -852,7 +907,6 @@ int
 rip6_usrreq(struct socket *so, int req, struct mbuf *m, 
 	struct mbuf *nam, struct mbuf *control, struct lwp *l)
 {
-	struct in6pcb *in6p = sotoin6pcb(so);
 	int error = 0;
 
 	KASSERT(req != PRU_ACCEPT);
@@ -867,6 +921,7 @@ rip6_usrreq(struct socket *so, int req, 
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	if (req == PRU_PURGEIF) {
@@ -884,47 +939,6 @@ rip6_usrreq(struct socket *so, int req, 
 		break;
 
 	/*
-	 * Ship a packet out. The appropriate raw output
-	 * routine handles any messaging necessary.
-	 */
-	case PRU_SEND:
-	{
-		struct sockaddr_in6 tmp;
-		struct sockaddr_in6 *dst;
-
-		/* always copy sockaddr to avoid overwrites */
-		if (so->so_state & SS_ISCONNECTED) {
-			if (nam) {
-				error = EISCONN;
-				break;
-			}
-			/* XXX */
-			sockaddr_in6_init(&tmp, &in6p->in6p_faddr, 0, 0, 0);
-			dst = &tmp;
-		} else {
-			if (nam == NULL) {
-				error = ENOTCONN;
-				break;
-			}
-			if (nam->m_len != sizeof(tmp)) {
-				error = EINVAL;
-				break;
-			}
-
-			tmp = *mtod(nam, struct sockaddr_in6 *);
-			dst = &tmp;
-
-			if (dst->sin6_family != AF_INET6) {
-				error = EAFNOSUPPORT;
-				break;
-			}
-		}
-		error = rip6_output(m, so, dst, control);
-		m = NULL;
-		break;
-	}
-
-	/*
 	 * Not supported.
 	 */
 	case PRU_RCVD:
@@ -993,6 +1007,7 @@ PR_WRAP_USRREQS(rip6)
 #define	rip6_peeraddr		rip6_peeraddr_wrapper
 #define	rip6_sockaddr		rip6_sockaddr_wrapper
 #define	rip6_recvoob		rip6_recvoob_wrapper
+#define	rip6_send		rip6_send_wrapper
 #define	rip6_sendoob		rip6_sendoob_wrapper
 #define	rip6_usrreq		rip6_usrreq_wrapper
 
@@ -1011,6 +1026,7 @@ const struct pr_usrreqs rip6_usrreqs = {
 	.pr_peeraddr	= rip6_peeraddr,
 	.pr_sockaddr	= rip6_sockaddr,
 	.pr_recvoob	= rip6_recvoob,
+	.pr_send	= rip6_send,
 	.pr_sendoob	= rip6_sendoob,
 	.pr_generic	= rip6_usrreq,
 };

Index: src/sys/netinet6/udp6_usrreq.c
diff -u src/sys/netinet6/udp6_usrreq.c:1.112 src/sys/netinet6/udp6_usrreq.c:1.113
--- src/sys/netinet6/udp6_usrreq.c:1.112	Tue Aug  5 05:24:27 2014
+++ src/sys/netinet6/udp6_usrreq.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: udp6_usrreq.c,v 1.112 2014/08/05 05:24:27 rtr Exp $	*/
+/*	$NetBSD: udp6_usrreq.c,v 1.113 2014/08/05 07:55:32 rtr Exp $	*/
 /*	$KAME: udp6_usrreq.c,v 1.86 2001/05/27 17:33:00 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.112 2014/08/05 05:24:27 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.113 2014/08/05 07:55:32 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet_csum.h"
@@ -836,6 +836,25 @@ udp6_recvoob(struct socket *so, struct m
 }
 
 static int
+udp6_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct in6pcb *in6p = sotoin6pcb(so);
+	int error = 0;
+	int s;
+
+	KASSERT(solocked(so));
+	KASSERT(in6p != NULL);
+	KASSERT(m != NULL);
+
+	s = splsoftnet();
+	error = udp6_output(in6p, m, nam, control, l);
+	splx(s);
+
+	return error;
+}
+
+static int
 udp6_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -853,7 +872,7 @@ udp6_usrreq(struct socket *so, int req, 
     struct mbuf *control, struct lwp *l)
 {
 	struct in6pcb *in6p = sotoin6pcb(so);
-	int s, error = 0;
+	int error = 0;
 
 	KASSERT(req != PRU_ATTACH);
 	KASSERT(req != PRU_DETACH);
@@ -869,6 +888,7 @@ udp6_usrreq(struct socket *so, int req, 
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	if (req == PRU_PURGEIF) {
@@ -885,12 +905,6 @@ udp6_usrreq(struct socket *so, int req, 
 	}
 
 	switch (req) {
-	case PRU_SEND:
-		s = splsoftnet();
-		error = udp6_output(in6p, m, addr6, control, l);
-		splx(s);
-		return error;
-
 	case PRU_CONNECT2:
 	case PRU_FASTTIMO:
 	case PRU_SLOWTIMO:
@@ -997,6 +1011,7 @@ PR_WRAP_USRREQS(udp6)
 #define	udp6_peeraddr	udp6_peeraddr_wrapper
 #define	udp6_sockaddr	udp6_sockaddr_wrapper
 #define	udp6_recvoob	udp6_recvoob_wrapper
+#define	udp6_send	udp6_send_wrapper
 #define	udp6_sendoob	udp6_sendoob_wrapper
 #define	udp6_usrreq	udp6_usrreq_wrapper
 
@@ -1015,6 +1030,7 @@ const struct pr_usrreqs udp6_usrreqs = {
 	.pr_peeraddr	= udp6_peeraddr,
 	.pr_sockaddr	= udp6_sockaddr,
 	.pr_recvoob	= udp6_recvoob,
+	.pr_send	= udp6_send,
 	.pr_sendoob	= udp6_sendoob,
 	.pr_generic	= udp6_usrreq,
 };

Index: src/sys/netipsec/keysock.c
diff -u src/sys/netipsec/keysock.c:1.40 src/sys/netipsec/keysock.c:1.41
--- src/sys/netipsec/keysock.c:1.40	Tue Aug  5 05:24:27 2014
+++ src/sys/netipsec/keysock.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: keysock.c,v 1.40 2014/08/05 05:24:27 rtr Exp $	*/
+/*	$NetBSD: keysock.c,v 1.41 2014/08/05 07:55:32 rtr Exp $	*/
 /*	$FreeBSD: src/sys/netipsec/keysock.c,v 1.3.2.1 2003/01/24 05:11:36 sam Exp $	*/
 /*	$KAME: keysock.c,v 1.25 2001/08/13 20:07:41 itojun Exp $	*/
 
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.40 2014/08/05 05:24:27 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.41 2014/08/05 07:55:32 rtr Exp $");
 
 #include "opt_ipsec.h"
 
@@ -617,6 +617,22 @@ key_recvoob(struct socket *so, struct mb
 }
 
 static int
+key_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	int error = 0;
+	int s;
+
+	KASSERT(solocked(so));
+
+	s = splsoftnet();
+	error = raw_send(so, m, nam, control, l);
+	splx(s);
+
+	return error;
+}
+
+static int
 key_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -651,6 +667,7 @@ key_usrreq(struct socket *so, int req,st
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	s = splsoftnet();
@@ -682,6 +699,7 @@ PR_WRAP_USRREQS(key)
 #define	key_peeraddr	key_peeraddr_wrapper
 #define	key_sockaddr	key_sockaddr_wrapper
 #define	key_recvoob	key_recvoob_wrapper
+#define	key_send	key_send_wrapper
 #define	key_sendoob	key_sendoob_wrapper
 #define	key_usrreq	key_usrreq_wrapper
 
@@ -700,6 +718,7 @@ const struct pr_usrreqs key_usrreqs = {
 	.pr_peeraddr	= key_peeraddr,
 	.pr_sockaddr	= key_sockaddr,
 	.pr_recvoob	= key_recvoob,
+	.pr_send	= key_send,
 	.pr_sendoob	= key_sendoob,
 	.pr_generic	= key_usrreq,
 };

Index: src/sys/netmpls/mpls_proto.c
diff -u src/sys/netmpls/mpls_proto.c:1.21 src/sys/netmpls/mpls_proto.c:1.22
--- src/sys/netmpls/mpls_proto.c:1.21	Tue Aug  5 05:24:27 2014
+++ src/sys/netmpls/mpls_proto.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: mpls_proto.c,v 1.21 2014/08/05 05:24:27 rtr Exp $ */
+/*	$NetBSD: mpls_proto.c,v 1.22 2014/08/05 07:55:32 rtr Exp $ */
 
 /*
  * Copyright (c) 2010 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.21 2014/08/05 05:24:27 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.22 2014/08/05 07:55:32 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_mbuftrace.h"
@@ -189,6 +189,15 @@ mpls_recvoob(struct socket *so, struct m
 }
 
 static int
+mpls_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	KASSERT(solocked(so));
+
+	return EOPNOTSUPP;
+}
+
+static int
 mpls_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -215,6 +224,7 @@ mpls_usrreq(struct socket *so, int req, 
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	return EOPNOTSUPP;
@@ -316,6 +326,7 @@ PR_WRAP_USRREQS(mpls)
 #define	mpls_peeraddr	mpls_peeraddr_wrapper
 #define	mpls_sockaddr	mpls_sockaddr_wrapper
 #define	mpls_recvoob	mpls_recvoob_wrapper
+#define	mpls_send	mpls_send_wrapper
 #define	mpls_sendoob	mpls_sendoob_wrapper
 #define	mpls_usrreq	mpls_usrreq_wrapper
 
@@ -334,6 +345,7 @@ static const struct pr_usrreqs mpls_usrr
 	.pr_peeraddr	= mpls_peeraddr,
 	.pr_sockaddr	= mpls_sockaddr,
 	.pr_recvoob	= mpls_recvoob,
+	.pr_send	= mpls_send,
 	.pr_sendoob	= mpls_sendoob,
 	.pr_generic	= mpls_usrreq,
 };

Index: src/sys/netnatm/natm.c
diff -u src/sys/netnatm/natm.c:1.42 src/sys/netnatm/natm.c:1.43
--- src/sys/netnatm/natm.c:1.42	Tue Aug  5 05:24:27 2014
+++ src/sys/netnatm/natm.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: natm.c,v 1.42 2014/08/05 05:24:27 rtr Exp $	*/
+/*	$NetBSD: natm.c,v 1.43 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*
  * Copyright (c) 1996 Charles D. Cranor and Washington University.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.42 2014/08/05 05:24:27 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.43 2014/08/05 07:55:32 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kmem.h>
@@ -327,6 +327,42 @@ natm_recvoob(struct socket *so, struct m
 }
 
 static int
+natm_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct natmpcb *npcb = (struct natmpcb *) so->so_pcb;
+	struct atm_pseudohdr *aph;
+
+	KASSERT(solocked(so));
+	KASSERT(pcb != NULL);
+	KASSERT(m != NULL);
+
+	if (control && control->m_len) {
+		m_freem(control);
+		m_freem(m);
+		return EINVAL;
+	}
+
+	/*
+	 * send the data.   we must put an atm_pseudohdr on first
+	 */
+	s = SPLSOFTNET();
+	M_PREPEND(m, sizeof(*aph), M_WAITOK);
+	if (m == NULL) {
+		error = ENOBUFS;
+		break;
+	}
+	aph = mtod(m, struct atm_pseudohdr *);
+	ATM_PH_VPI(aph) = npcb->npcb_vpi;
+	ATM_PH_SETVCI(aph, npcb->npcb_vci);
+	ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0;
+	error = atm_output(npcb->npcb_ifp, m, NULL, NULL);
+	splx(s);
+
+	return error;
+}
+
+static int
 natm_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
   KASSERT(solocked(so));
@@ -364,6 +400,7 @@ natm_usrreq(struct socket *so, int req, 
   KASSERT(req != PRU_PEERADDR);
   KASSERT(req != PRU_SOCKADDR);
   KASSERT(req != PRU_RCVOOB);
+  KASSERT(req != PRU_SEND);
   KASSERT(req != PRU_SENDOOB);
 
   s = SPLSOFTNET();
@@ -376,32 +413,6 @@ natm_usrreq(struct socket *so, int req, 
   }
 
   switch (req) {
-    case PRU_SEND:			/* send this data */
-      if (control && control->m_len) {
-	m_freem(control);
-	m_freem(m);
-	error = EINVAL;
-	break;
-      }
-
-      /*
-       * send the data.   we must put an atm_pseudohdr on first
-       */
-
-      M_PREPEND(m, sizeof(*aph), M_WAITOK);
-      if (m == NULL) {
-        error = ENOBUFS;
-	break;
-      }
-      aph = mtod(m, struct atm_pseudohdr *);
-      ATM_PH_VPI(aph) = npcb->npcb_vpi;
-      ATM_PH_SETVCI(aph, npcb->npcb_vci);
-      ATM_PH_FLAGS(aph) = (proto == PROTO_NATMAAL5) ? ATM_PH_AAL5 : 0;
-
-      error = atm_output(npcb->npcb_ifp, m, NULL, NULL);
-
-      break;
-
     case PRU_CONNECT2:			/* connect two sockets */
     case PRU_RCVD:			/* have taken data; more room now */
     case PRU_FASTTIMO:			/* 200ms timeout */
@@ -515,6 +526,7 @@ PR_WRAP_USRREQS(natm)
 #define	natm_peeraddr	natm_peeraddr_wrapper
 #define	natm_sockaddr	natm_sockaddr_wrapper
 #define	natm_recvoob	natm_recvoob_wrapper
+#define	natm_send	natm_send_wrapper
 #define	natm_sendoob	natm_sendoob_wrapper
 #define	natm_usrreq	natm_usrreq_wrapper
 
@@ -533,6 +545,7 @@ const struct pr_usrreqs natm_usrreqs = {
 	.pr_peeraddr	= natm_peeraddr,
 	.pr_sockaddr	= natm_sockaddr,
 	.pr_recvoob	= natm_recvoob,
+	.pr_send	= natm_send,
 	.pr_sendoob	= natm_sendoob,
 	.pr_generic	= natm_usrreq,
 };

Index: src/sys/nfs/nfs_socket.c
diff -u src/sys/nfs/nfs_socket.c:1.191 src/sys/nfs/nfs_socket.c:1.192
--- src/sys/nfs/nfs_socket.c:1.191	Sun May 18 14:46:16 2014
+++ src/sys/nfs/nfs_socket.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: nfs_socket.c,v 1.191 2014/05/18 14:46:16 rmind Exp $	*/
+/*	$NetBSD: nfs_socket.c,v 1.192 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*
  * Copyright (c) 1989, 1991, 1993, 1995
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.191 2014/05/18 14:46:16 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nfs_socket.c,v 1.192 2014/08/05 07:55:32 rtr Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_nfs.h"
@@ -805,11 +805,11 @@ nfs_timer(void *arg)
 		    nmp->nm_sent < nmp->nm_cwnd) &&
 		   (m = m_copym(rep->r_mreq, 0, M_COPYALL, M_DONTWAIT))){
 		        if (so->so_state & SS_ISCONNECTED)
-			    error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
-			    PRU_SEND, m, NULL, NULL, NULL);
+			    error = (*so->so_proto->pr_usrreqs->pr_send)(so,
+			    m, NULL, NULL, NULL);
 			else
-			    error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
-			    PRU_SEND, m, nmp->nm_nam, NULL, NULL);
+			    error = (*so->so_proto->pr_usrreqs->pr_send)(so,
+			    m, nmp->nm_nam, NULL, NULL);
 			if (error) {
 				if (NFSIGNORE_SOERROR(nmp->nm_soflags, error)) {
 #ifdef DEBUG

Index: src/sys/rump/net/lib/libsockin/sockin.c
diff -u src/sys/rump/net/lib/libsockin/sockin.c:1.55 src/sys/rump/net/lib/libsockin/sockin.c:1.56
--- src/sys/rump/net/lib/libsockin/sockin.c:1.55	Tue Aug  5 05:24:27 2014
+++ src/sys/rump/net/lib/libsockin/sockin.c	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: sockin.c,v 1.55 2014/08/05 05:24:27 rtr Exp $	*/
+/*	$NetBSD: sockin.c,v 1.56 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*
  * Copyright (c) 2008, 2009 Antti Kantee.  All Rights Reserved.
@@ -26,7 +26,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sockin.c,v 1.55 2014/08/05 05:24:27 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sockin.c,v 1.56 2014/08/05 07:55:32 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/condvar.h>
@@ -80,6 +80,8 @@ static int	sockin_stat(struct socket *, 
 static int	sockin_peeraddr(struct socket *, struct mbuf *);
 static int	sockin_sockaddr(struct socket *, struct mbuf *);
 static int	sockin_recvoob(struct socket *, struct mbuf *, int);
+static int	sockin_send(struct socket *, struct mbuf *, struct mbuf *,
+			    struct mbuf *, struct lwp *);
 static int	sockin_sendoob(struct socket *, struct mbuf *, struct mbuf *);
 static int	sockin_usrreq(struct socket *, int, struct mbuf *,
 			      struct mbuf *, struct mbuf *, struct lwp *);
@@ -100,6 +102,7 @@ static const struct pr_usrreqs sockin_us
 	.pr_peeraddr = sockin_peeraddr,
 	.pr_sockaddr = sockin_sockaddr,
 	.pr_recvoob = sockin_recvoob,
+	.pr_send = sockin_send,
 	.pr_sendoob = sockin_sendoob,
 	.pr_generic = sockin_usrreq,
 };
@@ -597,6 +600,66 @@ sockin_recvoob(struct socket *so, struct
 }
 
 static int
+sockin_send(struct socket *so, struct mbuf *m, struct mbuf *nam,
+    struct mbuf *control, struct lwp *l)
+{
+	struct sockaddr *saddr;
+	struct msghdr mhdr;
+	size_t iov_max, i;
+	struct iovec iov_buf[32], *iov;
+	struct mbuf *m2;
+	size_t tot, n;
+	int error = 0;
+	int s;
+
+	bpf_mtap_af(&sockin_if, AF_UNSPEC, m);
+
+	memset(&mhdr, 0, sizeof(mhdr));
+
+	iov_max = 0;
+	for (m2 = m; m2 != NULL; m2 = m2->m_next) {
+		iov_max++;
+	}
+
+	if (iov_max <= __arraycount(iov_buf)) {
+		iov = iov_buf;
+	} else {
+		iov = kmem_alloc(sizeof(struct iovec) * iov_max,
+		    KM_SLEEP);
+	}
+
+	tot = 0;
+	for (i = 0, m2 = m; m2 != NULL; m2 = m2->m_next, i++) {
+		iov[i].iov_base = m2->m_data;
+		iov[i].iov_len = m2->m_len;
+		tot += m2->m_len;
+	}
+	mhdr.msg_iov = iov;
+	mhdr.msg_iovlen = i;
+	s = SO2S(so);
+
+	if (nam != NULL) {
+		saddr = mtod(nam, struct sockaddr *);
+		mhdr.msg_name = saddr;
+		mhdr.msg_namelen = saddr->sa_len;
+	}
+
+	rumpcomp_sockin_sendmsg(s, &mhdr, 0, &n);
+
+	if (iov != iov_buf)
+		kmem_free(iov, sizeof(struct iovec) * iov_max);
+
+	m_freem(m);
+	m_freem(control);
+
+	/* this assumes too many things to list.. buthey, testing */
+	if (!rump_threads)
+		sockin_process(so);
+
+	return error;
+}
+
+static int
 sockin_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
 	KASSERT(solocked(so));
@@ -622,65 +685,10 @@ sockin_usrreq(struct socket *so, int req
 	KASSERT(req != PRU_PEERADDR);
 	KASSERT(req != PRU_SOCKADDR);
 	KASSERT(req != PRU_RCVOOB);
+	KASSERT(req != PRU_SEND);
 	KASSERT(req != PRU_SENDOOB);
 
 	switch (req) {
-	case PRU_SEND:
-	{
-		struct sockaddr *saddr;
-		struct msghdr mhdr;
-		size_t iov_max, i;
-		struct iovec iov_buf[32], *iov;
-		struct mbuf *m2;
-		size_t tot, n;
-		int s;
-
-		bpf_mtap_af(&sockin_if, AF_UNSPEC, m);
-
-		memset(&mhdr, 0, sizeof(mhdr));
-
-		iov_max = 0;
-		for (m2 = m; m2 != NULL; m2 = m2->m_next) {
-			iov_max++;
-		}
-
-		if (iov_max <= __arraycount(iov_buf)) {
-			iov = iov_buf;
-		} else {
-			iov = kmem_alloc(sizeof(struct iovec) * iov_max,
-			    KM_SLEEP);
-		}
-
-		tot = 0;
-		for (i = 0, m2 = m; m2 != NULL; m2 = m2->m_next, i++) {
-			iov[i].iov_base = m2->m_data;
-			iov[i].iov_len = m2->m_len;
-			tot += m2->m_len;
-		}
-		mhdr.msg_iov = iov;
-		mhdr.msg_iovlen = i;
-		s = SO2S(so);
-
-		if (nam != NULL) {
-			saddr = mtod(nam, struct sockaddr *);
-			mhdr.msg_name = saddr;
-			mhdr.msg_namelen = saddr->sa_len;
-		}
-
-		rumpcomp_sockin_sendmsg(s, &mhdr, 0, &n);
-
-		if (iov != iov_buf)
-			kmem_free(iov, sizeof(struct iovec) * iov_max);
-
-		m_freem(m);
-		m_freem(control);
-
-		/* this assumes too many things to list.. buthey, testing */
-		if (!rump_threads)
-			sockin_process(so);
-	}
-		break;
-
 	default:
 		panic("sockin_usrreq: IMPLEMENT ME, req %d not supported", req);
 	}

Index: src/sys/sys/protosw.h
diff -u src/sys/sys/protosw.h:1.57 src/sys/sys/protosw.h:1.58
--- src/sys/sys/protosw.h:1.57	Tue Aug  5 05:24:27 2014
+++ src/sys/sys/protosw.h	Tue Aug  5 07:55:32 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: protosw.h,v 1.57 2014/08/05 05:24:27 rtr Exp $	*/
+/*	$NetBSD: protosw.h,v 1.58 2014/08/05 07:55:32 rtr Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1993
@@ -250,6 +250,8 @@ struct pr_usrreqs {
 	int	(*pr_peeraddr)(struct socket *, struct mbuf *);
 	int	(*pr_sockaddr)(struct socket *, struct mbuf *);
 	int	(*pr_recvoob)(struct socket *, struct mbuf *, int);
+	int	(*pr_send)(struct socket *, struct mbuf *, struct mbuf *,
+	    struct mbuf *, struct lwp *);
 	int	(*pr_sendoob)(struct socket *, struct mbuf *, struct mbuf *);
 	int	(*pr_generic)(struct socket *, int, struct mbuf *,
 	    struct mbuf *, struct mbuf *, struct lwp *);
@@ -415,6 +417,16 @@ name##_recvoob_wrapper(struct socket *a,
 	return rv;					\
 }							\
 static int						\
+name##_send_wrapper(struct socket *a, struct mbuf *b,	\
+    struct mbuf *c, struct mbuf *d, struct lwp *e)	\
+{							\
+	int rv;						\
+	KERNEL_LOCK(1, NULL);				\
+	rv = name##_send(a, b, c, d, e);		\
+	KERNEL_UNLOCK_ONE(NULL);			\
+	return rv;					\
+}							\
+static int						\
 name##_sendoob_wrapper(struct socket *a,		\
     struct mbuf *b, struct mbuf *c)			\
 {							\

Reply via email to