From patchwork Fri Jun 2 15:07:42 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102588 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1100370vqr; Fri, 2 Jun 2023 08:13:42 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4VM1aHPboYQ3I4Wd11q0dN9MPEBfCRAMVJWL2WQFkfAXGP7cblIGupQtFF4VbZFcLnQcR1 X-Received: by 2002:a05:6a21:788b:b0:10e:c779:3eb1 with SMTP id bf11-20020a056a21788b00b0010ec7793eb1mr10579394pzc.6.1685718822200; Fri, 02 Jun 2023 08:13:42 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685718822; cv=none; d=google.com; s=arc-20160816; b=oj5g9bRhXOxgn4cdTYyFDSURLqeQ7FwJZxJ3KF1a+QyfatkcxwrzaOzIpolmSNX//5 bh2qUxIU64p5x9caoDRI5wRO/x0z+LpDfpjbwABCFXj9A5AjHJgA33CfSK3ISQwm3b1k ++DycPlwWdhhKmeSKfcuYT0cPPj4MpSqzlWjWZ4OXcUnPbws5jdJLqb7bDNN8vFWdUVH kMIg9Y3ZkZIC2hMKspINIeNY8/9iScYO0n1a7FM8CYtzwrvmpVPEj1sSH/ZAjVXfSQth 0QtUjOyaQsQqj4kBr0pbn5j33/vjwH7D1UmKKmqe/1lVber+BakMUOu4FURTZxXXKnHu Sk4Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=704Gul1es5vKB8f3fNlqLP0xfed1dEhsuWb+SLm3klg=; b=w5tqCHvpfZzd1Wdlar8+zS7f4tVN4V7jpxdM5Ts1tbjid2WBwb2GSuZPEX+d0FL1zu KJPWGL2Vc6FIbd13UFoG7HM6kcqcGOXHLjDlLteG+YIehblc+UqVI7ylyQI6OUfYEXBI WWMdyKGU6lacA5e4WDZDi/nO9i8FaXlObQgWlo9l8/W9R1VSew0Ls7D+V0VksWMmy3pH HwrFFLJbEZTOWjGo6oD/Fmw1stBzJo4gzlR3oId8v6EDTym4rvPjLDxY0lTPWzqi50CU 8Op1iwk1OQpH5rNO02iIb62l/p9HyX6u6SxWaubzGIHRlIDej67oYWr6KgP3nuCfZUfr +lDQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=ezR4Jv+I; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id s191-20020a6377c8000000b005401008809bsi1101023pgc.752.2023.06.02.08.13.26; Fri, 02 Jun 2023 08:13:42 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=ezR4Jv+I; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236414AbjFBPI5 (ORCPT + 99 others); Fri, 2 Jun 2023 11:08:57 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57704 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236399AbjFBPIw (ORCPT ); Fri, 2 Jun 2023 11:08:52 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 200B3E40 for ; Fri, 2 Jun 2023 08:08:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718487; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=704Gul1es5vKB8f3fNlqLP0xfed1dEhsuWb+SLm3klg=; b=ezR4Jv+I6jK3jXYv4Os435NCkQLkWH+QFa6voNVOGu37lgyXsC1FG8PjvIVcfA/rLhPr9z HcPho5yui9kWCYBvizxf1c68PmHhRwMFwTju1E8BzAV5cwgJNIewW+iy1SywY1UV9bdN3l s7b0svNiz1Ud6NXxK73iggfLCho87tQ= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-157-98r-sCduMDuRZbV631FDtg-1; Fri, 02 Jun 2023 11:08:02 -0400 X-MC-Unique: 98r-sCduMDuRZbV631FDtg-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 86197185A792; Fri, 2 Jun 2023 15:08:01 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7F0642026D49; Fri, 2 Jun 2023 15:07:59 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 01/11] net: Block MSG_SENDPAGE_* from being passed to sendmsg() by userspace Date: Fri, 2 Jun 2023 16:07:42 +0100 Message-ID: <20230602150752.1306532-2-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767604299824627778?= X-GMAIL-MSGID: =?utf-8?q?1767604299824627778?= It is necessary to allow MSG_SENDPAGE_* to be passed into ->sendmsg() to allow sendmsg(MSG_SPLICE_PAGES) to replace ->sendpage(). Unblocking them in the network protocol, however, allows these flags to be passed in by userspace too[1]. Fix this by marking MSG_SENDPAGE_NOPOLICY, MSG_SENDPAGE_NOTLAST and MSG_SENDPAGE_DECRYPTED as internal flags, which causes sendmsg() to object if they are passed to sendmsg() by userspace. Network protocol ->sendmsg() implementations can then allow them through. Note that it should be possible to remove MSG_SENDPAGE_NOTLAST once sendpage is removed as a whole slew of pages will be passed in in one go by splice through sendmsg, with MSG_MORE being set if it has more data waiting in the pipe. Signed-off-by: David Howells cc: Jakub Kicinski cc: Chuck Lever cc: Boris Pismenny cc: John Fastabend cc: Eric Dumazet cc: "David S. Miller" cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/20230526181338.03a99016@kernel.org/ [1] --- include/linux/socket.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/linux/socket.h b/include/linux/socket.h index bd1cc3238851..3fd3436bc09f 100644 --- a/include/linux/socket.h +++ b/include/linux/socket.h @@ -339,7 +339,9 @@ struct ucred { #endif /* Flags to be cleared on entry by sendmsg and sendmmsg syscalls */ -#define MSG_INTERNAL_SENDMSG_FLAGS (MSG_SPLICE_PAGES) +#define MSG_INTERNAL_SENDMSG_FLAGS \ + (MSG_SPLICE_PAGES | MSG_SENDPAGE_NOPOLICY | MSG_SENDPAGE_NOTLAST | \ + MSG_SENDPAGE_DECRYPTED) /* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */ #define SOL_IP 0 From patchwork Fri Jun 2 15:07:43 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102591 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1102276vqr; Fri, 2 Jun 2023 08:16:04 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6s4Uq1x01My00SqTgY3IjcPKk9biJeEVYcCwlo426fGulKRDnzx6kfav5+ubdlT1bbOu7Y X-Received: by 2002:a17:902:ea0a:b0:1b0:66b6:6ae5 with SMTP id s10-20020a170902ea0a00b001b066b66ae5mr223813plg.61.1685718964364; Fri, 02 Jun 2023 08:16:04 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685718964; cv=none; d=google.com; s=arc-20160816; b=GyiJQPnKlY0VbENndSFICTs4h6SGbUhpqCBmce1sbkPRc2B74Zuesp+deX9eEf8ULn Chd2YM9doeC699fDp718GdAXJrj6p+maGPxvp6mFeMdWGvsltydKqKXOYDQYAEy83LEe 0jq3SjgylLxN+oS/APh9fzLFbINpWi2skpXLfwpDM2bTDiw56XRsdZrGezmEvzara1DC 96Wd9S+SKOQ9zN2B/ORcupkTtKE+AtdbN1a7TgtN7ja7ktJqdLsA6+D+lW2UVV8Poxdw Xvoe88f8HB5kuUY5SSSSuhTBX71IdJK6fTM1XzWivsmKMASsYZ48IdsKvns7YJjHhcbV NDjg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=GIUHoDHkYJ6R7Kj3TX2onke+6WDgXd+OHlld+dEFkxk=; b=CorezBTsH9c8XBUNTGZcx5ny90tCB6L3VcBOGX+twqrEOrYlIkjHbHPi9Hnx++cpNr FXPH4Ye7EKcLL4RbYF1rTgIj5G38goSa2BzJDmRzGDsfCE5wINF8dkP1VjyW2vps+u/c 37fAosxhLQBtgHNMEmL3qUFN7PB0xyK8lUF07jdRUWYBXEWnQ4FnNKDeY+rSWpc2NEqv hPwZB1/ceF/cUhqkponH+QG2mzAewfRss1bJeNSpNrNvdNyau1zQ8/OkSSdJGQ+RUtUQ 1UfCHcHqfQ8jaVE/iPz/szTzMAtdIDg3yFRfJkU6bRz2Se9mNVbrSGeIyu/eN6fo2EdI eIMg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=K7bnd8tw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n9-20020a170902d2c900b001aae1eefc9bsi1079728plc.238.2023.06.02.08.15.50; Fri, 02 Jun 2023 08:16:04 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=K7bnd8tw; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236429AbjFBPJG (ORCPT + 99 others); Fri, 2 Jun 2023 11:09:06 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57802 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236428AbjFBPJC (ORCPT ); Fri, 2 Jun 2023 11:09:02 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A7F5E58 for ; Fri, 2 Jun 2023 08:08:15 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718494; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GIUHoDHkYJ6R7Kj3TX2onke+6WDgXd+OHlld+dEFkxk=; b=K7bnd8twd7hgXUrlrbkuYcTXvI35JEwwy7sLT5HygS4SFSW4rHpqL6lQj3cGaoPYAGmMPm 34Ejx362mplMJ5a6ZbCjsltZBxXFVxZLPppoL5sgKxGiIPQQYg4qnRjeBg95H8nmF+angD Op3XTK0qIUH/rTJb694QWa31y+tOHHs= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-575-BOuQHjwKMQyEta6FCH7Pyw-1; Fri, 02 Jun 2023 11:08:11 -0400 X-MC-Unique: BOuQHjwKMQyEta6FCH7Pyw-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id CAA3D3C0BE44; Fri, 2 Jun 2023 15:08:10 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 8D922492B00; Fri, 2 Jun 2023 15:08:07 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 02/11] tls: Allow MSG_SPLICE_PAGES but treat it as normal sendmsg Date: Fri, 2 Jun 2023 16:07:43 +0100 Message-ID: <20230602150752.1306532-3-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767604448806880777?= X-GMAIL-MSGID: =?utf-8?q?1767604448806880777?= Allow MSG_SPLICE_PAGES to be specified to sendmsg() but treat it as normal sendmsg for now. This means the data will just be copied until MSG_SPLICE_PAGES is handled. Signed-off-by: David Howells cc: Chuck Lever cc: Boris Pismenny cc: John Fastabend cc: Jakub Kicinski cc: Eric Dumazet cc: "David S. Miller" cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org --- net/tls/tls_device.c | 3 ++- net/tls/tls_sw.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index a959572a816f..9ef766e41c7a 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -447,7 +447,8 @@ static int tls_push_data(struct sock *sk, long timeo; if (flags & - ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_SENDPAGE_NOTLAST)) + ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_SENDPAGE_NOTLAST | + MSG_SPLICE_PAGES)) return -EOPNOTSUPP; if (unlikely(sk->sk_err)) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 6e6a7c37d685..cac1adc968e8 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -953,7 +953,7 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) int pending; if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | - MSG_CMSG_COMPAT)) + MSG_CMSG_COMPAT | MSG_SPLICE_PAGES)) return -EOPNOTSUPP; ret = mutex_lock_interruptible(&tls_ctx->tx_lock); From patchwork Fri Jun 2 15:07:44 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102586 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1100019vqr; Fri, 2 Jun 2023 08:13:09 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ7YqXyWb0QWhXUdvDVLTPx3jkuFrHanhPqvc/spDsqXkT4uvrm/BF+7mBr/aRNBIRhjrESr X-Received: by 2002:a17:90a:1d6:b0:256:c915:13ca with SMTP id 22-20020a17090a01d600b00256c91513camr217017pjd.20.1685718789057; Fri, 02 Jun 2023 08:13:09 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685718789; cv=none; d=google.com; s=arc-20160816; b=0QCBBBuwYmaPA7oQGXhxDRxBJRj5iP7W2UHdpNcUJi6Tgp1aKt9gddwLnS6Oef+y/W HEx3QQw85Jx2l5mMFvbG0U9IgYk22+ZBAUUTouwy4RsJidCJM5L9QvfYaKc+d+VpGLLW 90KhwNPKXEXf8AcA33+WUqnokeLWt0Apmopo3i9GY/dXplggRcTMRuzesH8Yo0f3WSyO ek1YvDw6Tfn3KH8B5mvpuhO/QfybAHCbi9p/G/9s0hQywllTs5YYtbMlS+6CqezVsVrs fCHrnmCBPYSVneoYstAbhe/YMN5cqC3hGxJJE7FD09IUoNaKX2TR0Srh5U41mL1T9q27 Brdg== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=GeaP7/vo94ZZDrAoROnlgLmkpbcL++cZl5U43JLGl7Y=; b=EpEQn/+owRfQBk62FvVRlXoh164DUKW+bUZ//7b9aNv+uR2oZ8nBER5dvFkiQrj3f9 XSs3SAQuCqUv4bnGOahfD40EJFppucgoK8P3urTclYZpJYQmMTYvquzSof/cu5ofhRj8 dvPHl0jkda+7zkY6VvChM853/PLZO9wJekHvNy6RO2OQex0iB5xTbaPgMKnduK0QyBgj 8+QMko/5WvejBokoe89pRRRbhzrV9hHR+Hks9+JWzR9b0xxP4P60ACqh5i0z+LKfjHub g/3tdxYQrH3okr5lBl3DKcMuqhOsUw8HZkL2jFR6/LW3/WFOYCxJ/pekeqIss3rQcMfj e5CA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=ZILjBOuX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b9-20020a63d809000000b005348f910e64si1129836pgh.693.2023.06.02.08.12.52; Fri, 02 Jun 2023 08:13:09 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=ZILjBOuX; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236428AbjFBPJP (ORCPT + 99 others); Fri, 2 Jun 2023 11:09:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57892 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236379AbjFBPJJ (ORCPT ); Fri, 2 Jun 2023 11:09:09 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 8E1D5E52 for ; Fri, 2 Jun 2023 08:08:23 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718502; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=GeaP7/vo94ZZDrAoROnlgLmkpbcL++cZl5U43JLGl7Y=; b=ZILjBOuXaBZFx/j7kah5/nSZvZSoEBPDxV/Ao9wvNxs/6wh7n7htuhXZrwIBJEo4rh5fln AFKyO+zdQs/qHXTHXN4v8M8iimeStyWHNAe2GhwgXb+PEq2dnRu97PpF8H+ZacToZ/WUzT OckRcHLv0cD45SAkfGZuX1Zd2XAoJAQ= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-675-r53cRdYeNt22xXrH4BTZSw-1; Fri, 02 Jun 2023 11:08:17 -0400 X-MC-Unique: r53cRdYeNt22xXrH4BTZSw-1 Received: from smtp.corp.redhat.com (int-mx01.intmail.prod.int.rdu2.redhat.com [10.11.54.1]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 77FF23C0BE49; Fri, 2 Jun 2023 15:08:16 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 7D52340CFD46; Fri, 2 Jun 2023 15:08:14 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 03/11] tls/sw: Use zero-length sendmsg() without MSG_MORE to flush Date: Fri, 2 Jun 2023 16:07:44 +0100 Message-ID: <20230602150752.1306532-4-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.1 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767604264702632034?= X-GMAIL-MSGID: =?utf-8?q?1767604264702632034?= Allow userspace to end a TLS record without supplying any data by calling send()/sendto()/sendmsg() with no data and no MSG_MORE flag. This can be used to flush a previous send/splice that had MSG_MORE or SPLICE_F_MORE set or a sendfile() that was incomplete. Without this, a zero-length send to tls-sw is just ignored. I think tls-device will do the right thing without modification. Signed-off-by: David Howells cc: Chuck Lever cc: Boris Pismenny cc: John Fastabend cc: Jakub Kicinski cc: Eric Dumazet cc: "David S. Miller" cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org --- net/tls/tls_sw.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index cac1adc968e8..6aa6d17888f5 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -945,7 +945,7 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) struct tls_rec *rec; int required_size; int num_async = 0; - bool full_record; + bool full_record = false; int record_room; int num_zc = 0; int orig_size; @@ -971,6 +971,9 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) } } + if (!msg_data_left(msg) && eor) + goto just_flush; + while (msg_data_left(msg)) { if (sk->sk_err) { ret = -sk->sk_err; @@ -1082,6 +1085,7 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) */ tls_ctx->pending_open_record_frags = true; copied += try_to_copy; +just_flush: if (full_record || eor) { ret = bpf_exec_tx_verdict(msg_pl, sk, full_record, record_type, &copied, From patchwork Fri Jun 2 15:07:45 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102585 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1099279vqr; Fri, 2 Jun 2023 08:12:06 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6BeCnX2ha+tZYP+pNVnU8jXFhvrSW010Und5QrIoWIIqkUILe1v3lfkUUXg7/ZFRfzW0jG X-Received: by 2002:a17:902:f550:b0:1af:c1a7:3bb5 with SMTP id h16-20020a170902f55000b001afc1a73bb5mr310930plf.4.1685718725645; Fri, 02 Jun 2023 08:12:05 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685718725; cv=none; d=google.com; s=arc-20160816; b=HBkAIFj+GW6/+cahiTQycS64SO+8cV92oWyhKuzvXEbDYIk4vjxJWDWX3zM8iIjpjq LfDZ7O9gXOB17DEc0uDuN7k71xOjF9QLC+PWjd2613nGRn9130BCqyqPaffZv/s8KRMO 6vU8cUJCREJWuwuy/rc7orJTsn13Cyu2CYCozjCEWx+kONJVDAUlgVGm0ELREZESOvWm sKv9uTfEWBcL9VlKVyaDuGQjODXPMzKgJfDHV4nr8O7OQFq0vzsm20/43YZd9fmY8iHF X93tym+3cVTyvrJuWLL743UwRTT9TO0Zt2wBiffiJJBKjX4xywDndTaT/SPyEr7xPekc EHYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=C5MeH3bkXFVlppirWEf/JAhtMhZSTtHegYn7rkL31b8=; b=L+85EeGjOY1PTiOi34QXN3n4aZlt90OboFWmoxjn5yAqXpNzH9ud8ClAEZmGS39M87 YnK+SGEz3NJyRJTARgIX4IkjFNX5tGQCN+zisDG5CDKvWINSyQWvmIItWhs2obkdJzTb BwKl2TGeHD3wQpTkiwKny2v09u1HVJlVNtF2eyOMvOpmDoFHfqXGYZ0yYa+Q6OLri9AG ngdLlu12F22i8+8Z5ENcUHTQaHNxhI7Ks6pupJSl/c37NS7TucE+VUcFCM2koxYh04si 95Qy5PpY9izOjpjWX2OV+Mpt6Sjg3IjSB5MkRJV0D9cdpSlRjl6JgrCvNGHqGBOcl0J/ D4DA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=a9ZFCp+C; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id j15-20020a170903024f00b001aaf91ae3acsi1006912plh.485.2023.06.02.08.11.48; Fri, 02 Jun 2023 08:12:05 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=a9ZFCp+C; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236440AbjFBPJM (ORCPT + 99 others); Fri, 2 Jun 2023 11:09:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57868 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236419AbjFBPJJ (ORCPT ); Fri, 2 Jun 2023 11:09:09 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 569FC123 for ; Fri, 2 Jun 2023 08:08:25 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718504; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=C5MeH3bkXFVlppirWEf/JAhtMhZSTtHegYn7rkL31b8=; b=a9ZFCp+CzmXnUTLEnhLLiWWC5jI8je+i8xJ7/+LMIpxecd6wMaZn82ZrDCbFJVs0YiW1KG V7jbIbl0S+g+rvBi1wMFuyU1JLSjDSCi9m/1MvGjNoTA6Tt97jR1z9RN42hzatcTlH9mmu iZSjoQfEnd8JJZXDTrLmPRC6Hi/Joh4= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-277-qdBthDuGP0-agnm9gHhsBw-1; Fri, 02 Jun 2023 11:08:22 -0400 X-MC-Unique: qdBthDuGP0-agnm9gHhsBw-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.rdu2.redhat.com [10.11.54.6]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 811FE3802268; Fri, 2 Jun 2023 15:08:21 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5EEA72166B25; Fri, 2 Jun 2023 15:08:18 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 04/11] splice, net: Use sendmsg(MSG_SPLICE_PAGES) rather than ->sendpage() Date: Fri, 2 Jun 2023 16:07:45 +0100 Message-ID: <20230602150752.1306532-5-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.6 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767604197981655756?= X-GMAIL-MSGID: =?utf-8?q?1767604197981655756?= Replace generic_splice_sendpage() + splice_from_pipe + pipe_to_sendpage() with a net-specific handler, splice_to_socket(), that calls sendmsg() with MSG_SPLICE_PAGES set instead of calling ->sendpage(). MSG_MORE is used to indicate if the sendmsg() is expected to be followed with more data. This allows multiple pipe-buffer pages to be passed in a single call in a BVEC iterator, allowing the processing to be pushed down to a loop in the protocol driver. This helps pave the way for passing multipage folios down too. Protocols that haven't been converted to handle MSG_SPLICE_PAGES yet should just ignore it and do a normal sendmsg() for now - although that may be a bit slower as it may copy everything. Signed-off-by: David Howells cc: "David S. Miller" cc: Eric Dumazet cc: Jakub Kicinski cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org --- fs/splice.c | 158 +++++++++++++++++++++++++++++++++-------- include/linux/fs.h | 2 - include/linux/splice.h | 2 + net/socket.c | 26 +------ 4 files changed, 131 insertions(+), 57 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index 3e06611d19ae..9b1d43c0c562 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -448,30 +449,6 @@ const struct pipe_buf_operations nosteal_pipe_buf_ops = { }; EXPORT_SYMBOL(nosteal_pipe_buf_ops); -/* - * Send 'sd->len' bytes to socket from 'sd->file' at position 'sd->pos' - * using sendpage(). Return the number of bytes sent. - */ -static int pipe_to_sendpage(struct pipe_inode_info *pipe, - struct pipe_buffer *buf, struct splice_desc *sd) -{ - struct file *file = sd->u.file; - loff_t pos = sd->pos; - int more; - - if (!likely(file->f_op->sendpage)) - return -EINVAL; - - more = (sd->flags & SPLICE_F_MORE) ? MSG_MORE : 0; - - if (sd->len < sd->total_len && - pipe_occupancy(pipe->head, pipe->tail) > 1) - more |= MSG_SENDPAGE_NOTLAST; - - return file->f_op->sendpage(file, buf->page, buf->offset, - sd->len, &pos, more); -} - static void wakeup_pipe_writers(struct pipe_inode_info *pipe) { smp_mb(); @@ -652,7 +629,7 @@ static void splice_from_pipe_end(struct pipe_inode_info *pipe, struct splice_des * Description: * This function does little more than loop over the pipe and call * @actor to do the actual moving of a single struct pipe_buffer to - * the desired destination. See pipe_to_file, pipe_to_sendpage, or + * the desired destination. See pipe_to_file, pipe_to_sendmsg, or * pipe_to_user. * */ @@ -833,8 +810,9 @@ iter_file_splice_write(struct pipe_inode_info *pipe, struct file *out, EXPORT_SYMBOL(iter_file_splice_write); +#ifdef CONFIG_NET /** - * generic_splice_sendpage - splice data from a pipe to a socket + * splice_to_socket - splice data from a pipe to a socket * @pipe: pipe to splice from * @out: socket to write to * @ppos: position in @out @@ -846,13 +824,131 @@ EXPORT_SYMBOL(iter_file_splice_write); * is involved. * */ -ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, struct file *out, - loff_t *ppos, size_t len, unsigned int flags) +ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags) { - return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_sendpage); -} + struct socket *sock = sock_from_file(out); + struct bio_vec bvec[16]; + struct msghdr msg = {}; + ssize_t ret; + size_t spliced = 0; + bool need_wakeup = false; + + pipe_lock(pipe); + + while (len > 0) { + unsigned int head, tail, mask, bc = 0; + size_t remain = len; + + /* + * Check for signal early to make process killable when there + * are always buffers available + */ + ret = -ERESTARTSYS; + if (signal_pending(current)) + break; + + while (pipe_empty(pipe->head, pipe->tail)) { + ret = 0; + if (!pipe->writers) + goto out; + + if (spliced) + goto out; + + ret = -EAGAIN; + if (flags & SPLICE_F_NONBLOCK) + goto out; + + ret = -ERESTARTSYS; + if (signal_pending(current)) + goto out; + + if (need_wakeup) { + wakeup_pipe_writers(pipe); + need_wakeup = false; + } + + pipe_wait_readable(pipe); + } + + head = pipe->head; + tail = pipe->tail; + mask = pipe->ring_size - 1; + + while (!pipe_empty(head, tail)) { + struct pipe_buffer *buf = &pipe->bufs[tail & mask]; + size_t seg; -EXPORT_SYMBOL(generic_splice_sendpage); + if (!buf->len) { + tail++; + continue; + } + + seg = min_t(size_t, remain, buf->len); + seg = min_t(size_t, seg, PAGE_SIZE); + + ret = pipe_buf_confirm(pipe, buf); + if (unlikely(ret)) { + if (ret == -ENODATA) + ret = 0; + break; + } + + bvec_set_page(&bvec[bc++], buf->page, seg, buf->offset); + remain -= seg; + if (seg >= buf->len) + tail++; + if (bc >= ARRAY_SIZE(bvec)) + break; + } + + if (!bc) + break; + + msg.msg_flags = MSG_SPLICE_PAGES; + if (flags & SPLICE_F_MORE) + msg.msg_flags |= MSG_MORE; + if (remain && pipe_occupancy(pipe->head, tail) > 0) + msg.msg_flags |= MSG_MORE; + + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, bvec, bc, + len - remain); + ret = sock_sendmsg(sock, &msg); + if (ret <= 0) + break; + + spliced += ret; + len -= ret; + tail = pipe->tail; + while (ret > 0) { + struct pipe_buffer *buf = &pipe->bufs[tail & mask]; + size_t seg = min_t(size_t, ret, buf->len); + + buf->offset += seg; + buf->len -= seg; + ret -= seg; + + if (!buf->len) { + pipe_buf_release(pipe, buf); + tail++; + } + } + + if (tail != pipe->tail) { + pipe->tail = tail; + if (pipe->files) + need_wakeup = true; + } + } + +out: + pipe_unlock(pipe); + if (need_wakeup) + wakeup_pipe_writers(pipe); + return spliced ?: ret; +} +#endif static int warn_unsupported(struct file *file, const char *op) { diff --git a/include/linux/fs.h b/include/linux/fs.h index 21a981680856..f8254c3acf83 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -2759,8 +2759,6 @@ extern ssize_t generic_file_splice_read(struct file *, loff_t *, struct pipe_inode_info *, size_t, unsigned int); extern ssize_t iter_file_splice_write(struct pipe_inode_info *, struct file *, loff_t *, size_t, unsigned int); -extern ssize_t generic_splice_sendpage(struct pipe_inode_info *pipe, - struct file *out, loff_t *, size_t len, unsigned int flags); extern long do_splice_direct(struct file *in, loff_t *ppos, struct file *out, loff_t *opos, size_t len, unsigned int flags); diff --git a/include/linux/splice.h b/include/linux/splice.h index a55179fd60fc..991ae318b6eb 100644 --- a/include/linux/splice.h +++ b/include/linux/splice.h @@ -84,6 +84,8 @@ extern long do_splice(struct file *in, loff_t *off_in, extern long do_tee(struct file *in, struct file *out, size_t len, unsigned int flags); +extern ssize_t splice_to_socket(struct pipe_inode_info *pipe, struct file *out, + loff_t *ppos, size_t len, unsigned int flags); /* * for dynamic pipe sizing diff --git a/net/socket.c b/net/socket.c index 3df96e9ba4e2..c4d9104418c8 100644 --- a/net/socket.c +++ b/net/socket.c @@ -57,6 +57,7 @@ #include #include #include +#include #include #include #include @@ -126,8 +127,6 @@ static long compat_sock_ioctl(struct file *file, unsigned int cmd, unsigned long arg); #endif static int sock_fasync(int fd, struct file *filp, int on); -static ssize_t sock_sendpage(struct file *file, struct page *page, - int offset, size_t size, loff_t *ppos, int more); static ssize_t sock_splice_read(struct file *file, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags); @@ -162,8 +161,7 @@ static const struct file_operations socket_file_ops = { .mmap = sock_mmap, .release = sock_close, .fasync = sock_fasync, - .sendpage = sock_sendpage, - .splice_write = generic_splice_sendpage, + .splice_write = splice_to_socket, .splice_read = sock_splice_read, .show_fdinfo = sock_show_fdinfo, }; @@ -1066,26 +1064,6 @@ int kernel_recvmsg(struct socket *sock, struct msghdr *msg, } EXPORT_SYMBOL(kernel_recvmsg); -static ssize_t sock_sendpage(struct file *file, struct page *page, - int offset, size_t size, loff_t *ppos, int more) -{ - struct socket *sock; - int flags; - int ret; - - sock = file->private_data; - - flags = (file->f_flags & O_NONBLOCK) ? MSG_DONTWAIT : 0; - /* more is a combination of MSG_MORE and MSG_SENDPAGE_NOTLAST */ - flags |= more; - - ret = kernel_sendpage(sock, page, offset, size, flags); - - if (trace_sock_send_length_enabled()) - call_trace_sock_send_length(sock->sk, ret, 0); - return ret; -} - static ssize_t sock_splice_read(struct file *file, loff_t *ppos, struct pipe_inode_info *pipe, size_t len, unsigned int flags) From patchwork Fri Jun 2 15:07:46 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102590 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1102134vqr; Fri, 2 Jun 2023 08:15:53 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4oeC1vSdxgaanF+f330+x2ZkV321nMwdJHaXn/X9VYNu7GEe9RsLLn9ns9cW1E5GAWIS6A X-Received: by 2002:a05:6a21:3398:b0:10c:2349:459e with SMTP id yy24-20020a056a21339800b0010c2349459emr14611285pzb.10.1685718952790; Fri, 02 Jun 2023 08:15:52 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685718952; cv=none; d=google.com; s=arc-20160816; b=hp+b/wPkgt0VQmdOWdqp7idvGaj3Rn2eBdZ0uzNctKh2Y7bWhPdWvLlOdyVUhn6Y93 PdBuJkjvqcYNC9Tk6Wv/fiklboa7DRgibJtuAomCG5InPChm/9uVDXO06WcV2siRVLh9 N46aLoMUjr7O8aEEoArKakIjAhG7d79LGWN5Kfseu3QI3c41YNJHNaLKo19Zg7llRG77 9s0T2PYgoeUjs+2LvJ6813SWLG2NyKWMDp1CUTkyldQGrMg147LeA5UzvaTWkN9X1Guv KYNO1LJJDcISjtQQv1pBfaJ7XoFUbvDd7xqbk48Mf/nbHGW+c7u2i2lgwmginbjosnzz CgXQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=jyBtAHnxIDOUxFx8QcCqc48iyvS91zdxptS6bgS5LhE=; b=QoHWRSOemPncubsZLqd02DDJ5tDs9EXWIeJ3gKm2wgoRewIhRSjYadlBLh/sHATYJr k3Sy50cFwH7TrJ2sTjVZMHrVCfJ6QlAevrDMNQVJ4KeU0mJsbdBOucCo00S5WFtifQT/ ulPKiUoBhM02+CheA+lmoEpBKpJSDVh46Sppw24diYR9P6OSFF6OFnoF7maI794R8tKQ d7kqlINgheBOIzbf9F8cM21f8uBbDhM9FoRb6jOlnPDYXHzlSsR8YI63asL6IsITCeS6 pda7nqxuZYseYoMGXBxOt81RX8xjQpjpOKRp1Fh2zT5cTi8CZAlCIWj+qaol5rbFYdP6 QpYQ== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Kwvr6nEJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id i8-20020a639d08000000b0053b86623b3asi1096994pgd.577.2023.06.02.08.15.40; Fri, 02 Jun 2023 08:15:52 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=Kwvr6nEJ; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236464AbjFBPJ3 (ORCPT + 99 others); Fri, 2 Jun 2023 11:09:29 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:57956 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236461AbjFBPJR (ORCPT ); Fri, 2 Jun 2023 11:09:17 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 50395E49 for ; Fri, 2 Jun 2023 08:08:30 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718509; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=jyBtAHnxIDOUxFx8QcCqc48iyvS91zdxptS6bgS5LhE=; b=Kwvr6nEJPCjtsqpQeS5DkJPp4skcMBfsM/eEaY66xVcEBuUvWEFlEnigdnjbEL9T9Fyd48 fl0Q1GLtics6RaaYtjVPFa2IN43Jh0npXlLE3kDeZUl3VNIo9KvdWrqvBVEcRKzUzqkY16 cztjpvx+9dgyMEGN8N0rmwlRkp3Q2n0= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-652-HJKW5r7wNUG_h4BsM00Cfg-1; Fri, 02 Jun 2023 11:08:26 -0400 X-MC-Unique: HJKW5r7wNUG_h4BsM00Cfg-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 42DA4811E8F; Fri, 2 Jun 2023 15:08:25 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 30388492B00; Fri, 2 Jun 2023 15:08:22 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Christoph Hellwig , Al Viro , Jan Kara , Jeff Layton , David Hildenbrand , Christian Brauner , linux-fsdevel@vger.kernel.org, linux-block@vger.kernel.org Subject: [PATCH net-next v3 05/11] splice, net: Fix SPLICE_F_MORE signalling in splice_direct_to_actor() Date: Fri, 2 Jun 2023 16:07:46 +0100 Message-ID: <20230602150752.1306532-6-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767604436656491763?= X-GMAIL-MSGID: =?utf-8?q?1767604436656491763?= splice_direct_to_actor() doesn't manage SPLICE_F_MORE correctly[1] - and, as a result, it incorrectly signals/fails to signal MSG_MORE when splicing to a socket. The problem I'm seeing happens when a short splice occurs because we got a short read due to hitting the EOF on a file: as the length read (read_len) is less than the remaining size to be spliced (len), SPLICE_F_MORE (and thus MSG_MORE) is set. The issue is that, for the moment, we have no way to know *why* the short read occurred and so can't make a good decision on whether we *should* keep MSG_MORE set. Further, the argument can be made that it should be left to userspace to decide how to handle it - userspace could perform some sort of cancellation for example. MSG_SENDPAGE_NOTLAST was added to work around this, but that is also set incorrectly under some circumstances - for example if a short read fills a single pipe_buffer, but the next read would return more (seqfile can do this). This was observed with the multi_chunk_sendfile tests in the tls kselftest program. Some of those tests would hang and time out when the last chunk of file was less than the sendfile request size: build/kselftest/net/tls -r tls.12_aes_gcm.multi_chunk_sendfile This has been observed before[2] and worked around in AF_TLS[3]. Fix this by making splice_direct_to_actor() always signal SPLICE_F_MORE if we haven't yet hit the requested operation size. SPLICE_F_MORE remains signalled if the user passed it in to splice() but otherwise gets cleared when we've read sufficient data to fulfill the request. The cleanup of a short splice to userspace is left to userspace. [!] Note that this changes user-visible behaviour. It will cause the multi_chunk_sendfile tests in the TLS kselftest to fail. This failure in the testsuite will be addressed in a subsequent patch by making userspace do a zero-length send(). It appears that SPLICE_F_MORE is only used by splice-to-socket. Signed-off-by: David Howells cc: Linus Torvalds cc: Jakub Kicinski cc: Jens Axboe cc: Christoph Hellwig cc: Al Viro cc: Matthew Wilcox cc: Jan Kara cc: Jeff Layton cc: David Hildenbrand cc: Christian Brauner cc: Chuck Lever cc: Boris Pismenny cc: John Fastabend cc: Eric Dumazet cc: "David S. Miller" cc: Paolo Abeni cc: linux-fsdevel@vger.kernel.org cc: linux-block@vger.kernel.org cc: linux-mm@kvack.org cc: netdev@vger.kernel.org Link: https://lore.kernel.org/r/499791.1685485603@warthog.procyon.org.uk/ [1] Link: https://lore.kernel.org/r/1591392508-14592-1-git-send-email-pooja.trivedi@stackpath.com/ [2] Link: https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git/commit/?id=d452d48b9f8b1a7f8152d33ef52cfd7fe1735b0a [3] --- fs/splice.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) diff --git a/fs/splice.c b/fs/splice.c index 9b1d43c0c562..c71bd8e03469 100644 --- a/fs/splice.c +++ b/fs/splice.c @@ -1052,13 +1052,17 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, */ bytes = 0; len = sd->total_len; + + /* Don't block on output, we have to drain the direct pipe. */ flags = sd->flags; + sd->flags &= ~SPLICE_F_NONBLOCK; /* - * Don't block on output, we have to drain the direct pipe. + * We signal MORE until we've read sufficient data to fulfill the + * request and we keep signalling it if the caller set it. */ - sd->flags &= ~SPLICE_F_NONBLOCK; more = sd->flags & SPLICE_F_MORE; + sd->flags |= SPLICE_F_MORE; WARN_ON_ONCE(!pipe_empty(pipe->head, pipe->tail)); @@ -1074,14 +1078,12 @@ ssize_t splice_direct_to_actor(struct file *in, struct splice_desc *sd, sd->total_len = read_len; /* - * If more data is pending, set SPLICE_F_MORE - * If this is the last data and SPLICE_F_MORE was not set - * initially, clears it. + * If we now have sufficient data to fulfill the request then + * we clear SPLICE_F_MORE if it was not set initially. */ - if (read_len < len) - sd->flags |= SPLICE_F_MORE; - else if (!more) + if (read_len >= len && !more) sd->flags &= ~SPLICE_F_MORE; + /* * NOTE: nonblocking mode only applies to the input. We * must not do the output in nonblocking mode as then we From patchwork Fri Jun 2 15:07:47 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102594 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1106320vqr; Fri, 2 Jun 2023 08:21:50 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6DaaufzKWgyqrEsnM50c9Ze8RUpgkBaTb3sWMq+GruqmGKem+pJLMzbYk858VRCL4D5xpS X-Received: by 2002:a17:90a:7147:b0:253:74f8:1e31 with SMTP id g7-20020a17090a714700b0025374f81e31mr152099pjs.39.1685719309960; Fri, 02 Jun 2023 08:21:49 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685719309; cv=none; d=google.com; s=arc-20160816; b=r1QynA9gX9L1fO0EASAdlipi5incm1bfaJP6nf8m3XkyjDSKehlu1cCm869fcjmjB6 K214wAEk6y9miWWaisEIAB7tyJ9MM7YSp+Ffj4cmDR1ulAPAm1hrgubNiKhEPH5nLZdH zshKSxdb5vpO1jr1/Ka3+shA4VUheAZiIxK8hnfkVIpvkgkb/8rlKZ0lwXaym7EsLr5C +8A3FDVjhcEVZPO5gnlPjJYgyT5u10ng0RMQk5ZlxAjw5YP5gSMlldKqR+CEK+/DNb2d MNMGzbFrKngOB8snrReNR9ekmI9t/PJnx3if1SUlciG3Wd9ozmk3NRas0OMLQPvi62kK NDcw== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=2ZNhwXeGIbA58IS6DHid2Q6FV7QVgcqbxppr3d+VzBk=; b=eIEVNSrGxysZci3mXRpQ49akr7Piz+DSiXKGI5O9R/e9ALByocEN47ukfy8VINs08J 5QOIsrNop6R2P6ejQ4wxuINOvYvR6SU4+dFYkpnHrJ3a3eCC1rmH6ndfLKwDGHxxCytW TTCrW0hopzBWPwJancOtNyYNsb3yHlC64wTlgUy7MlGBsFW504yY4qNXv2HewAdKJPYe k84ILqlBCbzwzSCPDsKPETVpj9BkpTKeTvYN2mMczVmzL4QjukEccbaOfwCaiFGLqfJh uSxORB83m3XHu3qb8CTV0oj8636+DEGMNFkzkBVVEZ8me4vpHHsfy9JXZ1A67mlkraCA JU/Q== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=aUCtBTl9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id gj22-20020a17090b109600b0024df8757367si1184011pjb.87.2023.06.02.08.21.35; Fri, 02 Jun 2023 08:21:49 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=aUCtBTl9; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236513AbjFBPJj (ORCPT + 99 others); Fri, 2 Jun 2023 11:09:39 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58030 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236407AbjFBPJY (ORCPT ); Fri, 2 Jun 2023 11:09:24 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 14E75E4A for ; Fri, 2 Jun 2023 08:08:35 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718514; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=2ZNhwXeGIbA58IS6DHid2Q6FV7QVgcqbxppr3d+VzBk=; b=aUCtBTl9gsDcwQXshNUm3oCfKjR4vr1TUw/JScwzeZdfnv9/WgcSr2TrRQQmzCr6+QkeaV mCkc2eTk/Ay5X2K+bdq2A1Mfpp9VjEv+h7gnu16ygs5sKd8wvKiNy78nBRPExmpFn3ZgOk b3W/K1LluMVOtzsVc6mfSI0gvUAxABg= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-257-hxUTvV89POCJp7sspC3Tpw-1; Fri, 02 Jun 2023 11:08:29 -0400 X-MC-Unique: hxUTvV89POCJp7sspC3Tpw-1 Received: from smtp.corp.redhat.com (int-mx05.intmail.prod.int.rdu2.redhat.com [10.11.54.5]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 49A92811E96; Fri, 2 Jun 2023 15:08:28 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 255369E60; Fri, 2 Jun 2023 15:08:26 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 06/11] tls: Address behaviour change in multi_chunk_sendfile kselftest Date: Fri, 2 Jun 2023 16:07:47 +0100 Message-ID: <20230602150752.1306532-7-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.5 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767604811109681126?= X-GMAIL-MSGID: =?utf-8?q?1767604811109681126?= The multi_chunk_sendfile tests in the TLS kselftest now fail because the behaviour of sendfile()[*] changed when SPLICE_F_MORE signalling was fixed. Now MSG_MORE is signalled to the socket until we have read sufficient data to fulfill the request - which means if we get a short read, MSG_MORE isn't seen to be dropped and the TLS record remains pending. [*] This will also affect splice() if SPLICE_F_MORE isn't included in the flags. Fix the TLS multi_chunk_sendfile kselftest to attempt to flush the outstanding TLS record if we get a short sendfile() by doing a zero-length send() with MSG_MORE unset. Signed-off-by: David Howells cc: Chuck Lever cc: Boris Pismenny cc: John Fastabend cc: Jakub Kicinski cc: Eric Dumazet cc: "David S. Miller" cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org --- tools/testing/selftests/net/tls.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/testing/selftests/net/tls.c b/tools/testing/selftests/net/tls.c index e699548d4247..8f4bed8aacc0 100644 --- a/tools/testing/selftests/net/tls.c +++ b/tools/testing/selftests/net/tls.c @@ -377,7 +377,7 @@ static void chunked_sendfile(struct __test_metadata *_metadata, char buf[TLS_PAYLOAD_MAX_LEN]; uint16_t test_payload_size; int size = 0; - int ret; + int ret = 0; char filename[] = "/tmp/mytemp.XXXXXX"; int fd = mkstemp(filename); off_t offset = 0; @@ -398,6 +398,10 @@ static void chunked_sendfile(struct __test_metadata *_metadata, size -= ret; } + /* Flush the TLS record on a short read. */ + if (ret < chunk_size) + EXPECT_EQ(send(self->fd, "", 0, 0), 0); + EXPECT_EQ(recv(self->cfd, buf, test_payload_size, MSG_WAITALL), test_payload_size); From patchwork Fri Jun 2 15:07:48 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102589 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1101738vqr; Fri, 2 Jun 2023 08:15:27 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6BS4zJcZgJVET1qzRAfZ6/7N2HlD+SNCuPHGGxqOP8MVA4z+KK5vlWAsPOE/BZWRgMbBG1 X-Received: by 2002:a17:903:1cc:b0:1b0:2658:db20 with SMTP id e12-20020a17090301cc00b001b02658db20mr213329plh.53.1685718926746; Fri, 02 Jun 2023 08:15:26 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685718926; cv=none; d=google.com; s=arc-20160816; b=PNkpnxP75zi8o+4YDryYc9zZJc5v1Dx39paQ0C9VA4hK3mr2hr1yQ/irI49nOqTCL5 PJFGXoOudUlPJ3g7Jd3JGrJTgT8cQffBsrm9+ULyHrLao/d74vdf7pO5vAUvPhg8WvYn H0SpDY7XsX8Dala3USDjqPZ5jn7CpXAlibm+CnzL1sYM0I3apfrtASdqG7ftljNXJE69 NFYUFOyxNVK1uZITe8ueipIWydF/ECgUyE/DOVMIdJPHMT4ZsCNUgEiVRuWvNrcsi0Gn AyAw6Rm3W78UuK2GNouSVKACJILO7VV2w0xo6g/v6npPS+bqdQnikczW7Y4VDQNLh8vw Em8A== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=VkjM4EGYNz4bsSc92zEJRjklGPZ81HVRDlJ8Fsl+T7k=; b=GhZJEPzqZDUGuh1I2GZU4ti5tgf2MP3UkxN5EXWjgCOvvU28ZXSAyTuQLWiUJWKjb3 3d/wOzl88CVQIz5SrGMWny2N+zQvkiYbGiWgg4b8+GykWQ7e6bQdPtHchYlKDk79tsvZ GaIHoFViWV+Tkh0f3GocFx8ohVc7zijFuDJukXPxXzm4wzY6J4mJS0LV+jih8u2DeS67 M/CxYbhiJu6Bxnq9b9kuKbcOxQQz4J4rdM5Rg6yZ+aQy2PZ2AUy0CY9YgSidcQ8tZ0BB djA2zaX2+4BLeLVSF3kp6k+fzySvn7xK8U49UlY6E7sbl2X9QnaW4CII3/5yew5RlfwD b7cg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=CRZ+loX6; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ik6-20020a170902ab0600b001ac6b926624si1036794plb.122.2023.06.02.08.15.14; Fri, 02 Jun 2023 08:15:26 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=CRZ+loX6; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236500AbjFBPJf (ORCPT + 99 others); Fri, 2 Jun 2023 11:09:35 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58040 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236449AbjFBPJY (ORCPT ); Fri, 2 Jun 2023 11:09:24 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id F3732E59 for ; Fri, 2 Jun 2023 08:08:36 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718516; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=VkjM4EGYNz4bsSc92zEJRjklGPZ81HVRDlJ8Fsl+T7k=; b=CRZ+loX6AIcvDMEHOvuFEDM/QYCDgkxX0VPtK5tGjDzb6kgIi3xj80YL4wwk9M5GSgw+xU YTkOP8E/gdbrHDzJc4OlLn9dE/qlxzELueataA4HO6K67HQ6RpqCm/UgDysCm5uFKp7/VC NbufJZXUq1XbPQ0twODJaAhf/1Rz+f0= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-552-_zaZ26ErPBGk4yKO8qBKjw-1; Fri, 02 Jun 2023 11:08:32 -0400 X-MC-Unique: _zaZ26ErPBGk4yKO8qBKjw-1 Received: from smtp.corp.redhat.com (int-mx09.intmail.prod.int.rdu2.redhat.com [10.11.54.9]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id 6021929AB3FA; Fri, 2 Jun 2023 15:08:31 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 1B13C40146F; Fri, 2 Jun 2023 15:08:29 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 07/11] tls/sw: Support MSG_SPLICE_PAGES Date: Fri, 2 Jun 2023 16:07:48 +0100 Message-ID: <20230602150752.1306532-8-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.9 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767604409388655683?= X-GMAIL-MSGID: =?utf-8?q?1767604409388655683?= Make TLS's sendmsg() support MSG_SPLICE_PAGES. This causes pages to be spliced from the source iterator if possible. This allows ->sendpage() to be replaced by something that can handle multiple multipage folios in a single transaction. Signed-off-by: David Howells cc: Chuck Lever cc: Boris Pismenny cc: John Fastabend cc: Jakub Kicinski cc: Eric Dumazet cc: "David S. Miller" cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org --- Notes: ver #2) - "rls_" should be "tls_". net/tls/tls_sw.c | 46 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 45 insertions(+), 1 deletion(-) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 6aa6d17888f5..14636cc6c3a4 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -929,6 +929,38 @@ static int tls_sw_push_pending_record(struct sock *sk, int flags) &copied, flags); } +static int tls_sw_sendmsg_splice(struct sock *sk, struct msghdr *msg, + struct sk_msg *msg_pl, size_t try_to_copy, + ssize_t *copied) +{ + struct page *page = NULL, **pages = &page; + + do { + ssize_t part; + size_t off; + bool put = false; + + part = iov_iter_extract_pages(&msg->msg_iter, &pages, + try_to_copy, 1, 0, &off); + if (part <= 0) + return part ?: -EIO; + + if (WARN_ON_ONCE(!sendpage_ok(page))) { + iov_iter_revert(&msg->msg_iter, part); + return -EIO; + } + + sk_msg_page_add(msg_pl, page, part, off); + sk_mem_charge(sk, part); + if (put) + put_page(page); + *copied += part; + try_to_copy -= part; + } while (try_to_copy && !sk_msg_full(msg_pl)); + + return 0; +} + int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) { long timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); @@ -1021,6 +1053,17 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) full_record = true; } + if (try_to_copy && (msg->msg_flags & MSG_SPLICE_PAGES)) { + ret = tls_sw_sendmsg_splice(sk, msg, msg_pl, + try_to_copy, &copied); + if (ret < 0) + goto send_end; + tls_ctx->pending_open_record_frags = true; + if (full_record || eor || sk_msg_full(msg_pl)) + goto copied; + continue; + } + if (!is_kvec && (full_record || eor) && !async_capable) { u32 first = msg_pl->sg.end; @@ -1083,8 +1126,9 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) /* Open records defined only if successfully copied, otherwise * we would trim the sg but not reset the open record frags. */ - tls_ctx->pending_open_record_frags = true; copied += try_to_copy; +copied: + tls_ctx->pending_open_record_frags = true; just_flush: if (full_record || eor) { ret = bpf_exec_tx_verdict(msg_pl, sk, full_record, From patchwork Fri Jun 2 15:07:49 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102613 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1116169vqr; Fri, 2 Jun 2023 08:36:30 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ4wtMf6q8alivz20oGzCNuM9SNfrHpY5tpvIKNiwETGsFvU9ZXqY1vo/FejNHX8oTjtxh6x X-Received: by 2002:a05:6a20:8f1d:b0:105:2e9e:b13a with SMTP id b29-20020a056a208f1d00b001052e9eb13amr6230861pzk.8.1685720190616; Fri, 02 Jun 2023 08:36:30 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685720190; cv=none; d=google.com; s=arc-20160816; b=jjIF+OmoFSwKMVchdP4UE7O6q6ZjMg0kWJOK5Bi4AmqiVOwF93KTYZJltPO2t4xyQu XHDt40UJ/2GdfoBDhB8PRne17sBA2b6qp3S8gERAVuhj3TDzwojpFxDKpebHuvDc7drr vUc8JrhqHcIpTsmMSCqIGc3JLD9nmswS2nr4Uc5RhpWQhJ4gBKarwY7fUJfjeqWkH2Ou WCBJMjsgAaGhIN0ZLyCvZrL23UO19z8D7r30FR2gjUowRs1zQPTCCw0Ow+qb0y1K4cMA KCU45+ea0ZhUzO3/e6tTkQLq1UKFP9xF9RiUSHaHrSjEGe0yoiUpcuuGeFnIP/yT3g6g go7Q== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=dyjSa8hJz7UgTqVeMMh3QM5bpfol5ixZ+Ouwr1vUw7E=; b=xWqs5Cmdda98I322tg8jNekEGHUgwlf8Vv4JIlK9xwuUlB3/rDJPs1ADl9UvbhCU2l wtwOHtBZi0642yGGaT/pMO8H5SthX/ixopYOMooaqaaGedJpwLakrepJCgRinT/W6BSY DhFMW5kKUaxHR9W4ze9/TIie6nsICSqrSbDxslm7Dhx4CchdcY89Sq4Dp9TYe19ecYTl M1PcND6rZYOOgN2pOzfdig6zlVoJHnpXTCi9nEpdX/a+DBK/liYvdN5AYvbZtRQ29ItW vKAwCI7bKON62mtU6Eum8S/aThNZEKAOlEO9XtQAbbP1ChWHLCbrLyTTyAH6MseA9Vi8 n6Ww== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=GopkkhdE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id b18-20020a637152000000b0053fb7d0fa78si1122380pgn.812.2023.06.02.08.36.18; Fri, 02 Jun 2023 08:36:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=GopkkhdE; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235625AbjFBPPN (ORCPT + 99 others); Fri, 2 Jun 2023 11:15:13 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:34952 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236742AbjFBPPD (ORCPT ); Fri, 2 Jun 2023 11:15:03 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 67D9BE58 for ; Fri, 2 Jun 2023 08:13:48 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718827; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=dyjSa8hJz7UgTqVeMMh3QM5bpfol5ixZ+Ouwr1vUw7E=; b=GopkkhdE5CYc8dAB7kUkTA7ycqER7/uBfU+GukBWOvJaxAfCmBMjO/n9G1uzKpzw3VzXwG 2k3w8/0zeotoVv+uoTamqo9AkZOx8/rvSWErx84R2uhXp+RYJYL3LPxPHjooYFRB5VUHys pY6XpHAqVExb2JH07nLsbTw74aqV92M= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-354-g2k8_go1Pi2GTrqqkIP0gg-1; Fri, 02 Jun 2023 11:13:44 -0400 X-MC-Unique: g2k8_go1Pi2GTrqqkIP0gg-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id B5BB63802267; Fri, 2 Jun 2023 15:08:36 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id A31F72026D49; Fri, 2 Jun 2023 15:08:32 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org, bpf@vger.kernel.org Subject: [PATCH net-next v3 08/11] tls/sw: Convert tls_sw_sendpage() to use MSG_SPLICE_PAGES Date: Fri, 2 Jun 2023 16:07:49 +0100 Message-ID: <20230602150752.1306532-9-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767605734775726151?= X-GMAIL-MSGID: =?utf-8?q?1767605734775726151?= Convert tls_sw_sendpage() and tls_sw_sendpage_locked() to use sendmsg() with MSG_SPLICE_PAGES rather than directly splicing in the pages itself. [!] Note that tls_sw_sendpage_locked() appears to have the wrong locking upstream. I think the caller will only hold the socket lock, but it should hold tls_ctx->tx_lock too. This allows ->sendpage() to be replaced by something that can handle multiple multipage folios in a single transaction. Signed-off-by: David Howells cc: Chuck Lever cc: Boris Pismenny cc: John Fastabend cc: Jakub Kicinski cc: Eric Dumazet cc: "David S. Miller" cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org cc: bpf@vger.kernel.org --- net/tls/tls_sw.c | 165 +++++++++-------------------------------------- 1 file changed, 31 insertions(+), 134 deletions(-) diff --git a/net/tls/tls_sw.c b/net/tls/tls_sw.c index 14636cc6c3a4..4caed478bef8 100644 --- a/net/tls/tls_sw.c +++ b/net/tls/tls_sw.c @@ -961,7 +961,8 @@ static int tls_sw_sendmsg_splice(struct sock *sk, struct msghdr *msg, return 0; } -int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) +static int tls_sw_sendmsg_locked(struct sock *sk, struct msghdr *msg, + size_t size) { long timeo = sock_sndtimeo(sk, msg->msg_flags & MSG_DONTWAIT); struct tls_context *tls_ctx = tls_get_ctx(sk); @@ -984,15 +985,6 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) int ret = 0; int pending; - if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | - MSG_CMSG_COMPAT | MSG_SPLICE_PAGES)) - return -EOPNOTSUPP; - - ret = mutex_lock_interruptible(&tls_ctx->tx_lock); - if (ret) - return ret; - lock_sock(sk); - if (unlikely(msg->msg_controllen)) { ret = tls_process_cmsg(sk, msg, &record_type); if (ret) { @@ -1197,157 +1189,62 @@ int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) send_end: ret = sk_stream_error(sk, msg->msg_flags, ret); - - release_sock(sk); - mutex_unlock(&tls_ctx->tx_lock); return copied > 0 ? copied : ret; } -static int tls_sw_do_sendpage(struct sock *sk, struct page *page, - int offset, size_t size, int flags) +int tls_sw_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) { - long timeo = sock_sndtimeo(sk, flags & MSG_DONTWAIT); struct tls_context *tls_ctx = tls_get_ctx(sk); - struct tls_sw_context_tx *ctx = tls_sw_ctx_tx(tls_ctx); - struct tls_prot_info *prot = &tls_ctx->prot_info; - unsigned char record_type = TLS_RECORD_TYPE_DATA; - struct sk_msg *msg_pl; - struct tls_rec *rec; - int num_async = 0; - ssize_t copied = 0; - bool full_record; - int record_room; - int ret = 0; - bool eor; - - eor = !(flags & MSG_SENDPAGE_NOTLAST); - sk_clear_bit(SOCKWQ_ASYNC_NOSPACE, sk); - - /* Call the sk_stream functions to manage the sndbuf mem. */ - while (size > 0) { - size_t copy, required_size; - - if (sk->sk_err) { - ret = -sk->sk_err; - goto sendpage_end; - } - - if (ctx->open_rec) - rec = ctx->open_rec; - else - rec = ctx->open_rec = tls_get_rec(sk); - if (!rec) { - ret = -ENOMEM; - goto sendpage_end; - } - - msg_pl = &rec->msg_plaintext; - - full_record = false; - record_room = TLS_MAX_PAYLOAD_SIZE - msg_pl->sg.size; - copy = size; - if (copy >= record_room) { - copy = record_room; - full_record = true; - } - - required_size = msg_pl->sg.size + copy + prot->overhead_size; - - if (!sk_stream_memory_free(sk)) - goto wait_for_sndbuf; -alloc_payload: - ret = tls_alloc_encrypted_msg(sk, required_size); - if (ret) { - if (ret != -ENOSPC) - goto wait_for_memory; - - /* Adjust copy according to the amount that was - * actually allocated. The difference is due - * to max sg elements limit - */ - copy -= required_size - msg_pl->sg.size; - full_record = true; - } - - sk_msg_page_add(msg_pl, page, copy, offset); - sk_mem_charge(sk, copy); - - offset += copy; - size -= copy; - copied += copy; - - tls_ctx->pending_open_record_frags = true; - if (full_record || eor || sk_msg_full(msg_pl)) { - ret = bpf_exec_tx_verdict(msg_pl, sk, full_record, - record_type, &copied, flags); - if (ret) { - if (ret == -EINPROGRESS) - num_async++; - else if (ret == -ENOMEM) - goto wait_for_memory; - else if (ret != -EAGAIN) { - if (ret == -ENOSPC) - ret = 0; - goto sendpage_end; - } - } - } - continue; -wait_for_sndbuf: - set_bit(SOCK_NOSPACE, &sk->sk_socket->flags); -wait_for_memory: - ret = sk_stream_wait_memory(sk, &timeo); - if (ret) { - if (ctx->open_rec) - tls_trim_both_msgs(sk, msg_pl->sg.size); - goto sendpage_end; - } + int ret; - if (ctx->open_rec) - goto alloc_payload; - } + if (msg->msg_flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | + MSG_CMSG_COMPAT | MSG_SPLICE_PAGES | + MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY)) + return -EOPNOTSUPP; - if (num_async) { - /* Transmit if any encryptions have completed */ - if (test_and_clear_bit(BIT_TX_SCHEDULED, &ctx->tx_bitmask)) { - cancel_delayed_work(&ctx->tx_work.work); - tls_tx_records(sk, flags); - } - } -sendpage_end: - ret = sk_stream_error(sk, flags, ret); - return copied > 0 ? copied : ret; + ret = mutex_lock_interruptible(&tls_ctx->tx_lock); + if (ret) + return ret; + lock_sock(sk); + ret = tls_sw_sendmsg_locked(sk, msg, size); + release_sock(sk); + mutex_unlock(&tls_ctx->tx_lock); + return ret; } int tls_sw_sendpage_locked(struct sock *sk, struct page *page, int offset, size_t size, int flags) { + struct bio_vec bvec; + struct msghdr msg = { .msg_flags = flags | MSG_SPLICE_PAGES, }; + if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY | MSG_NO_SHARED_FRAGS)) return -EOPNOTSUPP; + if (flags & MSG_SENDPAGE_NOTLAST) + msg.msg_flags |= MSG_MORE; - return tls_sw_do_sendpage(sk, page, offset, size, flags); + bvec_set_page(&bvec, page, size, offset); + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); + return tls_sw_sendmsg_locked(sk, &msg, size); } int tls_sw_sendpage(struct sock *sk, struct page *page, int offset, size_t size, int flags) { - struct tls_context *tls_ctx = tls_get_ctx(sk); - int ret; + struct bio_vec bvec; + struct msghdr msg = { .msg_flags = flags | MSG_SPLICE_PAGES, }; if (flags & ~(MSG_MORE | MSG_DONTWAIT | MSG_NOSIGNAL | MSG_SENDPAGE_NOTLAST | MSG_SENDPAGE_NOPOLICY)) return -EOPNOTSUPP; + if (flags & MSG_SENDPAGE_NOTLAST) + msg.msg_flags |= MSG_MORE; - ret = mutex_lock_interruptible(&tls_ctx->tx_lock); - if (ret) - return ret; - lock_sock(sk); - ret = tls_sw_do_sendpage(sk, page, offset, size, flags); - release_sock(sk); - mutex_unlock(&tls_ctx->tx_lock); - return ret; + bvec_set_page(&bvec, page, size, offset); + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); + return tls_sw_sendmsg(sk, &msg, size); } static int From patchwork Fri Jun 2 15:07:50 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102618 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1116679vqr; Fri, 2 Jun 2023 08:37:14 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5fXuQK5oIkSpVghUr2HexQY8RG0brwCbBpGYaRVGMYPPZUdOkao1f4ALyUXKHAU5PQLNt3 X-Received: by 2002:a05:6a00:1a8f:b0:64d:277c:77c3 with SMTP id e15-20020a056a001a8f00b0064d277c77c3mr15503476pfv.23.1685720233875; Fri, 02 Jun 2023 08:37:13 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685720233; cv=none; d=google.com; s=arc-20160816; b=iw+9EBWUND+ospLqcWG2BQqRKcHCOtxh03AjpS5kcfb84V4KoGPGZde8L3f5FQ0IEZ GB3IOiPU7f6E8wl+Dkly1PZ9oz0lB1y7CyJBKmQy2nfxHvEi9hB2oouKccXn04vYO+dl TJvN/TQq+09z7TzGv60Js8ax1CSOceajrB4ehDn8Nan2lQ4uJTNsb4OIXwtDvwc10qfp YtUto72VQfLWNJkywW35sGWYKiLSD6FjZiY1PuuOq0XZRW6+HPz5AQf3u8hMqLYFCh84 enpmPB+od1IlO/jq+ufa1aRDg9GpuPVkYmeLhsbUdxKaPCG91X5ocB8FCFtf0QkaLsn0 3KRQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=i1bosU+FfxRloSp1wkQbe5FyZjgR/CpUzjqQmhn8VOU=; b=e4g6XCMMIbaSXgDP4wdrxqcy+/qQgYFJDUr59Y4yJ+JSWr0GoL2QokGOaTcTTdiTEb DQJOASnl0joatn9Z9QNkA/pIyrSDpuAppbpSPz2t4Ta+iWqHrjoEWV+wHkjBOBxY1Pgi IpD5tKShTBC4L/+JQnnWSDHYGfnk/vcnsQG+dARqV/8csanqt8Q1jogNvShRdWvQy1/P pJai6iWrnHJqWzHRICijwcw1LU5vU1huEqBd9gt6vZb8sBHgc2JDf1bjlPU20CuCK5Ku P0n8qy4i/giCDWd36VQ50OfcRYdaFNuC4I/r2X5quwkuHIm4ndOcIOBHl3hJRyF2Fldr q0Iw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=XSK5j4vA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id h125-20020a625383000000b0064d2f7f1622si931137pfb.68.2023.06.02.08.37.01; Fri, 02 Jun 2023 08:37:13 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=XSK5j4vA; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236540AbjFBPJx (ORCPT + 99 others); Fri, 2 Jun 2023 11:09:53 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58170 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236485AbjFBPJf (ORCPT ); Fri, 2 Jun 2023 11:09:35 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 53AD0E41 for ; Fri, 2 Jun 2023 08:08:45 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718524; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=i1bosU+FfxRloSp1wkQbe5FyZjgR/CpUzjqQmhn8VOU=; b=XSK5j4vASOImozX0qe4hzxcz/uK711ej2eOOYUvLPorXWnzfvrjm2/H6gZPd+1pUk/mhq4 3TM6gXr4JjzwBqvLndNFc3mmmNgIWc2Y/jA+kXXxV6KsShIk26mryVROjXPm8sS1NNoG0z TGdTkp4BPsku9ypYK26VBu6ahaaX8So= Received: from mimecast-mx02.redhat.com (mimecast-mx02.redhat.com [66.187.233.88]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-618-i_fo6rKYNaiI2OVO_0s6fw-1; Fri, 02 Jun 2023 11:08:41 -0400 X-MC-Unique: i_fo6rKYNaiI2OVO_0s6fw-1 Received: from smtp.corp.redhat.com (int-mx10.intmail.prod.int.rdu2.redhat.com [10.11.54.10]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A77CA8028B2; Fri, 2 Jun 2023 15:08:40 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 785D0492B0C; Fri, 2 Jun 2023 15:08:37 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 09/11] tls/device: Support MSG_SPLICE_PAGES Date: Fri, 2 Jun 2023 16:07:50 +0100 Message-ID: <20230602150752.1306532-10-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.10 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767605779555136355?= X-GMAIL-MSGID: =?utf-8?q?1767605779555136355?= Make TLS's device sendmsg() support MSG_SPLICE_PAGES. This causes pages to be spliced from the source iterator if possible. This allows ->sendpage() to be replaced by something that can handle multiple multipage folios in a single transaction. Signed-off-by: David Howells cc: Chuck Lever cc: Boris Pismenny cc: John Fastabend cc: Jakub Kicinski cc: Eric Dumazet cc: "David S. Miller" cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org --- net/tls/tls_device.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index 9ef766e41c7a..f2f1aff19e4a 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -509,6 +509,29 @@ static int tls_push_data(struct sock *sk, tls_append_frag(record, &zc_pfrag, copy); iter_offset.offset += copy; + } else if (copy && (flags & MSG_SPLICE_PAGES)) { + struct page_frag zc_pfrag; + struct page **pages = &zc_pfrag.page; + size_t off; + + rc = iov_iter_extract_pages(iter_offset.msg_iter, + &pages, copy, 1, 0, &off); + if (rc <= 0) { + if (rc == 0) + rc = -EIO; + goto handle_error; + } + copy = rc; + + if (WARN_ON_ONCE(!sendpage_ok(zc_pfrag.page))) { + iov_iter_revert(iter_offset.msg_iter, copy); + rc = -EIO; + goto handle_error; + } + + zc_pfrag.offset = off; + zc_pfrag.size = copy; + tls_append_frag(record, &zc_pfrag, copy); } else if (copy) { copy = min_t(size_t, copy, pfrag->size - pfrag->offset); @@ -572,6 +595,9 @@ int tls_device_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) union tls_iter_offset iter; int rc; + if (!tls_ctx->zerocopy_sendfile) + msg->msg_flags &= ~MSG_SPLICE_PAGES; + mutex_lock(&tls_ctx->tx_lock); lock_sock(sk); From patchwork Fri Jun 2 15:07:51 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102614 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1116226vqr; Fri, 2 Jun 2023 08:36:34 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ6L5yU8dUcyZ6C++h1Um+NHKxd8Ih74W90EiZoXsIjQBhUc+1fGdArt8oOAJZeqPNhtPucZ X-Received: by 2002:a05:6a20:a122:b0:105:66d3:8538 with SMTP id q34-20020a056a20a12200b0010566d38538mr9799549pzk.8.1685720194397; Fri, 02 Jun 2023 08:36:34 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685720194; cv=none; d=google.com; s=arc-20160816; b=OWogG92A7WhxyWfUxexxonBHvcr4F7V1sLDMNxGZkSZbAZwZTaRV0UPToP0DsCoxyD 9l3lcCe3lkEFSDshv0DRc00SpmzdqmuyXsTxC2NBGyVWHeHYz0O5RcAWesWUbRnT0vq4 YOmFNituKcg+Qlp+bYlqg6qpLeYFjiTv3ZhMZMK/utaqoMXytc17A3WP3EGYnqbxqi7a AlFC1EdvpBcMOIrQHTZW3F4ZrPIN8ChjVJtOQmAHBJyVXBNABlyC6WfH6D4qyPRkgLNn vtc3lQYW4glRSygOJWqBpld62se9mJtQ6wwx5jcgvduXbxMG5fSVWrJY2TxJqcw7INtI +SYQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=mKfCy+bv0BFrGREXI3gIfX89zPW0d4xX2aV4J5lMm9c=; b=E1c/ds+dhwZZWAYCzWJYmSnMY72JJ/D4p9nme9gOMbH42orL3ZoIgjTf4gNOM2Rgno qytBO1499/7vcN0kLlAsFkpQdwMAyUCmFyLBirrqA5Y/NLWei9vMFWS4yKJAh0hF3WxV wddQ7naILilpPfg3gVT+pH8cHWd8onfLaCe9V3QNKIpGsM3m8mHz2iSEYHwoM+akoS0a N8yhQvD0H4SX4PtWTnx1yHY//7i/hlLn/yJJKwKmexa9JQ+guiWcRMkA5Um1K36hvtz5 yu2selwdwUOyGI2rjvDa8Nb6eZUXXiZZoJJFuRrklSewy/YIvai7Twd4koTXgd7oAi6O g7qg== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=B1yB6LDi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id n127-20020a632785000000b005287f5fbf5esi1172004pgn.254.2023.06.02.08.36.22; Fri, 02 Jun 2023 08:36:34 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=B1yB6LDi; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236434AbjFBPKQ (ORCPT + 99 others); Fri, 2 Jun 2023 11:10:16 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58224 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236514AbjFBPJk (ORCPT ); Fri, 2 Jun 2023 11:09:40 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B8A36E55 for ; Fri, 2 Jun 2023 08:08:52 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718532; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=mKfCy+bv0BFrGREXI3gIfX89zPW0d4xX2aV4J5lMm9c=; b=B1yB6LDiavCc6qtjXftc1Sm+eRdq2T3dXRan8gP2cLIofT3n8i1+Se4aKHSnD28Rr7TBx3 S0KGwANd5eB7JvfapO+iQHT1nA6kutEWvy760neOkcxXn6qxiyG0k1KrO6eD4QrVPZLtsz xn0dkWf3BBwBFFPqmhKWtTncgxSCq9A= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-486-9ryx0VvIPr2I-ceTIrBRHQ-1; Fri, 02 Jun 2023 11:08:45 -0400 X-MC-Unique: 9ryx0VvIPr2I-ceTIrBRHQ-1 Received: from smtp.corp.redhat.com (int-mx02.intmail.prod.int.rdu2.redhat.com [10.11.54.2]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id A84EF3C0C89F; Fri, 2 Jun 2023 15:08:44 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6F1AF40C6EC4; Fri, 2 Jun 2023 15:08:42 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org Subject: [PATCH net-next v3 10/11] tls/device: Convert tls_device_sendpage() to use MSG_SPLICE_PAGES Date: Fri, 2 Jun 2023 16:07:51 +0100 Message-ID: <20230602150752.1306532-11-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.2 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767605738418664395?= X-GMAIL-MSGID: =?utf-8?q?1767605738418664395?= Convert tls_device_sendpage() to use sendmsg() with MSG_SPLICE_PAGES rather than directly splicing in the pages itself. With that, the tls_iter_offset union is no longer necessary and can be replaced with an iov_iter pointer and the zc_page argument to tls_push_data() can also be removed. This allows ->sendpage() to be replaced by something that can handle multiple multipage folios in a single transaction. Signed-off-by: David Howells cc: Chuck Lever cc: Boris Pismenny cc: John Fastabend cc: Jakub Kicinski cc: Eric Dumazet cc: "David S. Miller" cc: Paolo Abeni cc: Jens Axboe cc: Matthew Wilcox cc: netdev@vger.kernel.org --- net/tls/tls_device.c | 84 +++++++++++--------------------------------- 1 file changed, 20 insertions(+), 64 deletions(-) diff --git a/net/tls/tls_device.c b/net/tls/tls_device.c index f2f1aff19e4a..c698d6d60219 100644 --- a/net/tls/tls_device.c +++ b/net/tls/tls_device.c @@ -422,16 +422,10 @@ static int tls_device_copy_data(void *addr, size_t bytes, struct iov_iter *i) return 0; } -union tls_iter_offset { - struct iov_iter *msg_iter; - int offset; -}; - static int tls_push_data(struct sock *sk, - union tls_iter_offset iter_offset, + struct iov_iter *iter, size_t size, int flags, - unsigned char record_type, - struct page *zc_page) + unsigned char record_type) { struct tls_context *tls_ctx = tls_get_ctx(sk); struct tls_prot_info *prot = &tls_ctx->prot_info; @@ -500,22 +494,13 @@ static int tls_push_data(struct sock *sk, record = ctx->open_record; copy = min_t(size_t, size, max_open_record_len - record->len); - if (copy && zc_page) { - struct page_frag zc_pfrag; - - zc_pfrag.page = zc_page; - zc_pfrag.offset = iter_offset.offset; - zc_pfrag.size = copy; - tls_append_frag(record, &zc_pfrag, copy); - - iter_offset.offset += copy; - } else if (copy && (flags & MSG_SPLICE_PAGES)) { + if (copy && (flags & MSG_SPLICE_PAGES)) { struct page_frag zc_pfrag; struct page **pages = &zc_pfrag.page; size_t off; - rc = iov_iter_extract_pages(iter_offset.msg_iter, - &pages, copy, 1, 0, &off); + rc = iov_iter_extract_pages(iter, &pages, + copy, 1, 0, &off); if (rc <= 0) { if (rc == 0) rc = -EIO; @@ -524,7 +509,7 @@ static int tls_push_data(struct sock *sk, copy = rc; if (WARN_ON_ONCE(!sendpage_ok(zc_pfrag.page))) { - iov_iter_revert(iter_offset.msg_iter, copy); + iov_iter_revert(iter, copy); rc = -EIO; goto handle_error; } @@ -537,7 +522,7 @@ static int tls_push_data(struct sock *sk, rc = tls_device_copy_data(page_address(pfrag->page) + pfrag->offset, copy, - iter_offset.msg_iter); + iter); if (rc) goto handle_error; tls_append_frag(record, pfrag, copy); @@ -592,7 +577,6 @@ int tls_device_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) { unsigned char record_type = TLS_RECORD_TYPE_DATA; struct tls_context *tls_ctx = tls_get_ctx(sk); - union tls_iter_offset iter; int rc; if (!tls_ctx->zerocopy_sendfile) @@ -607,8 +591,8 @@ int tls_device_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) goto out; } - iter.msg_iter = &msg->msg_iter; - rc = tls_push_data(sk, iter, size, msg->msg_flags, record_type, NULL); + rc = tls_push_data(sk, &msg->msg_iter, size, msg->msg_flags, + record_type); out: release_sock(sk); @@ -619,44 +603,18 @@ int tls_device_sendmsg(struct sock *sk, struct msghdr *msg, size_t size) int tls_device_sendpage(struct sock *sk, struct page *page, int offset, size_t size, int flags) { - struct tls_context *tls_ctx = tls_get_ctx(sk); - union tls_iter_offset iter_offset; - struct iov_iter msg_iter; - char *kaddr; - struct kvec iov; - int rc; + struct bio_vec bvec; + struct msghdr msg = { .msg_flags = flags | MSG_SPLICE_PAGES, }; if (flags & MSG_SENDPAGE_NOTLAST) - flags |= MSG_MORE; - - mutex_lock(&tls_ctx->tx_lock); - lock_sock(sk); + msg.msg_flags |= MSG_MORE; - if (flags & MSG_OOB) { - rc = -EOPNOTSUPP; - goto out; - } - - if (tls_ctx->zerocopy_sendfile) { - iter_offset.offset = offset; - rc = tls_push_data(sk, iter_offset, size, - flags, TLS_RECORD_TYPE_DATA, page); - goto out; - } - - kaddr = kmap(page); - iov.iov_base = kaddr + offset; - iov.iov_len = size; - iov_iter_kvec(&msg_iter, ITER_SOURCE, &iov, 1, size); - iter_offset.msg_iter = &msg_iter; - rc = tls_push_data(sk, iter_offset, size, flags, TLS_RECORD_TYPE_DATA, - NULL); - kunmap(page); + if (flags & MSG_OOB) + return -EOPNOTSUPP; -out: - release_sock(sk); - mutex_unlock(&tls_ctx->tx_lock); - return rc; + bvec_set_page(&bvec, page, size, offset); + iov_iter_bvec(&msg.msg_iter, ITER_SOURCE, &bvec, 1, size); + return tls_device_sendmsg(sk, &msg, size); } struct tls_record_info *tls_get_record(struct tls_offload_context_tx *context, @@ -721,12 +679,10 @@ EXPORT_SYMBOL(tls_get_record); static int tls_device_push_pending_record(struct sock *sk, int flags) { - union tls_iter_offset iter; - struct iov_iter msg_iter; + struct iov_iter iter; - iov_iter_kvec(&msg_iter, ITER_SOURCE, NULL, 0, 0); - iter.msg_iter = &msg_iter; - return tls_push_data(sk, iter, 0, flags, TLS_RECORD_TYPE_DATA, NULL); + iov_iter_kvec(&iter, ITER_SOURCE, NULL, 0, 0); + return tls_push_data(sk, &iter, 0, flags, TLS_RECORD_TYPE_DATA); } void tls_device_write_space(struct sock *sk, struct tls_context *ctx) From patchwork Fri Jun 2 15:07:52 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Howells X-Patchwork-Id: 102609 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:994d:0:b0:3d9:f83d:47d9 with SMTP id k13csp1112140vqr; Fri, 2 Jun 2023 08:30:44 -0700 (PDT) X-Google-Smtp-Source: ACHHUZ5CVtWQ9bPq5w9Ky34nTTxmIu0z96TrdSefrh4CHh/5K5wl/ex5IaEw+l+QGA8OLCsBugVE X-Received: by 2002:a05:6a20:e186:b0:110:493f:6bfd with SMTP id ks6-20020a056a20e18600b00110493f6bfdmr8173217pzb.46.1685719844264; Fri, 02 Jun 2023 08:30:44 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1685719844; cv=none; d=google.com; s=arc-20160816; b=J1n5zbt44vUcuw6m77r/ghUiG4yfq6GZBfABgoEATVnBkr82AkiEf55P/s8gdoR1Pi dEXOUIUsaR5UVpgQtyNKUXyeW0WATmGJf428UcLbAyzNnwvOVLi1YRfaBwHbrq41B7MQ C2EePS5MuNjh/F6P/FNLin+0ClPp9bT8Yf+xNX62Df9N9grtQ9s+HchX2N/0ivQEzwX/ CNa1d0gy/Lcn/c6VardYE7rbiEGONRJ1ruGCIcGApIvA0P+mB/PmuwFtL4pGY8fXBnaa 4A9w5IPQSvteQ9o6lpAcmdXnM0LqlNIzCQkwQy4fY3myYtUhJ2UvbriC2o75//aqoAFY lhDA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=lEYVSGbA7NoXu+U2Wu0+Nhg1lTDv/9jIqEWNAqaEbTg=; b=fGQFacwduBYJ1+jG+TwxDLIC+Re1TBSO7sApNGHQCp9G7xF5caRSFgFv8dx8Snp4Vu +Vs8CSOs6XSOBMNTBbB+62+OwFLsocxFJhzBkeWuVtJ0OMtdjxBWxBfAeKcXipQJ8jDO iJ1kWWz7+6no8furEQkK4gD/VXMCiNa1pc6K9SALxQnCHDjplwnzItshKHg59vAcIOsR pJHI7GCS2+cLXgzGY9SJ6N/aXhUKgeqM1Y2evWD1HaTVFy/aZPYtip4Anb9U/nFL2sys fytneEUyljdRvOlO48XgV2In7st6W9c3qqKZAgC1yvG0nj+/9CoiFokXBZU9JL0ZjNdd P9/w== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=gRUtiLsD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id bk13-20020a056a02028d00b0053ef95fa919si1103076pgb.458.2023.06.02.08.30.25; Fri, 02 Jun 2023 08:30:44 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=gRUtiLsD; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S236420AbjFBPKS (ORCPT + 99 others); Fri, 2 Jun 2023 11:10:18 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:58378 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S236534AbjFBPJs (ORCPT ); Fri, 2 Jun 2023 11:09:48 -0400 Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.133.124]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 61B1BE44 for ; Fri, 2 Jun 2023 08:08:55 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1685718534; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lEYVSGbA7NoXu+U2Wu0+Nhg1lTDv/9jIqEWNAqaEbTg=; b=gRUtiLsDP1a4Tijg0wsJvDwRP6cHs7ebcWdylsUfRs8U6K+gSF3zInwg8bax1bolUJHeS/ OBonc5n16ipCbUknkVuXcwuY+T7vUchWt6C0LcBBlgNk0MMjSq7GQqQjqWV5Hx5p6ECbvh NwgrF049Rw80Ir8N0+Pjar+N6roAQT8= Received: from mimecast-mx02.redhat.com (mx3-rdu2.redhat.com [66.187.233.73]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id us-mta-450-ueIYBq1NPI23Vhe8TEewXA-1; Fri, 02 Jun 2023 11:08:50 -0400 X-MC-Unique: ueIYBq1NPI23Vhe8TEewXA-1 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.rdu2.redhat.com [10.11.54.4]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx02.redhat.com (Postfix) with ESMTPS id E85EF3C0C897; Fri, 2 Jun 2023 15:08:48 +0000 (UTC) Received: from warthog.procyon.org.uk (unknown [10.42.28.182]) by smtp.corp.redhat.com (Postfix) with ESMTP id 6DE7C2026D49; Fri, 2 Jun 2023 15:08:45 +0000 (UTC) From: David Howells To: netdev@vger.kernel.org, Linus Torvalds Cc: David Howells , Chuck Lever , Boris Pismenny , John Fastabend , Jakub Kicinski , "David S. Miller" , Eric Dumazet , Paolo Abeni , Willem de Bruijn , David Ahern , Matthew Wilcox , Jens Axboe , linux-mm@kvack.org, linux-kernel@vger.kernel.org, Herbert Xu Subject: [PATCH net-next v3 11/11] net: Add samples for network I/O and splicing Date: Fri, 2 Jun 2023 16:07:52 +0100 Message-ID: <20230602150752.1306532-12-dhowells@redhat.com> In-Reply-To: <20230602150752.1306532-1-dhowells@redhat.com> References: <20230602150752.1306532-1-dhowells@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 3.1 on 10.11.54.4 X-Spam-Status: No, score=-2.3 required=5.0 tests=BAYES_00,DKIMWL_WL_HIGH, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_NONE,T_SCC_BODY_TEXT_LINE autolearn=unavailable autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: =?utf-8?q?INBOX?= X-GMAIL-THRID: =?utf-8?q?1767605371211781433?= X-GMAIL-MSGID: =?utf-8?q?1767605371211781433?= Add some small sample programs for doing network I/O including splicing. There are three IPv4/IPv6 servers: tcp-sink, tls-sink and udp-sink. They can be given a port number by passing "-p " and will listen on an IPv6 socket unless given a "-4" flag, in which case they'll listen for IPv4 only. There are three IPv4/IPv6 clients: tcp-send, tls-send and udp-send. They are given a file to get data from (or "-" for stdin) and the name of a server to talk to. They can also be given a port number by passing "-p ", "-4" or "-6" to force the use of IPv4 or IPv6, "-s" to indicate they should use splice/sendfile to transfer the data and "-n" to specify how much data to copy. If "-s" is given, the input will be spliced if it's a pipe and sendfiled otherwise. A driver program, splice-out, is provided to splice data from a file/stdin to stdout and can be used to pipe into the aforementioned clients for testing splice. This takes the name of the file to splice from (or "-" for stdin). It can also be given "-w " to indicate the maximum size of each splice, "-k " if a chunk of the input should be skipped between splices to prevent coalescence and "-s" if sendfile should be used instead of splice. Additionally, there is an AF_UNIX client and server. These are similar to the IPv[46] programs, except both take a socket path and there is no option to change the port number. And then there are two AF_ALG clients (there is no server). These are similar to the other clients, except no destination is specified. One exercised skcipher encryption and the other hashing. Examples include: ./splice-out -w0x400 /foo/16K 4K | ./alg-encrypt -s - ./splice-out -w0x400 /foo/1M | ./unix-send -s - /tmp/foo ./splice-out -w0x400 /foo/16K 16K -w1 | ./tls-send -s6 -n16K - servbox ./tcp-send /bin/ls 192.168.6.1 ./udp-send -4 -p5555 /foo/4K localhost where, for example, /foo/16K is a 16KiB file. Signed-off-by: David Howells cc: Willem de Bruijn cc: Boris Pismenny cc: John Fastabend cc: Herbert Xu cc: "David S. Miller" cc: Eric Dumazet cc: Jakub Kicinski cc: Paolo Abeni cc: Jens Axboe cc: netdev@vger.kernel.org --- samples/Kconfig | 14 +++ samples/Makefile | 1 + samples/net/Makefile | 13 +++ samples/net/alg-encrypt.c | 206 ++++++++++++++++++++++++++++++++++++++ samples/net/alg-hash.c | 147 +++++++++++++++++++++++++++ samples/net/splice-out.c | 147 +++++++++++++++++++++++++++ samples/net/tcp-send.c | 177 ++++++++++++++++++++++++++++++++ samples/net/tcp-sink.c | 80 +++++++++++++++ samples/net/tls-send.c | 188 ++++++++++++++++++++++++++++++++++ samples/net/tls-sink.c | 104 +++++++++++++++++++ samples/net/udp-send.c | 156 +++++++++++++++++++++++++++++ samples/net/udp-sink.c | 84 ++++++++++++++++ samples/net/unix-send.c | 151 ++++++++++++++++++++++++++++ samples/net/unix-sink.c | 54 ++++++++++ 14 files changed, 1522 insertions(+) create mode 100644 samples/net/Makefile create mode 100644 samples/net/alg-encrypt.c create mode 100644 samples/net/alg-hash.c create mode 100644 samples/net/splice-out.c create mode 100644 samples/net/tcp-send.c create mode 100644 samples/net/tcp-sink.c create mode 100644 samples/net/tls-send.c create mode 100644 samples/net/tls-sink.c create mode 100644 samples/net/udp-send.c create mode 100644 samples/net/udp-sink.c create mode 100644 samples/net/unix-send.c create mode 100644 samples/net/unix-sink.c diff --git a/samples/Kconfig b/samples/Kconfig index b2db430bd3ff..928e06b08b99 100644 --- a/samples/Kconfig +++ b/samples/Kconfig @@ -280,6 +280,20 @@ config SAMPLE_KMEMLEAK Build a sample program which have explicitly leaks memory to test kmemleak +config SAMPLE_NET + bool "Build example programs for driving network protocols" + depends on NET + help + Build example userspace programs for driving network protocols. Most + of the programs (tcp, udp, tls, unix) come as client-server pairs + that allow the test to be split across a network (but not in the unix + case); but some, such as the AF_ALG samples are standalone as there + is no server per se. + + The programs allow sendfile and splice to be used. An additional + program is provided that allows sendfile/splice to stdout for use in + piping in to the other programs to operate splice there. + source "samples/rust/Kconfig" endif # SAMPLES diff --git a/samples/Makefile b/samples/Makefile index 7727f1a0d6d1..b9fbf80a53be 100644 --- a/samples/Makefile +++ b/samples/Makefile @@ -37,3 +37,4 @@ obj-$(CONFIG_SAMPLE_KMEMLEAK) += kmemleak/ obj-$(CONFIG_SAMPLE_CORESIGHT_SYSCFG) += coresight/ obj-$(CONFIG_SAMPLE_FPROBE) += fprobe/ obj-$(CONFIG_SAMPLES_RUST) += rust/ +obj-$(CONFIG_SAMPLE_NET) += net/ diff --git a/samples/net/Makefile b/samples/net/Makefile new file mode 100644 index 000000000000..0ccd68a36edf --- /dev/null +++ b/samples/net/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0-only +userprogs-always-y += \ + alg-hash \ + alg-encrypt \ + splice-out \ + tcp-send \ + tcp-sink \ + tls-send \ + tls-sink \ + udp-send \ + udp-sink \ + unix-send \ + unix-sink diff --git a/samples/net/alg-encrypt.c b/samples/net/alg-encrypt.c new file mode 100644 index 000000000000..3851b5fbaeda --- /dev/null +++ b/samples/net/alg-encrypt.c @@ -0,0 +1,206 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* AF_ALG hash test + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) +#define min(x, y) ((x) < (y) ? (x) : (y)) + +static unsigned char buffer[4096 * 32] __attribute__((aligned(4096))); +static unsigned char iv[16]; +static unsigned char key[16]; + +static const struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "skcipher", + .salg_name = "cbc(aes)", +}; + +static void format(void) +{ + fprintf(stderr, "alg-send [-ds] [-n] |-\n"); + exit(2); +} + +static void algif_add_set_op(struct msghdr *msg, unsigned int op) +{ + struct cmsghdr *__cmsg; + + __cmsg = msg->msg_control + msg->msg_controllen; + __cmsg->cmsg_len = CMSG_LEN(sizeof(unsigned int)); + __cmsg->cmsg_level = SOL_ALG; + __cmsg->cmsg_type = ALG_SET_OP; + *(unsigned int *)CMSG_DATA(__cmsg) = op; + msg->msg_controllen += CMSG_ALIGN(__cmsg->cmsg_len); +} + +static void algif_add_set_iv(struct msghdr *msg, const void *iv, size_t ivlen) +{ + struct af_alg_iv *ivbuf; + struct cmsghdr *__cmsg; + + printf("%zx\n", msg->msg_controllen); + __cmsg = msg->msg_control + msg->msg_controllen; + __cmsg->cmsg_len = CMSG_LEN(sizeof(*ivbuf) + ivlen); + __cmsg->cmsg_level = SOL_ALG; + __cmsg->cmsg_type = ALG_SET_IV; + ivbuf = (struct af_alg_iv *)CMSG_DATA(__cmsg); + ivbuf->ivlen = ivlen; + memcpy(ivbuf->iv, iv, ivlen); + msg->msg_controllen += CMSG_ALIGN(__cmsg->cmsg_len); +} + +int main(int argc, char *argv[]) +{ + struct msghdr msg; + struct stat st; + const char *filename; + unsigned char ctrl[4096]; + unsigned int flags = O_RDONLY; + ssize_t r, w, o, ret; + size_t size = LONG_MAX, total = 0, i, out = 160; + char *end; + bool use_sendfile = false, all = true; + int opt, alg, sock, fd = 0; + + while ((opt = getopt(argc, argv, "dn:s")) != EOF) { + switch (opt) { + case 'd': + flags |= O_DIRECT; + break; + case 'n': + size = strtoul(optarg, &end, 0); + switch (*end) { + case 'K': + case 'k': + size *= 1024; + break; + case 'M': + case 'm': + size *= 1024 * 1024; + break; + } + all = false; + break; + case 's': + use_sendfile = true; + break; + default: + format(); + } + } + + argc -= optind; + argv += optind; + if (argc != 1) + format(); + filename = argv[0]; + + alg = socket(AF_ALG, SOCK_SEQPACKET, 0); + OSERROR(alg, "AF_ALG"); + OSERROR(bind(alg, (struct sockaddr *)&sa, sizeof(sa)), "bind"); + OSERROR(setsockopt(alg, SOL_ALG, ALG_SET_KEY, key, sizeof(key)), + "ALG_SET_KEY"); + sock = accept(alg, NULL, 0); + OSERROR(sock, "accept"); + + if (strcmp(filename, "-") != 0) { + fd = open(filename, flags); + OSERROR(fd, filename); + OSERROR(fstat(fd, &st), filename); + size = st.st_size; + } else { + OSERROR(fstat(fd, &st), argv[2]); + } + + memset(&msg, 0, sizeof(msg)); + msg.msg_control = ctrl; + algif_add_set_op(&msg, ALG_OP_ENCRYPT); + algif_add_set_iv(&msg, iv, sizeof(iv)); + + OSERROR(sendmsg(sock, &msg, MSG_MORE), "sock/sendmsg"); + + if (!use_sendfile) { + bool more = false; + + while (size) { + r = read(fd, buffer, sizeof(buffer)); + OSERROR(r, filename); + if (r == 0) + break; + size -= r; + + o = 0; + do { + more = size > 0; + w = send(sock, buffer + o, r - o, + more ? MSG_MORE : 0); + OSERROR(w, "sock/send"); + total += w; + o += w; + } while (o < r); + } + + if (more) + send(sock, NULL, 0, 0); + } else if (S_ISFIFO(st.st_mode)) { + do { + r = splice(fd, NULL, sock, NULL, size, + size > 0 ? SPLICE_F_MORE : 0); + OSERROR(r, "sock/splice"); + size -= r; + total += r; + } while (r > 0 && size > 0); + if (size && !all) { + fprintf(stderr, "Short splice\n"); + exit(1); + } + } else { + r = sendfile(sock, fd, NULL, size); + OSERROR(r, "sock/sendfile"); + if (r != size) { + fprintf(stderr, "Short sendfile\n"); + exit(1); + } + total = r; + } + + while (total > 0) { + ret = read(sock, buffer, min(sizeof(buffer), total)); + OSERROR(ret, "sock/read"); + if (ret == 0) + break; + total -= ret; + + if (out > 0) { + ret = min(out, ret); + out -= ret; + for (i = 0; i < ret; i++) + printf("%02x", (unsigned char)buffer[i]); + } + printf("...\n"); + } + + OSERROR(close(sock), "sock/close"); + OSERROR(close(alg), "alg/close"); + OSERROR(close(fd), "close"); + return 0; +} diff --git a/samples/net/alg-hash.c b/samples/net/alg-hash.c new file mode 100644 index 000000000000..df63c87e7661 --- /dev/null +++ b/samples/net/alg-hash.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* AF_ALG hash test + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) + +static unsigned char buffer[4096 * 32] __attribute__((aligned(4096))); + +static const struct sockaddr_alg sa = { + .salg_family = AF_ALG, + .salg_type = "hash", + .salg_name = "sha1", +}; + +static void format(void) +{ + fprintf(stderr, "alg-send [-ds] [-n] |-\n"); + exit(2); +} + +int main(int argc, char *argv[]) +{ + struct stat st; + const char *filename; + unsigned int flags = O_RDONLY; + ssize_t r, w, o, ret; + size_t size = LONG_MAX, i; + char *end; + int use_sendfile = 0; + int opt, alg, sock, fd = 0; + + while ((opt = getopt(argc, argv, "n:s")) != EOF) { + switch (opt) { + case 'd': + flags |= O_DIRECT; + break; + case 'n': + size = strtoul(optarg, &end, 0); + switch (*end) { + case 'K': + case 'k': + size *= 1024; + break; + case 'M': + case 'm': + size *= 1024 * 1024; + break; + } + break; + case 's': + use_sendfile = true; + break; + default: + format(); + } + } + + argc -= optind; + argv += optind; + if (argc != 1) + format(); + filename = argv[0]; + + alg = socket(AF_ALG, SOCK_SEQPACKET, 0); + OSERROR(alg, "AF_ALG"); + OSERROR(bind(alg, (struct sockaddr *)&sa, sizeof(sa)), "bind"); + sock = accept(alg, NULL, 0); + OSERROR(sock, "accept"); + + if (strcmp(filename, "-") != 0) { + fd = open(filename, flags); + OSERROR(fd, filename); + OSERROR(fstat(fd, &st), filename); + size = st.st_size; + } else { + OSERROR(fstat(fd, &st), argv[2]); + } + + if (!use_sendfile) { + bool more = false; + + while (size) { + r = read(fd, buffer, sizeof(buffer)); + OSERROR(r, filename); + if (r == 0) + break; + size -= r; + + o = 0; + do { + more = size > 0; + w = send(sock, buffer + o, r - o, + more ? MSG_MORE : 0); + OSERROR(w, "sock/send"); + o += w; + } while (o < r); + } + + if (more) + send(sock, NULL, 0, 0); + } else if (S_ISFIFO(st.st_mode)) { + r = splice(fd, NULL, sock, NULL, size, 0); + OSERROR(r, "sock/splice"); + if (r != size) { + fprintf(stderr, "Short splice\n"); + exit(1); + } + } else { + r = sendfile(sock, fd, NULL, size); + OSERROR(r, "sock/sendfile"); + if (r != size) { + fprintf(stderr, "Short sendfile\n"); + exit(1); + } + } + + ret = read(sock, buffer, sizeof(buffer)); + OSERROR(ret, "sock/read"); + + for (i = 0; i < ret; i++) + printf("%02x", (unsigned char)buffer[i]); + printf("\n"); + + OSERROR(close(sock), "sock/close"); + OSERROR(close(alg), "alg/close"); + OSERROR(close(fd), "close"); + return 0; +} diff --git a/samples/net/splice-out.c b/samples/net/splice-out.c new file mode 100644 index 000000000000..224010dfd387 --- /dev/null +++ b/samples/net/splice-out.c @@ -0,0 +1,147 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* Splice or sendfile from the given file/stdin to stdout. + * + * Format: splice-out [-s] |- [] + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) +#define min(x, y) ((x) < (y) ? (x) : (y)) + +static unsigned char buffer[4096]; + +static void format(void) +{ + fprintf(stderr, "splice-out [-dkN][-s][-wN] |- []\n"); + exit(2); +} + +int main(int argc, char *argv[]) +{ + struct stat st; + const char *filename; + unsigned int flags = O_RDONLY; + ssize_t r; + size_t size = 1024 * 1024, skip = 0, unit = 0, part; + char *end; + bool use_sendfile = false, all = true; + int opt, fd = 0; + + while ((opt = getopt(argc, argv, "dk:sw:")), + opt != -1) { + switch (opt) { + case 'd': + flags |= O_DIRECT; + break; + case 'k': + /* Skip size - prevent coalescence. */ + skip = strtoul(optarg, &end, 0); + if (skip < 1 || skip >= 4096) { + fprintf(stderr, "-kN must be 00\n"); + exit(2); + } + switch (*end) { + case 'K': + case 'k': + unit *= 1024; + break; + case 'M': + case 'm': + unit *= 1024 * 1024; + break; + } + break; + default: + format(); + } + } + + argc -= optind; + argv += optind; + + if (argc != 1 && argc != 2) + format(); + + filename = argv[0]; + if (argc == 2) { + size = strtoul(argv[1], &end, 0); + switch (*end) { + case 'K': + case 'k': + size *= 1024; + break; + case 'M': + case 'm': + size *= 1024 * 1024; + break; + } + all = false; + } + + OSERROR(fstat(1, &st), "stdout"); + if (!S_ISFIFO(st.st_mode)) { + fprintf(stderr, "stdout must be a pipe\n"); + exit(3); + } + + if (strcmp(filename, "-") != 0) { + fd = open(filename, flags); + OSERROR(fd, filename); + OSERROR(fstat(fd, &st), filename); + if (!all && size > st.st_size) { + fprintf(stderr, "%s: Specified size larger than file\n", + filename); + exit(3); + } + } + + do { + if (skip) { + part = skip; + do { + r = read(fd, buffer, skip); + OSERROR(r, filename); + part -= r; + } while (part > 0 && r > 0); + } + + part = unit ? min(size, unit) : size; + if (use_sendfile) { + r = sendfile(1, fd, NULL, part); + OSERROR(r, "sendfile"); + } else { + r = splice(fd, NULL, 1, NULL, part, 0); + OSERROR(r, "splice"); + } + if (!all) + size -= r; + } while (r > 0 && size > 0); + + OSERROR(close(fd), "close"); + return 0; +} diff --git a/samples/net/tcp-send.c b/samples/net/tcp-send.c new file mode 100644 index 000000000000..608055354789 --- /dev/null +++ b/samples/net/tcp-send.c @@ -0,0 +1,177 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * TCP send client. Pass -s to use splice/sendfile; -z to use MSG_ZEROCOPY. + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) + +static unsigned char buffer[4096] __attribute__((aligned(4096))); + +static void format(void) +{ + fprintf(stderr, + "tcp-send [-46dsz][-p][-n] |- \n"); + exit(2); +} + +int main(int argc, char *argv[]) +{ + struct addrinfo *addrs = NULL, hints = {}; + struct stat st; + const char *filename, *sockname, *service = "5555"; + unsigned int flags = O_RDONLY; + ssize_t r, w, o; + size_t size = LONG_MAX; + char *end; + bool use_sendfile = false, use_zerocopy = false, all = true; + int opt, sock, fd = 0, gai; + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + while ((opt = getopt(argc, argv, "46dn:p:sz")) != EOF) { + switch (opt) { + case '4': + hints.ai_family = AF_INET; + break; + case '6': + hints.ai_family = AF_INET6; + break; + case 'd': + flags |= O_DIRECT; + break; + case 'n': + size = strtoul(optarg, &end, 0); + switch (*end) { + case 'K': + case 'k': + size *= 1024; + break; + case 'M': + case 'm': + size *= 1024 * 1024; + break; + } + all = false; + break; + case 'p': + service = optarg; + break; + case 's': + use_sendfile = true; + break; + case 'z': + use_zerocopy = true; + break; + default: + format(); + } + } + + argc -= optind; + argv += optind; + if (argc != 2) + format(); + filename = argv[0]; + sockname = argv[1]; + + gai = getaddrinfo(sockname, service, &hints, &addrs); + if (gai) { + fprintf(stderr, "%s: %s\n", sockname, gai_strerror(gai)); + exit(3); + } + + if (!addrs) { + fprintf(stderr, "%s: No addresses\n", sockname); + exit(3); + } + + sockname = addrs->ai_canonname; + sock = socket(addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol); + OSERROR(sock, "socket"); + OSERROR(connect(sock, addrs->ai_addr, addrs->ai_addrlen), "connect"); + + if (strcmp(filename, "-") != 0) { + fd = open(filename, flags); + OSERROR(fd, filename); + OSERROR(fstat(fd, &st), filename); + if (size > st.st_size) + size = st.st_size; + } else { + OSERROR(fstat(fd, &st), filename); + } + + if (!use_sendfile) { + unsigned int flags = 0; + + if (use_zerocopy) { + int zcflag = 1; + + OSERROR(setsockopt(sock, SOL_SOCKET, SO_ZEROCOPY, + &zcflag, sizeof(zcflag)), + "SOCK_ZEROCOPY"); + flags |= MSG_ZEROCOPY; + } + + while (size) { + r = read(fd, buffer, sizeof(buffer)); + OSERROR(r, filename); + if (r == 0) + break; + size -= r; + + o = 0; + do { + flags &= ~MSG_MORE; + if (size > 0) + flags |= MSG_MORE; + w = send(sock, buffer + o, r - o, flags); + OSERROR(w, "sock/send"); + o += w; + } while (o < r); + } + + if (flags & MSG_MORE) + send(sock, NULL, 0, flags & ~MSG_MORE); + } else if (S_ISFIFO(st.st_mode)) { + do { + r = splice(fd, NULL, sock, NULL, size, + size > 0 ? SPLICE_F_MORE : 0); + OSERROR(r, "sock/splice"); + size -= r; + } while (r > 0 && size > 0); + if (size && !all) { + fprintf(stderr, "Short splice\n"); + exit(1); + } + } else { + r = sendfile(sock, fd, NULL, size); + OSERROR(r, "sock/sendfile"); + if (r != size) { + fprintf(stderr, "Short sendfile\n"); + exit(1); + } + } + + OSERROR(close(sock), "sock/close"); + OSERROR(close(fd), "close"); + return 0; +} diff --git a/samples/net/tcp-sink.c b/samples/net/tcp-sink.c new file mode 100644 index 000000000000..5c27c24dfb76 --- /dev/null +++ b/samples/net/tcp-sink.c @@ -0,0 +1,80 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * TCP sink server + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) + +static unsigned char buffer[512 * 1024]; + +static void format(void) +{ + fprintf(stderr, "tcp-sink [-4][-p]\n"); + exit(2); +} + +int main(int argc, char *argv[]) +{ + unsigned int port = 5555; + bool ipv6 = true; + int opt, server_sock, sock; + + + while ((opt = getopt(argc, argv, "4p:")) != EOF) { + switch (opt) { + case '4': + ipv6 = false; + break; + case 'p': + port = atoi(optarg); + break; + default: + format(); + } + } + + if (!ipv6) { + struct sockaddr_in sin = { + .sin_family = AF_INET, + .sin_port = htons(port), + }; + server_sock = socket(AF_INET, SOCK_STREAM, 0); + OSERROR(server_sock, "socket"); + OSERROR(bind(server_sock, (struct sockaddr *)&sin, sizeof(sin)), + "bind"); + OSERROR(listen(server_sock, 1), "listen"); + } else { + struct sockaddr_in6 sin6 = { + .sin6_family = AF_INET6, + .sin6_port = htons(port), + }; + server_sock = socket(AF_INET6, SOCK_STREAM, 0); + OSERROR(server_sock, "socket"); + OSERROR(bind(server_sock, (struct sockaddr *)&sin6, + sizeof(sin6)), + "bind"); + OSERROR(listen(server_sock, 1), "listen"); + } + + for (;;) { + sock = accept(server_sock, NULL, NULL); + if (sock != -1) { + while (read(sock, buffer, sizeof(buffer)) > 0) + ; + close(sock); + } + } +} diff --git a/samples/net/tls-send.c b/samples/net/tls-send.c new file mode 100644 index 000000000000..d99b79aaf536 --- /dev/null +++ b/samples/net/tls-send.c @@ -0,0 +1,188 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * TLS-over-TCP send client. Pass -s to splice. + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) + +static unsigned char buffer[4096]; + +static void format(void) +{ + fprintf(stderr, + "tls-send [-46ds][-n][-p] |- \n"); + exit(2); +} + +static void set_tls(int sock) +{ + struct tls12_crypto_info_aes_gcm_128 crypto_info; + + crypto_info.info.version = TLS_1_2_VERSION; + crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128; + memset(crypto_info.iv, 0, TLS_CIPHER_AES_GCM_128_IV_SIZE); + memset(crypto_info.rec_seq, 0, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + memset(crypto_info.key, 0, TLS_CIPHER_AES_GCM_128_KEY_SIZE); + memset(crypto_info.salt, 0, TLS_CIPHER_AES_GCM_128_SALT_SIZE); + + OSERROR(setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls")), + "TCP_ULP"); + OSERROR(setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, + sizeof(crypto_info)), + "TLS_TX"); + OSERROR(setsockopt(sock, SOL_TLS, TLS_RX, &crypto_info, + sizeof(crypto_info)), + "TLS_RX"); +} + +int main(int argc, char *argv[]) +{ + struct addrinfo *addrs = NULL, hints = {}; + struct stat st; + const char *filename, *sockname, *service = "5556"; + unsigned int flags = O_RDONLY; + ssize_t r, w, o; + size_t size = LONG_MAX; + char *end; + bool use_sendfile = false, all = true; + int opt, sock, fd = 0, gai; + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + while ((opt = getopt(argc, argv, "46dn:p:s")) != EOF) { + switch (opt) { + case '4': + hints.ai_family = AF_INET; + break; + case '6': + hints.ai_family = AF_INET6; + break; + case 'd': + flags |= O_DIRECT; + break; + case 'n': + size = strtoul(optarg, &end, 0); + switch (*end) { + case 'K': + case 'k': + size *= 1024; + break; + case 'M': + case 'm': + size *= 1024 * 1024; + break; + } + all = false; + break; + case 'p': + service = optarg; + break; + case 's': + use_sendfile = true; + break; + default: + format(); + } + } + + argc -= optind; + argv += optind; + if (argc != 2) + format(); + filename = argv[0]; + sockname = argv[1]; + + gai = getaddrinfo(sockname, service, &hints, &addrs); + if (gai) { + fprintf(stderr, "%s: %s\n", sockname, gai_strerror(gai)); + exit(3); + } + + if (!addrs) { + fprintf(stderr, "%s: No addresses\n", sockname); + exit(3); + } + + sockname = addrs->ai_canonname; + sock = socket(addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol); + OSERROR(sock, "socket"); + OSERROR(connect(sock, addrs->ai_addr, addrs->ai_addrlen), "connect"); + set_tls(sock); + + if (strcmp(filename, "-") != 0) { + fd = open(filename, flags); + OSERROR(fd, filename); + OSERROR(fstat(fd, &st), filename); + if (size > st.st_size) + size = st.st_size; + } else { + OSERROR(fstat(fd, &st), filename); + } + + if (!use_sendfile) { + bool more = false; + + while (size) { + r = read(fd, buffer, sizeof(buffer)); + OSERROR(r, filename); + if (r == 0) + break; + size -= r; + + o = 0; + do { + more = size > 0; + w = send(sock, buffer + o, r - o, + more ? MSG_MORE : 0); + OSERROR(w, "sock/send"); + o += w; + } while (o < r); + } + + if (more) + send(sock, NULL, 0, 0); + } else if (S_ISFIFO(st.st_mode)) { + do { + r = splice(fd, NULL, sock, NULL, size, + size > 0 ? SPLICE_F_MORE : 0); + OSERROR(r, "sock/splice"); + size -= r; + } while (r > 0 && size > 0); + if (size && !all) { + fprintf(stderr, "Short splice\n"); + exit(1); + } + } else { + r = sendfile(sock, fd, NULL, size); + OSERROR(r, "sock/sendfile"); + if (r != size) { + fprintf(stderr, "Short sendfile\n"); + exit(1); + } + } + + OSERROR(close(sock), "sock/close"); + OSERROR(close(fd), "close"); + return 0; +} diff --git a/samples/net/tls-sink.c b/samples/net/tls-sink.c new file mode 100644 index 000000000000..67900b74d6d6 --- /dev/null +++ b/samples/net/tls-sink.c @@ -0,0 +1,104 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * TLS-over-TCP sink server + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) + +static unsigned char buffer[512 * 1024]; + +static void format(void) +{ + fprintf(stderr, "tls-sink [-4][-p]\n"); + exit(2); +} + +static void set_tls(int sock) +{ + struct tls12_crypto_info_aes_gcm_128 crypto_info; + + crypto_info.info.version = TLS_1_2_VERSION; + crypto_info.info.cipher_type = TLS_CIPHER_AES_GCM_128; + memset(crypto_info.iv, 0, TLS_CIPHER_AES_GCM_128_IV_SIZE); + memset(crypto_info.rec_seq, 0, TLS_CIPHER_AES_GCM_128_REC_SEQ_SIZE); + memset(crypto_info.key, 0, TLS_CIPHER_AES_GCM_128_KEY_SIZE); + memset(crypto_info.salt, 0, TLS_CIPHER_AES_GCM_128_SALT_SIZE); + + OSERROR(setsockopt(sock, SOL_TCP, TCP_ULP, "tls", sizeof("tls")), + "TCP_ULP"); + OSERROR(setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, + sizeof(crypto_info)), + "TLS_TX"); + OSERROR(setsockopt(sock, SOL_TLS, TLS_RX, &crypto_info, + sizeof(crypto_info)), + "TLS_RX"); +} + +int main(int argc, char *argv[]) +{ + unsigned int port = 5556; + bool ipv6 = true; + int opt, server_sock, sock; + + + while ((opt = getopt(argc, argv, "4p:")) != EOF) { + switch (opt) { + case '4': + ipv6 = false; + break; + case 'p': + port = atoi(optarg); + break; + default: + format(); + } + } + + if (!ipv6) { + struct sockaddr_in sin = { + .sin_family = AF_INET, + .sin_port = htons(port), + }; + server_sock = socket(AF_INET, SOCK_STREAM, 0); + OSERROR(server_sock, "socket"); + OSERROR(bind(server_sock, (struct sockaddr *)&sin, sizeof(sin)), + "bind"); + OSERROR(listen(server_sock, 1), "listen"); + } else { + struct sockaddr_in6 sin6 = { + .sin6_family = AF_INET6, + .sin6_port = htons(port), + }; + server_sock = socket(AF_INET6, SOCK_STREAM, 0); + OSERROR(server_sock, "socket"); + OSERROR(bind(server_sock, (struct sockaddr *)&sin6, + sizeof(sin6)), + "bind"); + OSERROR(listen(server_sock, 1), "listen"); + } + + for (;;) { + sock = accept(server_sock, NULL, NULL); + if (sock != -1) { + set_tls(sock); + while (read(sock, buffer, sizeof(buffer)) > 0) + ; + close(sock); + } + } +} diff --git a/samples/net/udp-send.c b/samples/net/udp-send.c new file mode 100644 index 000000000000..7c6c27eb0fcc --- /dev/null +++ b/samples/net/udp-send.c @@ -0,0 +1,156 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * UDP send client. Pass -s to splice. + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) +#define min(x, y) ((x) < (y) ? (x) : (y)) + +static unsigned char buffer[65536]; + +static void format(void) +{ + fprintf(stderr, + "udp-send [-46s][-n][-p] |- \n"); + exit(2); +} + +int main(int argc, char *argv[]) +{ + struct addrinfo *addrs = NULL, hints = {}; + struct stat st; + const char *filename, *sockname, *service = "5555"; + unsigned int flags = O_RDONLY, len; + ssize_t r, o, size = 65535; + char *end; + bool use_sendfile = false; + int opt, sock, fd = 0, gai; + + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_DGRAM; + + while ((opt = getopt(argc, argv, "46dn:p:s")) != EOF) { + switch (opt) { + case '4': + hints.ai_family = AF_INET; + break; + case '6': + hints.ai_family = AF_INET6; + break; + case 'd': + flags |= O_DIRECT; + break; + case 'n': + size = strtoul(optarg, &end, 0); + switch (*end) { + case 'K': + case 'k': + size *= 1024; + break; + } + if (size > 65535) { + fprintf(stderr, + "Too much data for UDP packet\n"); + exit(2); + } + break; + case 'p': + service = optarg; + break; + case 's': + use_sendfile = true; + break; + default: + format(); + } + } + + argc -= optind; + argv += optind; + if (argc != 2) + format(); + filename = argv[0]; + sockname = argv[1]; + + gai = getaddrinfo(sockname, service, &hints, &addrs); + if (gai) { + fprintf(stderr, "%s: %s\n", sockname, gai_strerror(gai)); + exit(3); + } + + if (!addrs) { + fprintf(stderr, "%s: No addresses\n", sockname); + exit(3); + } + + sockname = addrs->ai_canonname; + sock = socket(addrs->ai_family, addrs->ai_socktype, addrs->ai_protocol); + OSERROR(sock, "socket"); + OSERROR(connect(sock, addrs->ai_addr, addrs->ai_addrlen), "connect"); + + if (strcmp(filename, "-") != 0) { + fd = open(filename, flags); + OSERROR(fd, filename); + OSERROR(fstat(fd, &st), filename); + if (size > st.st_size) + size = st.st_size; + } else { + OSERROR(fstat(fd, &st), filename); + } + + len = htonl(size); + OSERROR(send(sock, &len, 4, MSG_MORE), "sock/send"); + + if (!use_sendfile) { + while (size) { + r = read(fd, buffer, sizeof(buffer)); + OSERROR(r, filename); + if (r == 0) + break; + size -= r; + + o = 0; + do { + ssize_t w = send(sock, buffer + o, r - o, + size > 0 ? MSG_MORE : 0); + OSERROR(w, "sock/send"); + o += w; + } while (o < r); + } + } else if (S_ISFIFO(st.st_mode)) { + r = splice(fd, NULL, sock, NULL, size, 0); + OSERROR(r, "sock/splice"); + if (r != size) { + fprintf(stderr, "Short splice\n"); + exit(1); + } + } else { + r = sendfile(sock, fd, NULL, size); + OSERROR(r, "sock/sendfile"); + if (r != size) { + fprintf(stderr, "Short sendfile\n"); + exit(1); + } + } + + OSERROR(close(sock), "sock/close"); + OSERROR(close(fd), "close"); + return 0; +} diff --git a/samples/net/udp-sink.c b/samples/net/udp-sink.c new file mode 100644 index 000000000000..f23c64acec4a --- /dev/null +++ b/samples/net/udp-sink.c @@ -0,0 +1,84 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * UDP sink server + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) + +static unsigned char buffer[512 * 1024]; + +static void format(void) +{ + fprintf(stderr, "udp-sink [-4][-p]\n"); + exit(2); +} + +int main(int argc, char *argv[]) +{ + struct iovec iov[1] = { + [0] = { + .iov_base = buffer, + .iov_len = sizeof(buffer), + }, + }; + struct msghdr msg = { + .msg_iov = iov, + .msg_iovlen = 1, + }; + unsigned int port = 5555; + bool ipv6 = true; + int opt, sock; + + while ((opt = getopt(argc, argv, "4p:")) != EOF) { + switch (opt) { + case '4': + ipv6 = false; + break; + case 'p': + port = atoi(optarg); + break; + default: + format(); + } + } + + if (!ipv6) { + struct sockaddr_in sin = { + .sin_family = AF_INET, + .sin_port = htons(port), + }; + sock = socket(AF_INET, SOCK_DGRAM, 0); + OSERROR(sock, "socket"); + OSERROR(bind(sock, (struct sockaddr *)&sin, sizeof(sin)), + "bind"); + } else { + struct sockaddr_in6 sin6 = { + .sin6_family = AF_INET6, + .sin6_port = htons(port), + }; + sock = socket(AF_INET6, SOCK_DGRAM, 0); + OSERROR(sock, "socket"); + OSERROR(bind(sock, (struct sockaddr *)&sin6, sizeof(sin6)), + "bind"); + } + + for (;;) { + ssize_t r; + + r = recvmsg(sock, &msg, 0); + printf("rx %zd\n", r); + } +} diff --git a/samples/net/unix-send.c b/samples/net/unix-send.c new file mode 100644 index 000000000000..5950fcf1ccd2 --- /dev/null +++ b/samples/net/unix-send.c @@ -0,0 +1,151 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * AF_UNIX stream send client. Pass -s to use splice/sendfile. + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#define _GNU_SOURCE +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) +#define min(x, y) ((x) < (y) ? (x) : (y)) + +static unsigned char buffer[4096]; + +static void format(void) +{ + fprintf(stderr, "unix-send [-ds] [-n] |- \n"); + exit(2); +} + +int main(int argc, char *argv[]) +{ + struct sockaddr_un sun = { .sun_family = AF_UNIX, }; + struct stat st; + const char *filename, *sockname; + unsigned int flags = O_RDONLY; + ssize_t r, w, o, size = LONG_MAX; + size_t plen, total = 0; + char *end; + bool use_sendfile = false, all = true; + int opt, sock, fd = 0; + + while ((opt = getopt(argc, argv, "dn:s")) != EOF) { + switch (opt) { + case 'd': + flags |= O_DIRECT; + break; + case 'n': + size = strtoul(optarg, &end, 0); + switch (*end) { + case 'K': + case 'k': + size *= 1024; + break; + case 'M': + case 'm': + size *= 1024 * 1024; + break; + } + all = false; + break; + case 's': + use_sendfile = true; + break; + default: + format(); + } + } + + argc -= optind; + argv += optind; + if (argc != 2) + format(); + filename = argv[0]; + sockname = argv[1]; + + plen = strlen(sockname); + if (plen == 0 || plen > sizeof(sun.sun_path) - 1) { + fprintf(stderr, "socket filename too short or too long\n"); + exit(2); + } + memcpy(sun.sun_path, sockname, plen + 1); + + sock = socket(AF_UNIX, SOCK_STREAM, 0); + OSERROR(sock, "socket"); + OSERROR(connect(sock, (struct sockaddr *)&sun, sizeof(sun)), "connect"); + + if (strcmp(filename, "-") != 0) { + fd = open(filename, flags); + OSERROR(fd, filename); + OSERROR(fstat(fd, &st), filename); + if (size > st.st_size) + size = st.st_size; + } else { + OSERROR(fstat(fd, &st), argv[2]); + } + + if (!use_sendfile) { + bool more = false; + + while (size) { + r = read(fd, buffer, min(sizeof(buffer), size)); + OSERROR(r, filename); + if (r == 0) + break; + size -= r; + + o = 0; + do { + more = size > 0; + w = send(sock, buffer + o, r - o, + more ? MSG_MORE : 0); + OSERROR(w, "sock/send"); + o += w; + total += w; + } while (o < r); + } + + if (more) + send(sock, NULL, 0, 0); + } else if (S_ISFIFO(st.st_mode)) { + do { + r = splice(fd, NULL, sock, NULL, size, + size > 0 ? SPLICE_F_MORE : 0); + OSERROR(r, "sock/splice"); + size -= r; + total += r; + } while (r > 0 && size > 0); + if (size && !all) { + fprintf(stderr, "Short splice\n"); + exit(1); + } + } else { + r = sendfile(sock, fd, NULL, size); + OSERROR(r, "sock/sendfile"); + if (r != size) { + fprintf(stderr, "Short sendfile\n"); + exit(1); + } + total += r; + } + + printf("Sent %zu bytes\n", total); + OSERROR(close(sock), "sock/close"); + OSERROR(close(fd), "close"); + return 0; +} diff --git a/samples/net/unix-sink.c b/samples/net/unix-sink.c new file mode 100644 index 000000000000..9f0a5ac9c578 --- /dev/null +++ b/samples/net/unix-sink.c @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +/* + * UNIX stream sink server + * + * Copyright (C) 2023 Red Hat, Inc. All Rights Reserved. + * Written by David Howells (dhowells@redhat.com) + */ + +#include +#include +#include +#include +#include +#include +#include + +#define OSERROR(X, Y) \ + do { if ((long)(X) == -1) { perror(Y); exit(1); } } while (0) + +static unsigned char buffer[512 * 1024]; + +int main(int argc, char *argv[]) +{ + struct sockaddr_un sun = { .sun_family = AF_UNIX, }; + size_t plen; + int server_sock, sock; + + if (argc != 2) { + fprintf(stderr, "unix-sink \n"); + exit(2); + } + + plen = strlen(argv[1]); + if (plen == 0 || plen > sizeof(sun.sun_path) - 1) { + fprintf(stderr, "socket filename too short or too long\n"); + exit(2); + } + memcpy(sun.sun_path, argv[1], plen + 1); + + server_sock = socket(AF_UNIX, SOCK_STREAM, 0); + OSERROR(server_sock, "socket"); + OSERROR(bind(server_sock, (struct sockaddr *)&sun, sizeof(sun)), + "bind"); + OSERROR(listen(server_sock, 1), "listen"); + + for (;;) { + sock = accept(server_sock, NULL, NULL); + if (sock != -1) { + while (read(sock, buffer, sizeof(buffer)) > 0) + ; + close(sock); + } + } +}