Module Name:    src
Committed By:   rtr
Date:           Thu Jul 31 03:39:36 UTC 2014

Modified Files:
        src/sys/dev/bluetooth: bthidev.c btmagic.c btsco.c
        src/sys/kern: uipc_socket.c uipc_socket2.c uipc_usrreq.c
        src/sys/net: link_proto.c raw_usrreq.c rtsock.c
        src/sys/netatalk: ddp_usrreq.c
        src/sys/netbt: hci_socket.c l2cap.h 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 tcp_var.h 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/rump/net/lib/libsockin: sockin.c
        src/sys/sys: protosw.h un.h

Log Message:
split PRU_DISCONNECT, PRU_SHUTDOWN and PRU_ABORT function out of
pr_generic() usrreq switches and put into separate functions

   xxx_disconnect(struct socket *)
   xxx_shutdown(struct socket *)
   xxx_abort(struct socket *)

   - always KASSERT(solocked(so)) even if not implemented
   - replace calls to pr_generic() with req =
PRU_{DISCONNECT,SHUTDOWN,ABORT}
     with calls to pr_{disconnect,shutdown,abort}() respectively

rename existing internal functions used to implement above functionality
to permit use of the names for xxx_{disconnect,shutdown,abort}().

   - {l2cap,sco,rfcomm}_disconnect() ->
{l2cap,sco,rfcomm}_disconnect_pcb()
   - {unp,rip,tcp}_disconnect() -> {unp,rip,tcp}_disconnect1()
   - unp_shutdown() -> unp_shutdown1()

patch reviewed by rmind


To generate a diff of this commit:
cvs rdiff -u -r1.27 -r1.28 src/sys/dev/bluetooth/bthidev.c
cvs rdiff -u -r1.9 -r1.10 src/sys/dev/bluetooth/btmagic.c
cvs rdiff -u -r1.31 -r1.32 src/sys/dev/bluetooth/btsco.c
cvs rdiff -u -r1.228 -r1.229 src/sys/kern/uipc_socket.c
cvs rdiff -u -r1.119 -r1.120 src/sys/kern/uipc_socket2.c
cvs rdiff -u -r1.162 -r1.163 src/sys/kern/uipc_usrreq.c
cvs rdiff -u -r1.18 -r1.19 src/sys/net/link_proto.c
cvs rdiff -u -r1.46 -r1.47 src/sys/net/raw_usrreq.c
cvs rdiff -u -r1.158 -r1.159 src/sys/net/rtsock.c
cvs rdiff -u -r1.56 -r1.57 src/sys/netatalk/ddp_usrreq.c
cvs rdiff -u -r1.35 -r1.36 src/sys/netbt/hci_socket.c
cvs rdiff -u -r1.16 -r1.17 src/sys/netbt/l2cap.h src/sys/netbt/l2cap_upper.c
cvs rdiff -u -r1.26 -r1.27 src/sys/netbt/l2cap_socket.c
cvs rdiff -u -r1.15 -r1.16 src/sys/netbt/rfcomm.h
cvs rdiff -u -r1.21 -r1.22 src/sys/netbt/rfcomm_session.c
cvs rdiff -u -r1.27 -r1.28 src/sys/netbt/rfcomm_socket.c
cvs rdiff -u -r1.18 -r1.19 src/sys/netbt/rfcomm_upper.c
cvs rdiff -u -r1.9 -r1.10 src/sys/netbt/sco.h
cvs rdiff -u -r1.28 -r1.29 src/sys/netbt/sco_socket.c
cvs rdiff -u -r1.14 -r1.15 src/sys/netbt/sco_upper.c
cvs rdiff -u -r1.138 -r1.139 src/sys/netinet/raw_ip.c
cvs rdiff -u -r1.193 -r1.194 src/sys/netinet/tcp_usrreq.c
cvs rdiff -u -r1.174 -r1.175 src/sys/netinet/tcp_var.h
cvs rdiff -u -r1.211 -r1.212 src/sys/netinet/udp_usrreq.c
cvs rdiff -u -r1.131 -r1.132 src/sys/netinet6/raw_ip6.c
cvs rdiff -u -r1.110 -r1.111 src/sys/netinet6/udp6_usrreq.c
cvs rdiff -u -r1.38 -r1.39 src/sys/netipsec/keysock.c
cvs rdiff -u -r1.18 -r1.19 src/sys/netmpls/mpls_proto.c
cvs rdiff -u -r1.40 -r1.41 src/sys/netnatm/natm.c
cvs rdiff -u -r1.53 -r1.54 src/sys/rump/net/lib/libsockin/sockin.c
cvs rdiff -u -r1.55 -r1.56 src/sys/sys/protosw.h
cvs rdiff -u -r1.50 -r1.51 src/sys/sys/un.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/bluetooth/bthidev.c
diff -u src/sys/dev/bluetooth/bthidev.c:1.27 src/sys/dev/bluetooth/bthidev.c:1.28
--- src/sys/dev/bluetooth/bthidev.c:1.27	Wed Jul 30 10:04:25 2014
+++ src/sys/dev/bluetooth/bthidev.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: bthidev.c,v 1.27 2014/07/30 10:04:25 rtr Exp $	*/
+/*	$NetBSD: bthidev.c,v 1.28 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.27 2014/07/30 10:04:25 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bthidev.c,v 1.28 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/condvar.h>
@@ -370,14 +370,14 @@ bthidev_detach(device_t self, int flags)
 
 	/* close interrupt channel */
 	if (sc->sc_int != NULL) {
-		l2cap_disconnect(sc->sc_int, 0);
+		l2cap_disconnect_pcb(sc->sc_int, 0);
 		l2cap_detach_pcb(&sc->sc_int);
 		sc->sc_int = NULL;
 	}
 
 	/* close control channel */
 	if (sc->sc_ctl != NULL) {
-		l2cap_disconnect(sc->sc_ctl, 0);
+		l2cap_disconnect_pcb(sc->sc_ctl, 0);
 		l2cap_detach_pcb(&sc->sc_ctl);
 		sc->sc_ctl = NULL;
 	}
