On Sun, Mar 05, 2017 at 10:54:39AM +0100, Claudio Jeker wrote:
> Here is an updated version of the PRU_ATTACH diff. I looked at the pfkey
> code and decided to only do the minimum now. I will go in afterwards and
> kill the dynamic fiddling in there. There is no reason for all this
> complication since we only support one and only one version of pfkey.

This diff is not minimal.  By changing socket->so_proto->pr_protocol
to proto you broke socket(AF_KEY,0x3<SOCK_RAW>,0).  ipsecctl(9)
uses socket(AF_KEY,0x3<SOCK_RAW>,0x2) so this is not noticed.

Such a diff may not change user land semantics.

> I would like to commit this version and then do the pfkey cleanup on top
> of this.

Yes please.  I took me a while to understand that something broke.

> Any OKs?

Do not do unnecessary changes in pfkey_attach() to keep review simple.
The route_usrreq() chunk does not apply anymore after mpi@'s commit.

Everything else is OK bluhm@

> -- 
> :wq Claudio
> 
> Index: kern/uipc_proto.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_proto.c,v
> retrieving revision 1.13
> diff -u -p -r1.13 uipc_proto.c
> --- kern/uipc_proto.c 2 Mar 2017 08:58:24 -0000       1.13
> +++ kern/uipc_proto.c 5 Mar 2017 09:23:04 -0000
> @@ -55,6 +55,7 @@ struct protosw unixsw[] = {
>    .pr_protocol       = PF_LOCAL,
>    .pr_flags  = PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
>    .pr_usrreq = uipc_usrreq,
> +  .pr_attach = uipc_attach,
>  },
>  {
>    .pr_type   = SOCK_SEQPACKET,
> @@ -62,6 +63,7 @@ struct protosw unixsw[] = {
>    .pr_protocol       = PF_LOCAL,
>    .pr_flags  = PR_ATOMIC|PR_CONNREQUIRED|PR_WANTRCVD|PR_RIGHTS,
>    .pr_usrreq = uipc_usrreq,
> +  .pr_attach = uipc_attach,
>  },
>  {
>    .pr_type   = SOCK_DGRAM,
> @@ -69,6 +71,7 @@ struct protosw unixsw[] = {
>    .pr_protocol       = PF_LOCAL,
>    .pr_flags  = PR_ATOMIC|PR_ADDR|PR_RIGHTS,
>    .pr_usrreq = uipc_usrreq,
> +  .pr_attach = uipc_attach,
>  }
>  };
>  
> Index: kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.178
> diff -u -p -r1.178 uipc_socket.c
> --- kern/uipc_socket.c        3 Mar 2017 09:41:20 -0000       1.178
> +++ kern/uipc_socket.c        5 Mar 2017 09:39:34 -0000
> @@ -119,7 +119,7 @@ socreate(int dom, struct socket **aso, i
>               prp = pffindproto(dom, proto, type);
>       else
>               prp = pffindtype(dom, type);
> -     if (prp == NULL || prp->pr_usrreq == 0)
> +     if (prp == NULL || prp->pr_attach == NULL)
>               return (EPROTONOSUPPORT);
>       if (prp->pr_type != type)
>               return (EPROTOTYPE);
> @@ -135,9 +135,9 @@ socreate(int dom, struct socket **aso, i
>       so->so_egid = p->p_ucred->cr_gid;
>       so->so_cpid = p->p_p->ps_pid;
>       so->so_proto = prp;
> +
>       s = solock(so);
> -     error = (*prp->pr_usrreq)(so, PRU_ATTACH, NULL,
> -         (struct mbuf *)(long)proto, NULL, p);
> +     error = (*prp->pr_attach)(so, proto);
>       if (error) {
>               so->so_state |= SS_NOFDREF;
>               sofree(so);
> Index: kern/uipc_socket2.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket2.c,v
> retrieving revision 1.72
> diff -u -p -r1.72 uipc_socket2.c
> --- kern/uipc_socket2.c       14 Feb 2017 09:46:21 -0000      1.72
> +++ kern/uipc_socket2.c       25 Feb 2017 18:51:02 -0000
> @@ -187,8 +187,7 @@ sonewconn(struct socket *head, int conns
>       so->so_rcv.sb_timeo = head->so_rcv.sb_timeo;
>  
>       soqinsque(head, so, soqueue);
> -     if ((*so->so_proto->pr_usrreq)(so, PRU_ATTACH, NULL, NULL, NULL,
> -         curproc)) {
> +     if ((*so->so_proto->pr_attach)(so, 0)) {
>               (void) soqremque(so, soqueue);
>               pool_put(&socket_pool, so);
>               return (NULL);
> Index: kern/uipc_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_usrreq.c,v
> retrieving revision 1.116
> diff -u -p -r1.116 uipc_usrreq.c
> --- kern/uipc_usrreq.c        14 Feb 2017 09:46:21 -0000      1.116
> +++ kern/uipc_usrreq.c        26 Feb 2017 08:03:29 -0000
> @@ -117,7 +117,7 @@ uipc_usrreq(struct socket *so, int req, 
>               error = EOPNOTSUPP;
>               goto release;
>       }
> -     if (unp == NULL && req != PRU_ATTACH) {
> +     if (unp == NULL) {
>               error = EINVAL;
>               goto release;
>       }
> @@ -126,14 +126,6 @@ uipc_usrreq(struct socket *so, int req, 
>  
>       switch (req) {
>  
> -     case PRU_ATTACH:
> -             if (unp) {
> -                     error = EISCONN;
> -                     break;
> -             }
> -             error = unp_attach(so);
> -             break;
> -
>       case PRU_DETACH:
>               unp_detach(unp);
>               break;
> @@ -351,11 +343,13 @@ u_long  unpdg_recvspace = 4*1024;
>  int  unp_rights;                     /* file descriptors in flight */
>  
>  int
> -unp_attach(struct socket *so)
> +uipc_attach(struct socket *so, int proto)
>  {
>       struct unpcb *unp;
>       int error;
>       
> +     if (so->so_pcb)
> +             return EISCONN;
>       if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0) {
>               switch (so->so_type) {
>  
> Index: net/pfkey.c
> ===================================================================
> RCS file: /cvs/src/sys/net/pfkey.c,v
> retrieving revision 1.39
> diff -u -p -r1.39 pfkey.c
> --- net/pfkey.c       3 Mar 2017 15:48:02 -0000       1.39
> +++ net/pfkey.c       5 Mar 2017 09:46:15 -0000
> @@ -189,31 +189,37 @@ ret:
>       return (error);
>  }
>  
> -static int
> -pfkey_attach(struct socket *socket, struct mbuf *proto, struct proc *p)
> +int
> +pfkey_attach(struct socket *so, int proto)
>  {
>       int rval;
>  
> -     if (!(socket->so_pcb = malloc(sizeof(struct rawcb),
> +     if ((so->so_state & SS_PRIV) == 0)
> +             return EACCES;
> +
> +     if ((proto > PFKEY_PROTOCOL_MAX) || (proto < 0) ||
> +         !pfkey_versions[proto])
> +             return (EPROTONOSUPPORT);
> +
> +     if (!(so->so_pcb = malloc(sizeof(struct rawcb),
>           M_PCB, M_DONTWAIT | M_ZERO)))
>               return (ENOMEM);
>  
> -     rval = raw_usrreq(socket, PRU_ATTACH, NULL, proto, NULL, p);
> +     rval = raw_attach(so, proto);
>       if (rval)
>               goto ret;
>  
> -     ((struct rawcb *)socket->so_pcb)->rcb_faddr = &pfkey_addr;
> -     soisconnected(socket);
> +     ((struct rawcb *)so->so_pcb)->rcb_faddr = &pfkey_addr;
> +     soisconnected(so);
>  
> -     socket->so_options |= SO_USELOOPBACK;
> -     if ((rval =
> -         pfkey_versions[socket->so_proto->pr_protocol]->create(socket)) != 0)
> +     so->so_options |= SO_USELOOPBACK;
> +     if ((rval = pfkey_versions[proto]->create(so)) != 0)
>               goto ret;
>  
>       return (0);
>  
>  ret:
> -     free(socket->so_pcb, M_PCB, sizeof(struct rawcb));
> +     free(so->so_pcb, M_PCB, sizeof(struct rawcb));
>       return (rval);
>  }
>  
> @@ -243,9 +249,6 @@ pfkey_usrreq(struct socket *socket, int 
>               return (EPROTONOSUPPORT);
>  
>       switch (req) {
> -     case PRU_ATTACH:
> -             return (pfkey_attach(socket, nam, p));
> -
>       case PRU_DETACH:
>               return (pfkey_detach(socket, p));
>  
> @@ -268,7 +271,8 @@ static struct protosw pfkey_protosw_temp
>    .pr_protocol       = -1,
>    .pr_flags  = PR_ATOMIC | PR_ADDR,
>    .pr_output = pfkey_output,
> -  .pr_usrreq = pfkey_usrreq
> +  .pr_usrreq = pfkey_usrreq,
> +  .pr_attach = pfkey_attach,
>  };
>  
>  int
> Index: net/raw_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/net/raw_usrreq.c,v
> retrieving revision 1.29
> diff -u -p -r1.29 raw_usrreq.c
> --- net/raw_usrreq.c  3 Mar 2017 15:48:02 -0000       1.29
> +++ net/raw_usrreq.c  5 Mar 2017 09:25:55 -0000
> @@ -76,20 +76,6 @@ raw_usrreq(struct socket *so, int req, s
>               return (EINVAL);
>       }
>       switch (req) {
> -
> -     /*
> -      * Allocate a raw control block and fill in the
> -      * necessary info to allow packets to be routed to
> -      * the appropriate raw interface routine.
> -      */
> -     case PRU_ATTACH:
> -             if ((so->so_state & SS_PRIV) == 0) {
> -                     error = EACCES;
> -                     break;
> -             }
> -             error = raw_attach(so, (int)(long)nam);
> -             break;
> -
>       /*
>        * Destroy state just before socket deallocation.
>        * Flush data or not depending on the options.
> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.228
> diff -u -p -r1.228 rtsock.c
> --- net/rtsock.c      3 Mar 2017 15:48:02 -0000       1.228
> +++ net/rtsock.c      5 Mar 2017 09:25:55 -0000
> @@ -161,46 +161,6 @@ route_usrreq(struct socket *so, int req,
>       rp = sotorawcb(so);
>  
>       switch (req) {
> -     case PRU_ATTACH:
> -             /*
> -              * use the rawcb but allocate a routecb, this
> -              * code does not care about the additional fields
> -              * and works directly on the raw socket.
> -              */
> -             rop = malloc(sizeof(struct routecb), M_PCB, M_WAITOK|M_ZERO);
> -             rp = &rop->rcb;
> -             so->so_pcb = rp;
> -             /* Init the timeout structure */
> -             timeout_set(&((struct routecb *)rp)->timeout, rt_senddesync, 
> rp);
> -             /*
> -              * Don't call raw_usrreq() in the attach case, because
> -              * we want to allow non-privileged processes to listen
> -              * on and send "safe" commands to the routing socket.
> -              */
> -             if (curproc == 0)
> -                     error = EACCES;
> -             else
> -                     error = raw_attach(so, (int)(long)nam);
> -             if (error) {
> -                     free(rop, M_PCB, sizeof(struct routecb));
> -                     return (error);
> -             }
> -             rop->rtableid = curproc->p_p->ps_rtableid;
> -             af = rp->rcb_proto.sp_protocol;
> -             if (af == AF_INET)
> -                     route_cb.ip_count++;
> -             else if (af == AF_INET6)
> -                     route_cb.ip6_count++;
> -#ifdef MPLS
> -             else if (af == AF_MPLS)
> -                     route_cb.mpls_count++;
> -#endif
> -             rp->rcb_faddr = &route_src;
> -             route_cb.any_count++;
> -             soisconnected(so);
> -             so->so_options |= SO_USELOOPBACK;
> -             break;
> -
>       case PRU_RCVD:
>               rop = (struct routecb *)rp;
>  
> @@ -237,6 +197,53 @@ route_usrreq(struct socket *so, int req,
>  }
>  
>  int
> +route_attach(struct socket *so, int proto)
> +{
> +     struct rawcb    *rp;
> +     struct routecb  *rop;
> +     int              af;
> +     int              error = 0;
> +
> +     NET_ASSERT_LOCKED();
> +
> +     /*
> +      * use the rawcb but allocate a routecb, this
> +      * code does not care about the additional fields
> +      * and works directly on the raw socket.
> +      */
> +     rop = malloc(sizeof(struct routecb), M_PCB, M_WAITOK|M_ZERO);
> +     rp = &rop->rcb;
> +     so->so_pcb = rp;
> +     /* Init the timeout structure */
> +     timeout_set(&rop->timeout, rt_senddesync, rp);
> +
> +     if (curproc == NULL)
> +             error = EACCES;
> +     else
> +             error = raw_attach(so, proto);
> +     if (error) {
> +             free(rop, M_PCB, sizeof(struct routecb));
> +             return (error);
> +     }
> +     rop->rtableid = curproc->p_p->ps_rtableid;
> +     af = rp->rcb_proto.sp_protocol;
> +     if (af == AF_INET)
> +             route_cb.ip_count++;
> +     else if (af == AF_INET6)
> +             route_cb.ip6_count++;
> +#ifdef MPLS
> +     else if (af == AF_MPLS)
> +             route_cb.mpls_count++;
> +#endif
> +     rp->rcb_faddr = &route_src;
> +     route_cb.any_count++;
> +     soisconnected(so);
> +     so->so_options |= SO_USELOOPBACK;
> +
> +     return (error);
> +}
> +
> +int
>  route_ctloutput(int op, struct socket *so, int level, int optname,
>      struct mbuf *m)
>  {
> @@ -1738,6 +1745,7 @@ struct protosw routesw[] = {
>    .pr_output = route_output,
>    .pr_ctloutput      = route_ctloutput,
>    .pr_usrreq = route_usrreq,
> +  .pr_attach = route_attach,
>    .pr_init   = raw_init,
>    .pr_sysctl = sysctl_rtable
>  }
> Index: netinet/in_proto.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/in_proto.c,v
> retrieving revision 1.74
> diff -u -p -r1.74 in_proto.c
> --- netinet/in_proto.c        2 Mar 2017 08:58:24 -0000       1.74
> +++ netinet/in_proto.c        5 Mar 2017 09:23:04 -0000
> @@ -191,6 +191,7 @@ struct protosw inetsw[] = {
>    .pr_ctlinput       = udp_ctlinput,
>    .pr_ctloutput      = ip_ctloutput,
>    .pr_usrreq = udp_usrreq,
> +  .pr_attach = udp_attach,
>    .pr_init   = udp_init,
>    .pr_sysctl = udp_sysctl
>  },
> @@ -203,6 +204,7 @@ struct protosw inetsw[] = {
>    .pr_ctlinput       = tcp_ctlinput,
>    .pr_ctloutput      = tcp_ctloutput,
>    .pr_usrreq = tcp_usrreq,
> +  .pr_attach = tcp_attach,
>    .pr_init   = tcp_init,
>    .pr_slowtimo       = tcp_slowtimo,
>    .pr_sysctl = tcp_sysctl
> @@ -215,7 +217,8 @@ struct protosw inetsw[] = {
>    .pr_input  = rip_input,
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
> -  .pr_usrreq = rip_usrreq
> +  .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach
>  },
>  {
>    .pr_type   = SOCK_RAW,
> @@ -226,6 +229,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_init   = icmp_init,
>    .pr_sysctl = icmp_sysctl
>  },
> @@ -239,6 +243,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = ipip_sysctl
>  },
>  {
> @@ -250,6 +255,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = etherip_sysctl
>  },
>  #ifdef INET6
> @@ -260,7 +266,8 @@ struct protosw inetsw[] = {
>    .pr_flags  = PR_ATOMIC|PR_ADDR,
>    .pr_input  = in_gif_input,
>    .pr_output = rip_output,
> -  .pr_usrreq = rip_usrreq /* XXX */
> +  .pr_usrreq = rip_usrreq, /* XXX */
> +  .pr_attach = rip_attach
>  },
>  #endif
>  #ifdef MPLS
> @@ -271,7 +278,8 @@ struct protosw inetsw[] = {
>    .pr_flags  = PR_ATOMIC|PR_ADDR,
>    .pr_input  = etherip_input,
>    .pr_output = rip_output,
> -  .pr_usrreq = rip_usrreq
> +  .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach
>  },
>  #endif
>  #else /* NGIF */
> @@ -284,6 +292,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = ipip_sysctl
>  },
>  #ifdef INET6
> @@ -295,7 +304,8 @@ struct protosw inetsw[] = {
>    .pr_input  = ip4_input,
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
> -  .pr_usrreq = rip_usrreq /* XXX */
> +  .pr_usrreq = rip_usrreq, /* XXX */
> +  .pr_attach = rip_attach
>  },
>  #endif
>  #endif /*NGIF*/
> @@ -308,6 +318,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_init   = igmp_init,
>    .pr_fasttimo       = igmp_fasttimo,
>    .pr_slowtimo       = igmp_slowtimo,
> @@ -324,6 +335,7 @@ struct protosw inetsw[] = {
>    .pr_ctlinput       = ah4_ctlinput,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = ah_sysctl
>  },
>  {
> @@ -336,6 +348,7 @@ struct protosw inetsw[] = {
>    .pr_ctlinput       = esp4_ctlinput,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = esp_sysctl
>  },
>  {
> @@ -347,6 +360,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = ipcomp_sysctl
>  },
>  #endif /* IPSEC */
> @@ -360,6 +374,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = gre_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = gre_sysctl
>  },
>  {
> @@ -371,6 +386,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = ipmobile_sysctl
>  },
>  #endif /* NGRE > 0 */
> @@ -384,6 +400,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = carp_sysctl
>  },
>  #endif /* NCARP > 0 */
> @@ -397,6 +414,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = pfsync_sysctl
>  },
>  #endif /* NPFSYNC > 0 */
> @@ -408,6 +426,7 @@ struct protosw inetsw[] = {
>    .pr_flags  = PR_ATOMIC|PR_ADDR,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = divert_usrreq,
> +  .pr_attach = divert_attach,
>    .pr_init   = divert_init,
>    .pr_sysctl = divert_sysctl
>  },
> @@ -422,6 +441,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_sysctl = ip_etherip_sysctl
>  },
>  #endif /* NETHERIP */
> @@ -434,6 +454,7 @@ struct protosw inetsw[] = {
>    .pr_output = rip_output,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> +  .pr_attach = rip_attach,
>    .pr_init   = rip_init
>  }
>  };
> Index: netinet/ip_divert.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_divert.c,v
> retrieving revision 1.44
> diff -u -p -r1.44 ip_divert.c
> --- netinet/ip_divert.c       9 Feb 2017 15:32:56 -0000       1.44
> +++ netinet/ip_divert.c       26 Feb 2017 08:10:15 -0000
> @@ -249,31 +249,12 @@ divert_usrreq(struct socket *so, int req
>               return (in_control(so, (u_long)m, (caddr_t)addr,
>                   (struct ifnet *)control));
>       }
> -     if (inp == NULL && req != PRU_ATTACH) {
> +     if (inp == NULL) {
>               error = EINVAL;
>               goto release;
>       }
>       switch (req) {
>  
> -     case PRU_ATTACH:
> -             if (inp != NULL) {
> -                     error = EINVAL;
> -                     break;
> -             }
> -             if ((so->so_state & SS_PRIV) == 0) {
> -                     error = EACCES;
> -                     break;
> -             }
> -             error = in_pcballoc(so, &divbtable);
> -             if (error)
> -                     break;
> -
> -             error = soreserve(so, divert_sendspace, divert_recvspace);
> -             if (error)
> -                     break;
> -             sotoinpcb(so)->inp_flags |= INP_HDRINCL;
> -             break;
> -
>       case PRU_DETACH:
>               in_pcbdetach(inp);
>               break;
> @@ -330,6 +311,28 @@ release:
>       m_freem(control);
>       m_freem(m);
>       return (error);
> +}
> +
> +int
> +divert_attach(struct socket *so, int proto)
> +{
> +     int error;
> +
> +     if (so->so_pcb != NULL)
> +             return EINVAL;
> +     if ((so->so_state & SS_PRIV) == 0)
> +             return EACCES;
> +
> +     error = in_pcballoc(so, &divbtable);
> +     if (error)
> +             return error;
> +
> +     error = soreserve(so, divert_sendspace, divert_recvspace);
> +     if (error)
> +             return error;
> +
> +     sotoinpcb(so)->inp_flags |= INP_HDRINCL;
> +     return (0);
>  }
>  
>  int
> Index: netinet/ip_divert.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_divert.h,v
> retrieving revision 1.8
> diff -u -p -r1.8 ip_divert.h
> --- netinet/ip_divert.h       9 Feb 2017 15:32:56 -0000       1.8
> +++ netinet/ip_divert.h       25 Feb 2017 18:51:02 -0000
> @@ -78,6 +78,7 @@ int  divert_packet(struct mbuf *, int, u
>  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);
>  
>  #endif /* _KERNEL */
>  #endif /* _IP_DIVERT_H_ */
> Index: netinet/ip_var.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_var.h,v
> retrieving revision 1.69
> diff -u -p -r1.69 ip_var.h
> --- netinet/ip_var.h  3 Mar 2017 15:48:02 -0000       1.69
> +++ netinet/ip_var.h  5 Mar 2017 09:25:55 -0000
> @@ -257,6 +257,7 @@ int        rip_output(struct mbuf *, struct so
>           struct mbuf *);
>  int   rip_usrreq(struct socket *,
>           int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
> +int   rip_attach(struct socket *, int);
>  
>  #endif /* _KERNEL */
>  #endif /* _NETINET_IP_VAR_H_ */
> Index: netinet/raw_ip.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/raw_ip.c,v
> retrieving revision 1.96
> diff -u -p -r1.96 raw_ip.c
> --- netinet/raw_ip.c  3 Mar 2017 15:48:02 -0000       1.96
> +++ netinet/raw_ip.c  5 Mar 2017 09:25:55 -0000
> @@ -403,32 +403,13 @@ rip_usrreq(struct socket *so, int req, s
>               return (in_control(so, (u_long)m, (caddr_t)nam,
>                   (struct ifnet *)control));
>  
> -     if (inp == NULL && req != PRU_ATTACH) {
> +     if (inp == NULL) {
>               error = EINVAL;
>               goto release;
>       }
>  
>       switch (req) {
>  
> -     case PRU_ATTACH:
> -             if (inp)
> -                     panic("rip_attach");
> -             if ((so->so_state & SS_PRIV) == 0) {
> -                     error = EACCES;
> -                     break;
> -             }
> -             if ((long)nam < 0 || (long)nam >= IPPROTO_MAX) {
> -                     error = EPROTONOSUPPORT;
> -                     break;
> -             }
> -             if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
> -                 (error = in_pcballoc(so, &rawcbtable))) {
> -                     break;
> -             }
> -             inp = sotoinpcb(so);
> -             inp->inp_ip.ip_p = (long)nam;
> -             break;
> -
>       case PRU_DISCONNECT:
>               if ((so->so_state & SS_ISCONNECTED) == 0) {
>                       error = ENOTCONN;
> @@ -563,4 +544,26 @@ rip_usrreq(struct socket *so, int req, s
>  release:
>       m_freem(m);
>       return (error);
> +}
> +
> +int
> +rip_attach(struct socket *so, int proto)
> +{
> +     struct inpcb *inp;
> +     int error;
> +
> +     if (so->so_pcb)
> +             panic("rip_attach");
> +     if ((so->so_state & SS_PRIV) == 0)
> +             return EACCES;
> +     if (proto < 0 || proto >= IPPROTO_MAX)
> +             return EPROTONOSUPPORT;
> +
> +     if ((error = soreserve(so, rip_sendspace, rip_recvspace)) ||
> +         (error = in_pcballoc(so, &rawcbtable))) {
> +             return error;
> +     }
> +     inp = sotoinpcb(so);
> +     inp->inp_ip.ip_p = proto;
> +     return 0;
>  }
> Index: netinet/tcp_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
> retrieving revision 1.144
> diff -u -p -r1.144 tcp_usrreq.c
> --- netinet/tcp_usrreq.c      9 Feb 2017 15:19:32 -0000       1.144
> +++ netinet/tcp_usrreq.c      25 Feb 2017 18:51:02 -0000
> @@ -157,7 +157,7 @@ tcp_usrreq(struct socket *so, int req, s
>        * a (struct inpcb) pointed at by the socket, and this
>        * structure will point at a subsidiary (struct tcpcb).
>        */
> -     if (inp == NULL && req != PRU_ATTACH) {
> +     if (inp == NULL) {
>               error = so->so_error;
>               if (error == 0)
>                       error = EINVAL;
> @@ -184,23 +184,6 @@ tcp_usrreq(struct socket *so, int req, s
>       switch (req) {
>  
>       /*
> -      * TCP attaches to socket via PRU_ATTACH, reserving space,
> -      * and an internet control block.
> -      */
> -     case PRU_ATTACH:
> -             if (inp) {
> -                     error = EISCONN;
> -                     break;
> -             }
> -             error = tcp_attach(so);
> -             if (error)
> -                     break;
> -             if ((so->so_options & SO_LINGER) && so->so_linger == 0)
> -                     so->so_linger = TCP_LINGERTIME;
> -             tp = sototcpcb(so);
> -             break;
> -
> -     /*
>        * PRU_DETACH detaches the TCP protocol from the socket.
>        * If the protocol state is non-embryonic, then can't
>        * do this directly: have to initiate a PRU_DISCONNECT,
> @@ -608,12 +591,14 @@ tcp_ctloutput(int op, struct socket *so,
>   * bufer space, and entering LISTEN state if to accept connections.
>   */
>  int
> -tcp_attach(struct socket *so)
> +tcp_attach(struct socket *so, int proto)
>  {
>       struct tcpcb *tp;
>       struct inpcb *inp;
>       int error;
>  
> +     if (so->so_pcb)
> +             return EISCONN;
>       if (so->so_snd.sb_hiwat == 0 || so->so_rcv.sb_hiwat == 0 ||
>           sbcheckreserve(so->so_snd.sb_wat, tcp_sendspace) ||
>           sbcheckreserve(so->so_rcv.sb_wat, tcp_recvspace)) {
> @@ -645,6 +630,11 @@ tcp_attach(struct socket *so)
>  #else
>       tp->pf = PF_INET;
>  #endif
> +     if ((so->so_options & SO_LINGER) && so->so_linger == 0)
> +             so->so_linger = TCP_LINGERTIME;
> +
> +     if (tp && (so->so_options & SO_DEBUG))
> +             tcp_trace(TA_USER, 0, tp, (caddr_t)0, 0 /* XXX */, 0);
>       return (0);
>  }
>  
> Index: netinet/tcp_var.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/tcp_var.h,v
> retrieving revision 1.122
> diff -u -p -r1.122 tcp_var.h
> --- netinet/tcp_var.h 9 Feb 2017 15:19:32 -0000       1.122
> +++ netinet/tcp_var.h 25 Feb 2017 18:51:02 -0000
> @@ -716,7 +716,6 @@ extern    int tcp_syn_use_limit;   /* numbe
>  extern       struct syn_cache_set tcp_syn_cache[];
>  extern       int tcp_syn_cache_active; /* active syn cache, may be 0 or 1 */
>  
> -int   tcp_attach(struct socket *);
>  void  tcp_canceltimers(struct tcpcb *);
>  struct tcpcb *
>        tcp_close(struct tcpcb *);
> @@ -765,6 +764,7 @@ struct tcpcb *
>  int   tcp_sysctl(int *, u_int, void *, size_t *, void *, size_t);
>  int   tcp_usrreq(struct socket *,
>           int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
> +int   tcp_attach(struct socket *, int);
>  void  tcp_xmit_timer(struct tcpcb *, int);
>  void  tcpdropoldhalfopen(struct tcpcb *, u_int16_t);
>  #ifdef TCP_SACK
> Index: netinet/udp_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/udp_usrreq.c,v
> retrieving revision 1.231
> diff -u -p -r1.231 udp_usrreq.c
> --- netinet/udp_usrreq.c      5 Feb 2017 16:23:38 -0000       1.231
> +++ netinet/udp_usrreq.c      25 Feb 2017 18:51:02 -0000
> @@ -1115,7 +1115,7 @@ udp_usrreq(struct socket *so, int req, s
>       }
>  
>       inp = sotoinpcb(so);
> -     if (inp == NULL && req != PRU_ATTACH) {
> +     if (inp == NULL) {
>               error = EINVAL;
>               goto release;
>       }
> @@ -1126,22 +1126,6 @@ udp_usrreq(struct socket *so, int req, s
>        */
>       switch (req) {
>  
> -     case PRU_ATTACH:
> -             if (inp != NULL) {
> -                     error = EINVAL;
> -                     break;
> -             }
> -             if ((error = soreserve(so, udp_sendspace, udp_recvspace)) ||
> -                 (error = in_pcballoc(so, &udbtable)))
> -                     break;
> -#ifdef INET6
> -             if (sotoinpcb(so)->inp_flags & INP_IPV6)
> -                     sotoinpcb(so)->inp_ipv6.ip6_hlim = ip6_defhlim;
> -             else
> -#endif /* INET6 */
> -                     sotoinpcb(so)->inp_ip.ip_ttl = ip_defttl;
> -             break;
> -
>       case PRU_DETACH:
>               in_pcbdetach(inp);
>               break;
> @@ -1305,6 +1289,26 @@ release:
>       m_freem(control);
>       m_freem(m);
>       return (error);
> +}
> +
> +int
> +udp_attach(struct socket *so, int proto)
> +{
> +     int error;
> +
> +     if (so->so_pcb != NULL)
> +             return EINVAL;
> +
> +     if ((error = soreserve(so, udp_sendspace, udp_recvspace)) ||
> +         (error = in_pcballoc(so, &udbtable)))
> +             return error;
> +#ifdef INET6
> +     if (sotoinpcb(so)->inp_flags & INP_IPV6)
> +             sotoinpcb(so)->inp_ipv6.ip6_hlim = ip6_defhlim;
> +     else
> +#endif /* INET6 */
> +             sotoinpcb(so)->inp_ip.ip_ttl = ip_defttl;
> +     return 0;
>  }
>  
>  /*
> Index: netinet/udp_var.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet/udp_var.h,v
> retrieving revision 1.31
> diff -u -p -r1.31 udp_var.h
> --- netinet/udp_var.h 29 Jan 2017 19:58:47 -0000      1.31
> +++ netinet/udp_var.h 25 Feb 2017 18:51:02 -0000
> @@ -149,5 +149,6 @@ int        udp6_output(struct inpcb *, struct 
>  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);
>  #endif /* _KERNEL */
>  #endif /* _NETINET_UDP_VAR_H_ */
> Index: netinet6/in6_proto.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/in6_proto.c,v
> retrieving revision 1.90
> diff -u -p -r1.90 in6_proto.c
> --- netinet6/in6_proto.c      2 Mar 2017 08:58:24 -0000       1.90
> +++ netinet6/in6_proto.c      5 Mar 2017 09:23:04 -0000
> @@ -139,6 +139,7 @@ struct protosw inet6sw[] = {
>    .pr_ctlinput       = udp6_ctlinput,
>    .pr_ctloutput      = ip6_ctloutput,
>    .pr_usrreq = udp_usrreq,
> +  .pr_attach = udp_attach,
>    .pr_sysctl = udp_sysctl
>  },
>  {
> @@ -150,6 +151,7 @@ struct protosw inet6sw[] = {
>    .pr_ctlinput       = tcp6_ctlinput,
>    .pr_ctloutput      = tcp_ctloutput,
>    .pr_usrreq = tcp_usrreq,
> +  .pr_attach = tcp_attach,
>    .pr_sysctl = tcp_sysctl
>  },
>  {
> @@ -162,6 +164,7 @@ struct protosw inet6sw[] = {
>    .pr_ctlinput       = rip6_ctlinput,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
> +  .pr_attach = rip6_attach,
>    .pr_sysctl = rip6_sysctl
>  },
>  {
> @@ -174,6 +177,7 @@ struct protosw inet6sw[] = {
>    .pr_ctlinput       = rip6_ctlinput,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
> +  .pr_attach = rip6_attach,
>    .pr_init   = icmp6_init,
>    .pr_fasttimo       = icmp6_fasttimo,
>    .pr_sysctl = icmp6_sysctl
> @@ -209,6 +213,7 @@ struct protosw inet6sw[] = {
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
> +  .pr_attach = rip6_attach,
>    .pr_sysctl = ah_sysctl
>  },
>  {
> @@ -220,6 +225,7 @@ struct protosw inet6sw[] = {
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
> +  .pr_attach = rip6_attach,
>    .pr_sysctl = esp_sysctl
>  },
>  {
> @@ -231,6 +237,7 @@ struct protosw inet6sw[] = {
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
> +  .pr_attach = rip6_attach,
>    .pr_sysctl = ipcomp_sysctl
>  },
>  #endif /* IPSEC */
> @@ -244,6 +251,7 @@ struct protosw inet6sw[] = {
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
> +  .pr_attach = rip6_attach,
>    .pr_sysctl = etherip_sysctl
>  },
>  {
> @@ -254,7 +262,8 @@ struct protosw inet6sw[] = {
>    .pr_input  = in6_gif_input,
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
> -  .pr_usrreq = rip6_usrreq   /* XXX */
> +  .pr_usrreq = rip6_usrreq,  /* XXX */
> +  .pr_attach = rip6_attach
>  },
>  {
>    .pr_type   = SOCK_RAW,
> @@ -264,7 +273,8 @@ struct protosw inet6sw[] = {
>    .pr_input  = in6_gif_input,
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
> -  .pr_usrreq = rip6_usrreq   /* XXX */
> +  .pr_usrreq = rip6_usrreq,  /* XXX */
> +  .pr_attach = rip6_attach
>  },
>  #else /* NGIF */
>  {
> @@ -276,6 +286,7 @@ struct protosw inet6sw[] = {
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,  /* XXX */
> +  .pr_attach = rip6_attach,
>    .pr_sysctl = ipip_sysctl
>  },
>  {
> @@ -286,7 +297,8 @@ struct protosw inet6sw[] = {
>    .pr_input  = ip4_input,
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
> -  .pr_usrreq = rip6_usrreq   /* XXX */
> +  .pr_usrreq = rip6_usrreq,  /* XXX */
> +  .pr_attach = rip6_attach
>  },
>  #endif /* GIF */
>  #if NCARP > 0
> @@ -299,6 +311,7 @@ struct protosw inet6sw[] = {
>    .pr_output = rip6_output,
>    .pr_ctloutput = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
> +  .pr_attach = rip6_attach,
>    .pr_sysctl = carp_sysctl
>  },
>  #endif /* NCARP */
> @@ -310,6 +323,7 @@ struct protosw inet6sw[] = {
>    .pr_flags  = PR_ATOMIC|PR_ADDR,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = divert6_usrreq,
> +  .pr_attach = divert6_attach,
>    .pr_init   = divert6_init,
>    .pr_sysctl = divert6_sysctl
>  },
> @@ -324,6 +338,7 @@ struct protosw inet6sw[] = {
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
> +  .pr_attach = rip6_attach,
>    .pr_sysctl = ip_etherip_sysctl
>  },
>  #endif /* NETHERIP */
> @@ -336,6 +351,7 @@ struct protosw inet6sw[] = {
>    .pr_output = rip6_output,
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
> +  .pr_attach = rip6_attach,
>    .pr_init   = rip6_init
>  }
>  };
> Index: netinet6/ip6_divert.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/ip6_divert.c,v
> retrieving revision 1.45
> diff -u -p -r1.45 ip6_divert.c
> --- netinet6/ip6_divert.c     9 Feb 2017 15:32:56 -0000       1.45
> +++ netinet6/ip6_divert.c     26 Feb 2017 08:10:47 -0000
> @@ -250,31 +250,12 @@ divert6_usrreq(struct socket *so, int re
>               return (in6_control(so, (u_long)m, (caddr_t)addr,
>                   (struct ifnet *)control));
>       }
> -     if (inp == NULL && req != PRU_ATTACH) {
> +     if (inp == NULL) {
>               error = EINVAL;
>               goto release;
>       }
>       switch (req) {
>  
> -     case PRU_ATTACH:
> -             if (inp != NULL) {
> -                     error = EINVAL;
> -                     break;
> -             }
> -             if ((so->so_state & SS_PRIV) == 0) {
> -                     error = EACCES;
> -                     break;
> -             }
> -             error = in_pcballoc(so, &divb6table);
> -             if (error)
> -                     break;
> -
> -             error = soreserve(so, divert6_sendspace, divert6_recvspace);
> -             if (error)
> -                     break;
> -             sotoinpcb(so)->inp_flags |= INP_HDRINCL;
> -             break;
> -
>       case PRU_DETACH:
>               in_pcbdetach(inp);
>               break;
> @@ -331,6 +312,28 @@ release:
>       m_freem(control);
>       m_freem(m);
>       return (error);
> +}
> +
> +int
> +divert6_attach(struct socket *so, int proto)
> +{
> +     int error;
> +
> +     if (so->so_pcb != NULL)
> +             return EINVAL;
> +
> +     if ((so->so_state & SS_PRIV) == 0)
> +             return EACCES;
> +
> +     error = in_pcballoc(so, &divb6table);
> +     if (error)
> +             return (error);
> +
> +     error = soreserve(so, divert6_sendspace, divert6_recvspace);
> +     if (error)
> +             return (error);
> +     sotoinpcb(so)->inp_flags |= INP_HDRINCL;
> +     return (0);
>  }
>  
>  int
> Index: netinet6/ip6_divert.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/ip6_divert.h,v
> retrieving revision 1.6
> diff -u -p -r1.6 ip6_divert.h
> --- netinet6/ip6_divert.h     9 Feb 2017 15:32:56 -0000       1.6
> +++ netinet6/ip6_divert.h     25 Feb 2017 18:51:02 -0000
> @@ -78,6 +78,7 @@ int  divert6_packet(struct mbuf *, int, 
>  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);
>  #endif /* _KERNEL */
>  
>  #endif /* _IP6_DIVERT_H_ */
> Index: netinet6/ip6_var.h
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/ip6_var.h,v
> retrieving revision 1.70
> diff -u -p -r1.70 ip6_var.h
> --- netinet6/ip6_var.h        3 Mar 2017 15:48:02 -0000       1.70
> +++ netinet6/ip6_var.h        5 Mar 2017 09:25:55 -0000
> @@ -349,6 +349,7 @@ int       rip6_output(struct mbuf *, struct so
>           struct mbuf *);
>  int  rip6_usrreq(struct socket *,
>           int, struct mbuf *, struct mbuf *, struct mbuf *, struct proc *);
> +int  rip6_attach(struct socket *, int);
>  int  rip6_sysctl(int *, u_int, void *, size_t *, void *, size_t);
>  
>  int  dest6_input(struct mbuf **, int *, int);
> Index: netinet6/raw_ip6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v
> retrieving revision 1.107
> diff -u -p -r1.107 raw_ip6.c
> --- netinet6/raw_ip6.c        3 Mar 2017 15:48:02 -0000       1.107
> +++ netinet6/raw_ip6.c        5 Mar 2017 09:25:55 -0000
> @@ -556,48 +556,14 @@ rip6_usrreq(struct socket *so, int req, 
>  {
>       struct inpcb *in6p = sotoinpcb(so);
>       int error = 0;
> -     int priv;
>  
>       NET_ASSERT_LOCKED();
>  
> -     priv = 0;
> -     if ((so->so_state & SS_PRIV) != 0)
> -             priv++;
> -
>       if (req == PRU_CONTROL)
>               return (in6_control(so, (u_long)m, (caddr_t)nam,
>                   (struct ifnet *)control));
>  
>       switch (req) {
> -     case PRU_ATTACH:
> -             if (in6p)
> -                     panic("rip6_attach");
> -             if (!priv) {
> -                     error = EACCES;
> -                     break;
> -             }
> -             if ((long)nam < 0 || (long)nam >= IPPROTO_MAX) {
> -                     error = EPROTONOSUPPORT;
> -                     break;
> -             }
> -             if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)) ||
> -                 (error = in_pcballoc(so, &rawin6pcbtable))) {
> -                     break;
> -             }
> -             in6p = sotoinpcb(so);
> -             in6p->inp_ipv6.ip6_nxt = (long)nam;
> -             in6p->inp_cksum6 = -1;
> -
> -             in6p->inp_icmp6filt = malloc(sizeof(struct icmp6_filter),
> -                 M_PCB, M_NOWAIT);
> -             if (in6p->inp_icmp6filt == NULL) {
> -                     in_pcbdetach(in6p);
> -                     error = ENOMEM;
> -                     break;
> -             }
> -             ICMP6_FILTER_SETPASSALL(in6p->inp_icmp6filt);
> -             break;
> -
>       case PRU_DISCONNECT:
>               if ((so->so_state & SS_ISCONNECTED) == 0) {
>                       error = ENOTCONN;
> @@ -757,6 +723,37 @@ rip6_usrreq(struct socket *so, int req, 
>       }
>       m_freem(m);
>       return (error);
> +}
> +
> +int
> +rip6_attach(struct socket *so, int proto)
> +{
> +     struct inpcb *in6p;
> +     int error;
> +
> +     if (so->so_pcb)
> +             panic("rip6_attach");
> +     if ((so->so_state & SS_PRIV) == 0)
> +             return (EACCES);
> +     if (proto < 0 || proto >= IPPROTO_MAX)
> +             return EPROTONOSUPPORT;
> +
> +     if ((error = soreserve(so, rip6_sendspace, rip6_recvspace)) ||
> +         (error = in_pcballoc(so, &rawin6pcbtable)))
> +             return error;
> +
> +     in6p = sotoinpcb(so);
> +     in6p->inp_ipv6.ip6_nxt = proto;
> +     in6p->inp_cksum6 = -1;
> +
> +     in6p->inp_icmp6filt = malloc(sizeof(struct icmp6_filter),
> +         M_PCB, M_NOWAIT);
> +     if (in6p->inp_icmp6filt == NULL) {
> +             in_pcbdetach(in6p);
> +             return ENOMEM;
> +     }
> +     ICMP6_FILTER_SETPASSALL(in6p->inp_icmp6filt);
> +     return 0;
>  }
>  
>  int
> Index: sys/protosw.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/protosw.h,v
> retrieving revision 1.23
> diff -u -p -r1.23 protosw.h
> --- sys/protosw.h     3 Mar 2017 15:48:02 -0000       1.23
> +++ sys/protosw.h     5 Mar 2017 09:25:55 -0000
> @@ -83,6 +83,8 @@ struct protosw {
>       int     (*pr_usrreq)(struct socket *, int, struct mbuf *,
>                   struct mbuf *, struct mbuf *, struct proc *);
>  
> +     int     (*pr_attach)(struct socket *, int);
> +
>  /* utility hooks */
>       void    (*pr_init)(void);       /* initialization hook */
>       void    (*pr_fasttimo)(void);   /* fast timeout (200ms) */
> @@ -121,7 +123,6 @@ struct protosw {
>   * A non-zero return from usrreq gives an
>   * UNIX error number which should be passed to higher level software.
>   */
> -#define      PRU_ATTACH              0       /* attach protocol to up */
>  #define      PRU_DETACH              1       /* detach protocol from up */
>  #define      PRU_BIND                2       /* bind socket to address */
>  #define      PRU_LISTEN              3       /* listen for connection */
> @@ -149,7 +150,7 @@ struct protosw {
>  
>  #ifdef PRUREQUESTS
>  char *prurequests[] = {
> -     "ATTACH",       "DETACH",       "BIND",         "LISTEN",
> +     "",             "DETACH",       "BIND",         "LISTEN",
>       "CONNECT",      "ACCEPT",       "DISCONNECT",   "SHUTDOWN",
>       "RCVD",         "SEND",         "ABORT",        "CONTROL",
>       "SENSE",        "RCVOOB",       "SENDOOB",      "SOCKADDR",
> Index: sys/socketvar.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/socketvar.h,v
> retrieving revision 1.68
> diff -u -p -r1.68 socketvar.h
> --- sys/socketvar.h   14 Feb 2017 09:46:21 -0000      1.68
> +++ sys/socketvar.h   26 Feb 2017 08:05:05 -0000
> @@ -258,8 +258,6 @@ int       soo_poll(struct file *fp, int events
>  int  soo_kqfilter(struct file *fp, struct knote *kn);
>  int  soo_close(struct file *fp, struct proc *p);
>  int  soo_stat(struct file *, struct stat *, struct proc *);
> -int  uipc_usrreq(struct socket *, int , struct mbuf *,
> -                      struct mbuf *, struct mbuf *, struct proc *);
>  void sbappend(struct sockbuf *sb, struct mbuf *m);
>  void sbappendstream(struct sockbuf *sb, struct mbuf *m);
>  int  sbappendaddr(struct sockbuf *sb, struct sockaddr *asa,
> Index: sys/unpcb.h
> ===================================================================
> RCS file: /cvs/src/sys/sys/unpcb.h,v
> retrieving revision 1.14
> diff -u -p -r1.14 unpcb.h
> --- sys/unpcb.h       27 Jan 2017 20:31:42 -0000      1.14
> +++ sys/unpcb.h       26 Feb 2017 08:05:45 -0000
> @@ -91,7 +91,10 @@ struct fdpass {
>       int              flags;
>  };
>  
> -int  unp_attach(struct socket *);
> +int  uipc_usrreq(struct socket *, int , struct mbuf *,
> +                      struct mbuf *, struct mbuf *, struct proc *);
> +int  uipc_attach(struct socket *, int);
> +
>  int  unp_bind(struct unpcb *, struct mbuf *, struct proc *);
>  int  unp_connect(struct socket *, struct mbuf *, struct proc *);
>  int  unp_connect2(struct socket *, struct socket *);

Reply via email to