From patchwork Thu Dec 21 15:17:17 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Kumar, Rohit via dev" X-Patchwork-Id: 852013 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="Fn+2bllI"; 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 3z2Zy96hnGz9s81 for ; Fri, 22 Dec 2017 02:17:37 +1100 (AEDT) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 495FACCB; Thu, 21 Dec 2017 15:17:36 +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 30BC8C1C for ; Thu, 21 Dec 2017 15:17:35 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf0-f195.google.com (mail-pf0-f195.google.com [209.85.192.195]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id A27ED3F9 for ; Thu, 21 Dec 2017 15:17:34 +0000 (UTC) Received: by mail-pf0-f195.google.com with SMTP id y89so14072978pfk.0 for ; Thu, 21 Dec 2017 07:17:34 -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:references; bh=mVsnzfmkUwr/PIV8CXTXuhyrYNv4cUqm4U2Iuf01jcI=; b=Fn+2bllInShN6g2NfZWvsEyKLlzyKuM121ppstG4CPNRMetKDW5giXMa2jWosIVcLj xcMFLAlZtKPXL6EtyhOKMqVESWNaz8Uay6XcurV7mNUMNycAJzxDWvsVgh82u8VzjkIk CMUDFSQGt4liS8IZrsTQ8bVec1pXOcotN8/TE= 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:references; bh=mVsnzfmkUwr/PIV8CXTXuhyrYNv4cUqm4U2Iuf01jcI=; b=Eqsfo6Mz0DZH8S1GMWnVZ57MeWiVSzAOE0IYHW969RWb1wxlLLCB5vLKrJO1GSZ6TX 0looJVWrg1ZswvLgH84K+CQ3qh1q0GyRKZYCcLdJUtodkcvVm+nUDOJSBUXxc7RC5h71 0c6m73KV0chc6wKDnmtANcH/OyRmkNzhJepsweNYEo3vqTrgwrVHnjHM5aI6o7taue5v Z8p5aIAqW3OWfvOdfpZ9b4mRu7+pofcGlGEqlz63VVlC28xX0BNWXZGcL/nlQby3Hjbp NXND4frgguey8mkwmy0iUE5mxcwEzWydMnMdjWQRejbwbhtxSm5kAvDUtSEGiXqGhZxN zC8A== X-Gm-Message-State: AKGB3mLWKBhIg/QzkAG5AgPyiYSBLtvl44q3ygmCzgn18vUMc4nUA9XC oCQeJ/ImJ6eIJ3/kd/3mMg73+EJnvsM= X-Google-Smtp-Source: ACJfBosCs42H5zPNfmfxkSxjSYaHIgaHeddhB+hzkq3gIyVBzdrkyrNNEV89AIE/JiindwVsvbgxdA== X-Received: by 10.101.101.208 with SMTP id y16mr9905648pgv.159.1513869453781; Thu, 21 Dec 2017 07:17:33 -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 g7sm13386588pfm.76.2017.12.21.07.17.32 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Thu, 21 Dec 2017 07:17:33 -0800 (PST) To: ovs-dev@openvswitch.org, netdev@vger.kernel.org, Pravin Shelar Date: Thu, 21 Dec 2017 07:17:17 -0800 Message-Id: <1513869437-20059-1-git-send-email-eswierk@skyportsystems.com> X-Mailer: git-send-email 1.9.1 References: <1513095439-128864-1-git-send-email-eswierk@skyportsystems.com> 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 Cc: Keith Holleman , Benjamin Warren Subject: [ovs-dev] [PATCH v2] openvswitch: Trim off padding before L3+ netfilter 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: "Kumar, Rohit 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. In the normal IPv4 receive path, ip_rcv() trims the packet to ip_hdr->tot_len before invoking netfilter hooks (including conntrack and nat). 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 NF_INET_PRE_ROUTING hooks. 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_checksum() fails and logs "nf_ct_tcp: bad TCP checksum". 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. The assumption throughout nf_conntrack and nf_nat is that skb->len reflects the length of the L3 header and payload, so there is no need to refer back to ip_hdr->tot_len or ipv6_hdr->payload_len. This change brings OVS into line with other netfilter users, trimming IPv4 and IPv6 packets prior to L3+ netfilter processing. Signed-off-by: Ed Swierk --- v2: - Trim packet in nat receive path as well as conntrack - Free skb on error --- net/openvswitch/conntrack.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c index b27c5c6..1bdc78f 100644 --- a/net/openvswitch/conntrack.c +++ b/net/openvswitch/conntrack.c @@ -703,6 +703,33 @@ static bool skb_nfct_cached(struct net *net, return ct_executed; } +/* Trim the skb to the L3 length. Assumes the skb is already pulled to + * the L3 header. The skb is freed on error. + */ +static int skb_trim_l3(struct sk_buff *skb) +{ + unsigned int nh_len; + int err; + + switch (skb->protocol) { + case htons(ETH_P_IP): + nh_len = ntohs(ip_hdr(skb)->tot_len); + break; + case htons(ETH_P_IPV6): + nh_len = ntohs(ipv6_hdr(skb)->payload_len) + + sizeof(struct ipv6hdr); + break; + default: + nh_len = skb->len; + } + + err = pskb_trim_rcsum(skb, nh_len); + if (err) + kfree_skb(skb); + + return err; +} + #ifdef CONFIG_NF_NAT_NEEDED /* Modelled after nf_nat_ipv[46]_fn(). * range is only used for new, uninitialized NAT state. @@ -715,8 +742,12 @@ static int ovs_ct_nat_execute(struct sk_buff *skb, struct nf_conn *ct, { int hooknum, nh_off, err = NF_ACCEPT; + /* The nat module expects to be working at L3. */ nh_off = skb_network_offset(skb); skb_pull_rcsum(skb, nh_off); + err = skb_trim_l3(skb); + if (err) + return err; /* See HOOK2MANIP(). */ if (maniptype == NF_NAT_MANIP_SRC) @@ -1111,6 +1142,9 @@ int ovs_ct_execute(struct net *net, struct sk_buff *skb, /* The conntrack module expects to be working at L3. */ nh_ofs = skb_network_offset(skb); skb_pull_rcsum(skb, nh_ofs); + err = skb_trim_l3(skb); + if (err) + return err; if (key->ip.frag != OVS_FRAG_TYPE_NONE) { err = handle_fragments(net, key, info->zone.id, skb);