From patchwork Sun Dec 6 02:14:05 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bin Meng X-Patchwork-Id: 1411673 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=QaRMgZdQ; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4CpVSP4kTVz9sW0 for ; Sun, 6 Dec 2020 13:16:53 +1100 (AEDT) Received: from localhost ([::1]:51296 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kljbX-0000GK-Kl for incoming@patchwork.ozlabs.org; Sat, 05 Dec 2020 21:16:51 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:48072) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1klja2-00008o-SL for qemu-devel@nongnu.org; Sat, 05 Dec 2020 21:15:22 -0500 Received: from mail-qk1-x743.google.com ([2607:f8b0:4864:20::743]:41964) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kljZz-0004Q7-NY for qemu-devel@nongnu.org; Sat, 05 Dec 2020 21:15:18 -0500 Received: by mail-qk1-x743.google.com with SMTP id 19so1846914qkm.8 for ; Sat, 05 Dec 2020 18:15:14 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=2Uiiq4qQjczyfuHIEkIt5O5wZUUpd/eN4ovFrUj9k4g=; b=QaRMgZdQg83Xz+dMoZULdSf0W6EXZe08iGDYRJ5niglK8PSgsPol5wRXwnLusiv59G dS20Kb4NX74womh4Nghrsh6XszHa8jbPWv8UYhzWTjK2IMUxjgse+6Mma82eGasRMy6U BprWxLmLUdcYyFtGvGzl+PT0PPZ5D5PEfCf4PJTnMi3yabr7QjKw7H3sJtAYZc3Anijk +Z+1V3HbjCYVZAxbxo4oBuGVWuBwvrGaeUUeP5rg6/m5cnxc1m7StMwc4YHV+OrrrgFs v6FMRZzpTcgOYG07vdJ9eCExqodNAtw+KwsW71o8XsNVoRv2dZgKyrW+nWXhUWRTGx4O FSsw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id; bh=2Uiiq4qQjczyfuHIEkIt5O5wZUUpd/eN4ovFrUj9k4g=; b=JGadR5u38UUis5d7/ekn9lg5+xNeOAhwLiX+d7i/nvi0lgsMga0RoUZ2+nfOtF5Kn2 jSIPtShb+UosvRLc3EpG8xARIQxFPE/Cf6SU4o9hsH3WcUozRI0KiKANLZfWGD81OiNZ FbEArlxJNr0X+A2Gdyer510X/RpgFP3sX1ALKCp1jwmgHx0V/HWdy7lq2CRUJVbBpu/g hauDxriI9g2n1pBXRwv4b5U5Mh5oplPyXvIy5JENXJhUSpyHKJAI1cIyX0P5ZCwJFNiE 9OCp90PRVO+qdOirMWo20zjFN8p76tkAque2ec2qHOluS3LSLjhbcYqxbXgBTlwrB3BT ExCw== X-Gm-Message-State: AOAM532jUCRnXjGkc6P9evjePJVN/6LG0Tuz8flyt6U0zzcp8wBW/T59 VTT4fwCl/LreSLX9TeIxaUnWJqv7kLY= X-Google-Smtp-Source: ABdhPJwCNEKJ4A+fdNq1Fe7S2rSJEtlBTrnv5uQ8r3EVQagGIWqkooEimKsTh70C6OnENgpxnaItsA== X-Received: by 2002:a37:a402:: with SMTP id n2mr17076189qke.131.1607220914097; Sat, 05 Dec 2020 18:15:14 -0800 (PST) Received: from pek-vx-bsp2.wrs.com (unknown-124-94.windriver.com. [147.11.124.94]) by smtp.gmail.com with ESMTPSA id g18sm9296306qtv.79.2020.12.05.18.15.11 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 05 Dec 2020 18:15:13 -0800 (PST) From: Bin Meng To: qemu-devel@nongnu.org Subject: [PATCH 1/3] net: checksum: Skip fragmented IP packets Date: Sun, 6 Dec 2020 10:14:05 +0800 Message-Id: <1607220847-24096-1-git-send-email-bmeng.cn@gmail.com> X-Mailer: git-send-email 2.7.4 Received-SPF: pass client-ip=2607:f8b0:4864:20::743; envelope-from=bmeng.cn@gmail.com; helo=mail-qk1-x743.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, 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+incoming=patchwork.ozlabs.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 --- 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 Sun Dec 6 02:14:06 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bin Meng X-Patchwork-Id: 1411671 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=YhV2mC8T; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4CpVS76WsVz9sW0 for ; Sun, 6 Dec 2020 13:16:38 +1100 (AEDT) Received: from localhost ([::1]:51118 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kljbG-0000AQ-F9 for incoming@patchwork.ozlabs.org; Sat, 05 Dec 2020 21:16:34 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:48098) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1klja8-00009K-M8 for qemu-devel@nongnu.org; Sat, 05 Dec 2020 21:15:26 -0500 Received: from mail-qk1-x742.google.com ([2607:f8b0:4864:20::742]:46827) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1klja2-0004RN-Ar for qemu-devel@nongnu.org; Sat, 05 Dec 2020 21:15:24 -0500 Received: by mail-qk1-x742.google.com with SMTP id b144so9364883qkc.13 for ; Sat, 05 Dec 2020 18:15:17 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=88/g7x9jWgiFvWvysHBHT2ly75bddWfAdJU3sD69n0k=; b=YhV2mC8T5z54WDwC2w35XFe0RLa6IOUGK6voppIUMZPfRQC1ZdjLBqRBojyAIYgMtA l7g3zkZMOT8xagCH6cylwUITIybPNTM3PVdPVnOnvlU1K2lNxgZQgEh1U2+Qp0Pls2G9 GVObkbbFnZ7ykUnfRTlY/2+PHcU0ybc5oc6YeHuUaTajkm878EAU29yxqzNZPdSeSPOO RYL0I+gteyXulJAIeJq3nUQSchRJIZc2qcOvp8tnx/K01ffa9qxMLGze4kSi0Ss0zd4o UlC/2+ZZgiiqkPUGCOhSL2SftGJww9s2CiZ4eA+VaCgJm94+HVINY/oZUJZBMxJXfhzt JBoQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=88/g7x9jWgiFvWvysHBHT2ly75bddWfAdJU3sD69n0k=; b=R/+SiXvmoajIwYMDRpBdiqBxMzt4/pn2rKN6tDqkfiPiW78KPmuiV4ICinAvm5Pp8P UYmkiRsQQIx6ySNXJKAn3P8hmRf7ZaJMzBgfYe56Nb/8r3bxSsa0n2kYIi7ZKPCReTOz 394ZxhgGGO1C4Pmtj7R6GsEJPpHPF+QZpTYhJxANxV+dQ3rm0y8JBnViyL1OHRnlXimG mL1G/gkZ3A6sQa+l+1kAFVp9uqfb5D9Exzrit70v8whIzv3/zc6Nfe5cpafqK2UfLsmQ SYfdr5UhHSzeldSyENytU3WwkXiIS5hzh54vR8lqqvvIvCCpe/EGUaNQGfoNlkVoKHIA xNNw== X-Gm-Message-State: AOAM530/z3B3fcpYQtuZ1A9UlQBzyKRZ4HWhJgBs8KE0wRZ+TTP8Klek +bOYaGC/aZTP2A18dz4y3ew87NrEQmY= X-Google-Smtp-Source: ABdhPJwEabpIk/HH2VuY6NVnee8puE5hjdJwq33XegPOfYUc2VxC2bNQ2LQlU0BeVo4uQiaijN33GQ== X-Received: by 2002:a37:afc2:: with SMTP id y185mr17656589qke.149.1607220917403; Sat, 05 Dec 2020 18:15:17 -0800 (PST) Received: from pek-vx-bsp2.wrs.com (unknown-124-94.windriver.com. [147.11.124.94]) by smtp.gmail.com with ESMTPSA id g18sm9296306qtv.79.2020.12.05.18.15.14 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 05 Dec 2020 18:15:16 -0800 (PST) From: Bin Meng To: qemu-devel@nongnu.org Subject: [PATCH 2/3] net: checksum: Add IP header checksum calculation Date: Sun, 6 Dec 2020 10:14:06 +0800 Message-Id: <1607220847-24096-2-git-send-email-bmeng.cn@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1607220847-24096-1-git-send-email-bmeng.cn@gmail.com> References: <1607220847-24096-1-git-send-email-bmeng.cn@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::742; envelope-from=bmeng.cn@gmail.com; helo=mail-qk1-x742.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, 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+incoming=patchwork.ozlabs.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 chcksum 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 --- 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 Sun Dec 6 02:14:07 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bin Meng X-Patchwork-Id: 1411672 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20161025 header.b=TdyDkqCW; dkim-atps=neutral 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 ozlabs.org (Postfix) with ESMTPS id 4CpVS82Jmhz9sW1 for ; Sun, 6 Dec 2020 13:16:38 +1100 (AEDT) Received: from localhost ([::1]:51164 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1kljbI-0000CK-HN for incoming@patchwork.ozlabs.org; Sat, 05 Dec 2020 21:16:36 -0500 Received: from eggs.gnu.org ([2001:470:142:3::10]:48136) by lists.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.90_1) (envelope-from ) id 1kljaF-0000AT-Q3; Sat, 05 Dec 2020 21:15:32 -0500 Received: from mail-qk1-x742.google.com ([2607:f8b0:4864:20::742]:37283) by eggs.gnu.org with esmtps (TLS1.2:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.90_1) (envelope-from ) id 1kljaA-0004Sr-Gh; Sat, 05 Dec 2020 21:15:31 -0500 Received: by mail-qk1-x742.google.com with SMTP id h20so9441557qkk.4; Sat, 05 Dec 2020 18:15:24 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=su1F/v+5+aB1M38riLgjKG95V1Mh9HGEBldHjqNVRUM=; b=TdyDkqCWGblhOuKZpsO1dxV+LKOBRkwiBZTIHPq66a93eKkXM6ZRIb9GfI9Mla98vS DcmmN6P2DKo7qJ4WQUHVrmrEJ4C+dbQ0dsjQdMwuy03rhYFqtKqDNARJ3hmpbTeIDBSp RybTmnKTqhKGY8fsHdCLeesBkfvlM7iKsk19gYn4WW6de1mgh0zHvilrElLfXytHyklJ DyeAThJ/hEsft2Be5e3dZPNVw+BAxur2CFGh5Ohl16mMzYn/rbCGj9I8bF8vZFEUjFXK Lg1US5va1GpD9DOapI+KePYY0OJwqp1fCDFFucXsZZSFc13y0rW7y0YcmH4mjtjibHkF uVrg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=su1F/v+5+aB1M38riLgjKG95V1Mh9HGEBldHjqNVRUM=; b=ReK7XOJ5BRIbCrNmPnQ1MiFZLuqqC3a2fbWtNVmfifaCcM5/P9U+MXOPX7gLR9wPl5 7a0J4cmWVSDWDB/sj7YIVvcNq1XXlo/kxj5BKManC2UUext3snR4lL/wvIAgM00DF7dO YufvvWGBWK0E6gXHptkWbfdyWzgfPNz2nGgN8yCQQIGe6vY1iHZL4GW00tCVhtt8yLhn IPP4C74QpocSY/+K4nGoNTylz2af0S55McWv+t2H22l8vGQUXbT22qjJg/O+VBBRwJQe vRXZDCbOMGSUPMARlin6jGQLJBSvlLbbePdzpvVYcOmCefc24uiNWsJMdC64/FdUFfKb qSbw== X-Gm-Message-State: AOAM532KhgrruWQVgGurp92jJa5uCohOU2Zmt1PTFx6MKZFQqo9RUJ6C Ol0z7AnyMeohKVYxdJwRsIHUky9DlkY= X-Google-Smtp-Source: ABdhPJz6I806bbxlzJbwwb4kQ3YSWW06ZHnPeCzANSQUQT99JyJR1eK9gpq6LyJ0IUUONb6beAYzeA== X-Received: by 2002:a37:8943:: with SMTP id l64mr16832588qkd.212.1607220924201; Sat, 05 Dec 2020 18:15:24 -0800 (PST) Received: from pek-vx-bsp2.wrs.com (unknown-124-94.windriver.com. [147.11.124.94]) by smtp.gmail.com with ESMTPSA id g18sm9296306qtv.79.2020.12.05.18.15.17 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Sat, 05 Dec 2020 18:15:23 -0800 (PST) From: Bin Meng To: qemu-devel@nongnu.org Subject: [PATCH 3/3] net: checksum: Introduce fine control over checksum type Date: Sun, 6 Dec 2020 10:14:07 +0800 Message-Id: <1607220847-24096-3-git-send-email-bmeng.cn@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1607220847-24096-1-git-send-email-bmeng.cn@gmail.com> References: <1607220847-24096-1-git-send-email-bmeng.cn@gmail.com> Received-SPF: pass client-ip=2607:f8b0:4864:20::742; envelope-from=bmeng.cn@gmail.com; helo=mail-qk1-x742.google.com X-Spam_score_int: -20 X-Spam_score: -2.1 X-Spam_bar: -- X-Spam_report: (-2.1 / 5.0 requ) BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, DKIM_VALID_EF=-0.1, FREEMAIL_FROM=0.001, RCVD_IN_DNSWL_NONE=-0.0001, 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: Peter Maydell , Alistair Francis , Paul Durrant , Li Zhijian , "Michael S. Tsirkin" , Andrew Jeffery , Jason Wang , Bin Meng , Joel Stanley , Beniamino Galvani , Zhang Chen , Stefano Stabellini , Peter Chubb , =?utf-8?q?C=C3=A9dric_Le_Goater?= , qemu-arm@nongnu.org, xen-devel@lists.xenproject.org, Anthony Perard , "Edgar E. Iglesias" , qemu-ppc@nongnu.org, David Gibson Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.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 --- hw/net/allwinner-sun8i-emac.c | 2 +- hw/net/cadence_gem.c | 2 +- hw/net/fsl_etsec/rings.c | 8 +++----- hw/net/ftgmac100.c | 10 +++++++++- hw/net/imx_fec.c | 15 +++------------ 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, 41 insertions(+), 29 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..2b0afee 100644 --- a/hw/net/fsl_etsec/rings.c +++ b/hw/net/fsl_etsec/rings.c @@ -186,10 +186,8 @@ static void process_tx_fcb(eTSEC *etsec) /* 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); + etsec->tx_buffer_len - 8, CSUM_IP); } /* TODO Check the correct usage of the PHCS field of the FCB in case the NPH * flag is on */ @@ -203,7 +201,7 @@ static void process_tx_fcb(eTSEC *etsec) /* do UDP checksum */ net_checksum_calculate(etsec->tx_buffer + 8, - etsec->tx_buffer_len - 8); + etsec->tx_buffer_len - 8, CSUM_UDP); } else { /* set checksum field to 0 */ l4_header[6] = 0; @@ -212,7 +210,7 @@ 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); + etsec->tx_buffer_len - 8, CSUM_TCP); } } } diff --git a/hw/net/ftgmac100.c b/hw/net/ftgmac100.c index 782ff19..fbae1f1 100644 --- a/hw/net/ftgmac100.c +++ b/hw/net/ftgmac100.c @@ -573,7 +573,15 @@ static void ftgmac100_do_tx(FTGMAC100State *s, uint32_t tx_ring, } if (flags & FTGMAC100_TXDES1_IP_CHKSUM) { - net_checksum_calculate(s->frame, frame_size); + /* + * TODO: + * FTGMAC100_TXDES1_IP_CHKSUM seems to be only for IP checksum, + * however previous net_checksum_calculate() did not calculate + * IP checksum at all. Passing CSUM_ALL for now until someone + * who is familar with this MAC to figure out what should be + * properly added for TCP/UDP checksum offload. + */ + net_checksum_calculate(s->frame, frame_size, CSUM_ALL); } /* Last buffer in frame. */ qemu_send_packet(qemu_get_queue(s->nic), s->frame, frame_size); diff --git a/hw/net/imx_fec.c b/hw/net/imx_fec.c index 2c14804..45f96fa 100644 --- a/hw/net/imx_fec.c +++ b/hw/net/imx_fec.c @@ -562,20 +562,11 @@ static void imx_enet_do_tx(IMXFECState *s, uint32_t index) frame_size += len; if (bd.flags & ENET_BD_L) { 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); - } + net_checksum_calculate(s->frame, frame_size, + 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); - } + net_checksum_calculate(s->frame, frame_size, CSUM_IP); } /* Last buffer in frame. */ diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c index 9179013..77e9ded 100644 --- a/hw/net/virtio-net.c +++ b/hw/net/virtio-net.c @@ -1482,7 +1482,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 e063a81..80caac5 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); } }