On 02/02/17(Thu) 12:12, David Hill wrote:
> On Thu, Feb 02, 2017 at 09:34:07AM +0100, Martin Pieuchot wrote:
> > On 01/02/17(Wed) 19:27, David Hill wrote:
> > > Hello -
> > >
> > > This diff makes sosetopt responsible for m_free which is much simpler.
> > > Requested by bluhm@
> >
> > I'd suggest to move the m_free(9) calls to sys_setsockopt(). This
> > simplifies the existing code even more and will make it easier to use
> > the stack for this temporary storage.
> >
>
> New diff with mpi@'s suggestion.
You forgot NFS and BFD that should now call m_free(9) after sosetopt(9).
> Index: kern/uipc_socket.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_socket.c,v
> retrieving revision 1.176
> diff -u -p -r1.176 uipc_socket.c
> --- kern/uipc_socket.c 1 Feb 2017 20:59:47 -0000 1.176
> +++ kern/uipc_socket.c 2 Feb 2017 16:59:45 -0000
> @@ -1551,16 +1551,15 @@ sowwakeup(struct socket *so)
> }
>
> int
> -sosetopt(struct socket *so, int level, int optname, struct mbuf *m0)
> +sosetopt(struct socket *so, int level, int optname, struct mbuf *m)
> {
> int s, error = 0;
> - struct mbuf *m = m0;
>
> if (level != SOL_SOCKET) {
> if (so->so_proto && so->so_proto->pr_ctloutput) {
> NET_LOCK(s);
> error = (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
> - level, optname, m0);
> + level, optname, m);
> NET_UNLOCK(s);
> return (error);
> }
> @@ -1707,7 +1706,7 @@ sosetopt(struct socket *so, int level, i
> level = dom->dom_protosw->pr_protocol;
> NET_LOCK(s);
> error = (*so->so_proto->pr_ctloutput)
> - (PRCO_SETOPT, so, level, optname, m0);
> + (PRCO_SETOPT, so, level, optname, m);
> NET_UNLOCK(s);
> return (error);
> }
> @@ -1739,14 +1738,11 @@ sosetopt(struct socket *so, int level, i
> if (error == 0 && so->so_proto && so->so_proto->pr_ctloutput) {
> NET_LOCK(s);
> (*so->so_proto->pr_ctloutput)(PRCO_SETOPT, so,
> - level, optname, m0);
> + level, optname, m);
> NET_UNLOCK(s);
> - m = NULL; /* freed by protocol */
> }
> }
> bad:
> - if (m)
> - (void) m_free(m);
> return (error);
> }
>
> Index: kern/uipc_syscalls.c
> ===================================================================
> RCS file: /cvs/src/sys/kern/uipc_syscalls.c,v
> retrieving revision 1.148
> diff -u -p -r1.148 uipc_syscalls.c
> --- kern/uipc_syscalls.c 26 Jan 2017 01:58:00 -0000 1.148
> +++ kern/uipc_syscalls.c 2 Feb 2017 16:59:45 -0000
> @@ -962,19 +962,13 @@ sys_setsockopt(struct proc *p, void *v,
> goto bad;
> }
> }
> - if (m == NULL) {
> - error = ENOBUFS;
> - goto bad;
> - }
> error = copyin(SCARG(uap, val), mtod(m, caddr_t),
> SCARG(uap, valsize));
> - if (error) {
> + if (error)
> goto bad;
> - }
> m->m_len = SCARG(uap, valsize);
> }
> error = sosetopt(fp->f_data, SCARG(uap, level), SCARG(uap, name), m);
> - m = NULL;
> bad:
> m_freem(m);
> FRELE(fp, p);
> Index: net/rtsock.c
> ===================================================================
> RCS file: /cvs/src/sys/net/rtsock.c,v
> retrieving revision 1.222
> diff -u -p -r1.222 rtsock.c
> --- net/rtsock.c 1 Feb 2017 20:59:47 -0000 1.222
> +++ net/rtsock.c 2 Feb 2017 16:59:45 -0000
> @@ -240,12 +240,8 @@ route_ctloutput(int op, struct socket *s
> int error = 0;
> unsigned int tid;
>
> - if (level != AF_ROUTE) {
> - error = EINVAL;
> - if (op == PRCO_SETOPT && m)
> - m_free(m);
> - return (error);
> - }
> + if (level != AF_ROUTE)
> + return EINVAL;
>
> switch (op) {
> case PRCO_SETOPT:
> @@ -271,7 +267,6 @@ route_ctloutput(int op, struct socket *s
> error = ENOPROTOOPT;
> break;
> }
> - m_free(m);
> break;
> case PRCO_GETOPT:
> switch (optname) {
> Index: netinet/ip_mroute.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_mroute.c,v
> retrieving revision 1.108
> diff -u -p -r1.108 ip_mroute.c
> --- netinet/ip_mroute.c 1 Feb 2017 20:59:47 -0000 1.108
> +++ netinet/ip_mroute.c 2 Feb 2017 16:59:46 -0000
> @@ -209,7 +209,6 @@ ip_mrouter_set(struct socket *so, int op
> break;
> }
>
> - m_free(m);
> return (error);
> }
>
> Index: netinet/ip_output.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/ip_output.c,v
> retrieving revision 1.335
> diff -u -p -r1.335 ip_output.c
> --- netinet/ip_output.c 1 Feb 2017 20:59:47 -0000 1.335
> +++ netinet/ip_output.c 2 Feb 2017 16:59:46 -0000
> @@ -853,11 +853,10 @@ ip_ctloutput(int op, struct socket *so,
> int error = 0;
> u_int rtid = 0;
>
> - if (level != IPPROTO_IP) {
> - error = EINVAL;
> - if (op == PRCO_SETOPT)
> - (void) m_free(m);
> - } else switch (op) {
> + if (level != IPPROTO_IP)
> + return EINVAL;
> +
> + switch (op) {
> case PRCO_SETOPT:
> switch (optname) {
> case IP_OPTIONS:
> @@ -1073,7 +1072,6 @@ ip_ctloutput(int op, struct socket *so,
> error = ENOPROTOOPT;
> break;
> }
> - m_free(m);
> break;
>
> case PRCO_GETOPT:
> @@ -1235,12 +1233,11 @@ ip_pcbopts(struct mbuf **pcbopt, struct
>
> /* turn off any old options */
> m_free(*pcbopt);
> - *pcbopt = 0;
> + *pcbopt = NULL;
> if (m == NULL || m->m_len == 0) {
> /*
> * Only turning off any previous options.
> */
> - m_free(m);
> return (0);
> }
>
> @@ -1316,7 +1313,6 @@ ip_pcbopts(struct mbuf **pcbopt, struct
> return (0);
>
> bad:
> - (void)m_free(m);
> return (EINVAL);
> }
>
> Index: netinet/raw_ip.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/raw_ip.c,v
> retrieving revision 1.95
> diff -u -p -r1.95 raw_ip.c
> --- netinet/raw_ip.c 1 Feb 2017 20:59:47 -0000 1.95
> +++ netinet/raw_ip.c 2 Feb 2017 16:59:46 -0000
> @@ -305,11 +305,8 @@ rip_ctloutput(int op, struct socket *so,
> int error = 0;
> int dir;
>
> - if (level != IPPROTO_IP) {
> - if (op == PRCO_SETOPT)
> - (void) m_free(m);
> - return (EINVAL);
> - }
> + if (level != IPPROTO_IP)
> + return EINVAL;
>
> switch (optname) {
>
> @@ -322,7 +319,6 @@ rip_ctloutput(int op, struct socket *so,
> inp->inp_flags |= INP_HDRINCL;
> else
> inp->inp_flags &= ~INP_HDRINCL;
> - m_free(m);
> } else {
> m->m_len = sizeof(int);
> *mtod(m, int *) = inp->inp_flags & INP_HDRINCL;
> @@ -344,7 +340,6 @@ rip_ctloutput(int op, struct socket *so,
> inp->inp_divertfl = dir;
> else
> error = EINVAL;
> -
> break;
>
> case PRCO_GETOPT:
> @@ -357,8 +352,6 @@ rip_ctloutput(int op, struct socket *so,
> break;
> }
>
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
> return (error);
>
> case MRT_INIT:
> @@ -385,8 +378,6 @@ rip_ctloutput(int op, struct socket *so,
> }
> return (error);
> #else
> - if (op == PRCO_SETOPT)
> - m_free(m);
> return (EOPNOTSUPP);
> #endif
> }
> Index: netinet/tcp_usrreq.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet/tcp_usrreq.c,v
> retrieving revision 1.143
> diff -u -p -r1.143 tcp_usrreq.c
> --- netinet/tcp_usrreq.c 1 Feb 2017 20:59:47 -0000 1.143
> +++ netinet/tcp_usrreq.c 2 Feb 2017 16:59:46 -0000
> @@ -457,11 +457,9 @@ tcp_ctloutput(int op, struct socket *so,
> int i;
>
> inp = sotoinpcb(so);
> - if (inp == NULL) {
> - if (op == PRCO_SETOPT)
> - (void) m_free(m);
> - return (ECONNRESET);
> - }
> + if (inp == NULL)
> + return ECONNRESET;
> +
> if (level != IPPROTO_TCP) {
> switch (so->so_proto->pr_domain->dom_family) {
> #ifdef INET6
> @@ -481,10 +479,8 @@ tcp_ctloutput(int op, struct socket *so,
> tp = intotcpcb(inp);
>
> switch (op) {
> -
> case PRCO_SETOPT:
> switch (optname) {
> -
> case TCP_NODELAY:
> if (m == NULL || m->m_len < sizeof (int))
> error = EINVAL;
> @@ -567,7 +563,6 @@ tcp_ctloutput(int op, struct socket *so,
> error = ENOPROTOOPT;
> break;
> }
> - m_free(m);
> break;
>
> case PRCO_GETOPT:
> Index: netinet6/icmp6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/icmp6.c,v
> retrieving revision 1.198
> diff -u -p -r1.198 icmp6.c
> --- netinet6/icmp6.c 1 Feb 2017 20:59:47 -0000 1.198
> +++ netinet6/icmp6.c 2 Feb 2017 16:59:46 -0000
> @@ -1807,11 +1807,8 @@ icmp6_ctloutput(int op, struct socket *s
> int error = 0;
> struct inpcb *in6p = sotoinpcb(so);
>
> - if (level != IPPROTO_ICMPV6) {
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
> + if (level != IPPROTO_ICMPV6)
> return EINVAL;
> - }
>
> switch (op) {
> case PRCO_SETOPT:
> @@ -1839,7 +1836,6 @@ icmp6_ctloutput(int op, struct socket *s
> error = ENOPROTOOPT;
> break;
> }
> - m_freem(m);
> break;
>
> case PRCO_GETOPT:
> Index: netinet6/ip6_output.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/ip6_output.c,v
> retrieving revision 1.223
> diff -u -p -r1.223 ip6_output.c
> --- netinet6/ip6_output.c 1 Feb 2017 20:59:47 -0000 1.223
> +++ netinet6/ip6_output.c 2 Feb 2017 16:59:46 -0000
> @@ -1390,7 +1390,6 @@ do { \
> error = ENOPROTOOPT;
> break;
> }
> - m_free(m);
> break;
>
> case PRCO_GETOPT:
> @@ -1591,11 +1590,8 @@ do { \
> }
> break;
> }
> - } else {
> + } else
> error = EINVAL;
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
> - }
> return (error);
> }
>
> @@ -1607,11 +1603,8 @@ ip6_raw_ctloutput(int op, struct socket
> const int icmp6off = offsetof(struct icmp6_hdr, icmp6_cksum);
> struct inpcb *inp = sotoinpcb(so);
>
> - if (level != IPPROTO_IPV6) {
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
> + if (level != IPPROTO_IPV6)
> return (EINVAL);
> - }
>
> switch (optname) {
> case IPV6_CHECKSUM:
> @@ -1660,9 +1653,6 @@ ip6_raw_ctloutput(int op, struct socket
> error = ENOPROTOOPT;
> break;
> }
> -
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
>
> return (error);
> }
> Index: netinet6/raw_ip6.c
> ===================================================================
> RCS file: /cvs/src/sys/netinet6/raw_ip6.c,v
> retrieving revision 1.104
> diff -u -p -r1.104 raw_ip6.c
> --- netinet6/raw_ip6.c 1 Feb 2017 20:59:47 -0000 1.104
> +++ netinet6/raw_ip6.c 2 Feb 2017 16:59:46 -0000
> @@ -511,8 +511,6 @@ rip6_ctloutput(int op, struct socket *so
> break;
> }
>
> - if (op == PRCO_SETOPT)
> - (void)m_free(m);
> return (error);
>
> #ifdef MROUTING
> @@ -522,10 +520,9 @@ rip6_ctloutput(int op, struct socket *so
> case MRT6_DEL_MIF:
> case MRT6_ADD_MFC:
> case MRT6_DEL_MFC:
> - if (op == PRCO_SETOPT) {
> + if (op == PRCO_SETOPT)
> error = ip6_mrouter_set(optname, so, m);
> - m_free(m);
> - } else if (op == PRCO_GETOPT)
> + else if (op == PRCO_GETOPT)
> error = ip6_mrouter_get(optname, so, m);
> else
> error = EINVAL;
> @@ -545,8 +542,6 @@ rip6_ctloutput(int op, struct socket *so
> return (icmp6_ctloutput(op, so, level, optname, m));
>
> default:
> - if (op == PRCO_SETOPT)
> - m_free(m);
> return EINVAL;
> }
> }
>