The current (*pr_usrreq)() is not useful for sockets locking work. We
already have former PRU_ATTACH and PRU_DETACH splitted to the
(*pr_attach)() and (*pr_detach)() handlers. We don't want to add new
commands to (*pr_usrreq)() but introduce hew handlers to the 'protosw'
like (*pr_lock)() and (*pr_unlock)() from bluhm's "arallel divert packet
soreceive" diff.

This introduces (*pr_bind), (*pr_listen), (*pr_accept), (*pr_connect),
(*pr_connect2) and (*pr_disconnect) handlers for the corresponding PRU_
commands. I used these six ones mostly to expose, how this modification
will be and collect opinions, do we like the direction I propose. The
diff is mostly mechanical but huge, so I think these PRU_ commands
should be enough. Anyway, if this direction will be accepted, I want to
split the send/receive PRU_ commands separately. Also if the diff below
is fine, I could commit it as is and make the next (*pr_usrreq)()
modifications with separate diffs just to make them not very large.

Please note, the `so_pcb' can't be NULL. We nullify it only on dead
socket, which should not be passed to (*pr_userreq)(). The newly created
socket has `so_pcb' set to NULL only until we pass it to (*pr_attach)()
and we don't use sockets if attach failed. So I use KASSERT() instead of
pcb != NULL check.

Also, please keep in mind, this modification increases RAMDISK kernel
size. For amd64 it bumped from 4417155 to 4418234 bytes.

Index: sys/kern/uipc_proto.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_proto.c,v
retrieving revision 1.22
diff -u -p -r1.22 uipc_proto.c
--- sys/kern/uipc_proto.c       25 Feb 2022 23:51:03 -0000      1.22
+++ sys/kern/uipc_proto.c       7 Aug 2022 00:48:45 -0000
@@ -46,31 +46,49 @@
 
 const struct protosw unixsw[] = {
 {
-  .pr_type     = SOCK_STREAM,
-  .pr_domain   = &unixdomain,
-  .pr_protocol = PF_UNIX,
-  .pr_flags    = PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
-  .pr_usrreq   = uipc_usrreq,
-  .pr_attach   = uipc_attach,
-  .pr_detach   = uipc_detach,
+  .pr_type             = SOCK_STREAM,
+  .pr_domain           = &unixdomain,
+  .pr_protocol         = PF_UNIX,
+  .pr_flags            = PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
+  .pr_usrreq           = uipc_usrreq,
+  .pr_attach           = uipc_attach,
+  .pr_detach           = uipc_detach,
+  .pr_bind             = uipc_bind,
+  .pr_listen           = uipc_listen,
+  .pr_accept           = uipc_accept,
+  .pr_connect          = uipc_connect,
+  .pr_connect2         = uipc_connect2,
+  .pr_disconnect       = uipc_disconnect, 
 },
 {
-  .pr_type     = SOCK_SEQPACKET,
-  .pr_domain   = &unixdomain,
-  .pr_protocol = PF_UNIX,
-  .pr_flags    = PR_ATOMIC|PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
-  .pr_usrreq   = uipc_usrreq,
-  .pr_attach   = uipc_attach,
-  .pr_detach   = uipc_detach,
+  .pr_type             = SOCK_SEQPACKET,
+  .pr_domain           = &unixdomain,
+  .pr_protocol         = PF_UNIX,
+  .pr_flags            = PR_ATOMIC|PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
+  .pr_usrreq           = uipc_usrreq,
+  .pr_attach           = uipc_attach,
+  .pr_detach           = uipc_detach,
+  .pr_bind             = uipc_bind,
+  .pr_listen           = uipc_listen,
+  .pr_accept           = uipc_accept,
+  .pr_connect          = uipc_connect,
+  .pr_connect2         = uipc_connect2,
+  .pr_disconnect       = uipc_disconnect, 
 },
 {
-  .pr_type     = SOCK_DGRAM,
-  .pr_domain   = &unixdomain,
-  .pr_protocol = PF_UNIX,
-  .pr_flags    = PR_ATOMIC|PR_ADDR|PR_RIGHTS,
-  .pr_usrreq   = uipc_usrreq,
-  .pr_attach   = uipc_attach,
-  .pr_detach   = uipc_detach,
+  .pr_type             = SOCK_DGRAM,
+  .pr_domain           = &unixdomain,
+  .pr_protocol         = PF_UNIX,
+  .pr_flags            = PR_ATOMIC|PR_ADDR|PR_RIGHTS,
+  .pr_usrreq           = uipc_usrreq,
+  .pr_attach           = uipc_attach,
+  .pr_detach           = uipc_detach,
+  .pr_bind             = uipc_bind,
+  .pr_listen           = uipc_listen,
+  .pr_accept           = uipc_accept,
+  .pr_connect          = uipc_connect,
+  .pr_connect2         = uipc_connect2,
+  .pr_disconnect       = uipc_disconnect, 
 }
 };
 
Index: sys/kern/uipc_socket.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_socket.c,v
retrieving revision 1.280
diff -u -p -r1.280 uipc_socket.c
--- sys/kern/uipc_socket.c      25 Jul 2022 07:28:22 -0000      1.280
+++ sys/kern/uipc_socket.c      7 Aug 2022 00:48:45 -0000
@@ -214,7 +214,7 @@ sobind(struct socket *so, struct mbuf *n
 
        soassertlocked(so);
 
-       error = (*so->so_proto->pr_usrreq)(so, PRU_BIND, NULL, nam, NULL, p);
+       error = (*so->so_proto->pr_bind)(so, nam, p);
        return (error);
 }
 
@@ -231,8 +231,7 @@ solisten(struct socket *so, int backlog)
        if (isspliced(so) || issplicedback(so))
                return (EOPNOTSUPP);
 #endif /* SOCKET_SPLICE */
-       error = (*so->so_proto->pr_usrreq)(so, PRU_LISTEN, NULL, NULL, NULL,
-           curproc);
+       error = (*so->so_proto->pr_listen)(so);
        if (error)
                return (error);
        if (TAILQ_FIRST(&so->so_q) == NULL)
@@ -460,8 +459,7 @@ soaccept(struct socket *so, struct mbuf 
        so->so_state &= ~SS_NOFDREF;
        if ((so->so_state & SS_ISDISCONNECTED) == 0 ||
            (so->so_proto->pr_flags & PR_ABRTACPTDIS) == 0)
-               error = (*so->so_proto->pr_usrreq)(so, PRU_ACCEPT, NULL,
-                   nam, NULL, curproc);
+               error = (*so->so_proto->pr_accept)(so, nam);
        else
                error = ECONNABORTED;
        return (error);
@@ -487,8 +485,7 @@ soconnect(struct socket *so, struct mbuf
            (error = sodisconnect(so))))
                error = EISCONN;
        else
-               error = (*so->so_proto->pr_usrreq)(so, PRU_CONNECT,
-                   NULL, nam, NULL, curproc);
+               error = (*so->so_proto->pr_connect)(so, nam, curproc);
        return (error);
 }
 
@@ -502,8 +499,7 @@ soconnect2(struct socket *so1, struct so
        else
                solock(so1);
 
-       error = (*so1->so_proto->pr_usrreq)(so1, PRU_CONNECT2, NULL,
-           (struct mbuf *)so2, NULL, curproc);
+       error = (*so1->so_proto->pr_connect2)(so1, so2, curproc);
 
        if (persocket)
                sounlock(so2);
@@ -522,8 +518,7 @@ sodisconnect(struct socket *so)
                return (ENOTCONN);
        if (so->so_state & SS_ISDISCONNECTING)
                return (EALREADY);
-       error = (*so->so_proto->pr_usrreq)(so, PRU_DISCONNECT, NULL, NULL,
-           NULL, curproc);
+       error = (*so->so_proto->pr_disconnect)(so);
        return (error);
 }
 
