On 02/11/17(Thu) 09:06, Florian Obser wrote:
> this moves PRU_DETACH out of pr_usrreq into per proto pr_detach
> functions, like what claudio did to pr_attach.
> 
> Intentionally mostly mechanical. There might be some cleanup here and
> there in the functions themselves.

I like it, comments inline.

> diff --git kern/uipc_socket.c kern/uipc_socket.c
> index 615da029414..df08096a9ee 100644
> --- kern/uipc_socket.c
> +++ kern/uipc_socket.c
> @@ -266,8 +266,13 @@ soclose(struct socket *so)
>       }
>  drop:
>       if (so->so_pcb) {
> -             int error2 = (*so->so_proto->pr_usrreq)(so, PRU_DETACH, NULL,
> -                 NULL, NULL, curproc);
> +             int error2;
> +
> +             if (so->so_proto->pr_detach == NULL)
> +                     panic("soclose pr_detach == NULL: so %p, so_type %d",
> +                         so, so->so_type);

Since we're now enforcing the existence of pr_detach, a KASSERT() is
enough.

> +
> +             error2 = (*so->so_proto->pr_detach)(so);
>               if (error == 0)
>                       error = error2;
>       }
> diff --git kern/uipc_usrreq.c kern/uipc_usrreq.c
> index 07e032ca0a3..35871b7cf54 100644
> --- kern/uipc_usrreq.c
> +++ kern/uipc_usrreq.c
> @@ -126,10 +126,6 @@ uipc_usrreq(struct socket *so, int req, struct mbuf *m, 
> struct mbuf *nam,
>  
>       switch (req) {
>  
> -     case PRU_DETACH:
> -             unp_detach(unp);
> -             break;
> -
>       case PRU_BIND:
>               error = unp_bind(unp, nam, p);
>               break;
> @@ -378,6 +374,21 @@ uipc_attach(struct socket *so, int proto)
>       return (0);
>  }
>  
> +int
> +uipc_detach(struct socket *so)
> +{
> +     struct unpcb *unp = sotounpcb(so);
> +
> +     if (unp == NULL)
> +             return (EINVAL);
> +
> +     NET_ASSERT_UNLOCKED();
> +
> +     unp_detach(unp);
> +
> +     return (0);
> +}
> +
>  void
>  unp_detach(struct unpcb *unp)
>  {
> diff --git net/pfkeyv2.c net/pfkeyv2.c
> index ac593e4d5f1..f52ec9d3692 100644
> --- net/pfkeyv2.c
> +++ net/pfkeyv2.c
> @@ -159,7 +159,7 @@ static int npromisc = 0;
>  void pfkey_init(void);
>  
>  int pfkeyv2_attach(struct socket *, int);
> -int pfkeyv2_detach(struct socket *, struct proc *);
> +int pfkeyv2_detach(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 *,
> @@ -192,6 +192,7 @@ static struct protosw pfkeysw[] = {
>    .pr_output    = pfkeyv2_output,
>    .pr_usrreq    = pfkeyv2_usrreq,
>    .pr_attach    = pfkeyv2_attach,
> +  .pr_detach    = pfkeyv2_detach,
>    .pr_sysctl    = pfkeyv2_sysctl,
>  }
>  };
> @@ -255,7 +256,7 @@ pfkeyv2_attach(struct socket *so, int proto)
>   * Close a PF_KEYv2 socket.
>   */
>  int
> -pfkeyv2_detach(struct socket *so, struct proc *p)
> +pfkeyv2_detach(struct socket *so)
>  {
>       struct keycb *kp;
>  
> @@ -276,7 +277,7 @@ pfkeyv2_detach(struct socket *so, struct proc *p)
>               mtx_leave(&pfkeyv2_mtx);
>       }
>  
> -     raw_detach(&kp->rcb);
> +     raw_do_detach(&kp->rcb);

Claudio suggested merging the content of the raw functions in pfkey and
rtsock.  It doesn't make much sense to keep a function for calling
sofree().  So I'd get rid of raw_detach() and inline it here.

A next step could be to get rid of net/raw_cb.c

>       return (0);
>  }
>  
> @@ -284,12 +285,7 @@ int
>  pfkeyv2_usrreq(struct socket *so, int req, struct mbuf *mbuf,
>      struct mbuf *nam, struct mbuf *control, struct proc *p)
>  {
> -     switch (req) {
> -     case PRU_DETACH:
> -             return (pfkeyv2_detach(so, p));
> -     default:
> -             return (raw_usrreq(so, req, mbuf, nam, control, p));
> -     }
> +     return (raw_usrreq(so, req, mbuf, nam, control, p));
>  }
>  
>  int
> diff --git net/raw_cb.c net/raw_cb.c
> index e77da50b039..55c3fd21d2f 100644
> --- net/raw_cb.c
> +++ net/raw_cb.c
> @@ -76,12 +76,27 @@ raw_attach(struct socket *so, int proto)
>       return (0);
>  }
>  
> +int
> +raw_detach(struct socket *so)
> +{
> +     struct rawcb *rp = sotorawcb(so);
> +
> +     soassertlocked(so);
> +
> +     if (rp == NULL)
> +             return (EINVAL);
> +
> +     raw_do_detach(rp);
> +
> +     return (0);
> +}
> +
>  /*
>   * Detach the raw connection block and discard
>   * socket resources.
>   */
>  void
> -raw_detach(struct rawcb *rp)
> +raw_do_detach(struct rawcb *rp)
>  {
>       struct socket *so = rp->rcb_socket;
>  
> @@ -97,5 +112,5 @@ void
>  raw_disconnect(struct rawcb *rp)
>  {
>       if (rp->rcb_socket->so_state & SS_NOFDREF)
> -             raw_detach(rp);
> +             raw_do_detach(rp);
>  }
> diff --git net/raw_cb.h net/raw_cb.h
> index 00c3d30f98a..a3e964d807f 100644
> --- net/raw_cb.h
> +++ net/raw_cb.h
> @@ -56,7 +56,8 @@ struct rawcb {
>  
>  #define      sotorawcb(so)           ((struct rawcb *)(so)->so_pcb)
>  int   raw_attach(struct socket *, int);
> -void  raw_detach(struct rawcb *);
> +int   raw_detach(struct socket *);
> +void  raw_do_detach(struct rawcb *);
>  void  raw_disconnect(struct rawcb *);
>  void  raw_init(void);
>  int   raw_usrreq(struct socket *,
> diff --git net/raw_usrreq.c net/raw_usrreq.c
> index d72f242c892..0300ab65e1b 100644
> --- net/raw_usrreq.c
> +++ net/raw_usrreq.c
> @@ -67,14 +67,6 @@ raw_usrreq(struct socket *so, int req, struct mbuf *m, 
> struct mbuf *nam,
>               return (EINVAL);
>       }
>       switch (req) {
> -     /*
> -      * Destroy state just before socket deallocation.
> -      * Flush data or not depending on the options.
> -      */
> -     case PRU_DETACH:
> -             raw_detach(rp);
> -             break;
> -
>       case PRU_CONNECT:
>       case PRU_BIND:
>       case PRU_CONNECT2:
> diff --git net/rtsock.c net/rtsock.c
> index dc77a2411b3..08cef9d14a8 100644
> --- net/rtsock.c
> +++ net/rtsock.c
> @@ -174,7 +174,6 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, 
> struct mbuf *nam,
>      struct mbuf *control, struct proc *p)
>  {
>       struct routecb  *rop;
> -     int              af;
>       int              error = 0;
>  
>       soassertlocked(so);
> @@ -198,20 +197,6 @@ route_usrreq(struct socket *so, int req, struct mbuf *m, 
> struct mbuf *nam,
>                       rop->flags &= ~ROUTECB_FLAG_FLUSH;
>               break;
>  
> -     case PRU_DETACH:
> -             timeout_del(&rop->timeout);
> -             af = rop->rcb.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
> -             route_cb.any_count--;
> -             LIST_REMOVE(rop, rcb_list);
> -             /* FALLTHROUGH */
>       default:
>               error = raw_usrreq(so, req, m, nam, control, p);
>       }
> @@ -270,6 +255,33 @@ route_attach(struct socket *so, int proto)
>       return (0);
>  }
>  
> +int
> +route_detach(struct socket *so)
> +{
> +     struct routecb  *rop;
> +     int              af;
> +
> +     soassertlocked(so);
> +
> +     rop = sotoroutecb(so);
> +     if (rop == NULL)
> +             return (EINVAL);
> +
> +     timeout_del(&rop->timeout);
> +     af = rop->rcb.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
> +     route_cb.any_count--;
> +     LIST_REMOVE(rop, rcb_list);
> +     return (raw_detach(so));
> +}
> +
>  int
>  route_ctloutput(int op, struct socket *so, int level, int optname,
>      struct mbuf *m)
> @@ -1922,6 +1934,7 @@ struct protosw routesw[] = {
>    .pr_ctloutput      = route_ctloutput,
>    .pr_usrreq = route_usrreq,
>    .pr_attach = route_attach,
> +  .pr_detach = route_detach,
>    .pr_init   = route_prinit,
>    .pr_sysctl = sysctl_rtable
>  }
> diff --git netinet/in_proto.c netinet/in_proto.c
> index 2c3dbec3ed2..3a006cefcc7 100644
> --- netinet/in_proto.c
> +++ netinet/in_proto.c
> @@ -192,6 +192,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = ip_ctloutput,
>    .pr_usrreq = udp_usrreq,
>    .pr_attach = udp_attach,
> +  .pr_detach = udp_detach,
>    .pr_init   = udp_init,
>    .pr_sysctl = udp_sysctl
>  },
> @@ -205,6 +206,7 @@ struct protosw inetsw[] = {
>    .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
> @@ -217,7 +219,8 @@ struct protosw inetsw[] = {
>    .pr_input  = rip_input,
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
> -  .pr_attach = rip_attach
> +  .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>  },
>  {
>    .pr_type   = SOCK_RAW,
> @@ -228,6 +231,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_init   = icmp_init,
>    .pr_sysctl = icmp_sysctl
>  },
> @@ -244,6 +248,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = ipip_sysctl,
>    .pr_init   = ipip_init
>  },
> @@ -260,7 +265,8 @@ struct protosw inetsw[] = {
>  #endif
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq, /* XXX */
> -  .pr_attach = rip_attach
> +  .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>  },
>  #endif
>  #if NGIF > 0
> @@ -273,6 +279,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = etherip_sysctl
>  },
>  #endif /* NGIF */
> @@ -284,7 +291,8 @@ struct protosw inetsw[] = {
>    .pr_flags  = PR_ATOMIC|PR_ADDR,
>    .pr_input  = etherip_input,
>    .pr_usrreq = rip_usrreq,
> -  .pr_attach = rip_attach
> +  .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>  },
>  #endif /* MPLS && GIF */
>  {
> @@ -296,6 +304,7 @@ struct protosw inetsw[] = {
>    .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,
> @@ -312,6 +321,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = ah_sysctl
>  },
>  {
> @@ -324,6 +334,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = esp_sysctl
>  },
>  {
> @@ -335,6 +346,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = ipcomp_sysctl
>  },
>  #endif /* IPSEC */
> @@ -348,6 +360,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = gre_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = gre_sysctl
>  },
>  {
> @@ -359,6 +372,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = ipmobile_sysctl
>  },
>  #endif /* NGRE > 0 */
> @@ -372,6 +386,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = carp_sysctl
>  },
>  #endif /* NCARP > 0 */
> @@ -385,6 +400,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = pfsync_sysctl
>  },
>  #endif /* NPFSYNC > 0 */
> @@ -397,6 +413,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = divert_usrreq,
>    .pr_attach = divert_attach,
> +  .pr_detach = divert_detach,
>    .pr_init   = divert_init,
>    .pr_sysctl = divert_sysctl
>  },
> @@ -411,6 +428,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_sysctl = ip_etherip_sysctl
>  },
>  #endif /* NETHERIP */
> @@ -423,6 +441,7 @@ struct protosw inetsw[] = {
>    .pr_ctloutput      = rip_ctloutput,
>    .pr_usrreq = rip_usrreq,
>    .pr_attach = rip_attach,
> +  .pr_detach = rip_detach,
>    .pr_init   = rip_init
>  }
>  };
> diff --git netinet/ip_divert.c netinet/ip_divert.c
> index 6f1bc3e55ee..5ecd8c6189b 100644
> --- netinet/ip_divert.c
> +++ netinet/ip_divert.c
> @@ -254,10 +254,6 @@ divert_usrreq(struct socket *so, int req, struct mbuf 
> *m, struct mbuf *addr,
>       }
>       switch (req) {
>  
> -     case PRU_DETACH:
> -             in_pcbdetach(inp);
> -             break;
> -
>       case PRU_BIND:
>               error = in_pcbbind(inp, addr, p);
>               break;
> @@ -334,6 +330,20 @@ divert_attach(struct socket *so, int proto)
>       return (0);
>  }
>  
> +int
> +divert_detach(struct socket *so)
> +{
> +     struct inpcb *inp = sotoinpcb(so);
> +
> +     soassertlocked(so);
> +
> +     if (inp == NULL)
> +             return (EINVAL);
> +
> +     in_pcbdetach(inp);
> +     return (0);
> +}
> +
>  int
>  divert_sysctl_divstat(void *oldp, size_t *oldlenp, void *newp)
>  {
> diff --git netinet/ip_divert.h netinet/ip_divert.h
> index 31cdc0c09f8..2912921f30d 100644
> --- netinet/ip_divert.h
> +++ netinet/ip_divert.h
> @@ -78,6 +78,6 @@ 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 *);
>  #endif /* _KERNEL */
>  #endif /* _IP_DIVERT_H_ */
> diff --git netinet/ip_var.h netinet/ip_var.h
> index 23f824b5ed6..9fe65aad3f4 100644
> --- netinet/ip_var.h
> +++ netinet/ip_var.h
> @@ -253,7 +253,7 @@ int        rip_output(struct mbuf *, struct socket *, 
> struct sockaddr *,
>  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 *);
>  #ifdef MROUTING
>  extern struct socket *ip_mrouter[];  /* multicast routing daemon */
>  #endif
> diff --git netinet/raw_ip.c netinet/raw_ip.c
> index 3e4af999eea..8e815964705 100644
> --- netinet/raw_ip.c
> +++ netinet/raw_ip.c
> @@ -382,10 +382,8 @@ rip_usrreq(struct socket *so, int req, struct mbuf *m, 
> struct mbuf *nam,
>               /* FALLTHROUGH */
>       case PRU_ABORT:
>               soisdisconnected(so);
> -             /* FALLTHROUGH */
> -     case PRU_DETACH:
>               if (inp == NULL)
> -                     panic("rip_detach");
> +                     panic("rip_abort");
>  #ifdef MROUTING
>               if (so == ip_mrouter[inp->inp_rtableid])
>                       ip_mrouter_done(so);
> @@ -522,3 +520,22 @@ rip_attach(struct socket *so, int proto)
>       inp->inp_ip.ip_p = proto;
>       return 0;
>  }
> +
> +int
> +rip_detach(struct socket *so)
> +{
> +     struct inpcb *inp = sotoinpcb(so);
> +
> +     soassertlocked(so);
> +
> +     if (inp == NULL)
> +             return (EINVAL);
> +
> +#ifdef MROUTING
> +     if (so == ip_mrouter[inp->inp_rtableid])
> +             ip_mrouter_done(so);
> +#endif
> +     in_pcbdetach(inp);
> +
> +     return (0);
> +}
> diff --git netinet/tcp_usrreq.c netinet/tcp_usrreq.c
> index b4333507447..61ea6cdc6d5 100644
> --- netinet/tcp_usrreq.c
> +++ netinet/tcp_usrreq.c
> @@ -181,17 +181,6 @@ tcp_usrreq(struct socket *so, int req, struct mbuf *m, 
> struct mbuf *nam,
>               ostate = 0;
>       switch (req) {
>  
> -     /*
> -      * 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,
> -      * which may finish later; embryonic TCB's can just
> -      * be discarded here.
> -      */
> -     case PRU_DETACH:
> -             tp = tcp_disconnect(tp);
> -             break;
> -
>       /*
>        * Give the socket an address.
>        */
> @@ -618,6 +607,54 @@ tcp_attach(struct socket *so, int proto)
>       return (0);
>  }
>  
> +int
> +tcp_detach(struct socket *so)
> +{
> +     struct inpcb *inp;
> +     struct tcpcb *tp = NULL;
> +     int error = 0;
> +     short ostate;
> +
> +     soassertlocked(so);
> +
> +     inp = sotoinpcb(so);
> +     /*
> +      * When a TCP is attached to a socket, then there will be
> +      * a (struct inpcb) pointed at by the socket, and this
> +      * structure will point at a subsidiary (struct tcpcb).
> +      */
> +     if (inp == NULL) {
> +             error = so->so_error;
> +             if (error == 0)
> +                     error = EINVAL;
> +
> +             return (error);
> +     }
> +     if (inp) {
> +             tp = intotcpcb(inp);
> +             /* tp might get 0 when using socket splicing */
> +             if (tp == NULL) {
> +                     return (0);
> +             }
> +#ifdef KPROF
> +             tcp_acounts[tp->t_state][req]++;
> +#endif
> +             ostate = tp->t_state;
> +     } else
> +             ostate = 0;
> +
> +     /*
> +      * Detache 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,
> +      * which may finish later; embryonic TCB's can just
> +      * be discarded here.
> +      */
> +     tcp_disconnect(tp);
> +
> +     return (error);
> +}
> +
>  /*
>   * Initiate (or continue) disconnect.
>   * If embryonic state, just send reset (once).
> diff --git netinet/tcp_var.h netinet/tcp_var.h
> index 54e8aecc262..f2f398fc61c 100644
> --- netinet/tcp_var.h
> +++ netinet/tcp_var.h
> @@ -751,6 +751,7 @@ 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);
> +int   tcp_detach(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);
> diff --git netinet/udp_usrreq.c netinet/udp_usrreq.c
> index 95b093bee58..a5c4b52896b 100644
> --- netinet/udp_usrreq.c
> +++ netinet/udp_usrreq.c
> @@ -1085,10 +1085,6 @@ udp_usrreq(struct socket *so, int req, struct mbuf *m, 
> struct mbuf *addr,
>        */
>       switch (req) {
>  
> -     case PRU_DETACH:
> -             in_pcbdetach(inp);
> -             break;
> -
>       case PRU_BIND:
>               error = in_pcbbind(inp, addr, p);
>               break;
> @@ -1270,6 +1266,22 @@ udp_attach(struct socket *so, int proto)
>       return 0;
>  }
>  
> +int
> +udp_detach(struct socket *so)
> +{
> +     struct inpcb *inp;
> +
> +     soassertlocked(so);
> +
> +
^
Extra line.

> +     inp = sotoinpcb(so);
> +     if (inp == NULL)
> +             return (EINVAL);
> +
> +     in_pcbdetach(inp);
> +     return (0);
> +}
> +
>  /*
>   * Sysctl for udp variables.
>   */
> diff --git netinet/udp_var.h netinet/udp_var.h
> index 7a511e7b05b..ba405d30b20 100644
> --- netinet/udp_var.h
> +++ netinet/udp_var.h
> @@ -150,5 +150,6 @@ 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 *);
>  #endif /* _KERNEL */
>  #endif /* _NETINET_UDP_VAR_H_ */
> diff --git netinet6/in6_proto.c netinet6/in6_proto.c
> index 2a653e0286e..3cc11abbb7b 100644
> --- netinet6/in6_proto.c
> +++ netinet6/in6_proto.c
> @@ -140,6 +140,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = ip6_ctloutput,
>    .pr_usrreq = udp_usrreq,
>    .pr_attach = udp_attach,
> +  .pr_detach = udp_detach,
>    .pr_sysctl = udp_sysctl
>  },
>  {
> @@ -152,6 +153,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = tcp_ctloutput,
>    .pr_usrreq = tcp_usrreq,
>    .pr_attach = tcp_attach,
> +  .pr_detach = tcp_detach,
>    .pr_sysctl = tcp_sysctl
>  },
>  {
> @@ -164,6 +166,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
>    .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>    .pr_sysctl = rip6_sysctl
>  },
>  {
> @@ -176,6 +179,7 @@ struct protosw inet6sw[] = {
>    .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
> @@ -211,6 +215,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
>    .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>    .pr_sysctl = ah_sysctl
>  },
>  {
> @@ -222,6 +227,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
>    .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>    .pr_sysctl = esp_sysctl
>  },
>  {
> @@ -233,6 +239,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
>    .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>    .pr_sysctl = ipcomp_sysctl
>  },
>  #endif /* IPSEC */
> @@ -248,7 +255,8 @@ struct protosw inet6sw[] = {
>  #endif
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,  /* XXX */
> -  .pr_attach = rip6_attach
> +  .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>  },
>  {
>    .pr_type   = SOCK_RAW,
> @@ -263,6 +271,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,  /* XXX */
>    .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>  },
>  #if NGIF > 0
>  {
> @@ -274,6 +283,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
>    .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>    .pr_sysctl = etherip_sysctl
>  },
>  #endif /* NGIF */
> @@ -287,6 +297,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
>    .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>    .pr_sysctl = carp_sysctl
>  },
>  #endif /* NCARP */
> @@ -299,6 +310,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = divert6_usrreq,
>    .pr_attach = divert6_attach,
> +  .pr_detach = divert6_detach,
>    .pr_init   = divert6_init,
>    .pr_sysctl = divert6_sysctl
>  },
> @@ -313,6 +325,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
>    .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>    .pr_sysctl = ip_etherip_sysctl
>  },
>  #endif /* NETHERIP */
> @@ -325,6 +338,7 @@ struct protosw inet6sw[] = {
>    .pr_ctloutput      = rip6_ctloutput,
>    .pr_usrreq = rip6_usrreq,
>    .pr_attach = rip6_attach,
> +  .pr_detach = rip6_detach,
>    .pr_init   = rip6_init
>  }
>  };
> diff --git netinet6/ip6_divert.c netinet6/ip6_divert.c
> index 1f20dc64d83..c8b91c3298e 100644
> --- netinet6/ip6_divert.c
> +++ netinet6/ip6_divert.c
> @@ -257,10 +257,6 @@ divert6_usrreq(struct socket *so, int req, struct mbuf 
> *m, struct mbuf *addr,
>       }
>       switch (req) {
>  
> -     case PRU_DETACH:
> -             in_pcbdetach(inp);
> -             break;
> -
>       case PRU_BIND:
>               error = in_pcbbind(inp, addr, p);
>               break;
> @@ -337,6 +333,21 @@ divert6_attach(struct socket *so, int proto)
>       return (0);
>  }
>  
> +int
> +divert6_detach(struct socket *so)
> +{
> +     struct inpcb *inp = sotoinpcb(so);
> +
> +     soassertlocked(so);
> +
> +     if (inp == NULL)
> +             return (EINVAL);
> +
> +     in_pcbdetach(inp);
> +
> +     return (0);
> +}
> +
>  int
>  divert6_sysctl_div6stat(void *oldp, size_t *oldlenp, void *newp)
>  {
> diff --git netinet6/ip6_divert.h netinet6/ip6_divert.h
> index bbda15b4061..4e8daaca779 100644
> --- netinet6/ip6_divert.h
> +++ netinet6/ip6_divert.h
> @@ -78,6 +78,7 @@ 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 *);
>  #endif /* _KERNEL */
>  
>  #endif /* _IP6_DIVERT_H_ */
> diff --git netinet6/ip6_var.h netinet6/ip6_var.h
> index da11f5a1ee5..216392c6660 100644
> --- netinet6/ip6_var.h
> +++ netinet6/ip6_var.h
> @@ -345,6 +345,7 @@ int       rip6_output(struct mbuf *, struct socket *, 
> struct sockaddr *,
>  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_sysctl(int *, u_int, void *, size_t *, void *, size_t);
>  
>  int  dest6_input(struct mbuf **, int *, int, int);
> diff --git netinet6/raw_ip6.c netinet6/raw_ip6.c
> index c201852c69e..507d65539d0 100644
> --- netinet6/raw_ip6.c
> +++ netinet6/raw_ip6.c
> @@ -558,8 +558,6 @@ rip6_usrreq(struct socket *so, int req, struct mbuf *m, 
> struct mbuf *nam,
>  
>       case PRU_ABORT:
>               soisdisconnected(so);
> -             /* FALLTHROUGH */
> -     case PRU_DETACH:
>               if (in6p == NULL)
>                       panic("rip6_detach");
>  #ifdef MROUTING
> @@ -715,6 +713,27 @@ rip6_attach(struct socket *so, int proto)
>       return 0;
>  }
>  
> +int
> +rip6_detach(struct socket *so)
> +{
> +     struct inpcb *in6p = sotoinpcb(so);
> +
> +     soassertlocked(so);
> +
> +     if (in6p == NULL)
> +             panic("rip6_detach");

This should really be turned into an EINVAL like the others routine,
it's a different issue.

> +#ifdef MROUTING
> +     if (so == ip6_mrouter[in6p->inp_rtableid])
> +             ip6_mrouter_done(so);
> +#endif
> +     free(in6p->inp_icmp6filt, M_PCB, sizeof(struct icmp6_filter));
> +     in6p->inp_icmp6filt = NULL;
> +
> +     in_pcbdetach(in6p);
> +
> +     return (0);
> +}
> +
>  int
>  rip6_sysctl_rip6stat(void *oldp, size_t *oldplen, void *newp)
>  {
> diff --git sys/protosw.h sys/protosw.h
> index ccb2e004c22..e525f8b3f93 100644
> --- sys/protosw.h
> +++ sys/protosw.h
> @@ -84,6 +84,7 @@ struct protosw {
>                   struct mbuf *, struct mbuf *, struct proc *);
>  
>       int     (*pr_attach)(struct socket *, int);
> +     int     (*pr_detach)(struct socket *);
>  
>  /* utility hooks */
>       void    (*pr_init)(void);       /* initialization hook */
> @@ -123,7 +124,6 @@ struct protosw {
>   * A non-zero return from usrreq gives an
>   * UNIX error number which should be passed to higher level software.
>   */
> -#define      PRU_DETACH              1       /* detach protocol from up */
>  #define      PRU_BIND                2       /* bind socket to address */
>  #define      PRU_LISTEN              3       /* listen for connection */
>  #define      PRU_CONNECT             4       /* establish connection to peer 
> */
> diff --git sys/unpcb.h sys/unpcb.h
> index cae4f5af505..1733dea26ef 100644
> --- sys/unpcb.h
> +++ sys/unpcb.h
> @@ -94,6 +94,7 @@ struct fdpass {
>  int  uipc_usrreq(struct socket *, int , struct mbuf *,
>                        struct mbuf *, struct mbuf *, struct proc *);
>  int  uipc_attach(struct socket *, int);
> +int  uipc_detach(struct socket *);
>  
>  int  unp_bind(struct unpcb *, struct mbuf *, struct proc *);
>  int  unp_connect(struct socket *, struct mbuf *, struct proc *);
> 
> 
> -- 
> I'm not entirely sure you are real.
> 

Reply via email to