From patchwork Thu Feb 1 02:48:02 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Brendan Doyle via dev X-Patchwork-Id: 868126 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=openvswitch.org (client-ip=140.211.169.12; helo=mail.linuxfoundation.org; envelope-from=ovs-dev-bounces@openvswitch.org; receiver=) Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=skyportsystems.com header.i=@skyportsystems.com header.b="yJzwguC0"; dkim-atps=neutral Received: from mail.linuxfoundation.org (mail.linuxfoundation.org [140.211.169.12]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3zX4LM55T5z9sP9 for ; Thu, 1 Feb 2018 13:48:27 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 1E174F0B; Thu, 1 Feb 2018 02:48:24 +0000 (UTC) X-Original-To: ovs-dev@openvswitch.org Delivered-To: ovs-dev@mail.linuxfoundation.org Received: from smtp1.linuxfoundation.org (smtp1.linux-foundation.org [172.17.192.35]) by mail.linuxfoundation.org (Postfix) with ESMTPS id 6AE9EF05 for ; Thu, 1 Feb 2018 02:48:22 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg0-f66.google.com (mail-pg0-f66.google.com [74.125.83.66]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 0098FDF for ; Thu, 1 Feb 2018 02:48:21 +0000 (UTC) Received: by mail-pg0-f66.google.com with SMTP id m136so11664936pga.12 for ; Wed, 31 Jan 2018 18:48:21 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=skyportsystems.com; s=google; h=from:to:cc:subject:date:message-id; bh=hyBONFehz9P7b1u8nPVtehQ1rVzzAa0Zrf0uPoDyLt0=; b=yJzwguC0lj1QKPFuAKuxJjd0p+s6Qu2lMzSynpyxKTYf2Zkr+BEdl7X3phMqBj4do4 aMG32JnCso3L1IGhSNNttFWqgYGMnYE/7Qa5IVAx4bX4jA4pmFB584R8vVbUjwmSrIx+ xlrHifjwM2wDo4GWNWHUCKiEau33yx/5S0erA= 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=hyBONFehz9P7b1u8nPVtehQ1rVzzAa0Zrf0uPoDyLt0=; b=FiK37KzeQgtczJQYS9u9tL29+z7E3Y4vv0KlsazCW3UbrFywa208ovbgzt4t4UZ9Zl Rn07lt3bTagCxH0YFOcNkUkn277Bjm2D/CVPMvfeT0PYdgZrXTO/k405gufYhwCyXHie Z1ekrcKrtMHwKkj+NHT/z7l4u7KPbo6HgCkHjwu9+QJufkSOiCmWgTnYD85mj6f9ijgh NAg7bJpejl5RiLiX4qwGq04Mnhc1WDTZ9CN9vKr5zrBcDDKWi7KAiivJGbcQeRAAkekp 7CJlFXl9bNqsywy81YbcLUP7Fzw4780lRIyOrEd5ZC0hr1WR/HfBVK2Sa9xyWqNZe2vj xNtg== X-Gm-Message-State: AKwxytcrackfQALqx/pW5YxvDyqQQJZuYu9qrmk5gccMldKALmsGfQne EMSXez8b198IV6ZeIXfmhme4sw== X-Google-Smtp-Source: AH8x227xkGVyPH6jRhU3VwZk58mYvD4sbO3YkZ1KnZy4u91OeXqAQMugT8rk3auVRhe983fWsJkuOw== X-Received: by 10.99.51.203 with SMTP id z194mr26901994pgz.217.1517453301399; Wed, 31 Jan 2018 18:48:21 -0800 (PST) Received: from eswierk-sc.localdomain (67-207-112-138.static.wiline.com. [67.207.112.138]) by smtp.gmail.com with ESMTPSA id 8sm54787238pfh.170.2018.01.31.18.48.20 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Wed, 31 Jan 2018 18:48:20 -0800 (PST) To: Pravin Shelar , David Miller , netdev@vger.kernel.org, ovs-dev@openvswitch.org Date: Wed, 31 Jan 2018 18:48:02 -0800 Message-Id: <1517453282-27388-1-git-send-email-eswierk@skyportsystems.com> X-Mailer: git-send-email 1.9.1 X-Spam-Status: No, score=-2.0 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, RCVD_IN_DNSWL_NONE autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH v4] openvswitch: Remove padding from packet before L3+ conntrack processing X-BeenThere: ovs-dev@openvswitch.org X-Mailman-Version: 2.1.12 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Ed Swierk via dev From: Brendan Doyle via dev Reply-To: Ed Swierk MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org IPv4 and IPv6 packets may arrive with lower-layer padding that is not included in the L3 length. For example, a short IPv4 packet may have up to 6 bytes of padding following the IP payload when received on an Ethernet device with a minimum packet length of 64 bytes. Higher-layer processing functions in netfilter (e.g. nf_ip_checksum(), and help() in nf_conntrack_ftp) assume skb->len reflects the length of the L3 header and payload, rather than referring back to ip_hdr->tot_len or ipv6_hdr->payload_len, and get confused by lower-layer padding. In the normal IPv4 receive path, ip_rcv() trims the packet to ip_hdr->tot_len before invoking netfilter hooks. In the IPv6 receive path, ip6_rcv() does the same using ipv6_hdr->payload_len. Similarly in the br_netfilter receive path, br_validate_ipv4() and br_validate_ipv6() trim the packet to the L3 length before invoking netfilter hooks. Currently in the OVS conntrack receive path, ovs_ct_execute() pulls the skb to the L3 header but does not trim it to the L3 length before calling nf_conntrack_in(NF_INET_PRE_ROUTING). When nf_conntrack_proto_tcp encounters a packet with lower-layer padding, nf_ip_checksum() fails causing a "nf_ct_tcp: bad TCP checksum" log message. While extra zero bytes don't affect the checksum, the length in the IP pseudoheader does. That length is based on skb->len, and without trimming, it doesn't match the length the sender used when computing the checksum. In ovs_ct_execute(), trim the skb to the L3 length before higher-layer processing. Signed-off-by: Ed Swierk Acked-by: Pravin B Shelar --- net/openvswitch/conntrack.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index d558e88..285f879 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -1097,6 +1097,36 @@ static int ovs_ct_commit(struct net *net, struct sw_flow_key *key, return 0; } +/* Trim the skb to the length specified by the IP/IPv6 header, + * removing any trailing lower-layer padding. This prepares the skb + * for higher-layer processing that assumes skb->len excludes padding + * (such as nf_ip_checksum). The caller needs to pull the skb to the + * network header, and ensure ip_hdr/ipv6_hdr points to valid data. + */ +static int ovs_skb_network_trim(struct sk_buff *skb) +{ + unsigned int len; + int err; + + switch (skb->protocol) { + case htons(ETH_P_IP): + len = ntohs(ip_hdr(skb)->tot_len); + break; + case htons(ETH_P_IPV6): + len = sizeof(struct ipv6hdr) + + ntohs(ipv6_hdr(skb)->payload_len); + break; + default: + len = skb->len; + } + + err = pskb_trim_rcsum(skb, len); + if (err) + kfree_skb(skb); + + return err; +} + /* Returns 0 on success, -EINPROGRESS if 'skb' is stolen, or other nonzero * value if 'skb' is freed. */ @@ -1111,6 +1141,10 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb, nh_ofs = skb_network_offset(skb); skb_pull_rcsum(skb, nh_ofs); + err = ovs_skb_network_trim(skb); + if (err) + return err; + if (key->ip.frag != OVS_FRAG_TYPE_NONE) { err = handle_fragments(net, key, info->zone.id, skb); if (err)