From nobody Wed Oct 27 15:22:57 2021 X-Original-To: dev-commits-src-main@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id D946B1813F35; Wed, 27 Oct 2021 15:22:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4HfXWP5Nlrz3DZJ; Wed, 27 Oct 2021 15:22:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 8C36D126E9; Wed, 27 Oct 2021 15:22:57 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 19RFMvEM084024; Wed, 27 Oct 2021 15:22:57 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 19RFMvHK084023; Wed, 27 Oct 2021 15:22:57 GMT (envelope-from git) Date: Wed, 27 Oct 2021 15:22:57 GMT Message-Id: <202110271522.19RFMvHK084023@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Gleb Smirnoff Subject: git: fc4d53cc2ef3 - main - Split tcp_ctloutput() into set/get parts. List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: glebius X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: fc4d53cc2ef3345ad36c874010c4abc2317a61f8 Auto-Submitted: auto-generated X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by glebius: URL: https://cgit.FreeBSD.org/src/commit/?id=fc4d53cc2ef3345ad36c874010c4abc2317a61f8 commit fc4d53cc2ef3345ad36c874010c4abc2317a61f8 Author: Gleb Smirnoff AuthorDate: 2021-10-26 03:38:31 +0000 Commit: Gleb Smirnoff CommitDate: 2021-10-27 15:21:59 +0000 Split tcp_ctloutput() into set/get parts. Reviewed by: rrs Differential Revision: https://reviews.freebsd.org/D32655 --- sys/netinet/tcp_usrreq.c | 125 ++++++++++++++++++++++++++++++++++------------- 1 file changed, 90 insertions(+), 35 deletions(-) diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index f004d54b4657..0fca9b88e6f3 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1729,22 +1729,18 @@ tcp_fill_info(struct tcpcb *tp, struct tcp_info *ti) } while(0) #define INP_WLOCK_RECHECK(inp) INP_WLOCK_RECHECK_CLEANUP((inp), /* noop */) -int -tcp_ctloutput(struct socket *so, struct sockopt *sopt) +static int +tcp_ctloutput_set(struct inpcb *inp, struct sockopt *sopt) { - int error; - struct inpcb *inp; - struct tcpcb *tp; - struct tcp_function_block *blk; - struct tcp_function_set fsn; + struct tcpcb *tp = intotcpcb(inp); + int error = 0; + + MPASS(sopt->sopt_dir == SOPT_SET); - error = 0; - inp = sotoinpcb(so); - KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL")); if (sopt->sopt_level != IPPROTO_TCP) { #ifdef INET6 if (inp->inp_vflag & INP_IPV6PROTO) { - error = ip6_ctloutput(so, sopt); + error = ip6_ctloutput(inp->inp_socket, sopt); /* * In case of the IPV6_USE_MIN_MTU socket option, * the INC_IPV6MINMTU flag to announce a corresponding @@ -1755,7 +1751,6 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt) * be fragmented at the IPv6 layer. */ if ((error == 0) && - (sopt->sopt_dir == SOPT_SET) && (sopt->sopt_level == IPPROTO_IPV6) && (sopt->sopt_name == IPV6_USE_MIN_MTU)) { INP_WLOCK(inp); @@ -1788,29 +1783,29 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt) #endif #ifdef INET { - error = ip_ctloutput(so, sopt); + error = ip_ctloutput(inp->inp_socket, sopt); } #endif return (error); - } - INP_WLOCK(inp); - if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { - INP_WUNLOCK(inp); - return (ECONNRESET); - } - tp = intotcpcb(inp); - /* - * Protect the TCP option TCP_FUNCTION_BLK so - * that a sub-function can *never* overwrite this. - */ - if ((sopt->sopt_dir == SOPT_SET) && - (sopt->sopt_name == TCP_FUNCTION_BLK)) { - INP_WUNLOCK(inp); - error = sooptcopyin(sopt, &fsn, sizeof fsn, - sizeof fsn); + } else if (sopt->sopt_name == TCP_FUNCTION_BLK) { + /* + * Protect the TCP option TCP_FUNCTION_BLK so + * that a sub-function can *never* overwrite this. + */ + struct tcp_function_set fsn; + struct tcp_function_block *blk; + + error = sooptcopyin(sopt, &fsn, sizeof fsn, sizeof fsn); if (error) return (error); - INP_WLOCK_RECHECK(inp); + + INP_WLOCK(inp); + if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { + INP_WUNLOCK(inp); + return (ECONNRESET); + } + tp = intotcpcb(inp); + blk = find_and_ref_tcp_functions(&fsn); if (blk == NULL) { INP_WUNLOCK(inp); @@ -1875,7 +1870,7 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt) if((*tp->t_fb->tfb_tcp_fb_init)(tp) != 0) { /* Fall back failed, drop the connection */ INP_WUNLOCK(inp); - soabort(so); + soabort(inp->inp_socket); return(error); } } @@ -1893,9 +1888,50 @@ tcp_ctloutput(struct socket *so, struct sockopt *sopt) err_out: INP_WUNLOCK(inp); return (error); - } else if ((sopt->sopt_dir == SOPT_GET) && - ((sopt->sopt_name == TCP_FUNCTION_BLK) || + } + + INP_WLOCK(inp); + if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { + INP_WUNLOCK(inp); + return (ECONNRESET); + } + tp = intotcpcb(inp); + + /* Pass in the INP locked, caller must unlock it. */ + return (tp->t_fb->tfb_tcp_ctloutput(inp->inp_socket, sopt, inp, tp)); +} + +static int +tcp_ctloutput_get(struct inpcb *inp, struct sockopt *sopt) +{ + int error = 0; + struct tcpcb *tp; + + MPASS(sopt->sopt_dir == SOPT_GET); + + if (sopt->sopt_level != IPPROTO_TCP) { +#ifdef INET6 + if (inp->inp_vflag & INP_IPV6PROTO) + error = ip6_ctloutput(inp->inp_socket, sopt); +#endif /* INET6 */ +#if defined(INET6) && defined(INET) + else +#endif +#ifdef INET + error = ip_ctloutput(inp->inp_socket, sopt); +#endif + return (error); + } + INP_WLOCK(inp); + if (inp->inp_flags & (INP_TIMEWAIT | INP_DROPPED)) { + INP_WUNLOCK(inp); + return (ECONNRESET); + } + tp = intotcpcb(inp); + if (((sopt->sopt_name == TCP_FUNCTION_BLK) || (sopt->sopt_name == TCP_FUNCTION_ALIAS))) { + struct tcp_function_set fsn; + if (sopt->sopt_name == TCP_FUNCTION_ALIAS) { memset(&fsn, 0, sizeof(fsn)); find_tcp_function_alias(tp->t_fb, &fsn); @@ -1910,8 +1946,27 @@ err_out: error = sooptcopyout(sopt, &fsn, sizeof fsn); return (error); } - /* Pass in the INP locked, called must unlock it */ - return (tp->t_fb->tfb_tcp_ctloutput(so, sopt, inp, tp)); + + /* Pass in the INP locked, caller must unlock it. */ + return (tp->t_fb->tfb_tcp_ctloutput(inp->inp_socket, sopt, inp, tp)); +} + +int +tcp_ctloutput(struct socket *so, struct sockopt *sopt) +{ + int error; + struct inpcb *inp; + + error = 0; + inp = sotoinpcb(so); + KASSERT(inp != NULL, ("tcp_ctloutput: inp == NULL")); + + if (sopt->sopt_dir == SOPT_SET) + return (tcp_ctloutput_set(inp, sopt)); + else if (sopt->sopt_dir == SOPT_GET) + return (tcp_ctloutput_get(inp, sopt)); + else + panic("%s: sopt_dir $%d", __func__, sopt->sopt_dir); } /*