From patchwork Mon Jan 25 12:23:04 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Wang X-Patchwork-Id: 12043309 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id B642EC433DB for ; Mon, 25 Jan 2021 12:24:51 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 0AA9F222F9 for ; Mon, 25 Jan 2021 12:24:50 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 0AA9F222F9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:42526 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l40vK-0004bH-53 for qemu-devel@archiver.kernel.org; Mon, 25 Jan 2021 07:24:50 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:52904) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l40tt-0002uF-L8 for qemu-devel@nongnu.org; Mon, 25 Jan 2021 07:23:21 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:57704) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1l40tr-0007rL-Og for qemu-devel@nongnu.org; Mon, 25 Jan 2021 07:23:21 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611577398; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=e8mSm93PDo22g/Om/8RnrmZIy773rIqY04U8fKyMke0=; b=Rbs2nVro/rgIitYNGg1Jc134yW/fIt+JQ/sfFMaoK5TV/DB9Y93I1erzb/y6Yxy+3dDJRN QrgPjSXIscpH1WEXRxMWNDSIfbYgtwoUE7ou8JxelamKve3bZnSYZ8crMqf0GInIx6yaZi Y4L+coEh7yZz77sB6vzdwsJ+uAflzqw= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-447-vIbo_zdiNPi67M63ehX4KA-1; Mon, 25 Jan 2021 07:23:14 -0500 X-MC-Unique: vIbo_zdiNPi67M63ehX4KA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5A840100558A; Mon, 25 Jan 2021 12:23:13 +0000 (UTC) Received: from jason-ThinkPad-T430s.redhat.com (ovpn-12-126.pek2.redhat.com [10.72.12.126]) by smtp.corp.redhat.com (Postfix) with ESMTP id 66BFD19C44; Mon, 25 Jan 2021 12:23:11 +0000 (UTC) From: Jason Wang To: qemu-devel@nongnu.org, peter.maydell@linaro.org Subject: [RESEND PULL 1/4] net: Fix handling of id in netdev_add and netdev_del Date: Mon, 25 Jan 2021 20:23:04 +0800 Message-Id: <1611577387-4296-2-git-send-email-jasowang@redhat.com> In-Reply-To: <1611577387-4296-1-git-send-email-jasowang@redhat.com> References: <1611577387-4296-1-git-send-email-jasowang@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jasowang@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=jasowang@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.255, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=unavailable autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jason Wang , Markus Armbruster , qemu-stable@nongnu.org Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Markus Armbruster CLI -netdev accumulates in option group "netdev". Before commit 08712fcb85 "net: Track netdevs in NetClientState rather than QemuOpt", netdev_add added to the option group, and netdev_del removed from it, both HMP and QMP. Thus, every netdev had a corresponding QemuOpts in this option group. Commit 08712fcb85 dropped this for QMP netdev_add and both netdev_del. Now a netdev has a corresponding QemuOpts only when it was created with CLI or HMP. Two issues: * QMP and HMP netdev_del can leave QemuOpts behind, breaking HMP netdev_add. Reproducer: $ qemu-system-x86_64 -S -display none -nodefaults -monitor stdio QEMU 5.1.92 monitor - type 'help' for more information (qemu) netdev_add user,id=net0 (qemu) info network net0: index=0,type=user,net=10.0.2.0,restrict=off (qemu) netdev_del net0 (qemu) info network (qemu) netdev_add user,id=net0 upstream-qemu: Duplicate ID 'net0' for netdev Try "help netdev_add" for more information Fix by restoring the QemuOpts deletion in qmp_netdev_del(), but with a guard, because the QemuOpts need not exist. * QMP netdev_add loses its "no duplicate ID" check. Reproducer: $ qemu-system-x86_64 -S -display none -qmp stdio {"QMP": {"version": {"qemu": {"micro": 92, "minor": 1, "major": 5}, "package": "v5.2.0-rc2-1-g02c1f0142c"}, "capabilities": ["oob"]}} {"execute": "qmp_capabilities"} {"return": {}} {"execute": "netdev_add", "arguments": {"type": "user", "id":"net0"}} {"return": {}} {"execute": "netdev_add", "arguments": {"type": "user", "id":"net0"}} {"return": {}} Fix by adding a duplicate ID check to net_client_init1() to replace the lost one. The check is redundant for callers where QemuOpts still checks, i.e. for CLI and HMP. Reported-by: Andrew Melnichenko Fixes: 08712fcb851034228b61f75bd922863a984a4f60 Cc: qemu-stable@nongnu.org Signed-off-by: Markus Armbruster Reviewed-by: Eric Blake Signed-off-by: Jason Wang --- net/net.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/net/net.c b/net/net.c index e1035f2..c1cd9c7 100644 --- a/net/net.c +++ b/net/net.c @@ -983,6 +983,7 @@ static int (* const net_client_init_fun[NET_CLIENT_DRIVER__MAX])( static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp) { NetClientState *peer = NULL; + NetClientState *nc; if (is_netdev) { if (netdev->type == NET_CLIENT_DRIVER_NIC || @@ -1010,6 +1011,12 @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp) } } + nc = qemu_find_netdev(netdev->id); + if (nc) { + error_setg(errp, "Duplicate ID '%s'", netdev->id); + return -1; + } + if (net_client_init_fun[netdev->type](netdev, netdev->id, peer, errp) < 0) { /* FIXME drop when all init functions store an Error */ if (errp && !*errp) { @@ -1020,8 +1027,6 @@ static int net_client_init1(const Netdev *netdev, bool is_netdev, Error **errp) } if (is_netdev) { - NetClientState *nc; - nc = qemu_find_netdev(netdev->id); assert(nc); nc->is_netdev = true; @@ -1135,6 +1140,7 @@ void qmp_netdev_add(Netdev *netdev, Error **errp) void qmp_netdev_del(const char *id, Error **errp) { NetClientState *nc; + QemuOpts *opts; nc = qemu_find_netdev(id); if (!nc) { @@ -1149,6 +1155,16 @@ void qmp_netdev_del(const char *id, Error **errp) } qemu_del_net_client(nc); + + /* + * Wart: we need to delete the QemuOpts associated with netdevs + * created via CLI or HMP, to avoid bogus "Duplicate ID" errors in + * HMP netdev_add. + */ + opts = qemu_opts_find(qemu_find_opts("netdev"), id); + if (opts) { + qemu_opts_del(opts); + } } static void netfilter_print_info(Monitor *mon, NetFilterState *nf) From patchwork Mon Jan 25 12:23:05 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Wang X-Patchwork-Id: 12043321 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id C31F1C433DB for ; Mon, 25 Jan 2021 12:28:04 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 4490E2310C for ; Mon, 25 Jan 2021 12:28:03 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 4490E2310C Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:49390 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l40yQ-0007Z3-UW for qemu-devel@archiver.kernel.org; Mon, 25 Jan 2021 07:28:02 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:52958) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l40u0-00031J-Mq for qemu-devel@nongnu.org; Mon, 25 Jan 2021 07:23:28 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:37684) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1l40tt-0007tR-Ts for qemu-devel@nongnu.org; Mon, 25 Jan 2021 07:23:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611577401; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=u2G89Z36/wSDze7ulXLsFFw66Wxg90K6z0OfUh+k1qY=; b=SopUM0Tyz+1ehRqy0na6vvllVnAnwF4DcQdLJ2CT6bxYuVrqg+pjwVje3MIz+8qPA+JcaW QQAouyNN0aPsap8oh7r4droiFsOsZsbgUcJjrNYUGprCJHN7qHCDkPqr8rjTKBuNu4cqAy 5mb4d+0WlfPkXG3RKY1IXTb9/E9fKLI= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-550-Hf2P1JsPPLGNPWl_f-kxCg-1; Mon, 25 Jan 2021 07:23:17 -0500 X-MC-Unique: Hf2P1JsPPLGNPWl_f-kxCg-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id C17B5100558A; Mon, 25 Jan 2021 12:23:15 +0000 (UTC) Received: from jason-ThinkPad-T430s.redhat.com (ovpn-12-126.pek2.redhat.com [10.72.12.126]) by smtp.corp.redhat.com (Postfix) with ESMTP id D2C6419C44; Mon, 25 Jan 2021 12:23:13 +0000 (UTC) From: Jason Wang To: qemu-devel@nongnu.org, peter.maydell@linaro.org Subject: [RESEND PULL 2/4] net: checksum: Skip fragmented IP packets Date: Mon, 25 Jan 2021 20:23:05 +0800 Message-Id: <1611577387-4296-3-git-send-email-jasowang@redhat.com> In-Reply-To: <1611577387-4296-1-git-send-email-jasowang@redhat.com> References: <1611577387-4296-1-git-send-email-jasowang@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jasowang@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=jasowang@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.255, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jason Wang , Bin Meng , Markus Carlstedt Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Markus Carlstedt To calculate the TCP/UDP checksum we need the whole datagram. Unless the hardware has some logic to collect all fragments before sending the whole datagram first, it can only be done by the network stack, which is normally the case for the NICs we have seen so far. Skip these fragmented IP packets to avoid checksum corruption. Signed-off-by: Markus Carlstedt Signed-off-by: Bin Meng Signed-off-by: Jason Wang --- net/checksum.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/net/checksum.c b/net/checksum.c index aaa4000..5cb8b2c 100644 --- a/net/checksum.c +++ b/net/checksum.c @@ -106,6 +106,10 @@ void net_checksum_calculate(uint8_t *data, int length) return; /* not IPv4 */ } + if (IP4_IS_FRAGMENT(ip)) { + return; /* a fragmented IP packet */ + } + ip_len = lduw_be_p(&ip->ip_len); /* Last, check that we have enough data for the all IP frame */ From patchwork Mon Jan 25 12:23:06 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Jason Wang X-Patchwork-Id: 12043317 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E0E11C433E0 for ; Mon, 25 Jan 2021 12:26:38 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 688FF225A9 for ; Mon, 25 Jan 2021 12:26:38 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 688FF225A9 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:45826 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l40x3-00064o-8K for qemu-devel@archiver.kernel.org; Mon, 25 Jan 2021 07:26:37 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:52962) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l40u0-00031b-PY for qemu-devel@nongnu.org; Mon, 25 Jan 2021 07:23:28 -0500 Received: from us-smtp-delivery-124.mimecast.com ([216.205.24.124]:30952) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1l40tz-0007uG-1r for qemu-devel@nongnu.org; Mon, 25 Jan 2021 07:23:28 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611577402; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=7hHfDZ2RcIUnVWRCkZBOrLDzrIEoqdZ+sv/eDpbf5T8=; b=TT25y21NYafhT0VWoxAtCvHEX9gAUh0QExgxzTRVeE1wcwxbaxu1I04QrjerNoufzhXW9s TiKFVZQl/mP4DUmLClsPdlKoAJHW0NQaK1gm5YutEGjsnv9lMzlLcrXnndo8n8ol3x9QOx 45VMI7IPxaPPekKGOUomDiV97maM4Uc= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-133-YmbrQFTJNre46Leexs8Vmg-1; Mon, 25 Jan 2021 07:23:20 -0500 X-MC-Unique: YmbrQFTJNre46Leexs8Vmg-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 776098145E0; Mon, 25 Jan 2021 12:23:19 +0000 (UTC) Received: from jason-ThinkPad-T430s.redhat.com (ovpn-12-126.pek2.redhat.com [10.72.12.126]) by smtp.corp.redhat.com (Postfix) with ESMTP id 45B4319C44; Mon, 25 Jan 2021 12:23:16 +0000 (UTC) From: Jason Wang To: qemu-devel@nongnu.org, peter.maydell@linaro.org Subject: [RESEND PULL 3/4] net: checksum: Add IP header checksum calculation Date: Mon, 25 Jan 2021 20:23:06 +0800 Message-Id: <1611577387-4296-4-git-send-email-jasowang@redhat.com> In-Reply-To: <1611577387-4296-1-git-send-email-jasowang@redhat.com> References: <1611577387-4296-1-git-send-email-jasowang@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jasowang@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=216.205.24.124; envelope-from=jasowang@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.255, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H3=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Bin Meng , Yabing Liu , Jason Wang , Guishan Qin Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Guishan Qin At present net_checksum_calculate() only calculates TCP/UDP checksum in an IP packet, but assumes the IP header checksum to be provided by the software, e.g.: Linux kernel always calculates the IP header checksum. However this might not always be the case, e.g.: for an IP checksum offload enabled stack like VxWorks, the IP header checksum can be zero. This adds the checksum calculation of the IP header. Signed-off-by: Guishan Qin Signed-off-by: Yabing Liu Signed-off-by: Bin Meng Reviewed-by: Cédric Le Goater Signed-off-by: Jason Wang --- net/checksum.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/net/checksum.c b/net/checksum.c index 5cb8b2c..dabd290 100644 --- a/net/checksum.c +++ b/net/checksum.c @@ -61,6 +61,7 @@ void net_checksum_calculate(uint8_t *data, int length) { int mac_hdr_len, ip_len; struct ip_header *ip; + uint16_t csum; /* * Note: We cannot assume "data" is aligned, so the all code uses @@ -106,6 +107,11 @@ void net_checksum_calculate(uint8_t *data, int length) return; /* not IPv4 */ } + /* Calculate IP checksum */ + stw_he_p(&ip->ip_sum, 0); + csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip)); + stw_be_p(&ip->ip_sum, csum); + if (IP4_IS_FRAGMENT(ip)) { return; /* a fragmented IP packet */ } @@ -122,7 +128,6 @@ void net_checksum_calculate(uint8_t *data, int length) switch (ip->ip_p) { case IP_PROTO_TCP: { - uint16_t csum; tcp_header *tcp = (tcp_header *)(ip + 1); if (ip_len < sizeof(tcp_header)) { @@ -143,7 +148,6 @@ void net_checksum_calculate(uint8_t *data, int length) } case IP_PROTO_UDP: { - uint16_t csum; udp_header *udp = (udp_header *)(ip + 1); if (ip_len < sizeof(udp_header)) { From patchwork Mon Jan 25 12:23:07 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jason Wang X-Patchwork-Id: 12043323 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-13.6 required=3.0 tests=BAYES_00,DKIM_INVALID, DKIM_SIGNED,HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_CR_TRAILER,INCLUDES_PATCH, MAILING_LIST_MULTI,SPF_HELO_NONE,SPF_PASS,URIBL_BLOCKED autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id 0F578C433E0 for ; Mon, 25 Jan 2021 12:28:55 +0000 (UTC) Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by mail.kernel.org (Postfix) with ESMTPS id 7F17D2311B for ; Mon, 25 Jan 2021 12:28:54 +0000 (UTC) DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 7F17D2311B Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=redhat.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Received: from localhost ([::1]:52054 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1l40zF-0000Fj-I7 for qemu-devel@archiver.kernel.org; Mon, 25 Jan 2021 07:28:53 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:52970) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1l40u1-000343-T1 for qemu-devel@nongnu.org; Mon, 25 Jan 2021 07:23:29 -0500 Received: from us-smtp-delivery-124.mimecast.com ([63.128.21.124]:35505) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.90_1) (envelope-from ) id 1l40tz-0007uX-20 for qemu-devel@nongnu.org; Mon, 25 Jan 2021 07:23:29 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1611577404; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:content-type:content-type:in-reply-to:in-reply-to: references:references; bh=gT50dWcb6n+Vmf0qd3yXV4AfOgHc9f6xuSFTrODJjUc=; b=S5ZXduEuBnFniViDjbMVl4DF3KSxwvJF1zRFXcpghle1BfpvXP++iHk5MafS4+3kzejs4w lnX7hzDf6vpF2Dkm/1CbZilOkIvQ2NUX+xbVzru98PZXhkpv8nZtx5ZLjBoUt75400cUo9 lYm942Efi97aHgZVQhPT18B7FDxYE+A= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-316-ii243_9wPXiFGG9ijhclgA-1; Mon, 25 Jan 2021 07:23:22 -0500 X-MC-Unique: ii243_9wPXiFGG9ijhclgA-1 Received: from smtp.corp.redhat.com (int-mx08.intmail.prod.int.phx2.redhat.com [10.5.11.23]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id 5817110054FF; Mon, 25 Jan 2021 12:23:21 +0000 (UTC) Received: from jason-ThinkPad-T430s.redhat.com (ovpn-12-126.pek2.redhat.com [10.72.12.126]) by smtp.corp.redhat.com (Postfix) with ESMTP id C770719C44; Mon, 25 Jan 2021 12:23:19 +0000 (UTC) From: Jason Wang To: qemu-devel@nongnu.org, peter.maydell@linaro.org Subject: [RESEND PULL 4/4] net: checksum: Introduce fine control over checksum type Date: Mon, 25 Jan 2021 20:23:07 +0800 Message-Id: <1611577387-4296-5-git-send-email-jasowang@redhat.com> In-Reply-To: <1611577387-4296-1-git-send-email-jasowang@redhat.com> References: <1611577387-4296-1-git-send-email-jasowang@redhat.com> X-Scanned-By: MIMEDefang 2.84 on 10.5.11.23 Authentication-Results: relay.mimecast.com; auth=pass smtp.auth=CUSA124A263 smtp.mailfrom=jasowang@redhat.com X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com Received-SPF: pass client-ip=63.128.21.124; envelope-from=jasowang@redhat.com; helo=us-smtp-delivery-124.mimecast.com X-Spam_score_int: -30 X-Spam_score: -3.1 X-Spam_bar: --- X-Spam_report: (-3.1 / 5.0 requ) BAYES_00=-1.9, DKIMWL_WL_HIGH=-0.255, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, RCVD_IN_DNSWL_LOW=-0.7, RCVD_IN_MSPIKE_H4=0.001, RCVD_IN_MSPIKE_WL=0.001, SPF_HELO_NONE=0.001, SPF_PASS=-0.001 autolearn=ham autolearn_force=no X-Spam_action: no action X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Jason Wang , Bin Meng Errors-To: qemu-devel-bounces+qemu-devel=archiver.kernel.org@nongnu.org Sender: "Qemu-devel" From: Bin Meng At present net_checksum_calculate() blindly calculates all types of checksums (IP, TCP, UDP). Some NICs may have a per type setting in their BDs to control what checksum should be offloaded. To support such hardware behavior, introduce a 'csum_flag' parameter to the net_checksum_calculate() API to allow fine control over what type checksum is calculated. Existing users of this API are updated accordingly. Signed-off-by: Bin Meng Signed-off-by: Jason Wang --- hw/net/allwinner-sun8i-emac.c | 2 +- hw/net/cadence_gem.c | 2 +- hw/net/fsl_etsec/rings.c | 18 +++++++++--------- hw/net/ftgmac100.c | 13 ++++++++++++- hw/net/imx_fec.c | 20 ++++++++------------ hw/net/virtio-net.c | 2 +- hw/net/xen_nic.c | 2 +- include/net/checksum.h | 7 ++++++- net/checksum.c | 18 ++++++++++++++---- net/filter-rewriter.c | 4 ++-- 10 files changed, 55 insertions(+), 33 deletions(-) diff --git a/hw/net/allwinner-sun8i-emac.c b/hw/net/allwinner-sun8i-emac.c index 38d3285..0427689 100644 --- a/hw/net/allwinner-sun8i-emac.c +++ b/hw/net/allwinner-sun8i-emac.c @@ -514,7 +514,7 @@ static void allwinner_sun8i_emac_transmit(AwSun8iEmacState *s) /* After the last descriptor, send the packet */ if (desc.status2 & TX_DESC_STATUS2_LAST_DESC) { if (desc.status2 & TX_DESC_STATUS2_CHECKSUM_MASK) { - net_checksum_calculate(packet_buf, packet_bytes); + net_checksum_calculate(packet_buf, packet_bytes, CSUM_ALL); } qemu_send_packet(nc, packet_buf, packet_bytes); diff --git a/hw/net/cadence_gem.c b/hw/net/cadence_gem.c index 7a53469..9a4474a 100644 --- a/hw/net/cadence_gem.c +++ b/hw/net/cadence_gem.c @@ -1266,7 +1266,7 @@ static void gem_transmit(CadenceGEMState *s) /* Is checksum offload enabled? */ if (s->regs[GEM_DMACFG] & GEM_DMACFG_TXCSUM_OFFL) { - net_checksum_calculate(s->tx_packet, total_bytes); + net_checksum_calculate(s->tx_packet, total_bytes, CSUM_ALL); } /* Update MAC statistics */ diff --git a/hw/net/fsl_etsec/rings.c b/hw/net/fsl_etsec/rings.c index 628648a..121415a 100644 --- a/hw/net/fsl_etsec/rings.c +++ b/hw/net/fsl_etsec/rings.c @@ -183,13 +183,11 @@ static void process_tx_fcb(eTSEC *etsec) uint8_t *l3_header = etsec->tx_buffer + 8 + l3_header_offset; /* L4 header */ uint8_t *l4_header = l3_header + l4_header_offset; + int csum = 0; /* if packet is IP4 and IP checksum is requested */ if (flags & FCB_TX_IP && flags & FCB_TX_CIP) { - /* do IP4 checksum (TODO This function does TCP/UDP checksum - * but not sure if it also does IP4 checksum.) */ - net_checksum_calculate(etsec->tx_buffer + 8, - etsec->tx_buffer_len - 8); + csum |= CSUM_IP; } /* TODO Check the correct usage of the PHCS field of the FCB in case the NPH * flag is on */ @@ -201,9 +199,7 @@ static void process_tx_fcb(eTSEC *etsec) /* if checksum is requested */ if (flags & FCB_TX_CTU) { /* do UDP checksum */ - - net_checksum_calculate(etsec->tx_buffer + 8, - etsec->tx_buffer_len - 8); + csum |= CSUM_UDP; } else { /* set checksum field to 0 */ l4_header[6] = 0; @@ -211,10 +207,14 @@ static void process_tx_fcb(eTSEC *etsec) } } else if (flags & FCB_TX_CTU) { /* if TCP and checksum is requested */ /* do TCP checksum */ - net_checksum_calculate(etsec->tx_buffer + 8, - etsec->tx_buffer_len - 8); + csum |= CSUM_TCP; } } + + if (csum) { + net_checksum_calculate(etsec->tx_buffer + 8, + etsec->tx_buffer_len - 8, csum); + } } static void process_tx_bd(eTSEC *etsec, diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index 782ff19..25685ba 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -564,6 +564,7 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring, ptr += len; frame_size += len; if (bd.des0 & FTGMAC100_TXDES0_LTS) { + int csum = 0; /* Check for VLAN */ if (flags & FTGMAC100_TXDES1_INS_VLANTAG && @@ -573,8 +574,18 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring, } if (flags & FTGMAC100_TXDES1_IP_CHKSUM) { - net_checksum_calculate(s->frame, frame_size); + csum |= CSUM_IP; } + if (flags & FTGMAC100_TXDES1_TCP_CHKSUM) { + csum |= CSUM_TCP; + } + if (flags & FTGMAC100_TXDES1_UDP_CHKSUM) { + csum |= CSUM_UDP; + } + if (csum) { + net_checksum_calculate(s->frame, frame_size, csum); + } + /* Last buffer in frame. */ qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size); ptr = s->frame; diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c index 2c14804..f03450c 100644 --- a/hw/net/imx_fec.c +++ b/hw/net/imx_fec.c @@ -561,22 +561,18 @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index) ptr += len; frame_size += len; if (bd.flags & ENET_BD_L) { + int csum = 0; + if (bd.option & ENET_BD_PINS) { - struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame); - if (IP_HEADER_VERSION(ip_hd) == 4) { - net_checksum_calculate(s->frame, frame_size); - } + csum |= (CSUM_TCP | CSUM_UDP); } if (bd.option & ENET_BD_IINS) { - struct ip_header *ip_hd = PKT_GET_IP_HDR(s->frame); - /* We compute checksum only for IPv4 frames */ - if (IP_HEADER_VERSION(ip_hd) == 4) { - uint16_t csum; - ip_hd->ip_sum = 0; - csum = net_raw_checksum((uint8_t *)ip_hd, sizeof(*ip_hd)); - ip_hd->ip_sum = cpu_to_be16(csum); - } + csum |= CSUM_IP; + } + if (csum) { + net_checksum_calculate(s->frame, frame_size, csum); } + /* Last buffer in frame. */ qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size); diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 09ceb02..5150f29 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1464,7 +1464,7 @@ static void work_around_broken_dhclient(struct virtio_net_hdr *hdr, (buf[12] == 0x08 && buf[13] == 0x00) && /* ethertype == IPv4 */ (buf[23] == 17) && /* ip.protocol == UDP */ (buf[34] == 0 && buf[35] == 67)) { /* udp.srcport == bootps */ - net_checksum_calculate(buf, size); + net_checksum_calculate(buf, size, CSUM_UDP); hdr->flags &= ~VIRTIO_NET_HDR_F_NEEDS_CSUM; } } diff --git a/hw/net/xen_nic.c b/hw/net/xen_nic.c index 00a7fdf..5c815b4 100644 --- a/hw/net/xen_nic.c +++ b/hw/net/xen_nic.c @@ -174,7 +174,7 @@ static void net_tx_packets(struct XenNetDev *netdev) tmpbuf = g_malloc(XC_PAGE_SIZE); } memcpy(tmpbuf, page + txreq.offset, txreq.size); - net_checksum_calculate(tmpbuf, txreq.size); + net_checksum_calculate(tmpbuf, txreq.size, CSUM_ALL); qemu_send_packet(qemu_get_queue(netdev->nic), tmpbuf, txreq.size); } else { diff --git a/include/net/checksum.h b/include/net/checksum.h index 05a0d27..7dec37e 100644 --- a/include/net/checksum.h +++ b/include/net/checksum.h @@ -21,11 +21,16 @@ #include "qemu/bswap.h" struct iovec; +#define CSUM_IP 0x01 +#define CSUM_TCP 0x02 +#define CSUM_UDP 0x04 +#define CSUM_ALL (CSUM_IP | CSUM_TCP | CSUM_UDP) + uint32_t net_checksum_add_cont(int len, uint8_t *buf, int seq); uint16_t net_checksum_finish(uint32_t sum); uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto, uint8_t *addrs, uint8_t *buf); -void net_checksum_calculate(uint8_t *data, int length); +void net_checksum_calculate(uint8_t *data, int length, int csum_flag); static inline uint32_t net_checksum_add(int len, uint8_t *buf) diff --git a/net/checksum.c b/net/checksum.c index dabd290..70f4eae 100644 --- a/net/checksum.c +++ b/net/checksum.c @@ -57,7 +57,7 @@ uint16_t net_checksum_tcpudp(uint16_t length, uint16_t proto, return net_checksum_finish(sum); } -void net_checksum_calculate(uint8_t *data, int length) +void net_checksum_calculate(uint8_t *data, int length, int csum_flag) { int mac_hdr_len, ip_len; struct ip_header *ip; @@ -108,9 +108,11 @@ void net_checksum_calculate(uint8_t *data, int length) } /* Calculate IP checksum */ - stw_he_p(&ip->ip_sum, 0); - csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip)); - stw_be_p(&ip->ip_sum, csum); + if (csum_flag & CSUM_IP) { + stw_he_p(&ip->ip_sum, 0); + csum = net_raw_checksum((uint8_t *)ip, IP_HDR_GET_LEN(ip)); + stw_be_p(&ip->ip_sum, csum); + } if (IP4_IS_FRAGMENT(ip)) { return; /* a fragmented IP packet */ @@ -128,6 +130,10 @@ void net_checksum_calculate(uint8_t *data, int length) switch (ip->ip_p) { case IP_PROTO_TCP: { + if (!(csum_flag & CSUM_TCP)) { + return; + } + tcp_header *tcp = (tcp_header *)(ip + 1); if (ip_len < sizeof(tcp_header)) { @@ -148,6 +154,10 @@ void net_checksum_calculate(uint8_t *data, int length) } case IP_PROTO_UDP: { + if (!(csum_flag & CSUM_UDP)) { + return; + } + udp_header *udp = (udp_header *)(ip + 1); if (ip_len < sizeof(udp_header)) { diff --git a/net/filter-rewriter.c b/net/filter-rewriter.c index fc0e64c..10fe393 100644 --- a/net/filter-rewriter.c +++ b/net/filter-rewriter.c @@ -114,7 +114,7 @@ static int handle_primary_tcp_pkt(RewriterState *rf, tcp_pkt->th_ack = htonl(ntohl(tcp_pkt->th_ack) + conn->offset); net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len, - pkt->size - pkt->vnet_hdr_len); + pkt->size - pkt->vnet_hdr_len, CSUM_TCP); } /* @@ -216,7 +216,7 @@ static int handle_secondary_tcp_pkt(RewriterState *rf, tcp_pkt->th_seq = htonl(ntohl(tcp_pkt->th_seq) - conn->offset); net_checksum_calculate((uint8_t *)pkt->data + pkt->vnet_hdr_len, - pkt->size - pkt->vnet_hdr_len); + pkt->size - pkt->vnet_hdr_len, CSUM_TCP); } }