From patchwork Thu Aug 29 17:55:49 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gregory Rose X-Patchwork-Id: 1155454 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; 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.b="L3gY89eX"; 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 46K9RZ6MNGz9s4Y for ; Fri, 30 Aug 2019 04:02:02 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id D5FE51E51; Thu, 29 Aug 2019 17:57:33 +0000 (UTC) X-Original-To: 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 DDA504BAD for ; Thu, 29 Aug 2019 17:55:54 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pf1-f193.google.com (mail-pf1-f193.google.com [209.85.210.193]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 3FBF8EC for ; Thu, 29 Aug 2019 17:55:54 +0000 (UTC) Received: by mail-pf1-f193.google.com with SMTP id w16so2567924pfn.7 for ; Thu, 29 Aug 2019 10:55:54 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id; bh=7jvyBkI6v//j9yTGAlplimtJA6JNtlxIE4nBkTncMjc=; b=L3gY89eXvKZZ5Wz477TagAVdjKwMPwn1NLLzNCRpTR+su/3NiaVN/0bw2joqxmgl2/ shguiYkVtHk9oyz82AT5EkN0iX73dNUgjuny7z5SEC09XcC4VIa5Osjq05kYKKXQzYe/ aWtRHHCAqo/O0LEWF6MRy4GWk5/8RH3yFAafm8KvSQW8lejqtIyneGBFqRJwZ6zCsy+P e2d4bm41GMRj5nhuX1oegYy16u2YSCzCk+aqOrx2llxw40qsiUFVBoEcIV0MWJLn9aRa pnxRArsdZ1lX6PZp0vcBzzp9ieBhf9tVEIe7hnQNRVbhKRgMGkc+sBQVIARk1YEgYKjA onRg== 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=7jvyBkI6v//j9yTGAlplimtJA6JNtlxIE4nBkTncMjc=; b=AFngLehmhx4kGjXwTTYBfh0Ynzv/s6sEEZoIuHehaxPaz6inv5FAmVoIoi7EppDrrC o+Zqm/QKo86ACokQqTDjzI9kxFlZex+nQnTYIlVK+D2lOcaRlcxjP9VMoC8fngtpi5ng Ej2D4Chu4K9cSECSpLVPHk6VZ8RKL+BxfWLmUPpO/fQACVY+Opo+eVvG9nwfujAcRvoA 61+/KL8mHRDRnxKrSGtZNVmMtOTZHT4VDp6U8vVrFPY3a9VGLLCV4E5hxCBYLzjrjOoE U2UQin/mlD3Eg+XU7Gb2F76RRizupgBTUBjmiiIGIBKZ3x9BoOODU0eaXBgRv7HFtyeg uTUg== X-Gm-Message-State: APjAAAU1kQZlc2cLWYWOaKee8XKf80OVQN9fyDBLqcEqijb+RilTZZLw UVtwQ4kEgPyFZ2tgTuwhujEW58kv X-Google-Smtp-Source: APXvYqw502PflDtejtQ4DBr8EP0k9wauYG3fEG7DzsqJVYb5E6LQibCi7k/+V960JGStHcejkIy+Sw== X-Received: by 2002:aa7:9609:: with SMTP id q9mr12612787pfg.232.1567101353478; Thu, 29 Aug 2019 10:55:53 -0700 (PDT) Received: from gizo.domain (97-115-90-227.ptld.qwest.net. [97.115.90.227]) by smtp.gmail.com with ESMTPSA id g2sm3846840pfm.32.2019.08.29.10.55.52 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 29 Aug 2019 10:55:52 -0700 (PDT) From: Greg Rose To: dev@openvswitch.org, jpettit@ovn.org Date: Thu, 29 Aug 2019 10:55:49 -0700 Message-Id: <1567101350-27905-1-git-send-email-gvrose8192@gmail.com> X-Mailer: git-send-email 1.8.3.1 X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH branch-2.8 1/2] datapath: Properly set L4 keys on "later" IP fragments 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: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org Upstream commit: commit ad06a566e118e57b852cab5933dbbbaebb141de3 Author: Greg Rose Date: Tue Aug 27 07:58:09 2019 -0700 openvswitch: Properly set L4 keys on "later" IP fragments When IP fragments are reassembled before being sent to conntrack, the key from the last fragment is used. Unless there are reordering issues, the last fragment received will not contain the L4 ports, so the key for the reassembled datagram won't contain them. This patch updates the key once we have a reassembled datagram. The handle_fragments() function works on L3 headers so we pull the L3/L4 flow key update code from key_extract into a new function 'key_extract_l3l4'. Then we add a another new function ovs_flow_key_update_l3l4() and export it so that it is accessible by handle_fragments() for conntrack packet reassembly. Co-authored-by: Justin Pettit Signed-off-by: Greg Rose Acked-by: Pravin B Shelar Signed-off-by: David S. Miller Signed-off-by: Greg Rose Signed-off-by: Justin Pettit --- datapath/conntrack.c | 5 ++ datapath/flow.c | 157 +++++++++++++++++++++++++++++---------------------- datapath/flow.h | 1 + 3 files changed, 95 insertions(+), 68 deletions(-) diff --git a/datapath/conntrack.c b/datapath/conntrack.c index 1990984..2c3e441 100644 --- a/datapath/conntrack.c +++ b/datapath/conntrack.c @@ -537,6 +537,11 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key, return -EPFNOSUPPORT; } + /* The key extracted from the fragment that completed this datagram + * likely didn't have an L4 header, so regenerate it. + */ + ovs_flow_key_update_l3l4(skb, key); + key->ip.frag = OVS_FRAG_TYPE_NONE; skb_clear_hash(skb); skb->ignore_df = 1; diff --git a/datapath/flow.c b/datapath/flow.c index 99dae79..083288f 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -493,79 +493,14 @@ invalid: } /** - * key_extract - extracts a flow key from an Ethernet frame. + * key_extract_l3l4 - extracts L3/L4 header information. * @skb: sk_buff that contains the frame, with skb->data pointing to the - * Ethernet header + * L3 header * @key: output flow key - * - * The caller must ensure that skb->len >= ETH_HLEN. - * - * Returns 0 if successful, otherwise a negative errno value. - * - * Initializes @skb header fields as follows: - * - * - skb->mac_header: the L2 header. - * - * - skb->network_header: just past the L2 header, or just past the - * VLAN header, to the first byte of the L2 payload. - * - * - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6 - * on output, then just past the IP header, if one is present and - * of a correct length, otherwise the same as skb->network_header. - * For other key->eth.type values it is left untouched. - * - * - skb->protocol: the type of the data starting at skb->network_header. - * Equals to key->eth.type. */ -static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) +static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key) { int error; - struct ethhdr *eth; - - /* Flags are always used as part of stats */ - key->tp.flags = 0; - - skb_reset_mac_header(skb); - - /* Link layer. */ - clear_vlan(key); - if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) { - if (unlikely(eth_type_vlan(skb->protocol))) - return -EINVAL; - - skb_reset_network_header(skb); - key->eth.type = skb->protocol; - } else { - eth = eth_hdr(skb); - ether_addr_copy(key->eth.src, eth->h_source); - ether_addr_copy(key->eth.dst, eth->h_dest); - - __skb_pull(skb, 2 * ETH_ALEN); - /* We are going to push all headers that we pull, so no need to - * update skb->csum here. - */ - - if (unlikely(parse_vlan(skb, key))) - return -ENOMEM; - - key->eth.type = parse_ethertype(skb); - if (unlikely(key->eth.type == htons(0))) - return -ENOMEM; - - /* Multiple tagged packets need to retain TPID to satisfy - * skb_vlan_pop(), which will later shift the ethertype into - * skb->protocol. - */ - if (key->eth.cvlan.tci & htons(VLAN_TAG_PRESENT)) - skb->protocol = key->eth.cvlan.tpid; - else - skb->protocol = key->eth.type; - - skb_reset_network_header(skb); - __skb_push(skb, skb->data - skb_mac_header(skb)); - } - - skb_reset_mac_len(skb); /* Network layer. */ if (key->eth.type == htons(ETH_P_IP)) { @@ -756,6 +691,92 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) return 0; } +/** + * key_extract - extracts a flow key from an Ethernet frame. + * @skb: sk_buff that contains the frame, with skb->data pointing to the + * Ethernet header + * @key: output flow key + * + * The caller must ensure that skb->len >= ETH_HLEN. + * + * Returns 0 if successful, otherwise a negative errno value. + * + * Initializes @skb header fields as follows: + * + * - skb->mac_header: the L2 header. + * + * - skb->network_header: just past the L2 header, or just past the + * VLAN header, to the first byte of the L2 payload. + * + * - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6 + * on output, then just past the IP header, if one is present and + * of a correct length, otherwise the same as skb->network_header. + * For other key->eth.type values it is left untouched. + * + * - skb->protocol: the type of the data starting at skb->network_header. + * Equals to key->eth.type. + */ +static int key_extract(struct sk_buff *skb, struct sw_flow_key *key) +{ + struct ethhdr *eth; + + /* Flags are always used as part of stats */ + key->tp.flags = 0; + + skb_reset_mac_header(skb); + + /* Link layer. */ + clear_vlan(key); + if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) { + if (unlikely(eth_type_vlan(skb->protocol))) + return -EINVAL; + + skb_reset_network_header(skb); + key->eth.type = skb->protocol; + } else { + eth = eth_hdr(skb); + ether_addr_copy(key->eth.src, eth->h_source); + ether_addr_copy(key->eth.dst, eth->h_dest); + + __skb_pull(skb, 2 * ETH_ALEN); + /* We are going to push all headers that we pull, so no need to + * update skb->csum here. + */ + + if (unlikely(parse_vlan(skb, key))) + return -ENOMEM; + + key->eth.type = parse_ethertype(skb); + if (unlikely(key->eth.type == htons(0))) + return -ENOMEM; + + /* Multiple tagged packets need to retain TPID to satisfy + * skb_vlan_pop(), which will later shift the ethertype into + * skb->protocol. + */ + if (key->eth.cvlan.tci & htons(VLAN_CFI_MASK)) + skb->protocol = key->eth.cvlan.tpid; + else + skb->protocol = key->eth.type; + + skb_reset_network_header(skb); + __skb_push(skb, skb->data - skb_mac_header(skb)); + } + + skb_reset_mac_len(skb); + + /* Fill out L3/L4 key info, if any */ + return key_extract_l3l4(skb, key); +} + +/* In the case of conntrack fragment handling it expects L3 headers, + * add a helper. + */ +int ovs_flow_key_update_l3l4(struct sk_buff *skb, struct sw_flow_key *key) +{ + return key_extract_l3l4(skb, key); +} + int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key) { int res; diff --git a/datapath/flow.h b/datapath/flow.h index 07af912..78edb36 100644 --- a/datapath/flow.h +++ b/datapath/flow.h @@ -275,6 +275,7 @@ u64 ovs_flow_used_time(unsigned long flow_jiffies); /* Update the non-metadata part of the flow key using skb. */ int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key); +int ovs_flow_key_update_l3l4(struct sk_buff *skb, struct sw_flow_key *key); int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info, struct sk_buff *skb, struct sw_flow_key *key); From patchwork Thu Aug 29 17:55:50 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gregory Rose X-Patchwork-Id: 1155455 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; 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.b="dXbj1zZ1"; 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 46K9S86mkVz9s4Y for ; Fri, 30 Aug 2019 04:02:32 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 87FB94CA9; Thu, 29 Aug 2019 17:57:34 +0000 (UTC) X-Original-To: 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 76EF64BAD for ; Thu, 29 Aug 2019 17:55:56 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f196.google.com (mail-pg1-f196.google.com [209.85.215.196]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 8026013A for ; Thu, 29 Aug 2019 17:55:55 +0000 (UTC) Received: by mail-pg1-f196.google.com with SMTP id d1so1988289pgp.4 for ; Thu, 29 Aug 2019 10:55:55 -0700 (PDT) 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=9TWNkrtqoSMZGOaH5Kn9ARtfQMizfoP59irawbspN3E=; b=dXbj1zZ1PPA1VWpdSVVgKUdDkMkIIzkag6FoHxkv91H5OywiiZiJrqFZZZT9qStwrD kv7vKoPuYA7rwPvkEgdMj0IZItjtzPV64LchF/OnntWUihhjtaPXyhi4zUNTRKwj4OTZ pAHVIIxzugJfrHx/Aqa67fwk0YJw1DPz+TVOi7Mct+RYG47QY7AuJlzZTF1Ai3QTBqaX 7oH6gup/XShFUvYDRT1q6FL4He4c/ueSb07kjqujq0VL3WOPUiffTzMohSJPeZ0hjrDw xfcwwn7C3HcayRTHgh5liYFzfuv63w40y36+JkiSUFX83Gy8lt5rioJzPWv3aJEDdKQZ lsdA== 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=9TWNkrtqoSMZGOaH5Kn9ARtfQMizfoP59irawbspN3E=; b=UNUt2XioqIiTCecQ4uiQtB2h3N9rUpCJADloGBGPygjhqFnqZdkwkGBMcrpZS4/3l/ 5i97x46pfHLy9Ls6eJlrvIxUgL6OtqM2uw1J5o5Sl+9ZzCfBfqw3fLSWpGpRfFBrFdEm oU7o/bW23k0D3kO5GJvx4qPd0dZhD3nJ/Zi13iOXgVYg01AsRTWlazmTtmQzlo9qb7sK GlCeNJ1u5S9FZSuYIBwyef1NGi2ouVJKeUPwYM+zcqfxQAxDd4tMxK4laRkdXGU7Wveu vV97s9hg6EGMZXB5xbbfUfCWcaFxBd8e/Xb7BzstjDV5SZUEQWVHKkapxbWS6emvXEaR BnFA== X-Gm-Message-State: APjAAAVp37Z3bYV+wTjSr1cWPKQqXllvx5p33Qayt3rhlYXD8x8bpfyb YrIgOosulqFoAGU2AnyBLBDvCGel X-Google-Smtp-Source: APXvYqwaVij9vgYm6eIUwkKomliDpWLxCn0FmBkjBNvUProqPy/QiwTW2eWnrjnPbiJcjDdwjPrjrw== X-Received: by 2002:a62:1715:: with SMTP id 21mr13132825pfx.134.1567101354823; Thu, 29 Aug 2019 10:55:54 -0700 (PDT) Received: from gizo.domain (97-115-90-227.ptld.qwest.net. [97.115.90.227]) by smtp.gmail.com with ESMTPSA id g2sm3846840pfm.32.2019.08.29.10.55.53 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Thu, 29 Aug 2019 10:55:54 -0700 (PDT) From: Greg Rose To: dev@openvswitch.org, jpettit@ovn.org Date: Thu, 29 Aug 2019 10:55:50 -0700 Message-Id: <1567101350-27905-2-git-send-email-gvrose8192@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1567101350-27905-1-git-send-email-gvrose8192@gmail.com> References: <1567101350-27905-1-git-send-email-gvrose8192@gmail.com> X-Spam-Status: No, score=-1.7 required=5.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE autolearn=no version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on smtp1.linux-foundation.org Subject: [ovs-dev] [PATCH branch-2.8 2/2] datapath: Clear the L4 portion of the key for "later" fragments 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: , MIME-Version: 1.0 Sender: ovs-dev-bounces@openvswitch.org Errors-To: ovs-dev-bounces@openvswitch.org From: Justin Pettit Upstream commit: commit 0754b4e8cdf3eec6e4122e79af26ed9bab20f8f8 Author: Justin Pettit Date: Tue Aug 27 07:58:10 2019 -0700 openvswitch: Clear the L4 portion of the key for "later" fragments. Only the first fragment in a datagram contains the L4 headers. When the Open vSwitch module parses a packet, it always sets the IP protocol field in the key, but can only set the L4 fields on the first fragment. The original behavior would not clear the L4 portion of the key, so garbage values would be sent in the key for "later" fragments. This patch clears the L4 fields in that circumstance to prevent sending those garbage values as part of the upcall. Signed-off-by: Justin Pettit Acked-by: Pravin B Shelar Signed-off-by: David S. Miller Signed-off-by: Greg Rose Signed-off-by: Justin Pettit --- datapath/flow.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/datapath/flow.c b/datapath/flow.c index 083288f..92fc6ac 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -529,6 +529,7 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key) offset = nh->frag_off & htons(IP_OFFSET); if (offset) { key->ip.frag = OVS_FRAG_TYPE_LATER; + memset(&key->tp, 0, sizeof(key->tp)); return 0; } if (nh->frag_off & htons(IP_MF) || @@ -647,8 +648,11 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key) return error; } - if (key->ip.frag == OVS_FRAG_TYPE_LATER) + if (key->ip.frag == OVS_FRAG_TYPE_LATER) { + memset(&key->tp, 0, sizeof(key->tp)); return 0; + } +#ifdef HAVE_SKB_GSO_UDP if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP) key->ip.frag = OVS_FRAG_TYPE_FIRST;