@@ -450,12 +450,12 @@ bthidev_timeout(void *arg)
 	switch (sc->sc_state) {
 	case BTHID_CLOSED:
 		if (sc->sc_int != NULL) {
-			l2cap_disconnect(sc->sc_int, 0);
+			l2cap_disconnect_pcb(sc->sc_int, 0);
 			break;
 		}
 
 		if (sc->sc_ctl != NULL) {
-			l2cap_disconnect(sc->sc_ctl, 0);
+			l2cap_disconnect_pcb(sc->sc_ctl, 0);
 			break;
 		}
 
@@ -678,14 +678,14 @@ bthidev_process_one(struct bthidev_softc
 			mutex_enter(bt_lock);
 			/* close interrupt channel */
 			if (sc->sc_int != NULL) {
-				l2cap_disconnect(sc->sc_int, 0);
+				l2cap_disconnect_pcb(sc->sc_int, 0);
 				l2cap_detach_pcb(&sc->sc_int);
 				sc->sc_int = NULL;
 			}
 
 			/* close control channel */
 			if (sc->sc_ctl != NULL) {
-				l2cap_disconnect(sc->sc_ctl, 0);
+				l2cap_disconnect_pcb(sc->sc_ctl, 0);
 				l2cap_detach_pcb(&sc->sc_ctl);
 				sc->sc_ctl = NULL;
 			}
@@ -939,10 +939,10 @@ bthidev_linkmode(void *arg, int new)
 		return;
 
 	if (sc->sc_int != NULL)
-		l2cap_disconnect(sc->sc_int, 0);
+		l2cap_disconnect_pcb(sc->sc_int, 0);
 
 	if (sc->sc_ctl != NULL)
-		l2cap_disconnect(sc->sc_ctl, 0);
+		l2cap_disconnect_pcb(sc->sc_ctl, 0);
 }
 
 /*

Index: src/sys/dev/bluetooth/btmagic.c
diff -u src/sys/dev/bluetooth/btmagic.c:1.9 src/sys/dev/bluetooth/btmagic.c:1.10
--- src/sys/dev/bluetooth/btmagic.c:1.9	Wed Jul 30 10:04:25 2014
+++ src/sys/dev/bluetooth/btmagic.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: btmagic.c,v 1.9 2014/07/30 10:04:25 rtr Exp $	*/
+/*	$NetBSD: btmagic.c,v 1.10 2014/07/31 03:39:35 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.9 2014/07/30 10:04:25 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: btmagic.c,v 1.10 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/conf.h>
@@ -413,14 +413,14 @@ btmagic_detach(device_t self, int flags)
 
 	/* close interrupt channel */
 	if (sc->sc_int != NULL) {
-		l2cap_disconnect(sc->sc_int, 0);
+		l2cap_disconnect_pcb(sc->sc_int, 0);
 		l2cap_detach_pcb(&sc->sc_int);
 		sc->sc_int = NULL;
 	}
 
 	/* close control channel */
 	if (sc->sc_ctl != NULL) {
-		l2cap_disconnect(sc->sc_ctl, 0);
+		l2cap_disconnect_pcb(sc->sc_ctl, 0);
 		l2cap_detach_pcb(&sc->sc_ctl);
 		sc->sc_ctl = NULL;
 	}
@@ -670,12 +670,12 @@ btmagic_timeout(void *arg)
 	switch (sc->sc_state) {
 	case BTMAGIC_CLOSED:
 		if (sc->sc_int != NULL) {
-			l2cap_disconnect(sc->sc_int, 0);
+			l2cap_disconnect_pcb(sc->sc_int, 0);
 			break;
 		}
 
 		if (sc->sc_ctl != NULL) {
-			l2cap_disconnect(sc->sc_ctl, 0);
+			l2cap_disconnect_pcb(sc->sc_ctl, 0);
 			break;
 		}
 		break;
@@ -1005,10 +1005,10 @@ btmagic_linkmode(void *arg, int new)
 		return;
 
 	if (sc->sc_int != NULL)
-		l2cap_disconnect(sc->sc_int, 0);
+		l2cap_disconnect_pcb(sc->sc_int, 0);
 
 	if (sc->sc_ctl != NULL)
-		l2cap_disconnect(sc->sc_ctl, 0);
+		l2cap_disconnect_pcb(sc->sc_ctl, 0);
 }
 
 /*

Index: src/sys/dev/bluetooth/btsco.c
diff -u src/sys/dev/bluetooth/btsco.c:1.31 src/sys/dev/bluetooth/btsco.c:1.32
--- src/sys/dev/bluetooth/btsco.c:1.31	Wed Jul 30 10:04:25 2014
+++ src/sys/dev/bluetooth/btsco.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: btsco.c,v 1.31 2014/07/30 10:04:25 rtr Exp $	*/
+/*	$NetBSD: btsco.c,v 1.32 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.31 2014/07/30 10:04:25 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: btsco.c,v 1.32 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/audioio.h>
@@ -359,7 +359,7 @@ btsco_detach(device_t self, int flags)
 	mutex_enter(bt_lock);
 	if (sc->sc_sco != NULL) {
 		DPRINTF("sc_sco=%p\n", sc->sc_sco);
-		sco_disconnect(sc->sc_sco, 0);
+		sco_disconnect_pcb(sc->sc_sco, 0);
 		sco_detach_pcb(&sc->sc_sco);
 		sc->sc_sco = NULL;
 	}
@@ -672,7 +672,7 @@ btsco_close(void *hdl)
 	KASSERT(mutex_owned(bt_lock));
 
 	if (sc->sc_sco != NULL) {
-		sco_disconnect(sc->sc_sco, 0);
+		sco_disconnect_pcb(sc->sc_sco, 0);
 		sco_detach_pcb(&sc->sc_sco);
 	}
 

Index: src/sys/kern/uipc_socket.c
diff -u src/sys/kern/uipc_socket.c:1.228 src/sys/kern/uipc_socket.c:1.229
--- src/sys/kern/uipc_socket.c:1.228	Wed Jul 30 10:04:26 2014
+++ src/sys/kern/uipc_socket.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_socket.c,v 1.228 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: uipc_socket.c,v 1.229 2014/07/31 03:39:35 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.228 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket.c,v 1.229 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_compat_netbsd.h"
 #include "opt_sock_counters.h"
@@ -853,8 +853,7 @@ sodisconnect(struct socket *so)
 	} else if (so->so_state & SS_ISDISCONNECTING) {
 		error = EALREADY;
 	} else {
-		error = (*so->so_proto->pr_usrreqs->pr_generic)(so,
-		    PRU_DISCONNECT, NULL, NULL, NULL, NULL);
+		error = (*so->so_proto->pr_usrreqs->pr_disconnect)(so);
 	}
 	return (error);
 }
@@ -1611,8 +1610,7 @@ soshutdown(struct socket *so, int how)
 		error = 0;
 	}
 	if (how == SHUT_WR || how == SHUT_RDWR)
-		error = (*pr->pr_usrreqs->pr_generic)(so,
-		    PRU_SHUTDOWN, NULL, NULL, NULL, NULL);
+		error = (*pr->pr_usrreqs->pr_shutdown)(so);
 
 	return error;
 }

Index: src/sys/kern/uipc_socket2.c
diff -u src/sys/kern/uipc_socket2.c:1.119 src/sys/kern/uipc_socket2.c:1.120
--- src/sys/kern/uipc_socket2.c:1.119	Mon May 19 02:51:24 2014
+++ src/sys/kern/uipc_socket2.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_socket2.c,v 1.119 2014/05/19 02:51:24 rmind Exp $	*/
+/*	$NetBSD: uipc_socket2.c,v 1.120 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -58,7 +58,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.119 2014/05/19 02:51:24 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_socket2.c,v 1.120 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_mbuftrace.h"
 #include "opt_sb_max.h"
@@ -437,7 +437,7 @@ soqremque(struct socket *so, int q)
  * socantsendmore: indicates that no more data will be sent on the
  * socket; it would normally be applied to a socket when the user
  * informs the system that no more data is to be sent, by the protocol
- * code (in case PRU_SHUTDOWN).
+ * code (in case pr_shutdown()).
  */
 void
 socantsendmore(struct socket *so)

Index: src/sys/kern/uipc_usrreq.c
diff -u src/sys/kern/uipc_usrreq.c:1.162 src/sys/kern/uipc_usrreq.c:1.163
--- src/sys/kern/uipc_usrreq.c:1.162	Wed Jul 30 10:04:26 2014
+++ src/sys/kern/uipc_usrreq.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: uipc_usrreq.c,v 1.162 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: uipc_usrreq.c,v 1.163 2014/07/31 03:39:35 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.162 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: uipc_usrreq.c,v 1.163 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -399,6 +399,9 @@ unp_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -420,15 +423,6 @@ unp_usrreq(struct socket *so, int req, s
 		error = unp_connect2(so, (struct socket *)nam, PRU_CONNECT2);
 		break;
 
-	case PRU_DISCONNECT:
-		unp_disconnect(unp);
-		break;
-
-	case PRU_SHUTDOWN:
-		socantsendmore(so);
-		unp_shutdown(unp);
-		break;
-
 	case PRU_RCVD:
 		switch (so->so_type) {
 
@@ -513,7 +507,7 @@ unp_usrreq(struct socket *so, int req, s
 			KASSERT(l != NULL);
 			error = unp_output(m, control, unp, l);
 			if (nam)
-				unp_disconnect(unp);
+				unp_disconnect1(unp);
 			break;
 		}
 
@@ -578,13 +572,6 @@ unp_usrreq(struct socket *so, int req, s
 		}
 		break;
 
-	case PRU_ABORT:
-		(void)unp_drop(unp, ECONNABORTED);
-		KASSERT(so->so_head == NULL);
-		KASSERT(so->so_pcb != NULL);
-		unp_detach(so);
-		break;
-
 	default:
 		panic("piusrreq");
 	}
@@ -757,7 +744,7 @@ unp_detach(struct socket *so)
 		unp->unp_vnode = NULL;
 	}
 	if (unp->unp_conn)
-		unp_disconnect(unp);
+		unp_disconnect1(unp);
 	while (unp->unp_refs) {
 		KASSERT(solocked2(so, unp->unp_refs->unp_socket));
 		if (unp_drop(unp->unp_refs, ECONNRESET)) {
@@ -1039,6 +1026,40 @@ unp_listen(struct socket *so)
 	return 0;
 }
 
+static int
+unp_disconnect(struct socket *so)
+{
+	KASSERT(solocked(so));
+	KASSERT(sotounpcb(so) != NULL);
+
+	unp_disconnect1(sotounpcb(so));
+	return 0;
+}
+
+static int
+unp_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+	KASSERT(sotounpcb(so) != NULL);
+
+	socantsendmore(so);
+	unp_shutdown1(sotounpcb(so));
+	return 0;
+}
+
+static int
+unp_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+	KASSERT(sotounpcb(so) != NULL);
+
+	(void)unp_drop(sotounpcb(so), ECONNABORTED);
+	KASSERT(so->so_head == NULL);
+	KASSERT(so->so_pcb != NULL);
+	unp_detach(so);
+	return 0;
+}
+
 int
 unp_connect(struct socket *so, struct mbuf *nam)
 {
@@ -1206,7 +1227,7 @@ unp_connect2(struct socket *so, struct s
 }
 
 void
-unp_disconnect(struct unpcb *unp)
+unp_disconnect1(struct unpcb *unp)
 {
 	struct unpcb *unp2 = unp->unp_conn;
 	struct socket *so;
@@ -1224,7 +1245,7 @@ unp_disconnect(struct unpcb *unp)
 			for (;;) {
 				KASSERT(solocked2(so, unp2->unp_socket));
 				if (unp2 == 0)
-					panic("unp_disconnect");
+					panic("unp_disconnect1");
 				if (unp2->unp_nextref == unp)
 					break;
 				unp2 = unp2->unp_nextref;
@@ -1246,7 +1267,7 @@ unp_disconnect(struct unpcb *unp)
 }
 
 void
-unp_shutdown(struct unpcb *unp)
+unp_shutdown1(struct unpcb *unp)
 {
 	struct socket *so;
 
@@ -1269,7 +1290,7 @@ unp_drop(struct unpcb *unp, int errno)
 	KASSERT(solocked(so));
 
 	so->so_error = errno;
-	unp_disconnect(unp);
+	unp_disconnect1(unp);
 	if (so->so_head) {
 		so->so_pcb = NULL;
 		/* sofree() drops the socket lock */
@@ -1879,6 +1900,9 @@ const struct pr_usrreqs unp_usrreqs = {
 	.pr_bind	= unp_bind,
 	.pr_listen	= unp_listen,
 	.pr_connect	= unp_connect,
+	.pr_disconnect	= unp_disconnect,
+	.pr_shutdown	= unp_shutdown,
+	.pr_abort	= unp_abort,
 	.pr_ioctl	= unp_ioctl,
 	.pr_stat	= unp_stat,
 	.pr_peeraddr	= unp_peeraddr,

Index: src/sys/net/link_proto.c
diff -u src/sys/net/link_proto.c:1.18 src/sys/net/link_proto.c:1.19
--- src/sys/net/link_proto.c:1.18	Thu Jul 24 15:12:03 2014
+++ src/sys/net/link_proto.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: link_proto.c,v 1.18 2014/07/24 15:12:03 rtr Exp $	*/
+/*	$NetBSD: link_proto.c,v 1.19 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1993
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: link_proto.c,v 1.18 2014/07/24 15:12:03 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: link_proto.c,v 1.19 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/socket.h>
@@ -53,6 +53,9 @@ static void link_detach(struct socket *)
 static int link_accept(struct socket *, struct mbuf *);
 static int link_bind(struct socket *, struct mbuf *);
 static int link_listen(struct socket *);
+static int link_disconnect(struct socket *);
+static int link_shutdown(struct socket *);
+static int link_abort(struct socket *);
 static int link_ioctl(struct socket *, u_long, void *, struct ifnet *);
 static int link_stat(struct socket *, struct stat *);
 static int link_peeraddr(struct socket *, struct mbuf *);
@@ -73,6 +76,9 @@ static const struct pr_usrreqs link_usrr
 	.pr_accept	= link_accept,
 	.pr_bind	= link_bind,
 	.pr_listen	= link_listen,
+	.pr_disconnect	= link_disconnect,
+	.pr_shutdown	= link_shutdown,
+	.pr_abort	= link_abort,
 	.pr_ioctl	= link_ioctl,
 	.pr_stat	= link_stat,
 	.pr_peeraddr	= link_peeraddr,
@@ -269,6 +275,30 @@ link_listen(struct socket *so)
 }
 
 static int
+link_disconnect(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	return EOPNOTSUPP;
+}
+
+static int
+link_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	return EOPNOTSUPP;
+}
+
+static int
+link_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	return EOPNOTSUPP;
+}
+
+static int
 link_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	return link_control(so, cmd, nam, ifp);
@@ -307,6 +337,9 @@ link_usrreq(struct socket *so, int req, 
 	KASSERT(req != PRU_ACCEPT);
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);

Index: src/sys/net/raw_usrreq.c
diff -u src/sys/net/raw_usrreq.c:1.46 src/sys/net/raw_usrreq.c:1.47
--- src/sys/net/raw_usrreq.c:1.46	Wed Jul 30 10:04:26 2014
+++ src/sys/net/raw_usrreq.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_usrreq.c,v 1.46 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: raw_usrreq.c,v 1.47 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*
  * Copyright (c) 1980, 1986, 1993
@@ -36,7 +36,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.46 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_usrreq.c,v 1.47 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/mbuf.h>
@@ -166,6 +166,9 @@ raw_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -193,18 +196,6 @@ raw_usrreq(struct socket *so, int req, s
 		error = EOPNOTSUPP;
 		break;
 
-	case PRU_DISCONNECT:
-		soisdisconnected(so);
-		raw_disconnect(rp);
-		break;
-
-	/*
-	 * Mark the connection as being incapable of further input.
-	 */
-	case PRU_SHUTDOWN:
-		socantsendmore(so);
-		break;
-
 	case PRU_RCVD:
 		error = EOPNOTSUPP;
 		break;

Index: src/sys/net/rtsock.c
diff -u src/sys/net/rtsock.c:1.158 src/sys/net/rtsock.c:1.159
--- src/sys/net/rtsock.c:1.158	Wed Jul 30 10:04:26 2014
+++ src/sys/net/rtsock.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtsock.c,v 1.158 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: rtsock.c,v 1.159 2014/07/31 03:39:35 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.158 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rtsock.c,v 1.159 2014/07/31 03:39:35 rtr Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -258,6 +258,49 @@ COMPATNAME(route_connect)(struct socket 
 }
 
 static int
+COMPATNAME(route_disconnect)(struct socket *so)
+{
+	struct rawcb *rp = sotorawcb(so);
+	int s;
+
+	KASSERT(solocked(so));
+	KASSERT(rp != NULL);
+
+	s = splsoftnet();
+	soisdisconnected(so);
+	raw_disconnect(rp);
+	splx(s);
+
+	return 0;
+}
+
+static int
+COMPATNAME(route_shutdown)(struct socket *so)
+{
+	int s;
+
+	KASSERT(solocked(so));
+
+	/*
+	 * Mark the connection as being incapable of further input.
+	 */
+	s = splsoftnet();
+	socantsendmore(so);
+	splx(s);
+	return 0;
+}
+
+static int
+COMPATNAME(route_abort)(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	panic("route_abort");
+
+	return EOPNOTSUPP;
+}
+
+static int
 COMPATNAME(route_ioctl)(struct socket *so, u_long cmd, void *nam,
     struct ifnet * ifp)
 {
@@ -336,6 +379,9 @@ COMPATNAME(route_usrreq)(struct socket *
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -1442,6 +1488,9 @@ static const struct pr_usrreqs route_usr
 	.pr_bind	= COMPATNAME(route_bind_wrapper),
 	.pr_listen	= COMPATNAME(route_listen_wrapper),
 	.pr_connect	= COMPATNAME(route_connect_wrapper),
+	.pr_disconnect	= COMPATNAME(route_disconnect_wrapper),
+	.pr_shutdown	= COMPATNAME(route_shutdown_wrapper),
+	.pr_abort	= COMPATNAME(route_abort_wrapper),
 	.pr_ioctl	= COMPATNAME(route_ioctl_wrapper),
 	.pr_stat	= COMPATNAME(route_stat_wrapper),
 	.pr_peeraddr	= COMPATNAME(route_peeraddr_wrapper),

Index: src/sys/netatalk/ddp_usrreq.c
diff -u src/sys/netatalk/ddp_usrreq.c:1.56 src/sys/netatalk/ddp_usrreq.c:1.57
--- src/sys/netatalk/ddp_usrreq.c:1.56	Wed Jul 30 10:04:26 2014
+++ src/sys/netatalk/ddp_usrreq.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: ddp_usrreq.c,v 1.56 2014/07/30 10:04:26 rtr Exp $	 */
+/*	$NetBSD: ddp_usrreq.c,v 1.57 2014/07/31 03:39:35 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.56 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ddp_usrreq.c,v 1.57 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_mbuftrace.h"
 
@@ -88,6 +88,9 @@ ddp_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -112,19 +115,6 @@ ddp_usrreq(struct socket *so, int req, s
 		goto release;
 	}
 	switch (req) {
-	case PRU_DISCONNECT:
-		if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE) {
-			error = ENOTCONN;
-			break;
-		}
-		at_pcbdisconnect(ddp);
-		soisdisconnected(so);
-		break;
-
-	case PRU_SHUTDOWN:
-		socantsendmore(so);
-		break;
-
 	case PRU_SEND:{
 			int s = 0;
 
@@ -155,11 +145,6 @@ ddp_usrreq(struct socket *so, int req, s
 		}
 		break;
 
-	case PRU_ABORT:
-		soisdisconnected(so);
-		ddp_detach(so);
-		break;
-
 	case PRU_CONNECT2:
 	case PRU_FASTTIMO:
 	case PRU_SLOWTIMO:
@@ -503,6 +488,41 @@ ddp_connect(struct socket *so, struct mb
 }
 
 static int
+ddp_disconnect(struct socket *so)
+{
+	struct ddpcb *ddp = sotoddpcb(so);
+
+	KASSERT(solocked(so));
+	KASSERT(ddp != NULL);
+
+	if (ddp->ddp_fsat.sat_addr.s_node == ATADDR_ANYNODE)
+		return ENOTCONN;
+
+	at_pcbdisconnect(ddp);
+	soisdisconnected(so);
+	return 0;
+}
+
+static int
+ddp_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	socantsendmore(so);
+	return 0;
+}
+
+static int
+ddp_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	soisdisconnected(so);
+	ddp_detach(so);
+	return 0;
+}
+
+static int
 ddp_ioctl(struct socket *so, u_long cmd, void *addr, struct ifnet *ifp)
 {
 	return at_control(cmd, addr, ifp);
@@ -632,6 +652,9 @@ PR_WRAP_USRREQS(ddp)
 #define	ddp_bind	ddp_bind_wrapper
 #define	ddp_listen	ddp_listen_wrapper
 #define	ddp_connect	ddp_connect_wrapper
+#define	ddp_disconnect	ddp_disconnect_wrapper
+#define	ddp_shutdown	ddp_shutdown_wrapper
+#define	ddp_abort	ddp_abort_wrapper
 #define	ddp_ioctl	ddp_ioctl_wrapper
 #define	ddp_stat	ddp_stat_wrapper
 #define	ddp_peeraddr	ddp_peeraddr_wrapper
@@ -647,6 +670,9 @@ const struct pr_usrreqs ddp_usrreqs = {
 	.pr_bind	= ddp_bind,
 	.pr_listen	= ddp_listen,
 	.pr_connect	= ddp_connect,
+	.pr_disconnect	= ddp_disconnect,
+	.pr_shutdown	= ddp_shutdown,
+	.pr_abort	= ddp_abort,
 	.pr_ioctl	= ddp_ioctl,
 	.pr_stat	= ddp_stat,
 	.pr_peeraddr	= ddp_peeraddr,

Index: src/sys/netbt/hci_socket.c
diff -u src/sys/netbt/hci_socket.c:1.35 src/sys/netbt/hci_socket.c:1.36
--- src/sys/netbt/hci_socket.c:1.35	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/hci_socket.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: hci_socket.c,v 1.35 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: hci_socket.c,v 1.36 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.35 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: hci_socket.c,v 1.36 2014/07/31 03:39:35 rtr Exp $");
 
 /* load symbolic names */
 #ifdef BLUETOOTH_DEBUG
@@ -552,6 +552,45 @@ hci_connect(struct socket *so, struct mb
 }
 
 static int
+hci_disconnect(struct socket *so)
+{
+	struct hci_pcb *pcb = so->so_pcb;
+
+	KASSERT(solocked(so));
+	KASSERT(pcb != NULL);
+
+	bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY);
+
+	/* XXX we cannot call soisdisconnected() here, as it sets
+	 * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being,
+	 * that soisconnected() does not clear these and if you
+	 * try to reconnect this socket (which is permitted) you
+	 * get a broken pipe when you try to write any data.
+	 */
+	so->so_state &= ~SS_ISCONNECTED;
+	return 0;
+}
+
+static int
+hci_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	socantsendmore(so);
+	return 0;
+}
+
+static int
+hci_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	soisdisconnected(so);
+	hci_detach(so);
+	return 0;
+}
+
+static int
 hci_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	int err;
@@ -653,6 +692,9 @@ hci_usrreq(struct socket *up, int req, s
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -672,27 +714,6 @@ hci_usrreq(struct socket *up, int req, s
 	}
 
 	switch(req) {
-	case PRU_DISCONNECT:
-		bdaddr_copy(&pcb->hp_raddr, BDADDR_ANY);
-
-		/* XXX we cannot call soisdisconnected() here, as it sets
-		 * SS_CANTRCVMORE and SS_CANTSENDMORE. The problem being,
-		 * that soisconnected() does not clear these and if you
-		 * try to reconnect this socket (which is permitted) you
-		 * get a broken pipe when you try to write any data.
-		 */
-		up->so_state &= ~SS_ISCONNECTED;
-		break;
-
-	case PRU_ABORT:
-		soisdisconnected(up);
-		hci_detach(up);
-		return 0;
-
-	case PRU_SHUTDOWN:
-		socantsendmore(up);
-		break;
-
 	case PRU_SEND:
 		sa = NULL;
 		if (nam) {
@@ -951,6 +972,9 @@ PR_WRAP_USRREQS(hci)
 #define	hci_bind		hci_bind_wrapper
 #define	hci_listen		hci_listen_wrapper
 #define	hci_connect		hci_connect_wrapper
+#define	hci_disconnect		hci_disconnect_wrapper
+#define	hci_shutdown		hci_shutdown_wrapper
+#define	hci_abort		hci_abort_wrapper
 #define	hci_ioctl		hci_ioctl_wrapper
 #define	hci_stat		hci_stat_wrapper
 #define	hci_peeraddr		hci_peeraddr_wrapper
@@ -966,6 +990,9 @@ const struct pr_usrreqs hci_usrreqs = {
 	.pr_bind	= hci_bind,
 	.pr_listen	= hci_listen,
 	.pr_connect	= hci_connect,
+	.pr_disconnect	= hci_disconnect,
+	.pr_shutdown	= hci_shutdown,
+	.pr_abort	= hci_abort,
 	.pr_ioctl	= hci_ioctl,
 	.pr_stat	= hci_stat,
 	.pr_peeraddr	= hci_peeraddr,

Index: src/sys/netbt/l2cap.h
diff -u src/sys/netbt/l2cap.h:1.16 src/sys/netbt/l2cap.h:1.17
--- src/sys/netbt/l2cap.h:1.16	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/l2cap.h	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: l2cap.h,v 1.16 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: l2cap.h,v 1.17 2014/07/31 03:39:35 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.16 2014/07/30 10:04:26 rtr Exp $
+ * $Id: l2cap.h,v 1.17 2014/07/31 03:39:35 rtr Exp $
  * $FreeBSD: src/sys/netgraph/bluetooth/include/l2cap.h,v 1.4 2005/08/31 18:13:23 emax Exp $
  */
 
@@ -466,7 +466,7 @@ int l2cap_bind_pcb(struct l2cap_channel 
 int l2cap_sockaddr_pcb(struct l2cap_channel *, struct sockaddr_bt *);
 int l2cap_connect_pcb(struct l2cap_channel *, struct sockaddr_bt *);
 int l2cap_peeraddr_pcb(struct l2cap_channel *, struct sockaddr_bt *);
-int l2cap_disconnect(struct l2cap_channel *, int);
+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 *);
Index: src/sys/netbt/l2cap_upper.c
diff -u src/sys/netbt/l2cap_upper.c:1.16 src/sys/netbt/l2cap_upper.c:1.17
--- src/sys/netbt/l2cap_upper.c:1.16	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/l2cap_upper.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: l2cap_upper.c,v 1.16 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: l2cap_upper.c,v 1.17 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.16 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_upper.c,v 1.17 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -222,7 +222,7 @@ l2cap_peeraddr_pcb(struct l2cap_channel 
 }
 
 /*
- * l2cap_disconnect(l2cap_channel, linger)
+ * l2cap_disconnect_pcb(l2cap_channel, linger)
  *
  *	Initiate L2CAP disconnection. This corresponds to
  *	"Close Channel Request" in the L2CAP specification
@@ -235,7 +235,7 @@ l2cap_peeraddr_pcb(struct l2cap_channel 
  *	the queue.
  */
 int
-l2cap_disconnect(struct l2cap_channel *chan, int linger)
+l2cap_disconnect_pcb(struct l2cap_channel *chan, int linger)
 {
 	int err = 0;
 

Index: src/sys/netbt/l2cap_socket.c
diff -u src/sys/netbt/l2cap_socket.c:1.26 src/sys/netbt/l2cap_socket.c:1.27
--- src/sys/netbt/l2cap_socket.c:1.26	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/l2cap_socket.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: l2cap_socket.c,v 1.26 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: l2cap_socket.c,v 1.27 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2005 Iain Hibbert.
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.26 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: l2cap_socket.c,v 1.27 2014/07/31 03:39:35 rtr Exp $");
 
 /* load symbolic names */
 #ifdef BLUETOOTH_DEBUG
@@ -192,6 +192,45 @@ l2cap_connect(struct socket *so, struct 
 }
 
 static int
+l2cap_disconnect(struct socket *so)
+{
+	struct l2cap_channel *pcb = so->so_pcb;
+
+	KASSERT(solocked(so));
+
+	if (pcb == NULL)
+		return EINVAL;
+
+	soisdisconnecting(so);
+	return l2cap_disconnect_pcb(pcb, so->so_linger);
+}
+
+static int
+l2cap_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	socantsendmore(so);
+	return 0;
+}
+
+static int
+l2cap_abort(struct socket *so)
+{
+	struct l2cap_channel *pcb = so->so_pcb;
+
+	KASSERT(solocked(so));
+
+	if (pcb == NULL)
+		return EINVAL;
+
+	l2cap_disconnect_pcb(pcb, 0);
+	soisdisconnected(so);
+	l2cap_detach(so);
+	return 0;
+}
+
+static int
 l2cap_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	return EPASSTHROUGH;
@@ -286,6 +325,9 @@ l2cap_usrreq(struct socket *up, int req,
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -304,20 +346,6 @@ l2cap_usrreq(struct socket *up, int req,
 	}
 
 	switch(req) {
-	case PRU_DISCONNECT:
-		soisdisconnecting(up);
-		return l2cap_disconnect(pcb, up->so_linger);
-
-	case PRU_ABORT:
-		l2cap_disconnect(pcb, 0);
-		soisdisconnected(up);
-		l2cap_detach(up);
-		return 0;
-
-	case PRU_SHUTDOWN:
-		socantsendmore(up);
-		break;
-
 	case PRU_SEND:
 		KASSERT(m != NULL);
 		if (m->m_pkthdr.len == 0)
@@ -482,7 +510,7 @@ l2cap_linkmode(void *arg, int new)
 	if (((mode & L2CAP_LM_AUTH) && !(new & L2CAP_LM_AUTH))
 	    || ((mode & L2CAP_LM_ENCRYPT) && !(new & L2CAP_LM_ENCRYPT))
 	    || ((mode & L2CAP_LM_SECURE) && !(new & L2CAP_LM_SECURE)))
-		l2cap_disconnect(so->so_pcb, 0);
+		l2cap_disconnect_pcb(so->so_pcb, 0);
 }
 
 static void
@@ -511,6 +539,9 @@ PR_WRAP_USRREQS(l2cap)
 #define	l2cap_bind		l2cap_bind_wrapper
 #define	l2cap_listen		l2cap_listen_wrapper
 #define	l2cap_connect		l2cap_connect_wrapper
+#define	l2cap_disconnect	l2cap_disconnect_wrapper
+#define	l2cap_shutdown		l2cap_shutdown_wrapper
+#define	l2cap_abort		l2cap_abort_wrapper
 #define	l2cap_ioctl		l2cap_ioctl_wrapper
 #define	l2cap_stat		l2cap_stat_wrapper
 #define	l2cap_peeraddr		l2cap_peeraddr_wrapper
@@ -526,6 +557,9 @@ const struct pr_usrreqs l2cap_usrreqs = 
 	.pr_bind	= l2cap_bind,
 	.pr_listen	= l2cap_listen,
 	.pr_connect	= l2cap_connect,
+	.pr_disconnect	= l2cap_disconnect,
+	.pr_shutdown	= l2cap_shutdown,
+	.pr_abort	= l2cap_abort,
 	.pr_ioctl	= l2cap_ioctl,
 	.pr_stat	= l2cap_stat,
 	.pr_peeraddr	= l2cap_peeraddr,

Index: src/sys/netbt/rfcomm.h
diff -u src/sys/netbt/rfcomm.h:1.15 src/sys/netbt/rfcomm.h:1.16
--- src/sys/netbt/rfcomm.h:1.15	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/rfcomm.h	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rfcomm.h,v 1.15 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: rfcomm.h,v 1.16 2014/07/31 03:39:35 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.15 2014/07/30 10:04:26 rtr Exp $
+ * $Id: rfcomm.h,v 1.16 2014/07/31 03:39:35 rtr Exp $
  * $FreeBSD: src/sys/netgraph/bluetooth/include/ng_btsocket_rfcomm.h,v 1.4 2005/01/11 01:39:53 emax Exp $
  */
 
@@ -412,7 +412,7 @@ int rfcomm_bind_pcb(struct rfcomm_dlc *,
 int rfcomm_sockaddr_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
 int rfcomm_connect_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
 int rfcomm_peeraddr_pcb(struct rfcomm_dlc *, struct sockaddr_bt *);
-int rfcomm_disconnect(struct rfcomm_dlc *, int);
+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 *);

Index: src/sys/netbt/rfcomm_session.c
diff -u src/sys/netbt/rfcomm_session.c:1.21 src/sys/netbt/rfcomm_session.c:1.22
--- src/sys/netbt/rfcomm_session.c:1.21	Thu Jul 24 15:12:03 2014
+++ src/sys/netbt/rfcomm_session.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rfcomm_session.c,v 1.21 2014/07/24 15:12:03 rtr Exp $	*/
+/*	$NetBSD: rfcomm_session.c,v 1.22 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.21 2014/07/24 15:12:03 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_session.c,v 1.22 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -499,7 +499,7 @@ rfcomm_session_complete(void *arg, int c
 	 */
 	if (rs->rs_state == RFCOMM_SESSION_CLOSED) {
 		if (SIMPLEQ_EMPTY(&rs->rs_credits))
-			l2cap_disconnect(rs->rs_l2cap, 0);
+			l2cap_disconnect_pcb(rs->rs_l2cap, 0);
 	}
 }
 
@@ -853,7 +853,7 @@ rfcomm_session_recv_ua(struct rfcomm_ses
 		case RFCOMM_SESSION_WAIT_DISCONNECT:	/* We sent DISC */
 			callout_stop(&rs->rs_timeout);
 			rs->rs_state = RFCOMM_SESSION_CLOSED;
-			l2cap_disconnect(rs->rs_l2cap, 0);
+			l2cap_disconnect_pcb(rs->rs_l2cap, 0);
 			break;
 
 		default:

Index: src/sys/netbt/rfcomm_socket.c
diff -u src/sys/netbt/rfcomm_socket.c:1.27 src/sys/netbt/rfcomm_socket.c:1.28
--- src/sys/netbt/rfcomm_socket.c:1.27	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/rfcomm_socket.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rfcomm_socket.c,v 1.27 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: rfcomm_socket.c,v 1.28 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.27 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_socket.c,v 1.28 2014/07/31 03:39:35 rtr Exp $");
 
 /* load symbolic names */
 #ifdef BLUETOOTH_DEBUG
@@ -200,6 +200,45 @@ rfcomm_connect(struct socket *so, struct
 }
 
 static int
+rfcomm_disconnect(struct socket *so)
+{
+	struct rfcomm_dlc *pcb = so->so_pcb;
+
+	KASSERT(solocked(so));
+
+	if (pcb == NULL)
+		return EINVAL;
+
+	soisdisconnecting(so);
+	return rfcomm_disconnect_pcb(pcb, so->so_linger);
+}
+
+static int
+rfcomm_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	socantsendmore(so);
+	return 0;
+}
+
+static int
+rfcomm_abort(struct socket *so)
+{
+	struct rfcomm_dlc *pcb = so->so_pcb;
+
+	KASSERT(solocked(so));
+
+	if (pcb == NULL)
+		return EINVAL;
+
+	rfcomm_disconnect_pcb(pcb, 0);
+	soisdisconnected(so);
+	rfcomm_detach(so);
+	return 0;
+}
+
+static int
 rfcomm_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	return EPASSTHROUGH;
@@ -294,6 +333,9 @@ rfcomm_usrreq(struct socket *up, int req
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -311,20 +353,6 @@ rfcomm_usrreq(struct socket *up, int req
 	}
 
 	switch(req) {
-	case PRU_DISCONNECT:
-		soisdisconnecting(up);
-		return rfcomm_disconnect(pcb, up->so_linger);
-
-	case PRU_ABORT:
-		rfcomm_disconnect(pcb, 0);
-		soisdisconnected(up);
-		rfcomm_detach(up);
-		return 0;
-
-	case PRU_SHUTDOWN:
-		socantsendmore(up);
-		break;
-
 	case PRU_SEND:
 		KASSERT(m != NULL);
 
@@ -488,7 +516,7 @@ rfcomm_linkmode(void *arg, int new)
 	if (((mode & RFCOMM_LM_AUTH) && !(new & RFCOMM_LM_AUTH))
 	    || ((mode & RFCOMM_LM_ENCRYPT) && !(new & RFCOMM_LM_ENCRYPT))
 	    || ((mode & RFCOMM_LM_SECURE) && !(new & RFCOMM_LM_SECURE)))
-		rfcomm_disconnect(so->so_pcb, 0);
+		rfcomm_disconnect_pcb(so->so_pcb, 0);
 }
 
 /*
@@ -522,6 +550,9 @@ PR_WRAP_USRREQS(rfcomm)
 #define	rfcomm_bind		rfcomm_bind_wrapper
 #define	rfcomm_listen		rfcomm_listen_wrapper
 #define	rfcomm_connect		rfcomm_connect_wrapper
+#define	rfcomm_disconnect	rfcomm_disconnect_wrapper
+#define	rfcomm_shutdown		rfcomm_shutdown_wrapper
+#define	rfcomm_abort		rfcomm_abort_wrapper
 #define	rfcomm_ioctl		rfcomm_ioctl_wrapper
 #define	rfcomm_stat		rfcomm_stat_wrapper
 #define	rfcomm_peeraddr		rfcomm_peeraddr_wrapper
@@ -537,6 +568,9 @@ const struct pr_usrreqs rfcomm_usrreqs =
 	.pr_bind	= rfcomm_bind,
 	.pr_listen	= rfcomm_listen,
 	.pr_connect	= rfcomm_connect,
+	.pr_disconnect	= rfcomm_disconnect,
+	.pr_shutdown	= rfcomm_shutdown,
+	.pr_abort	= rfcomm_abort,
 	.pr_ioctl	= rfcomm_ioctl,
 	.pr_stat	= rfcomm_stat,
 	.pr_peeraddr	= rfcomm_peeraddr,

Index: src/sys/netbt/rfcomm_upper.c
diff -u src/sys/netbt/rfcomm_upper.c:1.18 src/sys/netbt/rfcomm_upper.c:1.19
--- src/sys/netbt/rfcomm_upper.c:1.18	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/rfcomm_upper.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: rfcomm_upper.c,v 1.18 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: rfcomm_upper.c,v 1.19 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: rfcomm_upper.c,v 1.18 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: rfcomm_upper.c,v 1.19 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -213,12 +213,12 @@ rfcomm_peeraddr_pcb(struct rfcomm_dlc *d
 }
 
 /*
- * rfcomm_disconnect(dlc, linger)
+ * rfcomm_disconnect_pcb(dlc, linger)
  *
  * disconnect RFCOMM DLC
  */
 int
-rfcomm_disconnect(struct rfcomm_dlc *dlc, int linger)
+rfcomm_disconnect_pcb(struct rfcomm_dlc *dlc, int linger)
 {
 	struct rfcomm_session *rs = dlc->rd_session;
 	int err = 0;

Index: src/sys/netbt/sco.h
diff -u src/sys/netbt/sco.h:1.9 src/sys/netbt/sco.h:1.10
--- src/sys/netbt/sco.h:1.9	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/sco.h	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: sco.h,v 1.9 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: sco.h,v 1.10 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -73,7 +73,7 @@ int sco_bind_pcb(struct sco_pcb *, struc
 int sco_sockaddr_pcb(struct sco_pcb *, struct sockaddr_bt *);
 int sco_connect_pcb(struct sco_pcb *, struct sockaddr_bt *);
 int sco_peeraddr_pcb(struct sco_pcb *, struct sockaddr_bt *);
-int sco_disconnect(struct sco_pcb *, int);
+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 *);

Index: src/sys/netbt/sco_socket.c
diff -u src/sys/netbt/sco_socket.c:1.28 src/sys/netbt/sco_socket.c:1.29
--- src/sys/netbt/sco_socket.c:1.28	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/sco_socket.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: sco_socket.c,v 1.28 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: sco_socket.c,v 1.29 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -30,7 +30,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.28 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sco_socket.c,v 1.29 2014/07/31 03:39:35 rtr Exp $");
 
 /* load symbolic names */
 #ifdef BLUETOOTH_DEBUG
@@ -183,6 +183,45 @@ sco_connect(struct socket *so, struct mb
 }
 
 static int
+sco_disconnect(struct socket *so)
+{
+	struct sco_pcb *pcb = so->so_pcb;
+
+	KASSERT(solocked(so));
+
+	if (pcb == NULL)
+		return EINVAL;
+
+	soisdisconnecting(so);
+	return sco_disconnect_pcb(pcb, so->so_linger);
+}
+
+static int
+sco_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	socantsendmore(so);
+	return 0;
+}
+
+static int
+sco_abort(struct socket *so)
+{
+	struct sco_pcb *pcb = so->so_pcb;
+
+	KASSERT(solocked(so));
+
+	if (pcb == NULL)
+		return EINVAL;
+
+	sco_disconnect_pcb(pcb, 0);
+	soisdisconnected(so);
+	sco_detach(so);
+	return 0;
+}
+
+static int
 sco_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	return EOPNOTSUPP;
@@ -273,6 +312,9 @@ sco_usrreq(struct socket *up, int req, s
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -292,20 +334,6 @@ sco_usrreq(struct socket *up, int req, s
 	}
 
 	switch(req) {
-	case PRU_DISCONNECT:
-		soisdisconnecting(up);
-		return sco_disconnect(pcb, up->so_linger);
-
-	case PRU_ABORT:
-		sco_disconnect(pcb, 0);
-		soisdisconnected(up);
-		sco_detach(up);
-		return 0;
-
-	case PRU_SHUTDOWN:
-		socantsendmore(up);
-		break;
-
 	case PRU_SEND:
 		KASSERT(m != NULL);
 		if (m->m_pkthdr.len == 0)
@@ -478,6 +506,9 @@ PR_WRAP_USRREQS(sco)
 #define	sco_bind		sco_bind_wrapper
 #define	sco_listen		sco_listen_wrapper
 #define	sco_connect		sco_connect_wrapper
+#define	sco_disconnect		sco_disconnect_wrapper
+#define	sco_shutdown		sco_shutdown_wrapper
+#define	sco_abort		sco_abort_wrapper
 #define	sco_ioctl		sco_ioctl_wrapper
 #define	sco_stat		sco_stat_wrapper
 #define	sco_peeraddr		sco_peeraddr_wrapper
@@ -493,6 +524,9 @@ const struct pr_usrreqs sco_usrreqs = {
 	.pr_bind	= sco_bind,
 	.pr_listen	= sco_listen,
 	.pr_connect	= sco_connect,
+	.pr_disconnect	= sco_disconnect,
+	.pr_shutdown	= sco_shutdown,
+	.pr_abort	= sco_abort,
 	.pr_ioctl	= sco_ioctl,
 	.pr_stat	= sco_stat,
 	.pr_peeraddr	= sco_peeraddr,

Index: src/sys/netbt/sco_upper.c
diff -u src/sys/netbt/sco_upper.c:1.14 src/sys/netbt/sco_upper.c:1.15
--- src/sys/netbt/sco_upper.c:1.14	Wed Jul 30 10:04:26 2014
+++ src/sys/netbt/sco_upper.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: sco_upper.c,v 1.14 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: sco_upper.c,v 1.15 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*-
  * Copyright (c) 2006 Itronix Inc.
@@ -32,7 +32,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: sco_upper.c,v 1.14 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sco_upper.c,v 1.15 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kernel.h>
@@ -193,12 +193,12 @@ sco_peeraddr_pcb(struct sco_pcb *pcb, st
 }
 
 /*
- * sco_disconnect(pcb, linger)
+ * sco_disconnect_pcb(pcb, linger)
  *
  *	Initiate disconnection of connected SCO pcb
  */
 int
-sco_disconnect(struct sco_pcb *pcb, int linger)
+sco_disconnect_pcb(struct sco_pcb *pcb, int linger)
 {
 	hci_discon_cp cp;
 	struct hci_link *sco;
@@ -236,7 +236,7 @@ sco_detach_pcb(struct sco_pcb **handle)
 	*handle = NULL;
 
 	if (pcb->sp_link != NULL) {
-		sco_disconnect(pcb, 0);
+		sco_disconnect_pcb(pcb, 0);
 		pcb->sp_link = NULL;
 	}
 

Index: src/sys/netinet/raw_ip.c
diff -u src/sys/netinet/raw_ip.c:1.138 src/sys/netinet/raw_ip.c:1.139
--- src/sys/netinet/raw_ip.c:1.138	Thu Jul 31 02:21:51 2014
+++ src/sys/netinet/raw_ip.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_ip.c,v 1.138 2014/07/31 02:21:51 ozaki-r Exp $	*/
+/*	$NetBSD: raw_ip.c,v 1.139 2014/07/31 03:39:35 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.138 2014/07/31 02:21:51 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.139 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -113,7 +113,7 @@ struct inpcbtable rawcbtable;
 int	 rip_pcbnotify(struct inpcbtable *, struct in_addr,
     struct in_addr, int, int, void (*)(struct inpcb *, int));
 int	 rip_connect_pcb(struct inpcb *, struct mbuf *);
-void	 rip_disconnect(struct inpcb *);
+static void	 rip_disconnect1(struct inpcb *);
 
 static void sysctl_net_inet_raw_setup(struct sysctllog **);
 
@@ -495,8 +495,8 @@ rip_connect_pcb(struct inpcb *inp, struc
 	return (0);
 }
 
-void
-rip_disconnect(struct inpcb *inp)
+static void
+rip_disconnect1(struct inpcb *inp)
 {
 
 	inp->inp_faddr = zeroin_addr;
@@ -623,6 +623,40 @@ rip_connect(struct socket *so, struct mb
 	return error;
 }
 
+static int
+rip_disconnect(struct socket *so)
+{
+	struct inpcb *inp = sotoinpcb(so);
+
+	KASSERT(solocked(so));
+	KASSERT(inp != NULL);
+
+	soisdisconnected(so);
+	rip_disconnect1(inp);
+	return 0;
+}
+
+static int
+rip_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	/*
+	 * Mark the connection as being incapable of further input.
+	 */
+	socantsendmore(so);
+	return 0;
+}
+
+static int
+rip_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	panic("rip_abort");
+
+	return EOPNOTSUPP;
+}
 
 static int
 rip_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
@@ -693,6 +727,9 @@ rip_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -726,18 +763,6 @@ rip_usrreq(struct socket *so, int req, s
 		error = EOPNOTSUPP;
 		break;
 
-	case PRU_DISCONNECT:
-		soisdisconnected(so);
-		rip_disconnect(inp);
-		break;
-
-	/*
-	 * Mark the connection as being incapable of further input.
-	 */
-	case PRU_SHUTDOWN:
-		socantsendmore(so);
-		break;
-
 	case PRU_RCVD:
 		error = EOPNOTSUPP;
 		break;
@@ -773,7 +798,7 @@ rip_usrreq(struct socket *so, int req, s
 		}
 		error = rip_output(m, inp);
 		if (nam)
-			rip_disconnect(inp);
+			rip_disconnect1(inp);
 	}
 		break;
 
@@ -792,6 +817,9 @@ PR_WRAP_USRREQS(rip)
 #define	rip_bind	rip_bind_wrapper
 #define	rip_listen	rip_listen_wrapper
 #define	rip_connect	rip_connect_wrapper
+#define	rip_disconnect	rip_disconnect_wrapper
+#define	rip_shutdown	rip_shutdown_wrapper
+#define	rip_abort	rip_abort_wrapper
 #define	rip_ioctl	rip_ioctl_wrapper
 #define	rip_stat	rip_stat_wrapper
 #define	rip_peeraddr	rip_peeraddr_wrapper
@@ -807,6 +835,9 @@ const struct pr_usrreqs rip_usrreqs = {
 	.pr_bind	= rip_bind,
 	.pr_listen	= rip_listen,
 	.pr_connect	= rip_connect,
+	.pr_disconnect	= rip_disconnect,
+	.pr_shutdown	= rip_shutdown,
+	.pr_abort	= rip_abort,
 	.pr_ioctl	= rip_ioctl,
 	.pr_stat	= rip_stat,
 	.pr_peeraddr	= rip_peeraddr,

Index: src/sys/netinet/tcp_usrreq.c
diff -u src/sys/netinet/tcp_usrreq.c:1.193 src/sys/netinet/tcp_usrreq.c:1.194
--- src/sys/netinet/tcp_usrreq.c:1.193	Wed Jul 30 10:04:26 2014
+++ src/sys/netinet/tcp_usrreq.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: tcp_usrreq.c,v 1.193 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: tcp_usrreq.c,v 1.194 2014/07/31 03:39:35 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.193 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.194 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -234,6 +234,9 @@ tcp_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -294,31 +297,6 @@ tcp_usrreq(struct socket *so, int req, s
 		break;
 
 	/*
-	 * Initiate disconnect from peer.
-	 * If connection never passed embryonic stage, just drop;
-	 * else if don't need to let data drain, then can just drop anyways,
-	 * else have to begin TCP shutdown process: mark socket disconnecting,
-	 * drain unread data, state switch to reflect user close, and
-	 * send segment (e.g. FIN) to peer.  Socket will be really disconnected
-	 * when peer sends FIN and acks ours.
-	 *
-	 * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
-	 */
-	case PRU_DISCONNECT:
-		tp = tcp_disconnect(tp);
-		break;
-
-	/*
-	 * Mark the connection as being incapable of further output.
-	 */
-	case PRU_SHUTDOWN:
-		socantsendmore(so);
-		tp = tcp_usrclosed(tp);
-		if (tp)
-			error = tcp_output(tp);
-		break;
-
-	/*
 	 * After a receive, possibly send window update to peer.
 	 */
 	case PRU_RCVD:
@@ -348,13 +326,6 @@ tcp_usrreq(struct socket *so, int req, s
 		error = tcp_output(tp);
 		break;
 
-	/*
-	 * Abort the TCP.
-	 */
-	case PRU_ABORT:
-		tp = tcp_drop(tp, ECONNABORTED);
-		break;
-
 	default:
 		panic("tcp_usrreq");
 	}
@@ -722,7 +693,7 @@ tcp_detach(struct socket *so)
 		return;
 
 	s = splsoftnet();
-	(void)tcp_disconnect(tp);
+	(void)tcp_disconnect1(tp);
 	splx(s);
 }
 
@@ -944,6 +915,100 @@ release:
 }
 
 static int
+tcp_disconnect(struct socket *so)
+{
+	struct inpcb *inp = NULL;
+	struct in6pcb *in6p = NULL;
+	struct tcpcb *tp = NULL;
+	int s;
+	int error = 0;
+	int ostate = 0;
+
+	KASSERT(solocked(so));
+
+	if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+		return error;
+
+	ostate = tcp_debug_capture(tp, PRU_DISCONNECT);
+
+	/*
+	 * Initiate disconnect from peer.
+	 * If connection never passed embryonic stage, just drop;
+	 * else if don't need to let data drain, then can just drop anyways,
+	 * else have to begin TCP shutdown process: mark socket disconnecting,
+	 * drain unread data, state switch to reflect user close, and
+	 * send segment (e.g. FIN) to peer.  Socket will be really disconnected
+	 * when peer sends FIN and acks ours.
+	 *
+	 * SHOULD IMPLEMENT LATER PRU_CONNECT VIA REALLOC TCPCB.
+	 */
+	s = splsoftnet();
+	tp = tcp_disconnect1(tp);
+	tcp_debug_trace(so, tp, ostate, PRU_DISCONNECT);
+	splx(s);
+
+	return error;
+}
+
+static int
+tcp_shutdown(struct socket *so)
+{
+	struct inpcb *inp = NULL;
+	struct in6pcb *in6p = NULL;
+	struct tcpcb *tp = NULL;
+	int s;
+	int error = 0;
+	int ostate = 0;
+
+	KASSERT(solocked(so));
+
+	if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+		return error;
+
+	ostate = tcp_debug_capture(tp, PRU_SHUTDOWN);
+	/*
+	 * Mark the connection as being incapable of further output.
+	 */
+	s = splsoftnet();
+	socantsendmore(so);
+	tp = tcp_usrclosed(tp);
+	if (tp)
+		error = tcp_output(tp);
+	tcp_debug_trace(so, tp, ostate, PRU_SHUTDOWN);
+	splx(s);
+
+	return error;
+}
+
+static int
+tcp_abort(struct socket *so)
+{
+	struct inpcb *inp = NULL;
+	struct in6pcb *in6p = NULL;
+	struct tcpcb *tp = NULL;
+	int s;
+	int error = 0;
+	int ostate = 0;
+
+	KASSERT(solocked(so));
+
+	if ((error = tcp_getpcb(so, &inp, &in6p, &tp)) != 0)
+		return error;
+
+	ostate = tcp_debug_capture(tp, PRU_ABORT);
+
+	/*
+	 * Abort the TCP.
+	 */
+	s = splsoftnet();
+	tp = tcp_drop(tp, ECONNABORTED);
+	tcp_debug_trace(so, tp, ostate, PRU_ABORT);
+	splx(s);
+
+	return error;
+}
+
+static int
 tcp_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	switch (so->so_proto->pr_domain->dom_family) {
@@ -1104,7 +1169,7 @@ tcp_sendoob(struct socket *so, struct mb
  * send segment to peer (with FIN).
  */
 struct tcpcb *
-tcp_disconnect(struct tcpcb *tp)
+tcp_disconnect1(struct tcpcb *tp)
 {
 	struct socket *so;
 
@@ -2335,6 +2400,9 @@ PR_WRAP_USRREQS(tcp)
 #define	tcp_bind	tcp_bind_wrapper
 #define	tcp_listen	tcp_listen_wrapper
 #define	tcp_connect	tcp_connect_wrapper
+#define	tcp_disconnect	tcp_disconnect_wrapper
+#define	tcp_shutdown	tcp_shutdown_wrapper
+#define	tcp_abort	tcp_abort_wrapper
 #define	tcp_ioctl	tcp_ioctl_wrapper
 #define	tcp_stat	tcp_stat_wrapper
 #define	tcp_peeraddr	tcp_peeraddr_wrapper
@@ -2350,6 +2418,9 @@ const struct pr_usrreqs tcp_usrreqs = {
 	.pr_bind	= tcp_bind,
 	.pr_listen	= tcp_listen,
 	.pr_connect	= tcp_connect,
+	.pr_disconnect	= tcp_disconnect,
+	.pr_shutdown	= tcp_shutdown,
+	.pr_abort	= tcp_abort,
 	.pr_ioctl	= tcp_ioctl,
 	.pr_stat	= tcp_stat,
 	.pr_peeraddr	= tcp_peeraddr,

Index: src/sys/netinet/tcp_var.h
diff -u src/sys/netinet/tcp_var.h:1.174 src/sys/netinet/tcp_var.h:1.175
--- src/sys/netinet/tcp_var.h:1.174	Mon May 19 02:51:25 2014
+++ src/sys/netinet/tcp_var.h	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: tcp_var.h,v 1.174 2014/05/19 02:51:25 rmind Exp $	*/
+/*	$NetBSD: tcp_var.h,v 1.175 2014/07/31 03:39:35 rtr Exp $	*/
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -901,7 +901,7 @@ void	 *tcp6_ctlinput(int, const struct s
 void	 *tcp_ctlinput(int, const struct sockaddr *, void *);
 int	 tcp_ctloutput(int, struct socket *, struct sockopt *);
 struct tcpcb *
-	 tcp_disconnect(struct tcpcb *);
+	 tcp_disconnect1(struct tcpcb *);
 struct tcpcb *
 	 tcp_drop(struct tcpcb *, int);
 #ifdef TCP_SIGNATURE

Index: src/sys/netinet/udp_usrreq.c
diff -u src/sys/netinet/udp_usrreq.c:1.211 src/sys/netinet/udp_usrreq.c:1.212
--- src/sys/netinet/udp_usrreq.c:1.211	Wed Jul 30 10:04:26 2014
+++ src/sys/netinet/udp_usrreq.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: udp_usrreq.c,v 1.211 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: udp_usrreq.c,v 1.212 2014/07/31 03:39:35 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.211 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp_usrreq.c,v 1.212 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_compat_netbsd.h"
@@ -950,6 +950,50 @@ udp_connect(struct socket *so, struct mb
 }
 
 static int
+udp_disconnect(struct socket *so)
+{
+	struct inpcb *inp = sotoinpcb(so);
+	int s;
+
+	KASSERT(solocked(so));
+	KASSERT(inp != NULL);
+
+	s = splsoftnet();
+	/*soisdisconnected(so);*/
+	so->so_state &= ~SS_ISCONNECTED;	/* XXX */
+	in_pcbdisconnect(inp);
+	inp->inp_laddr = zeroin_addr;		/* XXX */
+	in_pcbstate(inp, INP_BOUND);		/* XXX */
+	splx(s);
+
+	return 0;
+}
+
+static int
+udp_shutdown(struct socket *so)
+{
+	int s;
+
+	KASSERT(solocked(so));
+
+	s = splsoftnet();
+	socantsendmore(so);
+	splx(s);
+
+	return 0;
+}
+
+static int
+udp_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	panic("udp_abort");
+
+	return EOPNOTSUPP;
+}
+
+static int
 udp_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	return in_control(so, cmd, nam, ifp);
@@ -1018,6 +1062,9 @@ udp_usrreq(struct socket *so, int req, s
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -1054,18 +1101,6 @@ udp_usrreq(struct socket *so, int req, s
 		error = EOPNOTSUPP;
 		break;
 
-	case PRU_DISCONNECT:
-		/*soisdisconnected(so);*/
-		so->so_state &= ~SS_ISCONNECTED;	/* XXX */
-		in_pcbdisconnect(inp);
-		inp->inp_laddr = zeroin_addr;		/* XXX */
-		in_pcbstate(inp, INP_BOUND);		/* XXX */
-		break;
-
-	case PRU_SHUTDOWN:
-		socantsendmore(so);
-		break;
-
 	case PRU_RCVD:
 		error = EOPNOTSUPP;
 		break;
@@ -1341,6 +1376,9 @@ PR_WRAP_USRREQS(udp)
 #define	udp_bind	udp_bind_wrapper
 #define	udp_listen	udp_listen_wrapper
 #define	udp_connect	udp_connect_wrapper
+#define	udp_disconnect	udp_disconnect_wrapper
+#define	udp_shutdown	udp_shutdown_wrapper
+#define	udp_abort	udp_abort_wrapper
 #define	udp_ioctl	udp_ioctl_wrapper
 #define	udp_stat	udp_stat_wrapper
 #define	udp_peeraddr	udp_peeraddr_wrapper
@@ -1356,6 +1394,9 @@ const struct pr_usrreqs udp_usrreqs = {
 	.pr_bind	= udp_bind,
 	.pr_listen	= udp_listen,
 	.pr_connect	= udp_connect,
+	.pr_disconnect	= udp_disconnect,
+	.pr_shutdown	= udp_shutdown,
+	.pr_abort	= udp_abort,
 	.pr_ioctl	= udp_ioctl,
 	.pr_stat	= udp_stat,
 	.pr_peeraddr	= udp_peeraddr,

Index: src/sys/netinet6/raw_ip6.c
diff -u src/sys/netinet6/raw_ip6.c:1.131 src/sys/netinet6/raw_ip6.c:1.132
--- src/sys/netinet6/raw_ip6.c:1.131	Thu Jul 31 02:21:51 2014
+++ src/sys/netinet6/raw_ip6.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_ip6.c,v 1.131 2014/07/31 02:21:51 ozaki-r Exp $	*/
+/*	$NetBSD: raw_ip6.c,v 1.132 2014/07/31 03:39:35 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.131 2014/07/31 02:21:51 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.132 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_ipsec.h"
 
@@ -755,6 +755,44 @@ rip6_connect(struct socket *so, struct m
 }
 
 static int
+rip6_disconnect(struct socket *so)
+{
+	struct in6pcb *in6p = sotoin6pcb(so);
+
+	KASSERT(solocked(so));
+	KASSERT(in6p != NULL);
+
+	if ((so->so_state & SS_ISCONNECTED) == 0)
+		return ENOTCONN;
+
+	in6p->in6p_faddr = in6addr_any;
+	so->so_state &= ~SS_ISCONNECTED;	/* XXX */
+	return 0;
+}
+
+static int
+rip6_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	/*
+	 * Mark the connection as being incapable of futther input.
+	 */
+	socantsendmore(so);
+	return 0;
+}
+
+static int
+rip6_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	soisdisconnected(so);
+	rip6_detach(so);
+	return 0;
+}
+
+static int
 rip6_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	return in6_control(so, cmd, nam, ifp);
@@ -821,6 +859,9 @@ rip6_usrreq(struct socket *so, int req, 
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -838,31 +879,11 @@ rip6_usrreq(struct socket *so, int req, 
 	}
 
 	switch (req) {
-	case PRU_DISCONNECT:
-		if ((so->so_state & SS_ISCONNECTED) == 0) {
-			error = ENOTCONN;
-			break;
-		}
-		in6p->in6p_faddr = in6addr_any;
-		so->so_state &= ~SS_ISCONNECTED;	/* XXX */
-		break;
-
-	case PRU_ABORT:
-		soisdisconnected(so);
-		rip6_detach(so);
-		break;
-
 	case PRU_CONNECT2:
 		error = EOPNOTSUPP;
 		break;
 
 	/*
-	 * Mark the connection as being incapable of futther input.
-	 */
-	case PRU_SHUTDOWN:
-		socantsendmore(so);
-		break;
-	/*
 	 * Ship a packet out. The appropriate raw output
 	 * routine handles any messaging necessary.
 	 */
@@ -964,6 +985,9 @@ PR_WRAP_USRREQS(rip6)
 #define	rip6_bind		rip6_bind_wrapper
 #define	rip6_listen		rip6_listen_wrapper
 #define	rip6_connect		rip6_connect_wrapper
+#define	rip6_disconnect		rip6_disconnect_wrapper
+#define	rip6_shutdown		rip6_shutdown_wrapper
+#define	rip6_abort		rip6_abort_wrapper
 #define	rip6_ioctl		rip6_ioctl_wrapper
 #define	rip6_stat		rip6_stat_wrapper
 #define	rip6_peeraddr		rip6_peeraddr_wrapper
@@ -979,6 +1003,9 @@ const struct pr_usrreqs rip6_usrreqs = {
 	.pr_bind	= rip6_bind,
 	.pr_listen	= rip6_listen,
 	.pr_connect	= rip6_connect,
+	.pr_disconnect	= rip6_disconnect,
+	.pr_shutdown	= rip6_shutdown,
+	.pr_abort	= rip6_abort,
 	.pr_ioctl	= rip6_ioctl,
 	.pr_stat	= rip6_stat,
 	.pr_peeraddr	= rip6_peeraddr,

Index: src/sys/netinet6/udp6_usrreq.c
diff -u src/sys/netinet6/udp6_usrreq.c:1.110 src/sys/netinet6/udp6_usrreq.c:1.111
--- src/sys/netinet6/udp6_usrreq.c:1.110	Wed Jul 30 10:04:26 2014
+++ src/sys/netinet6/udp6_usrreq.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: udp6_usrreq.c,v 1.110 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: udp6_usrreq.c,v 1.111 2014/07/31 03:39:35 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.110 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: udp6_usrreq.c,v 1.111 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_inet_csum.h"
@@ -731,6 +731,56 @@ udp6_connect(struct socket *so, struct m
 }
 
 static int
+udp6_disconnect(struct socket *so)
+{
+	struct in6pcb *in6p = sotoin6pcb(so);
+	int s;
+
+	KASSERT(solocked(so));
+	KASSERT(in6p != NULL);
+
+	if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr))
+		return ENOTCONN;
+
+	s = splsoftnet();
+	in6_pcbdisconnect(in6p);
+	memset((void *)&in6p->in6p_laddr, 0, sizeof(in6p->in6p_laddr));
+	splx(s);
+
+	so->so_state &= ~SS_ISCONNECTED;	/* XXX */
+	in6_pcbstate(in6p, IN6P_BOUND);		/* XXX */
+	return 0;
+}
+
+static int
+udp6_shutdown(struct socket *so)
+{
+	int s;
+
+	s = splsoftnet();
+	socantsendmore(so);
+	splx(s);
+
+	return 0;
+}
+
+static int
+udp6_abort(struct socket *so)
+{
+	int s;
+
+	KASSERT(solocked(so));
+	KASSERT(sotoin6pcb(so) != NULL);
+
+	s = splsoftnet();
+	soisdisconnected(so);
+	in6_pcbdetach(sotoin6pcb(so));
+	splx(s);
+
+	return 0;
+}
+
+static int
 udp6_ioctl(struct socket *so, u_long cmd, void *addr6, struct ifnet *ifp)
 {
 	/*
@@ -811,6 +861,9 @@ udp6_usrreq(struct socket *so, int req, 
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -832,35 +885,12 @@ udp6_usrreq(struct socket *so, int req, 
 	}
 
 	switch (req) {
-
-	case PRU_DISCONNECT:
-		if (IN6_IS_ADDR_UNSPECIFIED(&in6p->in6p_faddr)) {
-			error = ENOTCONN;
-			break;
-		}
-		s = splsoftnet();
-		in6_pcbdisconnect(in6p);
-		memset((void *)&in6p->in6p_laddr, 0, sizeof(in6p->in6p_laddr));
-		splx(s);
-		so->so_state &= ~SS_ISCONNECTED;		/* XXX */
-		in6_pcbstate(in6p, IN6P_BOUND);		/* XXX */
-		break;
-
-	case PRU_SHUTDOWN:
-		socantsendmore(so);
-		break;
-
 	case PRU_SEND:
 		s = splsoftnet();
 		error = udp6_output(in6p, m, addr6, control, l);
 		splx(s);
 		return error;
 
-	case PRU_ABORT:
-		soisdisconnected(so);
-		in6_pcbdetach(in6p);
-		break;
-
 	case PRU_CONNECT2:
 	case PRU_FASTTIMO:
 	case PRU_SLOWTIMO:
@@ -959,6 +989,9 @@ PR_WRAP_USRREQS(udp6)
 #define	udp6_bind	udp6_bind_wrapper
 #define	udp6_listen	udp6_listen_wrapper
 #define	udp6_connect	udp6_connect_wrapper
+#define	udp6_disconnect	udp6_disconnect_wrapper
+#define	udp6_shutdown	udp6_shutdown_wrapper
+#define	udp6_abort	udp6_abort_wrapper
 #define	udp6_ioctl	udp6_ioctl_wrapper
 #define	udp6_stat	udp6_stat_wrapper
 #define	udp6_peeraddr	udp6_peeraddr_wrapper
@@ -974,6 +1007,9 @@ const struct pr_usrreqs udp6_usrreqs = {
 	.pr_bind	= udp6_bind,
 	.pr_listen	= udp6_listen,
 	.pr_connect	= udp6_connect,
+	.pr_disconnect	= udp6_disconnect,
+	.pr_shutdown	= udp6_shutdown,
+	.pr_abort	= udp6_abort,
 	.pr_ioctl	= udp6_ioctl,
 	.pr_stat	= udp6_stat,
 	.pr_peeraddr	= udp6_peeraddr,

Index: src/sys/netipsec/keysock.c
diff -u src/sys/netipsec/keysock.c:1.38 src/sys/netipsec/keysock.c:1.39
--- src/sys/netipsec/keysock.c:1.38	Wed Jul 30 10:04:26 2014
+++ src/sys/netipsec/keysock.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: keysock.c,v 1.38 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: keysock.c,v 1.39 2014/07/31 03:39:35 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.38 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: keysock.c,v 1.39 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_ipsec.h"
 
@@ -490,7 +490,7 @@ key_accept(struct socket *so, struct mbu
 	KASSERT(solocked(so));
 
 	panic("key_accept");
-	/* NOT REACHED */
+
 	return EOPNOTSUPP;
 }
 
@@ -519,6 +519,50 @@ key_connect(struct socket *so, struct mb
 }
 
 static int
+key_disconnect(struct socket *so)
+{
+	struct rawcb *rp = sotorawcb(so);
+	int s;
+        
+	KASSERT(solocked(so));
+	KASSERT(rp != NULL);
+
+	s = splsoftnet();
+	soisdisconnected(so);
+	raw_disconnect(rp);
+	splx(s);
+ 
+	return 0;                               
+}
+
+static int
+key_shutdown(struct socket *so)
+{
+	int s;
+
+	KASSERT(solocked(so));
+
+	/*
+	 * Mark the connection as being incapable of further input.
+	 */
+	s = splsoftnet();
+	socantsendmore(so);
+	splx(s);
+
+	return 0;
+}
+
+static int
+key_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	panic("key_abort");
+
+	return EOPNOTSUPP;
+}
+
+static int
 key_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	return EOPNOTSUPP;
@@ -599,6 +643,9 @@ key_usrreq(struct socket *so, int req,st
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -627,6 +674,9 @@ PR_WRAP_USRREQS(key)
 #define	key_bind	key_bind_wrapper
 #define	key_listen	key_listen_wrapper
 #define	key_connect	key_connect_wrapper
+#define	key_disconnect	key_disconnect_wrapper
+#define	key_shutdown	key_shutdown_wrapper
+#define	key_abort	key_abort_wrapper
 #define	key_ioctl	key_ioctl_wrapper
 #define	key_stat	key_stat_wrapper
 #define	key_peeraddr	key_peeraddr_wrapper
@@ -642,6 +692,9 @@ const struct pr_usrreqs key_usrreqs = {
 	.pr_bind	= key_bind,
 	.pr_listen	= key_listen,
 	.pr_connect	= key_connect,
+	.pr_disconnect	= key_disconnect,
+	.pr_shutdown	= key_shutdown,
+	.pr_abort	= key_abort,
 	.pr_ioctl	= key_ioctl,
 	.pr_stat	= key_stat,
 	.pr_peeraddr	= key_peeraddr,

Index: src/sys/netmpls/mpls_proto.c
diff -u src/sys/netmpls/mpls_proto.c:1.18 src/sys/netmpls/mpls_proto.c:1.19
--- src/sys/netmpls/mpls_proto.c:1.18	Wed Jul 30 10:04:26 2014
+++ src/sys/netmpls/mpls_proto.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: mpls_proto.c,v 1.18 2014/07/30 10:04:26 rtr Exp $ */
+/*	$NetBSD: mpls_proto.c,v 1.19 2014/07/31 03:39:35 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.18 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: mpls_proto.c,v 1.19 2014/07/31 03:39:35 rtr Exp $");
 
 #include "opt_inet.h"
 #include "opt_mbuftrace.h"
@@ -127,6 +127,30 @@ mpls_connect(struct socket *so, struct m
 }
 
 static int
+mpls_disconnect(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	return EOPNOTSUPP;
+}
+
+static int
+mpls_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	return EOPNOTSUPP;
+}
+
+static int
+mpls_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	return EOPNOTSUPP;
+}
+
+static int
 mpls_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
 {
 	return EOPNOTSUPP;
@@ -267,6 +291,9 @@ PR_WRAP_USRREQS(mpls)
 #define	mpls_bind	mpls_bind_wrapper
 #define	mpls_listen	mpls_listen_wrapper
 #define	mpls_connect	mpls_connect_wrapper
+#define	mpls_disconnect	mpls_disconnect_wrapper
+#define	mpls_shutdown	mpls_shutdown_wrapper
+#define	mpls_abort	mpls_abort_wrapper
 #define	mpls_ioctl	mpls_ioctl_wrapper
 #define	mpls_stat	mpls_stat_wrapper
 #define	mpls_peeraddr	mpls_peeraddr_wrapper
@@ -282,6 +309,9 @@ static const struct pr_usrreqs mpls_usrr
 	.pr_bind	= mpls_bind,
 	.pr_listen	= mpls_listen,
 	.pr_connect	= mpls_connect,
+	.pr_disconnect	= mpls_disconnect,
+	.pr_shutdown	= mpls_shutdown,
+	.pr_abort	= mpls_abort,
 	.pr_ioctl	= mpls_ioctl,
 	.pr_stat	= mpls_stat,
 	.pr_peeraddr	= mpls_peeraddr,

Index: src/sys/netnatm/natm.c
diff -u src/sys/netnatm/natm.c:1.40 src/sys/netnatm/natm.c:1.41
--- src/sys/netnatm/natm.c:1.40	Wed Jul 30 10:04:26 2014
+++ src/sys/netnatm/natm.c	Thu Jul 31 03:39:35 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: natm.c,v 1.40 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: natm.c,v 1.41 2014/07/31 03:39:35 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.40 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: natm.c,v 1.41 2014/07/31 03:39:35 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/kmem.h>
@@ -189,6 +189,58 @@ natm_connect(struct socket *so, struct m
 	return error;
 }
 
+static int
+natm_disconnect(struct socket *so)
+{
+	struct natmpcb *npcb = (struct natmpcb *)so->so_pcb;
+
+	KASSERT(solocked(so));
+	KASSERT(npcb != NULL);
+
+	if ((npcb->npcb_flags & NPCB_CONNECTED) == 0) {
+		printf("natm: disconnected check\n");
+		return EIO;
+	}
+	ifp = npcb->npcb_ifp;
+
+	/*
+	 * disable rx
+	 */
+	ATM_PH_FLAGS(&api.aph) = ATM_PH_AAL5;
+	ATM_PH_VPI(&api.aph) = npcb->npcb_vpi;
+	ATM_PH_SETVCI(&api.aph, npcb->npcb_vci);
+	api.rxhand = npcb;
+
+	s2 = splnet();
+	ifp->if_ioctl(ifp, SIOCATMDIS, &api);
+	splx(s);
+
+	npcb_free(npcb, NPCB_REMOVE);
+	soisdisconnected(so);
+	return 0;
+}
+
+static int
+natm_shutdown(struct socket *so)
+{
+	int s;
+
+	KASSERT(solocked(so));
+
+	s = splsoftnet();
+	socantsendmore(so);
+	splx(s);
+
+	return 0;
+}
+
+static int
+natm_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	return EOPNOTSUPP;
+}
 
 static int
 natm_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
@@ -304,6 +356,9 @@ natm_usrreq(struct socket *so, int req, 
   KASSERT(req != PRU_BIND);
   KASSERT(req != PRU_LISTEN);
   KASSERT(req != PRU_CONNECT);
+  KASSERT(req != PRU_DISCONNECT);
+  KASSERT(req != PRU_SHUTDOWN);
+  KASSERT(req != PRU_ABORT);
   KASSERT(req != PRU_CONTROL);
   KASSERT(req != PRU_SENSE);
   KASSERT(req != PRU_PEERADDR);
@@ -321,36 +376,6 @@ natm_usrreq(struct socket *so, int req, 
   }
 
   switch (req) {
-    case PRU_DISCONNECT:		/* disconnect from peer */
-
-      if ((npcb->npcb_flags & NPCB_CONNECTED) == 0) {
-        printf("natm: disconnected check\n");
-        error = EIO;
-	break;
-      }
-      ifp = npcb->npcb_ifp;
-
-      /*
-       * disable rx
-       */
-
-      ATM_PH_FLAGS(&api.aph) = ATM_PH_AAL5;
-      ATM_PH_VPI(&api.aph) = npcb->npcb_vpi;
-      ATM_PH_SETVCI(&api.aph, npcb->npcb_vci);
-      api.rxhand = npcb;
-      s2 = splnet();
-      ifp->if_ioctl(ifp, SIOCATMDIS, &api);
-      splx(s);
-
-      npcb_free(npcb, NPCB_REMOVE);
-      soisdisconnected(so);
-
-      break;
-
-    case PRU_SHUTDOWN:			/* won't send any more data */
-      socantsendmore(so);
-      break;
-
     case PRU_SEND:			/* send this data */
       if (control && control->m_len) {
 	m_freem(control);
@@ -378,8 +403,6 @@ natm_usrreq(struct socket *so, int req, 
       break;
 
     case PRU_CONNECT2:			/* connect two sockets */
-    case PRU_ABORT:			/* abort (fast DISCONNECT, DETATCH) */
-					/* (only happens if LISTEN socket) */
     case PRU_RCVD:			/* have taken data; more room now */
     case PRU_FASTTIMO:			/* 200ms timeout */
     case PRU_SLOWTIMO:			/* 500ms timeout */
@@ -484,6 +507,9 @@ PR_WRAP_USRREQS(natm)
 #define	natm_bind	natm_bind_wrapper
 #define	natm_listen	natm_listen_wrapper
 #define	natm_connect	natm_connect_wrapper
+#define	natm_disconnect	natm_disconnect_wrapper
+#define	natm_shutdown	natm_shutdown_wrapper
+#define	natm_abort	natm_abort_wrapper
 #define	natm_ioctl	natm_ioctl_wrapper
 #define	natm_stat	natm_stat_wrapper
 #define	natm_peeraddr	natm_peeraddr_wrapper
@@ -499,6 +525,9 @@ const struct pr_usrreqs natm_usrreqs = {
 	.pr_bind	= natm_bind,
 	.pr_listen	= natm_listen,
 	.pr_connect	= natm_connect,
+	.pr_disconnect	= natm_disconnect,
+	.pr_shutdown	= natm_shutdown,
+	.pr_abort	= natm_abort,
 	.pr_ioctl	= natm_ioctl,
 	.pr_stat	= natm_stat,
 	.pr_peeraddr	= natm_peeraddr,

Index: src/sys/rump/net/lib/libsockin/sockin.c
diff -u src/sys/rump/net/lib/libsockin/sockin.c:1.53 src/sys/rump/net/lib/libsockin/sockin.c:1.54
--- src/sys/rump/net/lib/libsockin/sockin.c:1.53	Wed Jul 30 10:04:26 2014
+++ src/sys/rump/net/lib/libsockin/sockin.c	Thu Jul 31 03:39:36 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: sockin.c,v 1.53 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: sockin.c,v 1.54 2014/07/31 03:39:36 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.53 2014/07/30 10:04:26 rtr Exp $");
+__KERNEL_RCSID(0, "$NetBSD: sockin.c,v 1.54 2014/07/31 03:39:36 rtr Exp $");
 
 #include <sys/param.h>
 #include <sys/condvar.h>
@@ -72,6 +72,9 @@ static int	sockin_accept(struct socket *
 static int	sockin_bind(struct socket *, struct mbuf *);
 static int	sockin_listen(struct socket *);
 static int	sockin_connect(struct socket *, struct mbuf *);
+static int	sockin_disconnect(struct socket *);
+static int	sockin_shutdown(struct socket *);
+static int	sockin_abort(struct socket *);
 static int	sockin_ioctl(struct socket *, u_long, void *, struct ifnet *);
 static int	sockin_stat(struct socket *, struct stat *);
 static int	sockin_peeraddr(struct socket *, struct mbuf *);
@@ -89,6 +92,9 @@ static const struct pr_usrreqs sockin_us
 	.pr_bind = sockin_bind,
 	.pr_listen = sockin_listen,
 	.pr_connect = sockin_connect,
+	.pr_disconnect = sockin_disconnect,
+	.pr_shutdown = sockin_shutdown,
+	.pr_abort = sockin_abort,
 	.pr_ioctl = sockin_ioctl,
 	.pr_stat = sockin_stat,
 	.pr_peeraddr = sockin_peeraddr,
@@ -513,6 +519,30 @@ sockin_connect(struct socket *so, struct
 	return error;
 }
 
+static int
+sockin_disconnect(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	panic("sockin_disconnect: IMPLEMENT ME, disconnect not supported");
+}
+
+static int
+sockin_shutdown(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	removesock(so);
+	return 0;
+}
+
+static int
+sockin_abort(struct socket *so)
+{
+	KASSERT(solocked(so));
+
+	panic("sockin_abort: IMPLEMENT ME, abort not supported");
+}
 
 static int
 sockin_ioctl(struct socket *so, u_long cmd, void *nam, struct ifnet *ifp)
@@ -561,12 +591,16 @@ sockin_sockaddr(struct socket *so, struc
 static int
 sockin_recvoob(struct socket *so, struct mbuf *m, int flags)
 {
+	KASSERT(solocked(so));
+
 	panic("sockin_recvoob: IMPLEMENT ME, recvoob not supported");
 }
 
 static int
 sockin_sendoob(struct socket *so, struct mbuf *m, struct mbuf *control)
 {
+	KASSERT(solocked(so));
+
 	panic("sockin_sendoob: IMPLEMENT ME, sendoob not supported");
 }
 
@@ -580,6 +614,9 @@ sockin_usrreq(struct socket *so, int req
 	KASSERT(req != PRU_BIND);
 	KASSERT(req != PRU_LISTEN);
 	KASSERT(req != PRU_CONNECT);
+	KASSERT(req != PRU_DISCONNECT);
+	KASSERT(req != PRU_SHUTDOWN);
+	KASSERT(req != PRU_ABORT);
 	KASSERT(req != PRU_CONTROL);
 	KASSERT(req != PRU_SENSE);
 	KASSERT(req != PRU_PEERADDR);
@@ -644,10 +681,6 @@ sockin_usrreq(struct socket *so, int req
 	}
 		break;
 
-	case PRU_SHUTDOWN:
-		removesock(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.55 src/sys/sys/protosw.h:1.56
--- src/sys/sys/protosw.h:1.55	Wed Jul 30 10:04:26 2014
+++ src/sys/sys/protosw.h	Thu Jul 31 03:39:36 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: protosw.h,v 1.55 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: protosw.h,v 1.56 2014/07/31 03:39:36 rtr Exp $	*/
 
 /*-
  * Copyright (c) 1982, 1986, 1993
@@ -242,6 +242,9 @@ struct pr_usrreqs {
 	int	(*pr_bind)(struct socket *, struct mbuf *);
 	int	(*pr_listen)(struct socket *);
 	int	(*pr_connect)(struct socket *, struct mbuf *);
+	int	(*pr_disconnect)(struct socket *);
+	int	(*pr_shutdown)(struct socket *);
+	int	(*pr_abort)(struct socket *);
 	int	(*pr_ioctl)(struct socket *, u_long, void *, struct ifnet *);
 	int	(*pr_stat)(struct socket *, struct stat *);
 	int	(*pr_peeraddr)(struct socket *, struct mbuf *);
@@ -336,6 +339,33 @@ name##_listen_wrapper(struct socket *a)	
 	return rv;					\
 }							\
 static int						\
+name##_disconnect_wrapper(struct socket *a)		\
+{							\
+	int rv;						\
+	KERNEL_LOCK(1, NULL);				\
+	rv = name##_disconnect(a);			\
+	KERNEL_UNLOCK_ONE(NULL);			\
+	return rv;					\
+}							\
+static int						\
+name##_shutdown_wrapper(struct socket *a)		\
+{							\
+	int rv;						\
+	KERNEL_LOCK(1, NULL);				\
+	rv = name##_shutdown(a);			\
+	KERNEL_UNLOCK_ONE(NULL);			\
+	return rv;					\
+}							\
+static int						\
+name##_abort_wrapper(struct socket *a)			\
+{							\
+	int rv;						\
+	KERNEL_LOCK(1, NULL);				\
+	rv = name##_abort(a);				\
+	KERNEL_UNLOCK_ONE(NULL);			\
+	return rv;					\
+}							\
+static int						\
 name##_ioctl_wrapper(struct socket *a, u_long b,	\
     void *c, struct ifnet *d)				\
 {							\

Index: src/sys/sys/un.h
diff -u src/sys/sys/un.h:1.50 src/sys/sys/un.h:1.51
--- src/sys/sys/un.h:1.50	Wed Jul 30 10:04:26 2014
+++ src/sys/sys/un.h	Thu Jul 31 03:39:36 2014
@@ -1,4 +1,4 @@
-/*	$NetBSD: un.h,v 1.50 2014/07/30 10:04:26 rtr Exp $	*/
+/*	$NetBSD: un.h,v 1.51 2014/07/31 03:39:36 rtr Exp $	*/
 
 /*
  * Copyright (c) 1982, 1986, 1993
@@ -88,9 +88,9 @@ int	unp_bind (struct socket *, struct mb
 int	unp_connect (struct socket *, struct mbuf *);
 int	unp_connect2 (struct socket *, struct socket *, int);
 void	unp_discard (struct file *);
-void	unp_disconnect (struct unpcb *);
+void	unp_disconnect1 (struct unpcb *);
 bool	unp_drop (struct unpcb *, int);
-void	unp_shutdown (struct unpcb *);
+void	unp_shutdown1 (struct unpcb *);
 int 	unp_externalize (struct mbuf *, struct lwp *, int);
 int	unp_internalize (struct mbuf **);
 void 	unp_dispose (struct mbuf *);

Reply via email to