On Fri, Feb 03, 2017 at 09:50:40AM +0100, Martin Pieuchot wrote: > 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). >
Indeed! Now with BFD and NFS... 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 3 Feb 2017 16:00:26 -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 3 Feb 2017 16:00:26 -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/bfd.c =================================================================== RCS file: /cvs/src/sys/net/bfd.c,v retrieving revision 1.58 diff -u -p -r1.58 bfd.c --- net/bfd.c 24 Jan 2017 10:08:30 -0000 1.58 +++ net/bfd.c 3 Feb 2017 16:00:26 -0000 @@ -418,7 +418,7 @@ bfd_listener(struct bfd_config *bfd, uns struct sockaddr_in *sin; struct sockaddr_in6 *sin6; struct socket *so; - struct mbuf *m = NULL, *mopt = NULL; + struct mbuf *m = NULL, *mopt; int *ip, error; /* sa_family and sa_len must be equal */ @@ -437,6 +437,7 @@ bfd_listener(struct bfd_config *bfd, uns ip = mtod(mopt, int *); *ip = MAXTTL; error = sosetopt(so, IPPROTO_IP, IP_MINTTL, mopt); + m_free(mopt); if (error) { printf("%s: sosetopt error %d\n", __func__, error); @@ -487,7 +488,7 @@ bfd_sender(struct bfd_config *bfd, unsig struct socket *so; struct rtentry *rt = bfd->bc_rt; struct proc *p = curproc; - struct mbuf *m = NULL, *mopt = NULL; + struct mbuf *m = NULL, *mopt; struct sockaddr *src = rt->rt_ifa->ifa_addr; struct sockaddr *dst = rt_key(rt); struct sockaddr *sa; @@ -509,6 +510,7 @@ bfd_sender(struct bfd_config *bfd, unsig ip = mtod(mopt, int *); *ip = IP_PORTRANGE_HIGH; error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt); + m_free(mopt); if (error) { printf("%s: sosetopt error %d\n", __func__, error); @@ -520,6 +522,7 @@ bfd_sender(struct bfd_config *bfd, unsig ip = mtod(mopt, int *); *ip = MAXTTL; error = sosetopt(so, IPPROTO_IP, IP_TTL, mopt); + m_free(mopt); if (error) { printf("%s: sosetopt error %d\n", __func__, error); @@ -531,6 +534,7 @@ bfd_sender(struct bfd_config *bfd, unsig ip = mtod(mopt, int *); *ip = IPTOS_PREC_INTERNETCONTROL; error = sosetopt(so, IPPROTO_IP, IP_TOS, mopt); + m_free(mopt); if (error) { printf("%s: sosetopt error %d\n", __func__, error); 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 3 Feb 2017 16:00:26 -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 3 Feb 2017 16:00:26 -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 3 Feb 2017 16:00:26 -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 3 Feb 2017 16:00:26 -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 3 Feb 2017 16:00:27 -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 3 Feb 2017 16:00:27 -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 3 Feb 2017 16:00:27 -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 3 Feb 2017 16:00:27 -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; } } Index: nfs/krpc_subr.c =================================================================== RCS file: /cvs/src/sys/nfs/krpc_subr.c,v retrieving revision 1.29 diff -u -p -r1.29 krpc_subr.c --- nfs/krpc_subr.c 24 Aug 2015 14:00:29 -0000 1.29 +++ nfs/krpc_subr.c 3 Feb 2017 16:00:27 -0000 @@ -239,7 +239,9 @@ krpc_call(struct sockaddr_in *sa, u_int tv.tv_usec = 0; memcpy(mtod(m, struct timeval *), &tv, sizeof tv); m->m_len = sizeof(tv); - if ((error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m))) + error = sosetopt(so, SOL_SOCKET, SO_RCVTIMEO, m); + m_free(m); + if (error) goto out; /* @@ -251,7 +253,9 @@ krpc_call(struct sockaddr_in *sa, u_int on = mtod(m, int32_t *); m->m_len = sizeof(*on); *on = 1; - if ((error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m))) + error = sosetopt(so, SOL_SOCKET, SO_BROADCAST, m); + m_free(m); + if (error) goto out; } @@ -265,6 +269,7 @@ krpc_call(struct sockaddr_in *sa, u_int ip = mtod(mopt, int *); *ip = IP_PORTRANGE_LOW; error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt); + m_free(mopt); if (error) goto out; @@ -287,6 +292,7 @@ krpc_call(struct sockaddr_in *sa, u_int ip = mtod(mopt, int *); *ip = IP_PORTRANGE_DEFAULT; error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt); + m_free(mopt); if (error) goto out; Index: nfs/nfs_socket.c =================================================================== RCS file: /cvs/src/sys/nfs/nfs_socket.c,v retrieving revision 1.112 diff -u -p -r1.112 nfs_socket.c --- nfs/nfs_socket.c 19 Dec 2016 08:36:50 -0000 1.112 +++ nfs/nfs_socket.c 3 Feb 2017 16:00:27 -0000 @@ -253,6 +253,7 @@ nfs_connect(struct nfsmount *nmp, struct ip = mtod(mopt, int *); *ip = IP_PORTRANGE_LOW; error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt); + m_free(mopt); if (error) goto bad; @@ -273,6 +274,7 @@ nfs_connect(struct nfsmount *nmp, struct ip = mtod(mopt, int *); *ip = IP_PORTRANGE_DEFAULT; error = sosetopt(so, IPPROTO_IP, IP_PORTRANGE, mopt); + m_free(mopt); if (error) goto bad; } @@ -341,12 +343,14 @@ nfs_connect(struct nfsmount *nmp, struct *mtod(m, int32_t *) = 1; m->m_len = sizeof(int32_t); sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m); + m_free(m); } if (so->so_proto->pr_protocol == IPPROTO_TCP) { MGET(m, M_WAIT, MT_SOOPTS); *mtod(m, int32_t *) = 1; m->m_len = sizeof(int32_t); sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m); + m_free(m); } sndreserve = (nmp->nm_wsize + NFS_MAXPKTHDR + sizeof (u_int32_t)) * 2; Index: nfs/nfs_syscalls.c =================================================================== RCS file: /cvs/src/sys/nfs/nfs_syscalls.c,v retrieving revision 1.106 diff -u -p -r1.106 nfs_syscalls.c --- nfs/nfs_syscalls.c 15 Sep 2016 02:00:18 -0000 1.106 +++ nfs/nfs_syscalls.c 3 Feb 2017 16:00:27 -0000 @@ -255,6 +255,7 @@ nfssvc_addsock(struct file *fp, struct m *mtod(m, int32_t *) = 1; m->m_len = sizeof(int32_t); sosetopt(so, SOL_SOCKET, SO_KEEPALIVE, m); + m_free(m); } if (so->so_proto->pr_domain->dom_family == AF_INET && so->so_proto->pr_protocol == IPPROTO_TCP) { @@ -262,6 +263,7 @@ nfssvc_addsock(struct file *fp, struct m *mtod(m, int32_t *) = 1; m->m_len = sizeof(int32_t); sosetopt(so, IPPROTO_TCP, TCP_NODELAY, m); + m_free(m); } so->so_rcv.sb_flags &= ~SB_NOINTR; so->so_rcv.sb_timeo = 0; @@ -270,8 +272,7 @@ nfssvc_addsock(struct file *fp, struct m if (tslp) slp = tslp; else { - slp = malloc(sizeof(*slp), M_NFSSVC, - M_WAITOK|M_ZERO); + slp = malloc(sizeof(*slp), M_NFSSVC, M_WAITOK|M_ZERO); TAILQ_INSERT_TAIL(&nfssvc_sockhead, slp, ns_chain); } slp->ns_so = so;