From patchwork Wed Aug 28 23:50:06 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gregory Rose X-Patchwork-Id: 1154940 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="mJ0FXlaf"; 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 46JjDC2ZC7z9sN6 for ; Thu, 29 Aug 2019 09:50:35 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 6D005405E; Wed, 28 Aug 2019 23:50: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 EB22D4051 for ; Wed, 28 Aug 2019 23:50:12 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f194.google.com (mail-pg1-f194.google.com [209.85.215.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 23A9F8B0 for ; Wed, 28 Aug 2019 23:50:12 +0000 (UTC) Received: by mail-pg1-f194.google.com with SMTP id n4so563831pgv.2 for ; Wed, 28 Aug 2019 16:50:12 -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=I+U+3IbtXXD7fl3Kniff9Hr3QD01x0WIX8aSmqJtz/g=; b=mJ0FXlafifRYxomn/yqXVlTV9J90//htDLhoo7N3WbzyVrXDcGNFXPh9iWAMaf9IFg CAVqwAhTFyOAucLIVxmzb2Me1qZnKzcj+1UjMC7QC5Io43BzJu7d34eDhYoZbSxuXjBe QNCqJlS3spqR/LHW02/RDemo5U0Laxa1C7KpwoDpr+qoaaA5KMNHomtrqbsMxWGgs7y3 Iyau6oKeM+aFvy5QUbAguPN+21mhWX8Rb94YsAaPYDJpbVDX8EULbcEuGFdcv+IBoM88 AuS8lJ2ezJBXyD/qfSI7vdM5gsHsSdSzcYdsByu5vyKgHBnIBE+pwimfkBxc5F4mOGbW xyPA== 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=I+U+3IbtXXD7fl3Kniff9Hr3QD01x0WIX8aSmqJtz/g=; b=UzjUvd3rwghAKC4iH2k+EgtpBtxhMkV2f2fxUQsKjREFppLWBFRUZUWqectd2nimzC q2uuzFhGsGqqaGjdxmXQJdk8XJnqMB003afnyRffod6zhRGiAC2hIlLAgUQNEW+5rYhX J0P7FYmrpeIN+sx7Yx+j+mvc78Sg3fHDmwx+998UPS01W7QwO/2munn8/Kw6pAtwyfCp LpqFZFS2GGxSBgrLTUxffjbwhP3q/Q//vEpzCvSDDjbdfKwOjlE7LbLZUyalR/22SxHe i3769uzh9oqbNzEPDUbrL2UVwVvuN7oUl4Of4wBMGRk1+IP04zZ0wsK0EoKfmfstzu+o H6Vw== X-Gm-Message-State: APjAAAWhuHW3XUAnCxtSPlic2G7zCmGDVLxXWbmDzyrvUuYmPn3uTrwt +TpBuUdNp40y+jw8l4R+7c+a//0y X-Google-Smtp-Source: APXvYqxSzNrerGQ1YdPN7YZxbn3qsTjfBu9Sr90tlyjLWQKrFKHKC9wwiJ7y5PTVXWTZsk8403GVwQ== X-Received: by 2002:a17:90a:9f4b:: with SMTP id q11mr6725353pjv.105.1567036211329; Wed, 28 Aug 2019 16:50:11 -0700 (PDT) Received: from gizo.domain (97-115-90-227.ptld.qwest.net. [97.115.90.227]) by smtp.gmail.com with ESMTPSA id y9sm505520pfn.152.2019.08.28.16.50.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 28 Aug 2019 16:50:10 -0700 (PDT) From: Greg Rose To: dev@openvswitch.org, jpettit@ovn.org Date: Wed, 28 Aug 2019 16:50:06 -0700 Message-Id: <1567036207-14322-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 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 Cc: Justin Pettit Signed-off-by: Greg Rose Acked-by: Yi-Hung Wei --- 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 292febb..4c96d90 100644 --- a/datapath/conntrack.c +++ b/datapath/conntrack.c @@ -570,6 +570,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 618c25e..dc93581 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -541,79 +541,14 @@ static int parse_nsh(struct sk_buff *skb, struct sw_flow_key *key) } /** - * 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_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); /* Network layer. */ if (key->eth.type == htons(ETH_P_IP)) { @@ -814,6 +749,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 4884c00..1a5df38 100644 --- a/datapath/flow.h +++ b/datapath/flow.h @@ -283,6 +283,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 Wed Aug 28 23:50:07 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Gregory Rose X-Patchwork-Id: 1154941 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="R5ZkB/Ps"; 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 46JjDd385lz9sN6 for ; Thu, 29 Aug 2019 09:50:57 +1000 (AEST) Received: from mail.linux-foundation.org (localhost [127.0.0.1]) by mail.linuxfoundation.org (Postfix) with ESMTP id 2D0EE4065; Wed, 28 Aug 2019 23:50: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 9D42F4051 for ; Wed, 28 Aug 2019 23:50:13 +0000 (UTC) X-Greylist: whitelisted by SQLgrey-1.7.6 Received: from mail-pg1-f194.google.com (mail-pg1-f194.google.com [209.85.215.194]) by smtp1.linuxfoundation.org (Postfix) with ESMTPS id 570608B0 for ; Wed, 28 Aug 2019 23:50:13 +0000 (UTC) Received: by mail-pg1-f194.google.com with SMTP id n9so565702pgc.1 for ; Wed, 28 Aug 2019 16:50:13 -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=nZmg8T5hams++6cY8ESdIjqCSAXdNvv+AuK/JEo7ras=; b=R5ZkB/Ps7O7J4KQH++Sg/RCLhXuWPC8JYnUl/8knNVj+FmMgQZcbxj+vU+29zU39eY U5sogZtnUl7UBYc0eSF7VCfgy709jCK7g2aXZ12SsL/mueMZDNYTzZueK7NIKCDHjzWW rahLDeZfpDF3hIKN9NnPd9j5LW6SZMEof3jVTjoFCPLvDIm0pTVnzicUgCFQ+tK+8Lq3 I+ngM964VNJthDX4MBWpsR2hBADV4xEEnHLyU37Afvbz7kK+ufwK9+jwdhMgNeVUy3DM LId317/tMBMVa4IggbsPl+uQk6kgrbmn4XZZUFhYIozsGlQgZvheIkpQeOEoJeISogOX Ov9g== 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=nZmg8T5hams++6cY8ESdIjqCSAXdNvv+AuK/JEo7ras=; b=sePZ45Z3QE4VwOh6pqOXFjatCZfZhHmtjyvxfjajKAFj1MOPP6WmX8Z0IWm+4VjzT9 gt0xaSwvfK0oVfdJCn+xlzCjYpRqPDFH+H+p6ovFp6skygIiewpLRT3urR9XkgMMoZIc 349Pz3+J4v0LJAVrgnkWbzBDuOO1EDu5LKxPQVAwxZXBBjAlpVDI127zPzslN/p+0UA+ rufsTcX4vIxfeelI3ysOoeqLisK3s4bA6t8Q5DA+roI4TxTW+B+mJZ4pONZrqdxiLZkp xwZeQNpLZBCHJfJlYuQdj5x7cdFP8hEzbtj09mvrDRn5dT3Sgwqf6f7W0yc2v4szTb5Y 6dKw== X-Gm-Message-State: APjAAAXS+jMcogIBH5q/ynTf3SEKx5gBSFI6fhxoHQS0Bw29qNQAGbEn FouZKc+PThAAe9xDFZCrbuDLHTHP X-Google-Smtp-Source: APXvYqxT3NP/nQX2Cxm9goJM2WGnYO4VuYoNMuwzckdPapg/9CNAs95R3bn7Zk107RVBa96hPXftOQ== X-Received: by 2002:a17:90a:b115:: with SMTP id z21mr6873595pjq.79.1567036212436; Wed, 28 Aug 2019 16:50:12 -0700 (PDT) Received: from gizo.domain (97-115-90-227.ptld.qwest.net. [97.115.90.227]) by smtp.gmail.com with ESMTPSA id y9sm505520pfn.152.2019.08.28.16.50.11 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 28 Aug 2019 16:50:11 -0700 (PDT) From: Greg Rose To: dev@openvswitch.org, jpettit@ovn.org Date: Wed, 28 Aug 2019 16:50:07 -0700 Message-Id: <1567036207-14322-2-git-send-email-gvrose8192@gmail.com> X-Mailer: git-send-email 1.8.3.1 In-Reply-To: <1567036207-14322-1-git-send-email-gvrose8192@gmail.com> References: <1567036207-14322-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 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 Cc: Justin Pettit Signed-off-by: Greg Rose Acked-by: Yi-Hung Wei --- datapath/flow.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/datapath/flow.c b/datapath/flow.c index dc93581..46e2bac 100644 --- a/datapath/flow.c +++ b/datapath/flow.c @@ -577,6 +577,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; } #ifdef HAVE_SKB_GSO_UDP @@ -699,8 +700,10 @@ 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;