Index: sys/kern/uipc_usrreq.c
===================================================================
RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
retrieving revision 1.167
diff -u -p -r1.167 uipc_usrreq.c
--- sys/kern/uipc_usrreq.c      2 Jul 2022 11:49:23 -0000       1.167
+++ sys/kern/uipc_usrreq.c      7 Aug 2022 00:48:45 -0000
@@ -199,7 +199,6 @@ uipc_usrreq(struct socket *so, int req, 
     struct mbuf *control, struct proc *p)
 {
        struct unpcb *unp = sotounpcb(so);
-       struct unpcb *unp2;
        struct socket *so2;
        int error = 0;
 
@@ -216,50 +215,6 @@ uipc_usrreq(struct socket *so, int req, 
 
        switch (req) {
 
-       case PRU_BIND:
-               error = unp_bind(unp, nam, p);
-               break;
-
-       case PRU_LISTEN:
-               if (unp->unp_vnode == NULL)
-                       error = EINVAL;
-               break;
-
-       case PRU_CONNECT:
-               error = unp_connect(so, nam, p);
-               break;
-
-       case PRU_CONNECT2:
-               error = unp_connect2(so, (struct socket *)nam);
-               if (!error) {
-                       unp->unp_connid.uid = p->p_ucred->cr_uid;
-                       unp->unp_connid.gid = p->p_ucred->cr_gid;
-                       unp->unp_connid.pid = p->p_p->ps_pid;
-                       unp->unp_flags |= UNP_FEIDS;
-                       unp2 = sotounpcb((struct socket *)nam);
-                       unp2->unp_connid.uid = p->p_ucred->cr_uid;
-                       unp2->unp_connid.gid = p->p_ucred->cr_gid;
-                       unp2->unp_connid.pid = p->p_p->ps_pid;
-                       unp2->unp_flags |= UNP_FEIDS;
-               }
-               break;
-
-       case PRU_DISCONNECT:
-               unp_disconnect(unp);
-               break;
-
-       case PRU_ACCEPT:
-               /*
-                * Pass back name of connected socket,
-                * if it was bound and we are still connected
-                * (our peer may have closed already!).
-                */
-               so2 = unp_solock_peer(so);
-               uipc_setaddr(unp->unp_conn, nam);
-               if (so2 != NULL && so2 != so)
-                       sounlock(so2);
-               break;
-
        case PRU_SHUTDOWN:
                socantsendmore(so);
                unp_shutdown(unp);
@@ -527,6 +482,98 @@ uipc_detach(struct socket *so)
                return (EINVAL);
 
        unp_detach(unp);
+
+       return (0);
+}
+
+int
+uipc_bind(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       struct unpcb *unp = sotounpcb(so);
+
+       soassertlocked(so);
+       KASSERT(unp != NULL);
+
+       return unp_bind(unp, nam, p);
+}
+
+int
+uipc_listen(struct socket *so)
+{
+       struct unpcb *unp = sotounpcb(so);
+       int error = 0;
+
+       soassertlocked(so);
+       KASSERT(unp != NULL);
+       
+       if (unp->unp_vnode == NULL)
+               error = EINVAL;
+       return error;
+}
+
+int
+uipc_accept(struct socket *so, struct mbuf *nam)
+{
+       struct unpcb *unp = sotounpcb(so);
+       struct socket *so2;
+
+       soassertlocked(so);
+       KASSERT(unp != NULL);
+       
+       /*
+        * Pass back name of connected socket,
+        * if it was bound and we are still connected
+        * (our peer may have closed already!).
+        */
+       so2 = unp_solock_peer(so);
+       uipc_setaddr(unp->unp_conn, nam);
+       if (so2 != NULL && so2 != so)
+               sounlock(so2);
+
+       return 0;
+}
+
+int
+uipc_connect(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       soassertlocked(so);
+       return unp_connect(so, nam, p);
+}
+
+int
+uipc_connect2(struct socket *so, struct socket *so2, struct proc *p)
+{
+       struct unpcb *unp = sotounpcb(so), *unp2;
+       int error;
+
+       soassertlocked(so);
+       soassertlocked(so2);
+       
+       if ((error = unp_connect2(so, so2)) != 0)
+               return error;
+
+       unp->unp_connid.uid = p->p_ucred->cr_uid;
+       unp->unp_connid.gid = p->p_ucred->cr_gid;
+       unp->unp_connid.pid = p->p_p->ps_pid;
+       unp->unp_flags |= UNP_FEIDS;
+       unp2 = sotounpcb(so2);
+       unp2->unp_connid.uid = p->p_ucred->cr_uid;
+       unp2->unp_connid.gid = p->p_ucred->cr_gid;
+       unp2->unp_connid.pid = p->p_p->ps_pid;
+       unp2->unp_flags |= UNP_FEIDS;
+
+       return 0;
+}
+
+int
+uipc_disconnect(struct socket *so)
+{
+       struct unpcb *unp = sotounpcb(so);
+
+       soassertlocked(so);
+       KASSERT(unp != NULL);
+
+       unp_disconnect(unp);
 
        return (0);
 }
Index: sys/net/pfkeyv2.c
===================================================================
RCS file: /cvs/src/sys/net/pfkeyv2.c,v
retrieving revision 1.234
diff -u -p -r1.234 pfkeyv2.c
--- sys/net/pfkeyv2.c   6 Jun 2022 14:45:41 -0000       1.234
+++ sys/net/pfkeyv2.c   7 Aug 2022 00:48:46 -0000
@@ -171,6 +171,12 @@ void pfkey_init(void);
 
 int pfkeyv2_attach(struct socket *, int);
 int pfkeyv2_detach(struct socket *);
+int pfkeyv2_bind(struct socket *, struct mbuf *, struct proc *);
+int pfkeyv2_listen(struct socket *);
+int pfkeyv2_accept(struct socket *, struct mbuf *);
+int pfkeyv2_connect(struct socket *, struct mbuf *, struct proc *);
+int pfkeyv2_connect2(struct socket *, struct socket *, struct proc *);
+int pfkeyv2_disconnect(struct socket *);
 int pfkeyv2_usrreq(struct socket *, int, struct mbuf *, struct mbuf *,
     struct mbuf *, struct proc *);
 int pfkeyv2_output(struct mbuf *, struct socket *, struct sockaddr *,
@@ -201,15 +207,21 @@ pfdatatopacket(void *data, int len, stru
 
 const struct protosw pfkeysw[] = {
 {
-  .pr_type      = SOCK_RAW,
-  .pr_domain    = &pfkeydomain,
-  .pr_protocol  = PF_KEY_V2,
-  .pr_flags     = PR_ATOMIC | PR_ADDR,
-  .pr_output    = pfkeyv2_output,
-  .pr_usrreq    = pfkeyv2_usrreq,
-  .pr_attach    = pfkeyv2_attach,
-  .pr_detach    = pfkeyv2_detach,
-  .pr_sysctl    = pfkeyv2_sysctl,
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &pfkeydomain,
+  .pr_protocol         = PF_KEY_V2,
+  .pr_flags            = PR_ATOMIC | PR_ADDR,
+  .pr_output           = pfkeyv2_output,
+  .pr_usrreq           = pfkeyv2_usrreq,
+  .pr_attach           = pfkeyv2_attach,
+  .pr_detach           = pfkeyv2_detach,
+  .pr_bind             = pfkeyv2_bind,
+  .pr_listen           = pfkeyv2_listen,
+  .pr_accept           = pfkeyv2_accept,
+  .pr_connect          = pfkeyv2_connect,
+  .pr_connect2         = pfkeyv2_connect2,
+  .pr_disconnect       = pfkeyv2_disconnect,
+  .pr_sysctl           = pfkeyv2_sysctl,
 }
 };
 
@@ -329,6 +341,45 @@ pfkeyv2_detach(struct socket *so)
 }
 
 int
+pfkeyv2_bind(struct socket *so, struct mbuf *name, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+pfkeyv2_listen(struct socket *so)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+pfkeyv2_accept(struct socket *so, struct mbuf *nam)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+pfkeyv2_connect(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+pfkeyv2_connect2(struct socket *so1, struct socket *so2, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+pfkeyv2_disconnect(struct socket *so)
+{
+       soassertlocked(so);
+       soisdisconnected(so);
+
+       return (0);
+}
+
+int
 pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *m,
     struct mbuf *nam, struct mbuf *control, struct proc *p)
 {
@@ -352,16 +403,6 @@ pfkeyv2_usrreq(struct socket *so, int re
        }
 
        switch (req) {
-       /* no connect, bind, accept. Socket is connected from the start */
-       case PRU_CONNECT:
-       case PRU_BIND:
-       case PRU_CONNECT2:
-       case PRU_LISTEN:
-       case PRU_ACCEPT:
-               error = EOPNOTSUPP;
-               break;
-
-       case PRU_DISCONNECT:
        case PRU_ABORT:
                soisdisconnected(so);
                break;
Index: sys/net/rtsock.c
===================================================================
RCS file: /cvs/src/sys/net/rtsock.c,v
retrieving revision 1.334
diff -u -p -r1.334 rtsock.c
--- sys/net/rtsock.c    28 Jun 2022 10:01:13 -0000      1.334
+++ sys/net/rtsock.c    7 Aug 2022 00:48:46 -0000
@@ -232,16 +232,6 @@ route_usrreq(struct socket *so, int req,
        }
 
        switch (req) {
-       /* no connect, bind, accept. Socket is connected from the start */
-       case PRU_CONNECT:
-       case PRU_BIND:
-       case PRU_CONNECT2:
-       case PRU_LISTEN:
-       case PRU_ACCEPT:
-               error = EOPNOTSUPP;
-               break;
-
-       case PRU_DISCONNECT:
        case PRU_ABORT:
                soisdisconnected(so);
                break;
@@ -367,6 +357,45 @@ route_detach(struct socket *so)
 }
 
 int
+route_bind(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+route_listen(struct socket *so)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+route_accept(struct socket *so, struct mbuf *nam)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+route_connect(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+route_connect2(struct socket *so1, struct socket *so2, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+route_disconnect(struct socket *so)
+{
+       soassertlocked(so);
+       soisdisconnected(so);
+
+       return (0);
+}
+
+int
 route_ctloutput(int op, struct socket *so, int level, int optname,
     struct mbuf *m)
 {
@@ -2403,16 +2432,22 @@ rt_setsource(unsigned int rtableid, stru
 
 const struct protosw routesw[] = {
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &routedomain,
-  .pr_flags    = PR_ATOMIC|PR_ADDR|PR_WANTRCVD,
-  .pr_output   = route_output,
-  .pr_ctloutput        = route_ctloutput,
-  .pr_usrreq   = route_usrreq,
-  .pr_attach   = route_attach,
-  .pr_detach   = route_detach,
-  .pr_init     = route_prinit,
-  .pr_sysctl   = sysctl_rtable
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &routedomain,
+  .pr_flags            = PR_ATOMIC|PR_ADDR|PR_WANTRCVD,
+  .pr_output           = route_output,
+  .pr_ctloutput                = route_ctloutput,
+  .pr_usrreq           = route_usrreq,
+  .pr_attach           = route_attach,
+  .pr_detach           = route_detach,
+  .pr_bind             = route_bind,
+  .pr_listen           = route_listen,
+  .pr_accept           = route_accept,
+  .pr_connect          = route_connect,
+  .pr_connect2         = route_connect2,
+  .pr_disconnect       = route_disconnect,
+  .pr_init             = route_prinit,
+  .pr_sysctl           = sysctl_rtable
 }
 };
 
Index: sys/netinet/in_proto.c
===================================================================
RCS file: /cvs/src/sys/netinet/in_proto.c,v
retrieving revision 1.98
diff -u -p -r1.98 in_proto.c
--- sys/netinet/in_proto.c      25 Feb 2022 23:51:03 -0000      1.98
+++ sys/netinet/in_proto.c      7 Aug 2022 00:48:46 -0000
@@ -182,240 +182,342 @@ const struct protosw inetsw[] = {
   .pr_sysctl   = ip_sysctl
 },
 {
-  .pr_type     = SOCK_DGRAM,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_UDP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR|PR_SPLICE,
-  .pr_input    = udp_input,
-  .pr_ctlinput = udp_ctlinput,
-  .pr_ctloutput        = ip_ctloutput,
-  .pr_usrreq   = udp_usrreq,
-  .pr_attach   = udp_attach,
-  .pr_detach   = udp_detach,
-  .pr_init     = udp_init,
-  .pr_sysctl   = udp_sysctl
-},
-{
-  .pr_type     = SOCK_STREAM,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_TCP,
-  .pr_flags    = PR_CONNREQUIRED|PR_WANTRCVD|PR_ABRTACPTDIS|PR_SPLICE,
-  .pr_input    = tcp_input,
-  .pr_ctlinput = tcp_ctlinput,
-  .pr_ctloutput        = tcp_ctloutput,
-  .pr_usrreq   = tcp_usrreq,
-  .pr_attach   = tcp_attach,
-  .pr_detach   = tcp_detach,
-  .pr_init     = tcp_init,
-  .pr_slowtimo = tcp_slowtimo,
-  .pr_sysctl   = tcp_sysctl
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_RAW,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = rip_input,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_ICMP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = icmp_input,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_init     = icmp_init,
-  .pr_sysctl   = icmp_sysctl
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_IPV4,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
+  .pr_type             = SOCK_DGRAM,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_UDP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR|PR_SPLICE,
+  .pr_input            = udp_input,
+  .pr_ctlinput         = udp_ctlinput,
+  .pr_ctloutput                = ip_ctloutput,
+  .pr_usrreq           = udp_usrreq,
+  .pr_attach           = udp_attach,
+  .pr_detach           = udp_detach,
+  .pr_bind             = udp_bind,
+  .pr_listen           = udp_listen,
+  .pr_accept           = udp_accept,
+  .pr_connect          = udp_connect,
+  .pr_connect2         = udp_connect2,
+  .pr_disconnect       = udp_disconnect,
+  .pr_init             = udp_init,
+  .pr_sysctl           = udp_sysctl
+},
+{
+  .pr_type             = SOCK_STREAM,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_TCP,
+  .pr_flags            = PR_CONNREQUIRED|PR_WANTRCVD|PR_ABRTACPTDIS|PR_SPLICE,
+  .pr_input            = tcp_input,
+  .pr_ctlinput         = tcp_ctlinput,
+  .pr_ctloutput                = tcp_ctloutput,
+  .pr_usrreq           = tcp_usrreq,
+  .pr_attach           = tcp_attach,
+  .pr_detach           = tcp_detach,
+  .pr_bind             = tcp_bind,
+  .pr_listen           = tcp_listen,
+  .pr_accept           = tcp_accept,
+  .pr_connect          = tcp_connect,
+  .pr_connect2         = tcp_connect2,
+  .pr_disconnect       = tcp_disconnect,
+  .pr_init             = tcp_init,
+  .pr_slowtimo         = tcp_slowtimo,
+  .pr_sysctl           = tcp_sysctl
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_RAW,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = rip_input,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_ICMP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = icmp_input,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_init             = icmp_init,
+  .pr_sysctl           = icmp_sysctl
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_IPV4,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
 #if NGIF > 0
-  .pr_input    = in_gif_input,
+  .pr_input            = in_gif_input,
 #else
-  .pr_input    = ipip_input,
+  .pr_input            = ipip_input,
 #endif
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_sysctl   = ipip_sysctl,
-  .pr_init     = ipip_init
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_sysctl           = ipip_sysctl,
+  .pr_init             = ipip_init
 },
 #ifdef INET6
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_IPV6,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_IPV6,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
 #if NGIF > 0
-  .pr_input    = in_gif_input,
+  .pr_input            = in_gif_input,
 #else
-  .pr_input    = ipip_input,
+  .pr_input            = ipip_input,
 #endif
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq, /* XXX */
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq, /* XXX */
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
 },
 #endif
 #if defined(MPLS) && NGIF > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_MPLS,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = in_gif_input,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_MPLS,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = in_gif_input,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
 },
 #endif /* MPLS && GIF */
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_IGMP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = igmp_input,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_init     = igmp_init,
-  .pr_fasttimo = igmp_fasttimo,
-  .pr_slowtimo = igmp_slowtimo,
-  .pr_sysctl   = igmp_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_IGMP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = igmp_input,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_init             = igmp_init,
+  .pr_fasttimo         = igmp_fasttimo,
+  .pr_slowtimo         = igmp_slowtimo,
+  .pr_sysctl           = igmp_sysctl
 },
 #ifdef IPSEC
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_AH,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = ah46_input,
-  .pr_ctlinput = ah4_ctlinput,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_sysctl   = ah_sysctl
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_ESP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = esp46_input,
-  .pr_ctlinput = esp4_ctlinput,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_sysctl   = esp_sysctl
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_IPCOMP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = ipcomp46_input,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_sysctl   = ipcomp_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_AH,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = ah46_input,
+  .pr_ctlinput         = ah4_ctlinput,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_sysctl           = ah_sysctl
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_ESP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = esp46_input,
+  .pr_ctlinput         = esp4_ctlinput,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_sysctl           = esp_sysctl
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_IPCOMP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = ipcomp46_input,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_sysctl           = ipcomp_sysctl
 },
 #endif /* IPSEC */
 #if NGRE > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_GRE,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = gre_input,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = gre_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_sysctl   = gre_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_GRE,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = gre_input,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = gre_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_sysctl           = gre_sysctl
 },
 #endif /* NGRE > 0 */
 #if NCARP > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_CARP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = carp_proto_input,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_sysctl   = carp_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_CARP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = carp_proto_input,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_sysctl           = carp_sysctl
 },
 #endif /* NCARP > 0 */
 #if NPFSYNC > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_PFSYNC,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = pfsync_input,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_sysctl   = pfsync_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_PFSYNC,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = pfsync_input,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_sysctl           = pfsync_sysctl
 },
 #endif /* NPFSYNC > 0 */
 #if NPF > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_DIVERT,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = divert_usrreq,
-  .pr_attach   = divert_attach,
-  .pr_detach   = divert_detach,
-  .pr_init     = divert_init,
-  .pr_sysctl   = divert_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_DIVERT,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = divert_usrreq,
+  .pr_attach           = divert_attach,
+  .pr_detach           = divert_detach,
+  .pr_bind             = divert_bind,
+  .pr_listen           = divert_listen,
+  .pr_accept           = divert_accept,
+  .pr_connect          = divert_connect,
+  .pr_connect2         = divert_connect2,
+  .pr_disconnect       = divert_disconnect,
+  .pr_init             = divert_init,
+  .pr_sysctl           = divert_sysctl
 },
 #endif /* NPF > 0 */
 #if NETHERIP > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_protocol = IPPROTO_ETHERIP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = ip_etherip_input,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_sysctl   = etherip_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_protocol         = IPPROTO_ETHERIP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = ip_etherip_input,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_sysctl           = etherip_sysctl
 },
 #endif /* NETHERIP */
 {
   /* raw wildcard */
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inetdomain,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = rip_input,
-  .pr_ctloutput        = rip_ctloutput,
-  .pr_usrreq   = rip_usrreq,
-  .pr_attach   = rip_attach,
-  .pr_detach   = rip_detach,
-  .pr_init     = rip_init
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inetdomain,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = rip_input,
+  .pr_ctloutput                = rip_ctloutput,
+  .pr_usrreq           = rip_usrreq,
+  .pr_attach           = rip_attach,
+  .pr_detach           = rip_detach,
+  .pr_bind             = rip_bind,
+  .pr_listen           = rip_listen,
+  .pr_accept           = rip_accept,
+  .pr_connect          = rip_connect,
+  .pr_connect2         = rip_connect2,
+  .pr_disconnect       = rip_disconnect,
+  .pr_init             = rip_init
 }
 };
 
Index: sys/netinet/ip_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet/ip_divert.c,v
retrieving revision 1.68
diff -u -p -r1.68 ip_divert.c
--- sys/netinet/ip_divert.c     9 May 2022 19:33:46 -0000       1.68
+++ sys/netinet/ip_divert.c     7 Aug 2022 00:48:46 -0000
@@ -268,10 +268,6 @@ divert_usrreq(struct socket *so, int req
        }
        switch (req) {
 
-       case PRU_BIND:
-               error = in_pcbbind(inp, addr, p);
-               break;
-
        case PRU_SHUTDOWN:
                socantsendmore(so);
                break;
@@ -295,11 +291,6 @@ divert_usrreq(struct socket *so, int req
        case PRU_SENSE:
                break;
 
-       case PRU_LISTEN:
-       case PRU_CONNECT:
-       case PRU_CONNECT2:
-       case PRU_ACCEPT:
-       case PRU_DISCONNECT:
        case PRU_SENDOOB:
        case PRU_FASTTIMO:
        case PRU_SLOWTIMO:
@@ -356,6 +347,47 @@ divert_detach(struct socket *so)
 
        in_pcbdetach(inp);
        return (0);
+}
+
+int
+divert_bind(struct socket *so, struct mbuf *addr, struct proc *p)
+{
+       struct inpcb *inp = sotoinpcb(so);
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       return in_pcbbind(inp, addr, p);
+}
+
+int
+divert_listen(struct socket *so)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+divert_accept(struct socket *so, struct mbuf *addr)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+divert_connect(struct socket *so, struct mbuf *addr, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+divert_connect2(struct socket *so, struct socket *so2, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+divert_disconnect(struct socket *so)
+{
+       return (EOPNOTSUPP);
 }
 
 int
Index: sys/netinet/ip_divert.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_divert.h,v
retrieving revision 1.15
diff -u -p -r1.15 ip_divert.h
--- sys/netinet/ip_divert.h     5 May 2022 16:44:22 -0000       1.15
+++ sys/netinet/ip_divert.h     7 Aug 2022 00:48:46 -0000
@@ -65,12 +65,18 @@ divstat_inc(enum divstat_counters c)
 
 extern struct  inpcbtable      divbtable;
 
-void    divert_init(void);
-void    divert_packet(struct mbuf *, int, u_int16_t);
-int     divert_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-int     divert_usrreq(struct socket *,
+void   divert_init(void);
+void   divert_packet(struct mbuf *, int, u_int16_t);
+int    divert_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+int    divert_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
-int     divert_attach(struct socket *, int);
-int     divert_detach(struct socket *);
+int    divert_attach(struct socket *, int);
+int    divert_detach(struct socket *);
+int    divert_bind(struct socket *, struct mbuf *, struct proc *);
+int    divert_listen(struct socket *);
+int    divert_accept(struct socket *, struct mbuf *);
+int    divert_connect(struct socket *, struct mbuf *, struct proc *);
+int    divert_connect2(struct socket *, struct socket *, struct proc *);
+int    divert_disconnect(struct socket *);
 #endif /* _KERNEL */
 #endif /* _IP_DIVERT_H_ */
Index: sys/netinet/ip_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/ip_var.h,v
retrieving revision 1.95
diff -u -p -r1.95 ip_var.h
--- sys/netinet/ip_var.h        4 Aug 2022 18:05:09 -0000       1.95
+++ sys/netinet/ip_var.h        7 Aug 2022 00:48:46 -0000
@@ -256,6 +256,12 @@ int         rip_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
 int     rip_attach(struct socket *, int);
 int     rip_detach(struct socket *);
+int      rip_bind(struct socket *, struct mbuf *, struct proc *);
+int      rip_listen(struct socket *);
+int      rip_accept(struct socket *, struct mbuf *);
+int      rip_connect(struct socket *, struct mbuf *, struct proc *);
+int      rip_connect2(struct socket *, struct socket *, struct proc *);
+int      rip_disconnect(struct socket *);
 #ifdef MROUTING
 extern struct socket *ip_mrouter[];    /* multicast routing daemon */
 #endif
Index: sys/netinet/raw_ip.c
===================================================================
RCS file: /cvs/src/sys/netinet/raw_ip.c,v
retrieving revision 1.128
diff -u -p -r1.128 raw_ip.c
--- sys/netinet/raw_ip.c        15 May 2022 09:12:20 -0000      1.128
+++ sys/netinet/raw_ip.c        7 Aug 2022 00:48:46 -0000
@@ -460,14 +460,6 @@ rip_usrreq(struct socket *so, int req, s
 
        switch (req) {
 
-       case PRU_DISCONNECT:
-               if ((so->so_state & SS_ISCONNECTED) == 0) {
-                       error = ENOTCONN;
-                       break;
-               }
-               soisdisconnected(so);
-               inp->inp_faddr.s_addr = INADDR_ANY;
-               break;
        case PRU_ABORT:
                soisdisconnected(so);
                if (inp == NULL)
@@ -479,38 +471,6 @@ rip_usrreq(struct socket *so, int req, s
                in_pcbdetach(inp);
                break;
 
-       case PRU_BIND:
-           {
-               struct sockaddr_in *addr;
-
-               if ((error = in_nam2sin(nam, &addr)))
-                       break;
-               if (!((so->so_options & SO_BINDANY) ||
-                   addr->sin_addr.s_addr == INADDR_ANY ||
-                   addr->sin_addr.s_addr == INADDR_BROADCAST ||
-                   in_broadcast(addr->sin_addr, inp->inp_rtableid) ||
-                   ifa_ifwithaddr(sintosa(addr), inp->inp_rtableid))) {
-                       error = EADDRNOTAVAIL;
-                       break;
-               }
-               inp->inp_laddr = addr->sin_addr;
-               break;
-           }
-       case PRU_CONNECT:
-           {
-               struct sockaddr_in *addr;
-
-               if ((error = in_nam2sin(nam, &addr)))
-                       break;
-               inp->inp_faddr = addr->sin_addr;
-               soisconnected(so);
-               break;
-           }
-
-       case PRU_CONNECT2:
-               error = EOPNOTSUPP;
-               break;
-
        /*
         * Mark the connection as being incapable of further input.
         */
@@ -563,8 +523,6 @@ rip_usrreq(struct socket *so, int req, s
        /*
         * Not supported.
         */
-       case PRU_LISTEN:
-       case PRU_ACCEPT:
        case PRU_SENDOOB:
        case PRU_RCVD:
        case PRU_RCVOOB:
@@ -628,6 +586,84 @@ rip_detach(struct socket *so)
                ip_mrouter_done(so);
 #endif
        in_pcbdetach(inp);
+
+       return (0);
+}
+
+int
+rip_bind(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       struct sockaddr_in *addr;
+       int error;
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       if ((error = in_nam2sin(nam, &addr)))
+               return (error);
+
+       if (!((so->so_options & SO_BINDANY) ||
+           addr->sin_addr.s_addr == INADDR_ANY ||
+           addr->sin_addr.s_addr == INADDR_BROADCAST ||
+           in_broadcast(addr->sin_addr, inp->inp_rtableid) ||
+           ifa_ifwithaddr(sintosa(addr), inp->inp_rtableid)))
+               return (EADDRNOTAVAIL);
+
+       inp->inp_laddr = addr->sin_addr;
+       return (0);
+}
+
+int
+rip_listen(struct socket *so)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+rip_accept(struct socket *so, struct mbuf *nam)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+rip_connect(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       struct sockaddr_in *addr;
+       int error;
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       if ((error = in_nam2sin(nam, &addr)))
+               return (error);
+
+       inp->inp_faddr = addr->sin_addr;
+       soisconnected(so);
+
+       return (0);
+}
+
+int
+rip_connect2(struct socket *so1, struct socket *so2, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+rip_disconnect(struct socket *so)
+{
+       struct inpcb *inp = sotoinpcb(so);
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       if ((so->so_state & SS_ISCONNECTED) == 0)
+               return (ENOTCONN);
+
+       soisdisconnected(so);
+       inp->inp_faddr.s_addr = INADDR_ANY;
 
        return (0);
 }
Index: sys/netinet/tcp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
retrieving revision 1.183
diff -u -p -r1.183 tcp_usrreq.c
--- sys/netinet/tcp_usrreq.c    25 Feb 2022 23:51:03 -0000      1.183
+++ sys/netinet/tcp_usrreq.c    7 Aug 2022 00:48:46 -0000
@@ -191,122 +191,6 @@ tcp_usrreq(struct socket *so, int req, s
        switch (req) {
 
        /*
-        * Give the socket an address.
-        */
-       case PRU_BIND:
-               error = in_pcbbind(inp, nam, p);
-               break;
-
-       /*
-        * Prepare to accept connections.
-        */
-       case PRU_LISTEN:
-               if (inp->inp_lport == 0)
-                       error = in_pcbbind(inp, NULL, p);
-               /* If the in_pcbbind() above is called, the tp->pf
-                  should still be whatever it was before. */
-               if (error == 0)
-                       tp->t_state = TCPS_LISTEN;
-               break;
-
-       /*
-        * Initiate connection to peer.
-        * Create a template for use in transmissions on this connection.
-        * Enter SYN_SENT state, and mark socket as connecting.
-        * Start keep-alive timer, and seed output sequence space.
-        * Send initial segment on connection.
-        */
-       case PRU_CONNECT:
-#ifdef INET6
-               if (inp->inp_flags & INP_IPV6) {
-                       struct sockaddr_in6 *sin6;
-
-                       if ((error = in6_nam2sin6(nam, &sin6)))
-                               break;
-                       if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
-                           IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
-                               error = EINVAL;
-                               break;
-                       }
-                       error = in6_pcbconnect(inp, nam);
-               } else
-#endif /* INET6 */
-               {
-                       struct sockaddr_in *sin;
-
-                       if ((error = in_nam2sin(nam, &sin)))
-                               break;
-                       if ((sin->sin_addr.s_addr == INADDR_ANY) ||
-                           (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
-                           IN_MULTICAST(sin->sin_addr.s_addr) ||
-                           in_broadcast(sin->sin_addr, inp->inp_rtableid)) {
-                               error = EINVAL;
-                               break;
-                       }
-                       error = in_pcbconnect(inp, nam);
-               }
-               if (error)
-                       break;
-
-               tp->t_template = tcp_template(tp);
-               if (tp->t_template == 0) {
-                       in_pcbdisconnect(inp);
-                       error = ENOBUFS;
-                       break;
-               }
-
-               so->so_state |= SS_CONNECTOUT;
-
-               /* Compute window scaling to request.  */
-               tcp_rscale(tp, sb_max);
-
-               soisconnecting(so);
-               tcpstat_inc(tcps_connattempt);
-               tp->t_state = TCPS_SYN_SENT;
-               TCP_TIMER_ARM(tp, TCPT_KEEP, tcptv_keep_init);
-               tcp_set_iss_tsm(tp);
-               tcp_sendseqinit(tp);
-               tp->snd_last = tp->snd_una;
-               error = tcp_output(tp);
-               break;
-
-       /*
-        * Create a TCP connection between two sockets.
-        */
-       case PRU_CONNECT2:
-               error = EOPNOTSUPP;
-               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;
-
-       /*
-        * Accept a connection.  Essentially all the work is
-        * done at higher levels; just return the address
-        * of the peer, storing through addr.
-        */
-       case PRU_ACCEPT:
-#ifdef INET6
-               if (inp->inp_flags & INP_IPV6)
-                       in6_setpeeraddr(inp, nam);
-               else
-#endif
-                       in_setpeeraddr(inp, nam);
-               break;
-
-       /*
         * Mark the connection as being incapable of further output.
         */
        case PRU_SHUTDOWN:
@@ -662,7 +546,7 @@ tcp_detach(struct socket *so)
         * which may finish later; embryonic TCB's can just
         * be discarded here.
         */
-       tp = tcp_disconnect(tp);
+       tp = tcp_dodisconnect(tp);
 
        if (otp)
                tcp_trace(TA_USER, ostate, tp, otp, NULL, PRU_DETACH, 0);
@@ -670,6 +554,263 @@ tcp_detach(struct socket *so)
 }
 
 /*
+ * Give the socket an address.
+ */
+int
+tcp_bind(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       struct tcpcb *otp = NULL, *tp = NULL;
+       int error;
+       short ostate;
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       tp = intotcpcb(inp);
+       /* tp might get 0 when using socket splicing */
+       if (tp == NULL)
+               return (0);
+       if (so->so_options & SO_DEBUG) {
+               otp = tp;
+               ostate = tp->t_state;
+       }
+
+       error = in_pcbbind(inp, nam, p);
+
+       if (otp)
+               tcp_trace(TA_USER, ostate, tp, otp, NULL, PRU_BIND, 0);
+
+       return (error);
+}
+
+/*
+ * Prepare to accept connections.
+ */
+int
+tcp_listen(struct socket *so)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       struct tcpcb *otp = NULL, *tp = NULL;
+       struct proc *p = curproc;
+       int error = 0;
+       short ostate;
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       tp = intotcpcb(inp);
+       /* tp might get 0 when using socket splicing */
+       if (tp == NULL)
+               return (0);
+       if (so->so_options & SO_DEBUG) {
+               otp = tp;
+               ostate = tp->t_state;
+       }
+
+       if (inp->inp_lport == 0)
+               error = in_pcbbind(inp, NULL, p);
+       /* If the in_pcbbind() above is called, the tp->pf
+          should still be whatever it was before. */
+       if (error == 0)
+               tp->t_state = TCPS_LISTEN;
+
+       if (otp)
+               tcp_trace(TA_USER, ostate, tp, otp, NULL, PRU_LISTEN, 0);
+
+       return (error);
+}
+
+/*
+ * Accept a connection.  Essentially all the work is
+ * done at higher levels; just return the address
+ * of the peer, storing through addr.
+ */
+int
+tcp_accept(struct socket *so, struct mbuf *nam)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       struct tcpcb *otp = NULL, *tp = NULL;
+       short ostate;
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       tp = intotcpcb(inp);
+       /* tp might get 0 when using socket splicing */
+       if (tp == NULL)
+               return (0);
+       if (so->so_options & SO_DEBUG) {
+               otp = tp;
+               ostate = tp->t_state;
+       }
+
+#ifdef INET6
+       if (inp->inp_flags & INP_IPV6)
+               in6_setpeeraddr(inp, nam);
+       else
+#endif
+               in_setpeeraddr(inp, nam);
+
+       if (otp)
+               tcp_trace(TA_USER, ostate, tp, otp, NULL, PRU_ACCEPT, 0);
+
+       return (0);
+}
+
+/*
+ * Initiate connection to peer.
+ * Create a template for use in transmissions on this connection.
+ * Enter SYN_SENT state, and mark socket as connecting.
+ * Start keep-alive timer, and seed output sequence space.
+ * Send initial segment on connection.
+ */
+int
+tcp_connect(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       struct tcpcb *otp = NULL, *tp = NULL;
+       int error;
+       short ostate;
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       tp = intotcpcb(inp);
+       /* tp might get 0 when using socket splicing */
+       if (tp == NULL)
+               return (0);
+       if (so->so_options & SO_DEBUG) {
+               otp = tp;
+               ostate = tp->t_state;
+       }
+
+#ifdef INET6
+       if (inp->inp_flags & INP_IPV6) {
+               struct sockaddr_in6 *sin6;
+
+               if ((error = in6_nam2sin6(nam, &sin6)))
+                       goto out;
+               if (IN6_IS_ADDR_UNSPECIFIED(&sin6->sin6_addr) ||
+                   IN6_IS_ADDR_MULTICAST(&sin6->sin6_addr)) {
+                       error = EINVAL;
+                       goto out;
+               }
+               error = in6_pcbconnect(inp, nam);
+       } else
+#endif /* INET6 */
+       {
+               struct sockaddr_in *sin;
+
+               if ((error = in_nam2sin(nam, &sin)))
+                       goto out;
+               if ((sin->sin_addr.s_addr == INADDR_ANY) ||
+                   (sin->sin_addr.s_addr == INADDR_BROADCAST) ||
+                   IN_MULTICAST(sin->sin_addr.s_addr) ||
+                   in_broadcast(sin->sin_addr, inp->inp_rtableid)) {
+                       error = EINVAL;
+                       goto out;
+               }
+               error = in_pcbconnect(inp, nam);
+       }
+       if (error)
+               goto out;
+
+       tp->t_template = tcp_template(tp);
+       if (tp->t_template == 0) {
+               in_pcbdisconnect(inp);
+               error = ENOBUFS;
+               goto out;
+       }
+
+       so->so_state |= SS_CONNECTOUT;
+
+       /* Compute window scaling to request.  */
+       tcp_rscale(tp, sb_max);
+
+       soisconnecting(so);
+       tcpstat_inc(tcps_connattempt);
+       tp->t_state = TCPS_SYN_SENT;
+       TCP_TIMER_ARM(tp, TCPT_KEEP, tcptv_keep_init);
+       tcp_set_iss_tsm(tp);
+       tcp_sendseqinit(tp);
+       tp->snd_last = tp->snd_una;
+       error = tcp_output(tp);
+
+out:
+       if (otp)
+               tcp_trace(TA_USER, ostate, tp, otp, NULL, PRU_CONNECT, 0);
+
+       return (error);
+}
+
+/*
+ * Create a TCP connection between two sockets.
+ */
+int
+tcp_connect2(struct socket *so, struct socket *so2, struct proc *p)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       struct tcpcb *otp = NULL, *tp = NULL;
+       short ostate;
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       tp = intotcpcb(inp);
+       /* tp might get 0 when using socket splicing */
+       if (tp == NULL)
+               return (0);
+       if (so->so_options & SO_DEBUG) {
+               otp = tp;
+               ostate = tp->t_state;
+       }
+
+       if (otp)
+               tcp_trace(TA_USER, ostate, tp, otp, NULL, PRU_CONNECT2, 0);
+
+       return (EOPNOTSUPP);
+}
+
+/*
+ * 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.
+ */
+int
+tcp_disconnect(struct socket *so)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       struct tcpcb *otp = NULL, *tp = NULL;
+       short ostate;
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       tp = intotcpcb(inp);
+       /* tp might get 0 when using socket splicing */
+       if (tp == NULL)
+               return (0);
+       if (so->so_options & SO_DEBUG) {
+               otp = tp;
+               ostate = tp->t_state;
+       }
+
+       tp = tcp_dodisconnect(tp);
+
+       if (otp)
+               tcp_trace(TA_USER, ostate, tp, otp, NULL, PRU_DISCONNECT, 0);
+
+       return (0);
+}
+
+/*
  * Initiate (or continue) disconnect.
  * If embryonic state, just send reset (once).
  * If in ``let data drain'' option and linger null, just drop.
@@ -678,7 +819,7 @@ tcp_detach(struct socket *so)
  * send segment to peer (with FIN).
  */
 struct tcpcb *
-tcp_disconnect(struct tcpcb *tp)
+tcp_dodisconnect(struct tcpcb *tp)
 {
        struct socket *so = tp->t_inpcb->inp_socket;
 
Index: sys/netinet/tcp_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/tcp_var.h,v
retrieving revision 1.139
diff -u -p -r1.139 tcp_var.h
--- sys/netinet/tcp_var.h       25 Feb 2022 23:51:03 -0000      1.139
+++ sys/netinet/tcp_var.h       7 Aug 2022 00:48:46 -0000
@@ -663,7 +663,7 @@ void         tcp6_ctlinput(int, struct sockaddr
 void    tcp_ctlinput(int, struct sockaddr *, u_int, void *);
 int     tcp_ctloutput(int, struct socket *, int, int, struct mbuf *);
 struct tcpcb *
-        tcp_disconnect(struct tcpcb *);
+        tcp_dodisconnect(struct tcpcb *);
 struct tcpcb *
         tcp_drop(struct tcpcb *, int);
 int     tcp_dooptions(struct tcpcb *, u_char *, int, struct tcphdr *,
@@ -705,6 +705,12 @@ int         tcp_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
 int     tcp_attach(struct socket *, int);
 int     tcp_detach(struct socket *);
+int     tcp_bind(struct socket *, struct mbuf *, struct proc *);
+int     tcp_listen(struct socket *);
+int     tcp_accept(struct socket *, struct mbuf *);
+int     tcp_connect(struct socket *, struct mbuf *, struct proc *);
+int     tcp_connect2(struct socket *, struct socket *, struct proc *);
+int     tcp_disconnect(struct socket *);
 void    tcp_xmit_timer(struct tcpcb *, int);
 void    tcpdropoldhalfopen(struct tcpcb *, u_int16_t);
 void    tcp_sack_option(struct tcpcb *,struct tcphdr *,u_char *,int);
Index: sys/netinet/udp_usrreq.c
===================================================================
RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
retrieving revision 1.279
diff -u -p -r1.279 udp_usrreq.c
--- sys/netinet/udp_usrreq.c    26 Jun 2022 15:50:21 -0000      1.279
+++ sys/netinet/udp_usrreq.c    7 Aug 2022 00:48:46 -0000
@@ -1063,71 +1063,6 @@ udp_usrreq(struct socket *so, int req, s
         */
        switch (req) {
 
-       case PRU_BIND:
-               error = in_pcbbind(inp, addr, p);
-               break;
-
-       case PRU_LISTEN:
-               error = EOPNOTSUPP;
-               break;
-
-       case PRU_CONNECT:
-#ifdef INET6
-               if (inp->inp_flags & INP_IPV6) {
-                       if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
-                               error = EISCONN;
-                               break;
-                       }
-                       error = in6_pcbconnect(inp, addr);
-               } else
-#endif /* INET6 */
-               {
-                       if (inp->inp_faddr.s_addr != INADDR_ANY) {
-                               error = EISCONN;
-                               break;
-                       }
-                       error = in_pcbconnect(inp, addr);
-               }
-
-               if (error == 0)
-                       soisconnected(so);
-               break;
-
-       case PRU_CONNECT2:
-               error = EOPNOTSUPP;
-               break;
-
-       case PRU_ACCEPT:
-               error = EOPNOTSUPP;
-               break;
-
-       case PRU_DISCONNECT:
-#ifdef INET6
-               if (inp->inp_flags & INP_IPV6) {
-                       if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6)) {
-                               error = ENOTCONN;
-                               break;
-                       }
-               } else
-#endif /* INET6 */
-               {
-                       if (inp->inp_faddr.s_addr == INADDR_ANY) {
-                               error = ENOTCONN;
-                               break;
-                       }
-               }
-
-#ifdef INET6
-               if (inp->inp_flags & INP_IPV6)
-                       inp->inp_laddr6 = in6addr_any;
-               else
-#endif /* INET6 */
-                       inp->inp_laddr.s_addr = INADDR_ANY;
-               in_pcbdisconnect(inp);
-
-               so->so_state &= ~SS_ISCONNECTED;                /* XXX */
-               break;
-
        case PRU_SHUTDOWN:
                socantsendmore(so);
                break;
@@ -1261,6 +1196,97 @@ udp_detach(struct socket *so)
                return (EINVAL);
 
        in_pcbdetach(inp);
+       return (0);
+}
+
+int
+udp_bind(struct socket *so, struct mbuf *addr, struct proc *p)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       return in_pcbbind(inp, addr, p);
+}
+
+int
+udp_listen(struct socket *so)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+udp_accept(struct socket *so, struct mbuf *addr)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+udp_connect(struct socket *so, struct mbuf *addr, struct proc *p)
+{
+       struct inpcb *inp = sotoinpcb(so);
+       int error;
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+#ifdef INET6
+       if (inp->inp_flags & INP_IPV6) {
+               if (!IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6))
+                       return (EISCONN);
+
+               error = in6_pcbconnect(inp, addr);
+       } else
+#endif /* INET6 */
+       {
+               if (inp->inp_faddr.s_addr != INADDR_ANY)
+                       return (EISCONN);
+
+               error = in_pcbconnect(inp, addr);
+       }
+
+       if (error == 0)
+               soisconnected(so);
+
+       return (error);
+}
+
+int
+udp_connect2(struct socket *so1, struct socket *so2, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+udp_disconnect(struct socket *so)
+{
+       struct inpcb *inp = sotoinpcb(so);
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+#ifdef INET6
+       if (inp->inp_flags & INP_IPV6) {
+               if (IN6_IS_ADDR_UNSPECIFIED(&inp->inp_faddr6))
+                       return (ENOTCONN);
+       } else
+#endif /* INET6 */
+       {
+               if (inp->inp_faddr.s_addr == INADDR_ANY)
+                       return (ENOTCONN);
+       }
+
+#ifdef INET6
+       if (inp->inp_flags & INP_IPV6)
+               inp->inp_laddr6 = in6addr_any;
+       else
+#endif /* INET6 */
+               inp->inp_laddr.s_addr = INADDR_ANY;
+       in_pcbdisconnect(inp);
+
+       so->so_state &= ~SS_ISCONNECTED;                /* XXX */
+
        return (0);
 }
 
Index: sys/netinet/udp_var.h
===================================================================
RCS file: /cvs/src/sys/netinet/udp_var.h,v
retrieving revision 1.37
diff -u -p -r1.37 udp_var.h
--- sys/netinet/udp_var.h       25 Feb 2022 23:51:03 -0000      1.37
+++ sys/netinet/udp_var.h       7 Aug 2022 00:48:46 -0000
@@ -129,17 +129,23 @@ extern struct     udpstat udpstat;
 #ifdef INET6
 void   udp6_ctlinput(int, struct sockaddr *, u_int, void *);
 #endif /* INET6 */
-void    udp_ctlinput(int, struct sockaddr *, u_int, void *);
-void    udp_init(void);
-int     udp_input(struct mbuf **, int *, int, int);
+void   udp_ctlinput(int, struct sockaddr *, u_int, void *);
+void   udp_init(void);
+int    udp_input(struct mbuf **, int *, int, int);
 #ifdef INET6
-int     udp6_output(struct inpcb *, struct mbuf *, struct mbuf *,
+int    udp6_output(struct inpcb *, struct mbuf *, struct mbuf *,
        struct mbuf *);
 #endif /* INET6 */
-int     udp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-int     udp_usrreq(struct socket *,
+int    udp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+int    udp_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
-int     udp_attach(struct socket *, int);
-int     udp_detach(struct socket *);
+int    udp_attach(struct socket *, int);
+int    udp_detach(struct socket *);
+int    udp_bind(struct socket *, struct mbuf *, struct proc *);
+int    udp_listen(struct socket *);
+int    udp_accept(struct socket *, struct mbuf *);
+int    udp_connect(struct socket *, struct mbuf *, struct proc *);
+int    udp_connect2(struct socket *, struct socket *, struct proc *);
+int    udp_disconnect(struct socket *);
 #endif /* _KERNEL */
 #endif /* _NETINET_UDP_VAR_H_ */
Index: sys/netinet6/in6_proto.c
===================================================================
RCS file: /cvs/src/sys/netinet6/in6_proto.c,v
retrieving revision 1.109
diff -u -p -r1.109 in6_proto.c
--- sys/netinet6/in6_proto.c    25 Feb 2022 23:51:04 -0000      1.109
+++ sys/netinet6/in6_proto.c    7 Aug 2022 00:48:46 -0000
@@ -133,58 +133,82 @@ const struct protosw inet6sw[] = {
   .pr_sysctl   = ip6_sysctl
 },
 {
-  .pr_type     = SOCK_DGRAM,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_UDP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR|PR_SPLICE,
-  .pr_input    = udp_input,
-  .pr_ctlinput = udp6_ctlinput,
-  .pr_ctloutput        = ip6_ctloutput,
-  .pr_usrreq   = udp_usrreq,
-  .pr_attach   = udp_attach,
-  .pr_detach   = udp_detach,
-  .pr_sysctl   = udp_sysctl
-},
-{
-  .pr_type     = SOCK_STREAM,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_TCP,
-  .pr_flags    = PR_CONNREQUIRED|PR_WANTRCVD|PR_ABRTACPTDIS|PR_SPLICE,
-  .pr_input    = tcp_input,
-  .pr_ctlinput = tcp6_ctlinput,
-  .pr_ctloutput        = tcp_ctloutput,
-  .pr_usrreq   = tcp_usrreq,
-  .pr_attach   = tcp_attach,
-  .pr_detach   = tcp_detach,
-  .pr_sysctl   = tcp_sysctl
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_RAW,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = rip6_input,
-  .pr_ctlinput = rip6_ctlinput,
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
-  .pr_sysctl   = rip6_sysctl
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_ICMPV6,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = icmp6_input,
-  .pr_ctlinput = rip6_ctlinput,
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
-  .pr_init     = icmp6_init,
-  .pr_fasttimo = icmp6_fasttimo,
-  .pr_sysctl   = icmp6_sysctl
+  .pr_type             = SOCK_DGRAM,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_UDP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR|PR_SPLICE,
+  .pr_input            = udp_input,
+  .pr_ctlinput         = udp6_ctlinput,
+  .pr_ctloutput                = ip6_ctloutput,
+  .pr_usrreq           = udp_usrreq,
+  .pr_attach           = udp_attach,
+  .pr_detach           = udp_detach,
+  .pr_bind             = udp_bind,
+  .pr_listen           = udp_listen,
+  .pr_accept           = udp_accept,
+  .pr_connect          = udp_connect,
+  .pr_connect2         = udp_connect2,
+  .pr_disconnect       = udp_disconnect,
+  .pr_sysctl           = udp_sysctl
+},
+{
+  .pr_type             = SOCK_STREAM,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_TCP,
+  .pr_flags            = PR_CONNREQUIRED|PR_WANTRCVD|PR_ABRTACPTDIS|PR_SPLICE,
+  .pr_input            = tcp_input,
+  .pr_ctlinput         = tcp6_ctlinput,
+  .pr_ctloutput                = tcp_ctloutput,
+  .pr_usrreq           = tcp_usrreq,
+  .pr_attach           = tcp_attach,
+  .pr_detach           = tcp_detach,
+  .pr_bind             = tcp_bind,
+  .pr_listen           = tcp_listen,
+  .pr_accept           = tcp_accept,
+  .pr_connect          = tcp_connect,
+  .pr_connect2         = tcp_connect2,
+  .pr_disconnect       = tcp_disconnect,
+  .pr_sysctl           = tcp_sysctl
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_RAW,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = rip6_input,
+  .pr_ctlinput         = rip6_ctlinput,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
+  .pr_sysctl           = rip6_sysctl
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_ICMPV6,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = icmp6_input,
+  .pr_ctlinput         = rip6_ctlinput,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
+  .pr_init             = icmp6_init,
+  .pr_fasttimo         = icmp6_fasttimo,
+  .pr_sysctl           = icmp6_sysctl
 },
 {
   .pr_type     = SOCK_RAW,
@@ -209,154 +233,220 @@ const struct protosw inet6sw[] = {
 },
 #ifdef IPSEC
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_AH,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = ah46_input,
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
-  .pr_sysctl   = ah_sysctl
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_ESP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = esp46_input,
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
-  .pr_sysctl   = esp_sysctl
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_IPCOMP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = ipcomp46_input,
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
-  .pr_sysctl   = ipcomp_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_AH,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = ah46_input,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
+  .pr_sysctl           = ah_sysctl
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_ESP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = esp46_input,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
+  .pr_sysctl           = esp_sysctl
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_IPCOMP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = ipcomp46_input,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
+  .pr_sysctl           = ipcomp_sysctl
 },
 #endif /* IPSEC */
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_IPV4,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_IPV4,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
 #if NGIF > 0
-  .pr_input    = in6_gif_input,
+  .pr_input            = in6_gif_input,
 #else
-  .pr_input    = ipip_input,
+  .pr_input            = ipip_input,
 #endif
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,  /* XXX */
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
-},
-{
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_IPV6,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,  /* XXX */
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
+},
+{
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_IPV6,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
 #if NGIF > 0
-  .pr_input    = in6_gif_input,
+  .pr_input            = in6_gif_input,
 #else
-  .pr_input    = ipip_input,
+  .pr_input            = ipip_input,
 #endif
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,  /* XXX */
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,  /* XXX */
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
 },
 #if defined(MPLS) && NGIF > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_MPLS,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_MPLS,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
 #if NGIF > 0
-  .pr_input    = in6_gif_input,
+  .pr_input            = in6_gif_input,
 #else
-  .pr_input    = ipip_input,
+  .pr_input            = ipip_input,
 #endif
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,  /* XXX */
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,  /* XXX */
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
 },
 #endif /* MPLS */
 #if NCARP > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_CARP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = carp6_proto_input,
-  .pr_ctloutput = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
-  .pr_sysctl   = carp_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_CARP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = carp6_proto_input,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
+  .pr_sysctl           = carp_sysctl
 },
 #endif /* NCARP */
 #if NPF > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_DIVERT,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = divert6_usrreq,
-  .pr_attach   = divert6_attach,
-  .pr_detach   = divert6_detach,
-  .pr_init     = divert6_init,
-  .pr_sysctl   = divert6_sysctl
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_DIVERT,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = divert6_usrreq,
+  .pr_attach           = divert6_attach,
+  .pr_detach           = divert6_detach,
+  .pr_bind             = divert6_bind,
+  .pr_listen           = divert6_listen,
+  .pr_accept           = divert6_accept,
+  .pr_connect          = divert6_connect,
+  .pr_connect2         = divert6_connect2,
+  .pr_disconnect       = divert6_disconnect,
+  .pr_init             = divert6_init,
+  .pr_sysctl           = divert6_sysctl
 },
 #endif /* NPF > 0 */
 #if NETHERIP > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_ETHERIP,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = ip6_etherip_input,
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_ETHERIP,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = ip6_etherip_input,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
 },
 #endif /* NETHERIP */
 #if NGRE > 0
 {
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_protocol = IPPROTO_GRE,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = gre_input6,
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_protocol         = IPPROTO_GRE,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = gre_input6,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
 },
 #endif /* NGRE */
 {
   /* raw wildcard */
-  .pr_type     = SOCK_RAW,
-  .pr_domain   = &inet6domain,
-  .pr_flags    = PR_ATOMIC|PR_ADDR,
-  .pr_input    = rip6_input,
-  .pr_ctloutput        = rip6_ctloutput,
-  .pr_usrreq   = rip6_usrreq,
-  .pr_attach   = rip6_attach,
-  .pr_detach   = rip6_detach,
-  .pr_init     = rip6_init
+  .pr_type             = SOCK_RAW,
+  .pr_domain           = &inet6domain,
+  .pr_flags            = PR_ATOMIC|PR_ADDR,
+  .pr_input            = rip6_input,
+  .pr_ctloutput                = rip6_ctloutput,
+  .pr_usrreq           = rip6_usrreq,
+  .pr_attach           = rip6_attach,
+  .pr_detach           = rip6_detach,
+  .pr_bind             = rip6_bind,
+  .pr_listen           = rip6_listen,
+  .pr_accept           = rip6_accept,
+  .pr_connect          = rip6_connect,
+  .pr_connect2         = rip6_connect2,
+  .pr_disconnect       = rip6_disconnect,
+  .pr_init             = rip6_init
 }
 };
 
Index: sys/netinet6/ip6_divert.c
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v
retrieving revision 1.67
diff -u -p -r1.67 ip6_divert.c
--- sys/netinet6/ip6_divert.c   9 May 2022 19:33:46 -0000       1.67
+++ sys/netinet6/ip6_divert.c   7 Aug 2022 00:48:46 -0000
@@ -274,10 +274,6 @@ divert6_usrreq(struct socket *so, int re
        }
        switch (req) {
 
-       case PRU_BIND:
-               error = in_pcbbind(inp, addr, p);
-               break;
-
        case PRU_SHUTDOWN:
                socantsendmore(so);
                break;
@@ -301,11 +297,6 @@ divert6_usrreq(struct socket *so, int re
        case PRU_SENSE:
                break;
 
-       case PRU_LISTEN:
-       case PRU_CONNECT:
-       case PRU_CONNECT2:
-       case PRU_ACCEPT:
-       case PRU_DISCONNECT:
        case PRU_SENDOOB:
        case PRU_FASTTIMO:
        case PRU_SLOWTIMO:
@@ -363,6 +354,47 @@ divert6_detach(struct socket *so)
        in_pcbdetach(inp);
 
        return (0);
+}
+
+int
+divert6_bind(struct socket *so, struct mbuf *addr, struct proc *p)
+{
+       struct inpcb *inp = sotoinpcb(so);
+
+       soassertlocked(so);
+       KASSERT(inp != NULL);
+
+       return in_pcbbind(inp, addr, p);
+}
+
+int
+divert6_listen(struct socket *so)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+divert6_accept(struct socket *so, struct mbuf *addr)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+divert6_connect(struct socket *so, struct mbuf *addr, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+divert6_connect2(struct socket *so1, struct socket *so2, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+divert6_disconnect(struct socket *so)
+{
+       return (EOPNOTSUPP);
 }
 
 int
Index: sys/netinet6/ip6_divert.h
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_divert.h,v
retrieving revision 1.13
diff -u -p -r1.13 ip6_divert.h
--- sys/netinet6/ip6_divert.h   5 May 2022 16:44:22 -0000       1.13
+++ sys/netinet6/ip6_divert.h   7 Aug 2022 00:48:46 -0000
@@ -65,13 +65,19 @@ div6stat_inc(enum div6stat_counters c)
 
 extern struct  inpcbtable      divb6table;
 
-void    divert6_init(void);
-void    divert6_packet(struct mbuf *, int, u_int16_t);
-int     divert6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
-int     divert6_usrreq(struct socket *,
+void   divert6_init(void);
+void   divert6_packet(struct mbuf *, int, u_int16_t);
+int    divert6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
+int    divert6_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
-int     divert6_attach(struct socket *, int);
-int     divert6_detach(struct socket *);
+int    divert6_attach(struct socket *, int);
+int    divert6_detach(struct socket *);
+int    divert6_bind(struct socket *, struct mbuf *, struct proc *);
+int    divert6_listen(struct socket *);
+int    divert6_accept(struct socket *, struct mbuf *);
+int    divert6_connect(struct socket *, struct mbuf *, struct proc *);
+int    divert6_connect2(struct socket *, struct socket *, struct proc *);
+int    divert6_disconnect(struct socket *);
 #endif /* _KERNEL */
 
 #endif /* _IP6_DIVERT_H_ */
Index: sys/netinet6/ip6_var.h
===================================================================
RCS file: /cvs/src/sys/netinet6/ip6_var.h,v
retrieving revision 1.93
diff -u -p -r1.93 ip6_var.h
--- sys/netinet6/ip6_var.h      29 Jun 2022 22:45:24 -0000      1.93
+++ sys/netinet6/ip6_var.h      7 Aug 2022 00:48:46 -0000
@@ -350,6 +350,12 @@ int        rip6_usrreq(struct socket *,
            int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
 int    rip6_attach(struct socket *, int);
 int    rip6_detach(struct socket *);
+int    rip6_bind(struct socket *, struct mbuf *, struct proc *);
+int    rip6_listen(struct socket *);
+int    rip6_accept(struct socket *, struct mbuf *);
+int    rip6_connect(struct socket *, struct mbuf *, struct proc *);
+int    rip6_connect2(struct socket *, struct socket *, struct proc *);
+int    rip6_disconnect(struct socket *);
 int    rip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
 
 int    dest6_input(struct mbuf **, int *, int, int);
Index: sys/netinet6/raw_ip6.c
===================================================================
RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v
retrieving revision 1.147
diff -u -p -r1.147 raw_ip6.c
--- sys/netinet6/raw_ip6.c      23 Mar 2022 00:16:07 -0000      1.147
+++ sys/netinet6/raw_ip6.c      7 Aug 2022 00:48:46 -0000
@@ -574,15 +574,6 @@ rip6_usrreq(struct socket *so, int req, 
        }
 
        switch (req) {
-       case PRU_DISCONNECT:
-               if ((so->so_state & SS_ISCONNECTED) == 0) {
-                       error = ENOTCONN;
-                       break;
-               }
-               in6p->inp_faddr6 = in6addr_any;
-               so->so_state &= ~SS_ISCONNECTED;        /* XXX */
-               break;
-
        case PRU_ABORT:
                soisdisconnected(so);
                if (in6p == NULL)
@@ -597,46 +588,6 @@ rip6_usrreq(struct socket *so, int req, 
                in_pcbdetach(in6p);
                break;
 
-       case PRU_BIND:
-           {
-               struct sockaddr_in6 *addr;
-
-               if ((error = in6_nam2sin6(nam, &addr)))
-                       break;
-               /*
-                * Make sure to not enter in_pcblookup_local(), local ports
-                * are non-sensical for raw sockets.
-                */
-               addr->sin6_port = 0;
-
-               if ((error = in6_pcbaddrisavail(in6p, addr, 0, p)))
-                       break;
-
-               in6p->inp_laddr6 = addr->sin6_addr;
-               break;
-           }
-
-       case PRU_CONNECT:
-       {
-               struct sockaddr_in6 *addr;
-               struct in6_addr *in6a = NULL;
-
-               if ((error = in6_nam2sin6(nam, &addr)))
-                       break;
-               /* Source address selection. XXX: need pcblookup? */
-               error = in6_pcbselsrc(&in6a, addr, in6p, in6p->inp_outputopts6);
-               if (error)
-                       break;
-               in6p->inp_laddr6 = *in6a;
-               in6p->inp_faddr6 = addr->sin6_addr;
-               soisconnected(so);
-               break;
-       }
-
-       case PRU_CONNECT2:
-               error = EOPNOTSUPP;
-               break;
-
        /*
         * Mark the connection as being incapable of further input.
         */
@@ -687,8 +638,6 @@ rip6_usrreq(struct socket *so, int req, 
        /*
         * Not supported.
         */
-       case PRU_LISTEN:
-       case PRU_ACCEPT:
        case PRU_SENDOOB:
        case PRU_RCVD:
        case PRU_RCVOOB:
@@ -764,6 +713,93 @@ rip6_detach(struct socket *so)
        in6p->inp_icmp6filt = NULL;
 
        in_pcbdetach(in6p);
+
+       return (0);
+}
+
+int
+rip6_bind(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       struct inpcb *in6p = sotoinpcb(so);
+       struct sockaddr_in6 *addr;
+       int error;
+
+       soassertlocked(so);
+       KASSERT(in6p != NULL);
+
+       if ((error = in6_nam2sin6(nam, &addr)))
+               return (error);
+       /*
+        * Make sure to not enter in_pcblookup_local(), local ports
+        * are non-sensical for raw sockets.
+        */
+       addr->sin6_port = 0;
+
+       if ((error = in6_pcbaddrisavail(in6p, addr, 0, p)))
+               return (error);
+
+       in6p->inp_laddr6 = addr->sin6_addr;
+       
+       return (0);
+}
+
+int
+rip6_listen(struct socket *so)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+rip6_accept(struct socket *so, struct mbuf *nam)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+rip6_connect(struct socket *so, struct mbuf *nam, struct proc *p)
+{
+       struct inpcb *in6p = sotoinpcb(so);
+       struct sockaddr_in6 *addr;
+       struct in6_addr *in6a = NULL;
+       int error;
+
+       soassertlocked(so);
+       KASSERT(in6p != NULL);
+
+       error = in6_nam2sin6(nam, &addr);
+       if (error != 0)
+               return (error);
+       /* Source address selection. XXX: need pcblookup? */
+       error = in6_pcbselsrc(&in6a, addr, in6p, in6p->inp_outputopts6);
+       if (error != 0)
+               return (error);
+
+       in6p->inp_laddr6 = *in6a;
+       in6p->inp_faddr6 = addr->sin6_addr;
+       soisconnected(so);
+
+       return (0);
+}
+
+int
+rip6_connect2(struct socket *so1, struct socket *so2, struct proc *p)
+{
+       return (EOPNOTSUPP);
+}
+
+int
+rip6_disconnect(struct socket *so)
+{
+       struct inpcb *in6p = sotoinpcb(so);
+
+       soassertlocked(so);
+       KASSERT(in6p != NULL);
+       
+       if ((so->so_state & SS_ISCONNECTED) == 0)
+               return (ENOTCONN);
+
+       in6p->inp_faddr6 = in6addr_any;
+       so->so_state &= ~SS_ISCONNECTED;        /* XXX */
 
        return (0);
 }
Index: sys/sys/protosw.h
===================================================================
RCS file: /cvs/src/sys/sys/protosw.h,v
retrieving revision 1.35
diff -u -p -r1.35 protosw.h
--- sys/sys/protosw.h   25 Feb 2022 23:51:04 -0000      1.35
+++ sys/sys/protosw.h   7 Aug 2022 00:48:46 -0000
@@ -83,6 +83,12 @@ struct protosw {
 
        int     (*pr_attach)(struct socket *, int);
        int     (*pr_detach)(struct socket *);
+       int     (*pr_bind)(struct socket *, struct mbuf *, struct proc *);
+       int     (*pr_listen)(struct socket *);
+       int     (*pr_accept)(struct socket *, struct mbuf *);
+       int     (*pr_connect)(struct socket *, struct mbuf *, struct proc *);
+       int     (*pr_connect2)(struct socket *, struct socket *, struct proc *);
+       int     (*pr_disconnect)(struct socket *);
 
 /* utility hooks */
        void    (*pr_init)(void);       /* initialization hook */
Index: sys/sys/unpcb.h
===================================================================
RCS file: /cvs/src/sys/sys/unpcb.h,v
retrieving revision 1.26
diff -u -p -r1.26 unpcb.h
--- sys/sys/unpcb.h     1 Jul 2022 09:56:17 -0000       1.26
+++ sys/sys/unpcb.h     7 Aug 2022 00:48:46 -0000
@@ -111,6 +111,12 @@ int        uipc_usrreq(struct socket *, int , s
                         struct mbuf *, struct mbuf *, struct proc *);
 int    uipc_attach(struct socket *, int);
 int    uipc_detach(struct socket *);
+int    uipc_bind(struct socket *, struct mbuf *, struct proc *);
+int    uipc_listen(struct socket *);
+int    uipc_accept(struct socket *, struct mbuf *);
+int    uipc_connect(struct socket *, struct mbuf *, struct proc *);
+int    uipc_connect2(struct socket *, struct socket *, struct proc *);
+int    uipc_disconnect(struct socket *);
 
 void   unp_init(void);
 int    unp_bind(struct unpcb *, struct mbuf *, struct proc *);

Reply via email to