From patchwork Wed Jan 2 17:00:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1020034 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43VHPr1HTCz9s4s for ; Thu, 3 Jan 2019 04:01:20 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730539AbfABRBT (ORCPT ); Wed, 2 Jan 2019 12:01:19 -0500 Received: from youngberry.canonical.com ([91.189.89.112]:41789 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729284AbfABRBS (ORCPT ); Wed, 2 Jan 2019 12:01:18 -0500 Received: from mail-qk1-f197.google.com ([209.85.222.197]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1gejtN-00043j-D2 for netdev@vger.kernel.org; Wed, 02 Jan 2019 17:01:17 +0000 Received: by mail-qk1-f197.google.com with SMTP id z126so37576173qka.10 for ; Wed, 02 Jan 2019 09:01:17 -0800 (PST) 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=7hsB4K/KXe1k3QlsGyVqMxbvu2djv1itGQLn7RbJ1+Q=; b=tlSPn8mUNxz71dxI1yGF8UaS/cAK9/IkAp15EYCuGFTHO43NXN/UaRgK0l3uWtaBVR rHFY+Fq4KyE71qtbAvT6vkAyH+7VLYxSsMk+fpfca7OP0ZW6CMVhmmuskBq5fbIhP7HB wer+1biTF8hp6CFZGbiXZoIGuQRJh/C361iLLjcurYxmK6V5Qi88oWhPDQ7ODbEd9GH4 8ZepxnaVqPvm0uy/6t+27a57xFiRibk5W1Vd3R2/aCcMgxenu0WFpuvPQBD+Y5vxwMiZ nehdsuumeENPHAPdvqpmaOxFaEYngDSZnCyCTL/uzRKCSp/J+8IeOrliHbb8tL61zevK LZvw== X-Gm-Message-State: AJcUukc5aR4YHpDxl0nYgEeEK2SblZhtXhjLjAyK/j+g6V2Y276Vvzo4 yHt0l2tpwFYeoeLTRLCvI/rBp27lLifldO2gFzQYMx9EUXt/EuvAQVWqV9R6b067FWeuZQqZR8u bIWU7U8T9JIwrpseSkAJpqaX4r690K+qiaw== X-Received: by 2002:a0c:e010:: with SMTP id j16mr43155393qvk.111.1546448475912; Wed, 02 Jan 2019 09:01:15 -0800 (PST) X-Google-Smtp-Source: ALg8bN6SIXcRuZMkbpeZ+9HAX6zSjU+1doht1KY83mLKhErU3/VZyoxlmVBd9XVMRfkd8oYYj0vM9w== X-Received: by 2002:a0c:e010:: with SMTP id j16mr43155286qvk.111.1546448474488; Wed, 02 Jan 2019 09:01:14 -0800 (PST) Received: from localhost.localdomain ([179.159.56.118]) by smtp.gmail.com with ESMTPSA id i26sm20333938qkg.12.2019.01.02.09.01.10 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Jan 2019 09:01:12 -0800 (PST) From: Mauricio Faria de Oliveira To: stable@vger.kernel.org, netdev@vger.kernel.org, Florian Westphal Cc: Alakesh Haloi , nivedita.singhvi@canonical.com, Pablo Neira Ayuso , Jozsef Kadlecsik , "David S. Miller" , Yi-Hung Wei Subject: [PATCH 4.14 1/4] netfilter: xt_connlimit: don't store address in the conn nodes Date: Wed, 2 Jan 2019 15:00:20 -0200 Message-Id: <20190102170023.10415-2-mfo@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190102170023.10415-1-mfo@canonical.com> References: <20190102170023.10415-1-mfo@canonical.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Florian Westphal commit ce49480dba8666cba0106e8e31a942c9ce4c438a upstream. Only stored, never read. This is a leftover from commit 7d08487777c8 ("netfilter: connlimit: use rbtree for per-host conntrack obj storage"), which added the rbtree node struct that stores the address instead. Signed-off-by: Florian Westphal Signed-off-by: Pablo Neira Ayuso [mfo: backport: refresh context lines and use older symbol/file names: - nf_conncount.c -> xt_connlimit.c. - nf_conncount_rb -> xt_connlimit_rb - nf_conncount_tuple -> xt_connlimit_conn - additionally, remove the add_hlist() 'addr' parameter that isn't used and removed later upstream with commit 625c556118f3 ("netfilter: connlimit: split xt_connlimit into front and backend") in the rename from 'xt_connlimit.c' to 'nf_conncount.c', a big refactor, so do it here, while still here in this related patch.] Signed-off-by: Mauricio Faria de Oliveira --- net/netfilter/xt_connlimit.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index ffa8eec..79d4151 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -46,7 +46,6 @@ struct xt_connlimit_conn { struct hlist_node node; struct nf_conntrack_tuple tuple; - union nf_inet_addr addr; }; struct xt_connlimit_rb { @@ -116,8 +115,7 @@ same_source_net(const union nf_inet_addr *addr, } static bool add_hlist(struct hlist_head *head, - const struct nf_conntrack_tuple *tuple, - const union nf_inet_addr *addr) + const struct nf_conntrack_tuple *tuple) { struct xt_connlimit_conn *conn; @@ -125,7 +123,6 @@ static bool add_hlist(struct hlist_head *head, if (conn == NULL) return false; conn->tuple = *tuple; - conn->addr = *addr; hlist_add_head(&conn->node, head); return true; } @@ -231,7 +228,7 @@ count_tree(struct net *net, struct rb_root *root, if (!addit) return count; - if (!add_hlist(&rbconn->hhead, tuple, addr)) + if (!add_hlist(&rbconn->hhead, tuple)) return 0; /* hotdrop */ return count + 1; @@ -270,7 +267,6 @@ count_tree(struct net *net, struct rb_root *root, } conn->tuple = *tuple; - conn->addr = *addr; rbconn->addr = *addr; INIT_HLIST_HEAD(&rbconn->hhead); From patchwork Wed Jan 2 17:00:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1020035 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43VHPt1vsMz9s4s for ; Thu, 3 Jan 2019 04:01:22 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730546AbfABRBV (ORCPT ); Wed, 2 Jan 2019 12:01:21 -0500 Received: from youngberry.canonical.com ([91.189.89.112]:41799 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729284AbfABRBU (ORCPT ); Wed, 2 Jan 2019 12:01:20 -0500 Received: from mail-qt1-f199.google.com ([209.85.160.199]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1gejtP-00044A-2k for netdev@vger.kernel.org; Wed, 02 Jan 2019 17:01:19 +0000 Received: by mail-qt1-f199.google.com with SMTP id q33so38921253qte.23 for ; Wed, 02 Jan 2019 09:01:19 -0800 (PST) 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=cHMHvmTNqlp/UIh+cKOmQ9ElxYY2GNXRHT3+2VDoDIw=; b=Id65HzJwAWKPoQhC3D00nCIPj4pkb+Xr7yHeyYUiS/2KZGJ6ZCE6ZE8zrg+xYR7Zhg VlhBOVtPg6RmuEgXynMqOWpiEUlOpSpnEWoNgRq3EinVP1nl2DxGKv27Ka4SGJFZhPoc LpVt7wVAeXc/QAtO2o282BcGbQmqWO6PKxE8HyHQ3RcBmy1KWXs2Ecxr46htedW8z5Q4 C72cm6WJT4Fai8i3R4AP9HKh6EVy1z5GkHCu3pl/4ujTIjtVMl6x65riRsUTlqpVp/O3 fNqRYfKZkgI6WtfXF2Oz0UF3Ob3vtsXJe+szPq+jsmJuOC8QlhGUP0H1hgJ3nw6/3StZ 0s6A== X-Gm-Message-State: AA+aEWbd/t2xuTtushf9r9Rx/izRXWJGhTmgGCPs5YvJdWw9tOd78Q9K 9cIixDrlDXlCfts2rc5QW+404uuRmFd/zYNCXdh726BV1eu2Ho0TgfSyBUbWj1TW8HqMb/od2yH qgVqzblymuobmqv0XpFWF4c2T77NPJcNgpA== X-Received: by 2002:ac8:839:: with SMTP id u54mr42046642qth.313.1546448478171; Wed, 02 Jan 2019 09:01:18 -0800 (PST) X-Google-Smtp-Source: AFSGD/Xkh7InG8FwuxwuZHRwlX2JW2H2cZrZQyOugtKwiHFzFV0AcIzh38s3JObvbctHLBYcfjeyuQ== X-Received: by 2002:ac8:839:: with SMTP id u54mr42046614qth.313.1546448477972; Wed, 02 Jan 2019 09:01:17 -0800 (PST) Received: from localhost.localdomain ([179.159.56.118]) by smtp.gmail.com with ESMTPSA id i26sm20333938qkg.12.2019.01.02.09.01.14 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Jan 2019 09:01:17 -0800 (PST) From: Mauricio Faria de Oliveira To: stable@vger.kernel.org, netdev@vger.kernel.org, Florian Westphal Cc: Alakesh Haloi , nivedita.singhvi@canonical.com, Pablo Neira Ayuso , Jozsef Kadlecsik , "David S. Miller" , Yi-Hung Wei Subject: [PATCH 4.14 2/4] netfilter: nf_conncount: expose connection list interface Date: Wed, 2 Jan 2019 15:00:21 -0200 Message-Id: <20190102170023.10415-3-mfo@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190102170023.10415-1-mfo@canonical.com> References: <20190102170023.10415-1-mfo@canonical.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Pablo Neira Ayuso commit 5e5cbc7b23eaf13e18652c03efbad5be6995de6a upstream. This patch provides an interface to maintain the list of connections and the lookup function to obtain the number of connections in the list. Signed-off-by: Pablo Neira Ayuso [mfo: backport: refresh context lines and use older symbol/file names: - nf_conntrack_count.h: new file, add include guards. - nf_conncount.c -> xt_connlimit.c. - nf_conncount_rb -> xt_connlimit_rb - nf_conncount_tuple -> xt_connlimit_conn - conncount_rb_cachep -> connlimit_rb_cachep - conncount_conn_cachep -> connlimit_conn_cachep] Signed-off-by: Mauricio Faria de Oliveira --- include/net/netfilter/nf_conntrack_count.h | 14 ++++++++++++ net/netfilter/xt_connlimit.c | 36 +++++++++++++++++++----------- 2 files changed, 37 insertions(+), 13 deletions(-) create mode 100644 include/net/netfilter/nf_conntrack_count.h diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h new file mode 100644 index 0000000..54e43b8 --- /dev/null +++ b/include/net/netfilter/nf_conntrack_count.h @@ -0,0 +1,14 @@ +#ifndef _NF_CONNTRACK_COUNT_H +#define _NF_CONNTRACK_COUNT_H + +unsigned int nf_conncount_lookup(struct net *net, struct hlist_head *head, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone, + bool *addit); + +bool nf_conncount_add(struct hlist_head *head, + const struct nf_conntrack_tuple *tuple); + +void nf_conncount_cache_free(struct hlist_head *hhead); + +#endif diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 79d4151..7af5875 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -114,7 +114,7 @@ same_source_net(const union nf_inet_addr *addr, } } -static bool add_hlist(struct hlist_head *head, +bool nf_conncount_add(struct hlist_head *head, const struct nf_conntrack_tuple *tuple) { struct xt_connlimit_conn *conn; @@ -126,12 +126,12 @@ static bool add_hlist(struct hlist_head *head, hlist_add_head(&conn->node, head); return true; } +EXPORT_SYMBOL_GPL(nf_conncount_add); -static unsigned int check_hlist(struct net *net, - struct hlist_head *head, - const struct nf_conntrack_tuple *tuple, - const struct nf_conntrack_zone *zone, - bool *addit) +unsigned int nf_conncount_lookup(struct net *net, struct hlist_head *head, + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone, + bool *addit) { const struct nf_conntrack_tuple_hash *found; struct xt_connlimit_conn *conn; @@ -176,6 +176,7 @@ static unsigned int check_hlist(struct net *net, return length; } +EXPORT_SYMBOL_GPL(nf_conncount_lookup); static void tree_nodes_free(struct rb_root *root, struct xt_connlimit_rb *gc_nodes[], @@ -222,13 +223,15 @@ count_tree(struct net *net, struct rb_root *root, } else { /* same source network -> be counted! */ unsigned int count; - count = check_hlist(net, &rbconn->hhead, tuple, zone, &addit); + + count = nf_conncount_lookup(net, &rbconn->hhead, tuple, + zone, &addit); tree_nodes_free(root, gc_nodes, gc_count); if (!addit) return count; - if (!add_hlist(&rbconn->hhead, tuple)) + if (!nf_conncount_add(&rbconn->hhead, tuple)) return 0; /* hotdrop */ return count + 1; @@ -238,7 +241,7 @@ count_tree(struct net *net, struct rb_root *root, continue; /* only used for GC on hhead, retval and 'addit' ignored */ - check_hlist(net, &rbconn->hhead, tuple, zone, &addit); + nf_conncount_lookup(net, &rbconn->hhead, tuple, zone, &addit); if (hlist_empty(&rbconn->hhead)) gc_nodes[gc_count++] = rbconn; } @@ -378,11 +381,19 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par) return 0; } -static void destroy_tree(struct rb_root *r) +void nf_conncount_cache_free(struct hlist_head *hhead) { struct xt_connlimit_conn *conn; - struct xt_connlimit_rb *rbconn; struct hlist_node *n; + + hlist_for_each_entry_safe(conn, n, hhead, node) + kmem_cache_free(connlimit_conn_cachep, conn); +} +EXPORT_SYMBOL_GPL(nf_conncount_cache_free); + +static void destroy_tree(struct rb_root *r) +{ + struct xt_connlimit_rb *rbconn; struct rb_node *node; while ((node = rb_first(r)) != NULL) { @@ -390,8 +401,7 @@ static void destroy_tree(struct rb_root *r) rb_erase(node, r); - hlist_for_each_entry_safe(conn, n, &rbconn->hhead, node) - kmem_cache_free(connlimit_conn_cachep, conn); + nf_conncount_cache_free(&rbconn->hhead); kmem_cache_free(connlimit_rb_cachep, rbconn); } From patchwork Wed Jan 2 17:00:22 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1020036 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43VHPy2BMfz9sBn for ; Thu, 3 Jan 2019 04:01:26 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730551AbfABRBZ (ORCPT ); Wed, 2 Jan 2019 12:01:25 -0500 Received: from youngberry.canonical.com ([91.189.89.112]:41805 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1728720AbfABRBZ (ORCPT ); Wed, 2 Jan 2019 12:01:25 -0500 Received: from mail-qk1-f198.google.com ([209.85.222.198]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1gejtS-00044m-Fu for netdev@vger.kernel.org; Wed, 02 Jan 2019 17:01:22 +0000 Received: by mail-qk1-f198.google.com with SMTP id j125so37143441qke.12 for ; Wed, 02 Jan 2019 09:01:22 -0800 (PST) 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:mime-version:content-transfer-encoding; bh=620lz93blX+gMAhdPhC4jRp9+2hZlpL4Fhkk7irNqdg=; b=uA9FrFBUrLvSJZEdcjsF8X3COHXHtuWV6OZSCcRmSOE4JPqoM/veOc5JodV+Xg1GDk FHcu1yxvJJ9JbYjIccOpAFbwtXAkVpweE1gzETJuCQ1c8Vlv/b4iF/7DTzCHWrZrHHbo uL4ygbXPe0n1muk7sehzkMjHyHnnLERk10mCvnPcbSa9+atBH1Gd5BCNKhe/qQa8xbg0 +njrng2sK+IAuQ24bRlvU81D0x3hI1FDy0kSnMXKeIW7+1R4MiWo0B8tWCzOWEs7YHl0 HqgTxzAxqFAfPhZ9/ADD23CZ2R8c2BeogOj+mYYkYT8Ytffwlmk6KiHru21mvtCGejJH SE9Q== X-Gm-Message-State: AJcUukd46C0QUj5qp0jInrF2C3tU/5dUXszUe5timB9MBcGjYh2INRNW Ee1nIQ2wCmBY+3IGGge0SsdVOPuzmESqH3pIT7ZTJRlqZofk618QRBbH9LDoKv4dV8Up3Nfw0/n pJwLHV7XNfdLavcp+5RR4PmYQ5gF3eNCd+g== X-Received: by 2002:a0c:878d:: with SMTP id 13mr43197612qvj.8.1546448481680; Wed, 02 Jan 2019 09:01:21 -0800 (PST) X-Google-Smtp-Source: ALg8bN7aAEayhah8E5ubJhuRjxoDV0uBueJ0vu4+z03HG2v4WY48oK/BXqth9L7SPwF4OQpn9YSW5w== X-Received: by 2002:a0c:878d:: with SMTP id 13mr43197589qvj.8.1546448481464; Wed, 02 Jan 2019 09:01:21 -0800 (PST) Received: from localhost.localdomain ([179.159.56.118]) by smtp.gmail.com with ESMTPSA id i26sm20333938qkg.12.2019.01.02.09.01.18 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Jan 2019 09:01:20 -0800 (PST) From: Mauricio Faria de Oliveira To: stable@vger.kernel.org, netdev@vger.kernel.org, Florian Westphal Cc: Alakesh Haloi , nivedita.singhvi@canonical.com, Pablo Neira Ayuso , Jozsef Kadlecsik , "David S. Miller" , Yi-Hung Wei Subject: [PATCH 4.14 3/4] netfilter: nf_conncount: Fix garbage collection with zones Date: Wed, 2 Jan 2019 15:00:22 -0200 Message-Id: <20190102170023.10415-4-mfo@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190102170023.10415-1-mfo@canonical.com> References: <20190102170023.10415-1-mfo@canonical.com> MIME-Version: 1.0 Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Yi-Hung Wei commit 21ba8847f857028dc83a0f341e16ecc616e34740 upstream. Currently, we use check_hlist() for garbage colleciton. However, we use the ‘zone’ from the counted entry to query the existence of existing entries in the hlist. This could be wrong when they are in different zones, and this patch fixes this issue. Fixes: e59ea3df3fc2 ("netfilter: xt_connlimit: honor conntrack zone if available") Signed-off-by: Yi-Hung Wei Signed-off-by: Pablo Neira Ayuso [mfo: backport: refresh context lines and use older symbol/file names, note hunk 5: - nf_conncount.c -> xt_connlimit.c - nf_conncount_rb -> xt_connlimit_rb - nf_conncount_tuple -> xt_connlimit_conn - hunk 5: remove check for non-NULL 'tuple', that isn't required as it's introduced by upstream commit 35d8deb80 ("netfilter: conncount: Support count only use case") which addresses nf_conncount_count() that does not exist yet -- it's introduced by upstream commit 625c556118f3 ("netfilter: connlimit: split xt_connlimit into front and backend"), a refactor change. - nft_connlimit.c -> removed, not used/doesn't exist yet.] Signed-off-by: Mauricio Faria de Oliveira --- include/net/netfilter/nf_conntrack_count.h | 3 ++- net/netfilter/xt_connlimit.c | 13 +++++++++---- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h index 54e43b8..4b71a2f 100644 --- a/include/net/netfilter/nf_conntrack_count.h +++ b/include/net/netfilter/nf_conntrack_count.h @@ -7,7 +7,8 @@ unsigned int nf_conncount_lookup(struct net *net, struct hlist_head *head, bool *addit); bool nf_conncount_add(struct hlist_head *head, - const struct nf_conntrack_tuple *tuple); + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone); void nf_conncount_cache_free(struct hlist_head *hhead); diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index 7af5875..ab1f849 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -46,6 +46,7 @@ struct xt_connlimit_conn { struct hlist_node node; struct nf_conntrack_tuple tuple; + struct nf_conntrack_zone zone; }; struct xt_connlimit_rb { @@ -115,7 +116,8 @@ same_source_net(const union nf_inet_addr *addr, } bool nf_conncount_add(struct hlist_head *head, - const struct nf_conntrack_tuple *tuple) + const struct nf_conntrack_tuple *tuple, + const struct nf_conntrack_zone *zone) { struct xt_connlimit_conn *conn; @@ -123,6 +125,7 @@ bool nf_conncount_add(struct hlist_head *head, if (conn == NULL) return false; conn->tuple = *tuple; + conn->zone = *zone; hlist_add_head(&conn->node, head); return true; } @@ -143,7 +146,7 @@ unsigned int nf_conncount_lookup(struct net *net, struct hlist_head *head, /* check the saved connections */ hlist_for_each_entry_safe(conn, n, head, node) { - found = nf_conntrack_find_get(net, zone, &conn->tuple); + found = nf_conntrack_find_get(net, &conn->zone, &conn->tuple); if (found == NULL) { hlist_del(&conn->node); kmem_cache_free(connlimit_conn_cachep, conn); @@ -152,7 +155,8 @@ unsigned int nf_conncount_lookup(struct net *net, struct hlist_head *head, found_ct = nf_ct_tuplehash_to_ctrack(found); - if (nf_ct_tuple_equal(&conn->tuple, tuple)) { + if (nf_ct_tuple_equal(&conn->tuple, tuple) && + nf_ct_zone_equal(found_ct, zone, zone->dir)) { /* * Just to be sure we have it only once in the list. * We should not see tuples twice unless someone hooks @@ -231,7 +235,7 @@ count_tree(struct net *net, struct rb_root *root, if (!addit) return count; - if (!nf_conncount_add(&rbconn->hhead, tuple)) + if (!nf_conncount_add(&rbconn->hhead, tuple, zone)) return 0; /* hotdrop */ return count + 1; @@ -270,6 +274,7 @@ count_tree(struct net *net, struct rb_root *root, } conn->tuple = *tuple; + conn->zone = *zone; rbconn->addr = *addr; INIT_HLIST_HEAD(&rbconn->hhead); From patchwork Wed Jan 2 17:00:23 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Mauricio Faria de Oliveira X-Patchwork-Id: 1020037 X-Patchwork-Delegate: davem@davemloft.net Return-Path: X-Original-To: patchwork-incoming-netdev@ozlabs.org Delivered-To: patchwork-incoming-netdev@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; dmarc=fail (p=none dis=none) header.from=canonical.com Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by ozlabs.org (Postfix) with ESMTP id 43VHQ125SMz9s9G for ; Thu, 3 Jan 2019 04:01:29 +1100 (AEDT) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1730556AbfABRB2 (ORCPT ); Wed, 2 Jan 2019 12:01:28 -0500 Received: from youngberry.canonical.com ([91.189.89.112]:41822 "EHLO youngberry.canonical.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1729869AbfABRB1 (ORCPT ); Wed, 2 Jan 2019 12:01:27 -0500 Received: from mail-qk1-f200.google.com ([209.85.222.200]) by youngberry.canonical.com with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.76) (envelope-from ) id 1gejtW-00045R-6b for netdev@vger.kernel.org; Wed, 02 Jan 2019 17:01:26 +0000 Received: by mail-qk1-f200.google.com with SMTP id y83so37201048qka.7 for ; Wed, 02 Jan 2019 09:01:26 -0800 (PST) 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=E2Gs61w0fpdX78U7pMEDisXwaDylJYVJC2KFhQ7sJJ8=; b=q6xo4t/24c8f9Mqh+ZSPj1NvH49ef+fS1HHuPoMmLbzj+EXD6gEZAJFhW9aut15ORL 8g5Km2rm6rMhoP0Pm7H66aUteAqbPe9HZmhesubD9V1fu+yrM1RbxC38xhTT/ZLmOcAU HVtcsoi6Dq1BGd0I401/Bwn8XIJGzqpdoBMGRp+f0vu7e1+ZgBT8loKD6dA0QR1Y8UqX YxlAIXS7YLZJKF24pC082u3Chq9K0mNdOi1sYxqiimNgjkoJFRFZsRBsElWTX0LkIHuI ODQthoaS+1p8370NwOOb8T4MIRijSVwjDrEO8LlfNpNZDhiKpdLQfiSH3GNSpHVq2ihV FSPg== X-Gm-Message-State: AA+aEWZlYw3bMPhYtsaJYW+Ula8ihnyvLwnKUeZiTe7IEVN7X9aq/y02 eSIbAVSPbj5iIWnRTlpHOxKQ3WJmHsDd8/lp+FAOAXOVq5cMHdD4M0fNX7MPBn83l6SUGxOXe8g g3kkc1lhJQsHbKL8gCjEcW7JZperuxXIqsQ== X-Received: by 2002:aed:3263:: with SMTP id y90mr41751599qtd.269.1546448485394; Wed, 02 Jan 2019 09:01:25 -0800 (PST) X-Google-Smtp-Source: ALg8bN5/QusLzYVwDGV5rcftFfPDPK619zJXkxPijPcUCrc72ZNzhppr3L6BLwzCyfiUC/32+CXiVA== X-Received: by 2002:aed:3263:: with SMTP id y90mr41751572qtd.269.1546448485181; Wed, 02 Jan 2019 09:01:25 -0800 (PST) Received: from localhost.localdomain ([179.159.56.118]) by smtp.gmail.com with ESMTPSA id i26sm20333938qkg.12.2019.01.02.09.01.21 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Wed, 02 Jan 2019 09:01:24 -0800 (PST) From: Mauricio Faria de Oliveira To: stable@vger.kernel.org, netdev@vger.kernel.org, Florian Westphal Cc: Alakesh Haloi , nivedita.singhvi@canonical.com, Pablo Neira Ayuso , Jozsef Kadlecsik , "David S. Miller" , Yi-Hung Wei Subject: [PATCH 4.14 4/4] netfilter: nf_conncount: fix garbage collection confirm race Date: Wed, 2 Jan 2019 15:00:23 -0200 Message-Id: <20190102170023.10415-5-mfo@canonical.com> X-Mailer: git-send-email 2.17.1 In-Reply-To: <20190102170023.10415-1-mfo@canonical.com> References: <20190102170023.10415-1-mfo@canonical.com> Sender: netdev-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: netdev@vger.kernel.org From: Florian Westphal commit b36e4523d4d56e2595e28f16f6ccf1cd6a9fc452 upstream. Yi-Hung Wei and Justin Pettit found a race in the garbage collection scheme used by nf_conncount. When doing list walk, we lookup the tuple in the conntrack table. If the lookup fails we remove this tuple from our list because the conntrack entry is gone. This is the common cause, but turns out its not the only one. The list entry could have been created just before by another cpu, i.e. the conntrack entry might not yet have been inserted into the global hash. The avoid this, we introduce a timestamp and the owning cpu. If the entry appears to be stale, evict only if: 1. The current cpu is the one that added the entry, or, 2. The timestamp is older than two jiffies The second constraint allows GC to be taken over by other cpu too (e.g. because a cpu was offlined or napi got moved to another cpu). We can't pretend the 'doubtful' entry wasn't in our list. Instead, when we don't find an entry indicate via IS_ERR that entry was removed ('did not exist' or withheld ('might-be-unconfirmed'). This most likely also fixes a xt_connlimit imbalance earlier reported by Dmitry Andrianov. Cc: Dmitry Andrianov Reported-by: Justin Pettit Reported-by: Yi-Hung Wei Signed-off-by: Florian Westphal Acked-by: Yi-Hung Wei Signed-off-by: Pablo Neira Ayuso [mfo: backport: refresh context lines and use older symbol/file names: - nf_conncount.c -> xt_connlimit.c. - nf_conncount_rb -> xt_connlimit_rb - nf_conncount_tuple -> xt_connlimit_conn - conncount_conn_cachep -> connlimit_conn_cachep] Signed-off-by: Mauricio Faria de Oliveira --- net/netfilter/xt_connlimit.c | 52 +++++++++++++++++++++++++++++++++++++++----- 1 file changed, 47 insertions(+), 5 deletions(-) diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c index ab1f849..913b86ef 100644 --- a/net/netfilter/xt_connlimit.c +++ b/net/netfilter/xt_connlimit.c @@ -47,6 +47,8 @@ struct xt_connlimit_conn { struct hlist_node node; struct nf_conntrack_tuple tuple; struct nf_conntrack_zone zone; + int cpu; + u32 jiffies32; }; struct xt_connlimit_rb { @@ -126,11 +128,42 @@ bool nf_conncount_add(struct hlist_head *head, return false; conn->tuple = *tuple; conn->zone = *zone; + conn->cpu = raw_smp_processor_id(); + conn->jiffies32 = (u32)jiffies; hlist_add_head(&conn->node, head); return true; } EXPORT_SYMBOL_GPL(nf_conncount_add); +static const struct nf_conntrack_tuple_hash * +find_or_evict(struct net *net, struct xt_connlimit_conn *conn) +{ + const struct nf_conntrack_tuple_hash *found; + unsigned long a, b; + int cpu = raw_smp_processor_id(); + __s32 age; + + found = nf_conntrack_find_get(net, &conn->zone, &conn->tuple); + if (found) + return found; + b = conn->jiffies32; + a = (u32)jiffies; + + /* conn might have been added just before by another cpu and + * might still be unconfirmed. In this case, nf_conntrack_find() + * returns no result. Thus only evict if this cpu added the + * stale entry or if the entry is older than two jiffies. + */ + age = a - b; + if (conn->cpu == cpu || age >= 2) { + hlist_del(&conn->node); + kmem_cache_free(connlimit_conn_cachep, conn); + return ERR_PTR(-ENOENT); + } + + return ERR_PTR(-EAGAIN); +} + unsigned int nf_conncount_lookup(struct net *net, struct hlist_head *head, const struct nf_conntrack_tuple *tuple, const struct nf_conntrack_zone *zone, @@ -138,18 +171,27 @@ unsigned int nf_conncount_lookup(struct net *net, struct hlist_head *head, { const struct nf_conntrack_tuple_hash *found; struct xt_connlimit_conn *conn; - struct hlist_node *n; struct nf_conn *found_ct; + struct hlist_node *n; unsigned int length = 0; *addit = true; /* check the saved connections */ hlist_for_each_entry_safe(conn, n, head, node) { - found = nf_conntrack_find_get(net, &conn->zone, &conn->tuple); - if (found == NULL) { - hlist_del(&conn->node); - kmem_cache_free(connlimit_conn_cachep, conn); + found = find_or_evict(net, conn); + if (IS_ERR(found)) { + /* Not found, but might be about to be confirmed */ + if (PTR_ERR(found) == -EAGAIN) { + length++; + if (!tuple) + continue; + + if (nf_ct_tuple_equal(&conn->tuple, tuple) && + nf_ct_zone_id(&conn->zone, conn->zone.dir) == + nf_ct_zone_id(zone, zone->dir)) + *addit = false; + } continue; }