]> git.proxmox.com Git - mirror_ubuntu-bionic-kernel.git/commitdiff
netfilter: nf_conncount: expose connection list interface
authorPablo Neira Ayuso <pablo@netfilter.org>
Thu, 10 Jan 2019 03:36:00 +0000 (04:36 +0100)
committerKleber Sacilotto de Souza <kleber.souza@canonical.com>
Mon, 14 Jan 2019 09:28:55 +0000 (09:28 +0000)
BugLink: https://bugs.launchpad.net/bugs/1811094
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 <pablo@netfilter.org>
(backported from commit 5e5cbc7b23eaf13e18652c03efbad5be6995de6a)
[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 <mfo@canonical.com>
Acked-by: Khalid Elmously <khalid.elmously@canonical.com>
Acked-by: Stefan Bader <stefan.bader@canonical.com>
Signed-off-by: Kleber Sacilotto de Souza <kleber.souza@canonical.com>
include/net/netfilter/nf_conntrack_count.h [new file with mode: 0644]
net/netfilter/xt_connlimit.c

diff --git a/include/net/netfilter/nf_conntrack_count.h b/include/net/netfilter/nf_conntrack_count.h
new file mode 100644 (file)
index 0000000..54e43b8
--- /dev/null
@@ -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
index 580239db4af2275c047877396aefd7d678a1fb54..7f543db6c5628ebceeebfdb85c539d0d2771fd63 100644 (file)
@@ -96,7 +96,7 @@ same_source(const union nf_inet_addr *addr,
        return memcmp(addr->ip6, u3->ip6, sizeof(addr->ip6));
 }
 
-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;
@@ -108,12 +108,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;
@@ -158,6 +158,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[],
@@ -204,13 +205,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;
@@ -220,7 +223,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;
        }
@@ -366,11 +369,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) {
@@ -378,8 +389,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);
        }