From patchwork Tue Jan 30 01:14:46 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 867372 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=axtens.net header.i=@axtens.net header.b="qHqw9j0b"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zVpNY6qq3z9s7F for ; Tue, 30 Jan 2018 12:15:57 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752391AbeA3BP4 (ORCPT ); Mon, 29 Jan 2018 20:15:56 -0500 Received: from mail-pg0-f65.google.com ([74.125.83.65]:41489 "EHLO mail-pg0-f65.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752250AbeA3BPy (ORCPT ); Mon, 29 Jan 2018 20:15:54 -0500 Received: by mail-pg0-f65.google.com with SMTP id 136so5880308pgd.8 for ; Mon, 29 Jan 2018 17:15:54 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PfA6AeN4dFngzfAlsZALJeJdLluXVIdfPIompY1owUE=; b=qHqw9j0bKMlGXVnZGBnn+0/+jFK9/kukUsQoRM++Rx2Vz1TFJeAUzkW3lf+XNLZfLp XEkt8ic9OUJkXraX/DQM1Z6hTu1Y2I+GObVKs2wo0IPDLpM6kpa02emtuJT/jsVjI8bO 0LrDpxaYQTBlP2NsI4vUUcM3c/BQ8ib/QCIYU= 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=PfA6AeN4dFngzfAlsZALJeJdLluXVIdfPIompY1owUE=; b=qiPLK2xyue+wW3ED90POht/Yq1/MGkwtNbUjBUF1W4pR+W6YKfqNb5AvVZdnQtemB6 LQ18udXipiegJmhsqEQXzd2zo4ror4NSJZEbKXiKfWTY0+X34RYOI9KvkPEcUjHx7Oiz 6ot/mJeU7wIKDH1TrIsjLtzonY7iIjy85aaCXQbCvJG1feskhbbi+01NamuNIzrWgmg5 AIJh+QL5+AW1zPQSajU4LQVTbYbV+2nsM1pmpH85ZzWqCl06Ur1RDpHwTKxq8cUqXDio nAdcvqNS8AY/ds/JGfRIxLvAF0urs+KsxU9odZnb4vR4KT8O6KSdqFyXSiGHlFMpQewi 1dyA== X-Gm-Message-State: AKwxytfLM7/2udyP+pxfINDCg07j5CNan0CD7LpeBjcCyPap/Lh8X1Oo z+AC+4d2suAX+8jKnOpx0WBpbPQcJo0= X-Google-Smtp-Source: AH8x226x8vt2WH9iIKZYwzKi7f6Txh2Ysr92XIp6peOKUcv6lfSlwdNk9i/RUlpPT2WIoERMEcv6Uw== X-Received: by 10.99.65.134 with SMTP id o128mr14132737pga.323.1517274953817; Mon, 29 Jan 2018 17:15:53 -0800 (PST) Received: from localhost.localdomain ([2001:67c:1562:8007::aac:4356]) by smtp.gmail.com with ESMTPSA id p73sm9773672pfa.109.2018.01.29.17.15.45 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Jan 2018 17:15:52 -0800 (PST) From: Daniel Axtens To: netdev@vger.kernel.org Cc: Daniel Axtens , Manish.Chopra@cavium.com, Jason Wang , Pravin Shelar , Marcelo Ricardo Leitner Subject: [PATCH v3 1/2] net: create skb_gso_validate_mac_len() Date: Tue, 30 Jan 2018 12:14:46 +1100 Message-Id: <20180130011447.24916-2-dja@axtens.net> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180130011447.24916-1-dja@axtens.net> References: <20180130011447.24916-1-dja@axtens.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If you take a GSO skb, and split it into packets, will the MAC length (L2 + L3 + L4 headers + payload) of those packets be small enough to fit within a given length? Move skb_gso_mac_seglen() to skbuff.h with other related functions like skb_gso_network_seglen() so we can use it, and then create skb_gso_validate_mac_len to do the full calculation. Signed-off-by: Daniel Axtens --- include/linux/skbuff.h | 16 +++++++++++++ net/core/skbuff.c | 65 +++++++++++++++++++++++++++++++++++++++----------- net/sched/sch_tbf.c | 10 -------- 3 files changed, 67 insertions(+), 24 deletions(-) diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h index b8e0da6c27d6..242d6773c7c2 100644 --- a/include/linux/skbuff.h +++ b/include/linux/skbuff.h @@ -3287,6 +3287,7 @@ int skb_shift(struct sk_buff *tgt, struct sk_buff *skb, int shiftlen); void skb_scrub_packet(struct sk_buff *skb, bool xnet); unsigned int skb_gso_transport_seglen(const struct sk_buff *skb); bool skb_gso_validate_mtu(const struct sk_buff *skb, unsigned int mtu); +bool skb_gso_validate_mac_len(const struct sk_buff *skb, unsigned int len); struct sk_buff *skb_segment(struct sk_buff *skb, netdev_features_t features); struct sk_buff *skb_vlan_untag(struct sk_buff *skb); int skb_ensure_writable(struct sk_buff *skb, int write_len); @@ -4120,6 +4121,21 @@ static inline unsigned int skb_gso_network_seglen(const struct sk_buff *skb) return hdr_len + skb_gso_transport_seglen(skb); } +/** + * skb_gso_mac_seglen - Return length of individual segments of a gso packet + * + * @skb: GSO skb + * + * skb_gso_mac_seglen is used to determine the real size of the + * individual segments, including MAC/L2, Layer3 (IP, IPv6) and L4 + * headers (TCP/UDP). + */ +static inline unsigned int skb_gso_mac_seglen(const struct sk_buff *skb) +{ + unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb); + return hdr_len + skb_gso_transport_seglen(skb); +} + /* Local Checksum Offload. * Compute outer checksum based on the assumption that the * inner checksum will be offloaded later. diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 01e8285aea73..55d84ab7d093 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4914,36 +4914,73 @@ unsigned int skb_gso_transport_seglen(const struct sk_buff *skb) EXPORT_SYMBOL_GPL(skb_gso_transport_seglen); /** - * skb_gso_validate_mtu - Return in case such skb fits a given MTU + * skb_gso_size_check - check the skb size, considering GSO_BY_FRAGS * - * @skb: GSO skb - * @mtu: MTU to validate against + * There are a couple of instances where we have a GSO skb, and we + * want to determine what size it would be after it is segmented. * - * skb_gso_validate_mtu validates if a given skb will fit a wanted MTU - * once split. + * We might want to check: + * - L3+L4+payload size (e.g. IP forwarding) + * - L2+L3+L4+payload size (e.g. sanity check before passing to driver) + * + * This is a helper to do that correctly considering GSO_BY_FRAGS. + * + * @seg_len: The segmented length (from skb_gso_*_seglen). In the + * GSO_BY_FRAGS case this will be [header sizes + GSO_BY_FRAGS]. + * + * @max_len: The maximum permissible length. + * + * Returns true if the segmented length <= max length. */ -bool skb_gso_validate_mtu(const struct sk_buff *skb, unsigned int mtu) -{ +static inline bool skb_gso_size_check(const struct sk_buff *skb, + unsigned int seg_len, + unsigned int max_len) { const struct skb_shared_info *shinfo = skb_shinfo(skb); const struct sk_buff *iter; - unsigned int hlen; - - hlen = skb_gso_network_seglen(skb); if (shinfo->gso_size != GSO_BY_FRAGS) - return hlen <= mtu; + return seg_len <= max_len; /* Undo this so we can re-use header sizes */ - hlen -= GSO_BY_FRAGS; + seg_len -= GSO_BY_FRAGS; skb_walk_frags(skb, iter) { - if (hlen + skb_headlen(iter) > mtu) + if (seg_len + skb_headlen(iter) > max_len) return false; } return true; } -EXPORT_SYMBOL_GPL(skb_gso_validate_mtu); + +/** + * skb_gso_validate_mtu - Return in case such skb fits a given MTU + * + * @skb: GSO skb + * @mtu: MTU to validate against + * + * skb_gso_validate_mtu validates if a given skb will fit a wanted MTU + * once split. + */ +bool skb_gso_validate_mtu(const struct sk_buff *skb, unsigned int mtu) +{ + return skb_gso_size_check(skb, skb_gso_network_seglen(skb), mtu); +} +EXPORT_SYMBOL_GPL(skb_gso_validate_network_len); + +/** + * skb_gso_validate_mac_len - Will a split GSO skb fit in a given length? + * + * @skb: GSO skb + * @len: length to validate against + * + * skb_gso_validate_mac_len validates if a given skb will fit a wanted + * length once split, including L2, L3 and L4 headers and the payload. + */ +bool skb_gso_validate_mac_len(const struct sk_buff *skb, unsigned int len) +{ + return skb_gso_size_check(skb, skb_gso_mac_seglen(skb), len); +} +EXPORT_SYMBOL_GPL(skb_gso_validate_mac_len); static struct sk_buff *skb_reorder_vlan_header(struct sk_buff *skb) { diff --git a/net/sched/sch_tbf.c b/net/sched/sch_tbf.c index 83e76d046993..229172d509cc 100644 --- a/net/sched/sch_tbf.c +++ b/net/sched/sch_tbf.c @@ -142,16 +142,6 @@ static u64 psched_ns_t2l(const struct psched_ratecfg *r, return len; } -/* - * Return length of individual segments of a gso packet, - * including all headers (MAC, IP, TCP/UDP) - */ -static unsigned int skb_gso_mac_seglen(const struct sk_buff *skb) -{ - unsigned int hdr_len = skb_transport_header(skb) - skb_mac_header(skb); - return hdr_len + skb_gso_transport_seglen(skb); -} - /* GSO packet is too big, segment it so that tbf can transmit * each segment in time */ From patchwork Tue Jan 30 01:14:47 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Daniel Axtens X-Patchwork-Id: 867373 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming@ozlabs.org Delivered-To: patchwork-incoming@ozlabs.org Authentication-Results: ozlabs.org; spf=none (mailfrom) smtp.mailfrom=vger.kernel.org (client-ip=209.132.180.67; helo=vger.kernel.org; envelope-from=netdev-owner@vger.kernel.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=axtens.net header.i=@axtens.net header.b="N1dQCfqg"; dkim-atps=neutral Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 3zVpNk4zMzz9s7F for ; Tue, 30 Jan 2018 12:16:06 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752401AbeA3BQE (ORCPT ); Mon, 29 Jan 2018 20:16:04 -0500 Received: from mail-pg0-f68.google.com ([74.125.83.68]:42545 "EHLO mail-pg0-f68.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752114AbeA3BQD (ORCPT ); Mon, 29 Jan 2018 20:16:03 -0500 Received: by mail-pg0-f68.google.com with SMTP id j16so4479516pgn.9 for ; Mon, 29 Jan 2018 17:16:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=axtens.net; s=google; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=dYu0lZI7Lx9ipKfH51y29xcSq1hHTQwjozYghyQIubc=; b=N1dQCfqgXftLiBIxe8gOiTHaQiIsI8EiGsG5jGYEbGYAlF4pWrE3x+DkeCcd8digyH C3sEeL0iarpsc8IttBFOJ8nn6TNvZZfYW08ikzBTUgNGWR/3UKtBd1VGzc02piiQLBu3 AVSJeBfJZXUN7W2aBg8+v6CXV6ZdNmVG38MNs= 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=dYu0lZI7Lx9ipKfH51y29xcSq1hHTQwjozYghyQIubc=; b=TV0Zwg6vhB3C3yjfpH0qmFYwuvX69xWhqwXeHLVIAYgJEQ/j7zZMVR08PGtRNMIyfl ZiUyHsSlZMOc6E6+W8jUpsZeppNVBy2DvMgY6fGS62fmhzLwd8W4fwEr1I8ZOI3APiGZ T9ZJR+6dhvJtXEUeNRD/3z1BiW/4XnK/f4BpGK9n+1/TNC/JX/t2/zmcmRkILox3EP1W lxsXcyi5OPeYkccpir9Nle4VHi0D69Ke2nSsHWgx6Z20nuV9ptX7+BECoKXMh/QfEQzK JULZRE/MgH0H2FCpszdvHkRsNcPjcFosjp/TucHr4RqNMuUClMk7PdtUuuH46hnVsvoj cTEg== X-Gm-Message-State: AKwxytfVbecNDaNmABhmsWbkkFeHKTk/BvC/coCeRkvowruRcqA5aJPP ACS5G0IdjuZt3JKRayMNb0yyKxHMK3Y= X-Google-Smtp-Source: AH8x225qid0yoBFATgnThAzVrHnQp69Qy50/zF038Qlf1O0tiyb9afeRSAJ0FiPsSBbb7oNGHoszyg== X-Received: by 2002:a17:902:6945:: with SMTP id k5-v6mr14030877plt.389.1517274963007; Mon, 29 Jan 2018 17:16:03 -0800 (PST) Received: from localhost.localdomain ([2001:67c:1562:8007::aac:4356]) by smtp.gmail.com with ESMTPSA id p73sm9773672pfa.109.2018.01.29.17.15.54 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 29 Jan 2018 17:16:02 -0800 (PST) From: Daniel Axtens To: netdev@vger.kernel.org Cc: Daniel Axtens , Manish.Chopra@cavium.com, Jason Wang , Pravin Shelar , Marcelo Ricardo Leitner Subject: [PATCH v3 2/2] bnx2x: disable GSO where gso_size is too big for hardware Date: Tue, 30 Jan 2018 12:14:47 +1100 Message-Id: <20180130011447.24916-3-dja@axtens.net> X-Mailer: git-send-email 2.14.1 In-Reply-To: <20180130011447.24916-1-dja@axtens.net> References: <20180130011447.24916-1-dja@axtens.net> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org If a bnx2x card is passed a GSO packet with a gso_size larger than ~9700 bytes, it will cause a firmware error that will bring the card down: bnx2x: [bnx2x_attn_int_deasserted3:4323(enP24p1s0f0)]MC assert! bnx2x: [bnx2x_mc_assert:720(enP24p1s0f0)]XSTORM_ASSERT_LIST_INDEX 0x2 bnx2x: [bnx2x_mc_assert:736(enP24p1s0f0)]XSTORM_ASSERT_INDEX 0x0 = 0x00000000 0x25e43e47 0x00463e01 0x00010052 bnx2x: [bnx2x_mc_assert:750(enP24p1s0f0)]Chip Revision: everest3, FW Version: 7_13_1 ... (dump of values continues) ... Detect when the mac length of a GSO packet is greater than the maximum packet size (9700 bytes) and disable GSO. Signed-off-by: Daniel Axtens --- v3: use skb_gso_validate_mac_len to get the actual size, to allow jumbo frames to work. I don't have local access to a bnx2x card and sending this off to the user who does would add about a month of round-trip time, so this particular spin is build-tested only. (Earlier spins were tested on real hardware.) --- drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c index 7b08323e3f3d..fbb08e360625 100644 --- a/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c +++ b/drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c @@ -12934,6 +12934,15 @@ static netdev_features_t bnx2x_features_check(struct sk_buff *skb, struct net_device *dev, netdev_features_t features) { + /* + * A skb with gso_size + header length > 9700 will cause a + * firmware panic. Drop GSO support. + * + * Eventually the upper layer should not pass these packets down. + */ + if (unlikely(skb_is_gso(skb) && !skb_gso_validate_mac_len(skb, 9700))) + features &= ~NETIF_F_GSO_MASK; + features = vlan_features_check(skb, features); return vxlan_features_check(skb, features); }