|
|
df4535 |
From 3e8e2f0a6590a3b1eeb989e364fe4b5638be108f Mon Sep 17 00:00:00 2001
|
|
|
df4535 |
From: Phil Sutter <phil@nwl.cc>
|
|
|
df4535 |
Date: Tue, 15 Dec 2020 15:40:56 +0100
|
|
|
df4535 |
Subject: [PATCH] libxtables: Implement notargets hash table
|
|
|
df4535 |
|
|
|
df4535 |
Target lookup is relatively costly due to the filesystem access. Avoid
|
|
|
df4535 |
this overhead in huge rulesets which contain many chain jumps by caching
|
|
|
df4535 |
the failed lookups into a hashtable for later.
|
|
|
df4535 |
|
|
|
df4535 |
Signed-off-by: Phil Sutter <phil@nwl.cc>
|
|
|
df4535 |
Acked-by: Florian Westphal <fw@strlen.de>
|
|
|
df4535 |
(cherry picked from commit f58b0d7406451afbb4b9b6c7888990c964fa7c79)
|
|
|
df4535 |
|
|
|
df4535 |
Conflicts:
|
|
|
df4535 |
libxtables/xtables.c
|
|
|
df4535 |
-> Context changes and missing xtables_fini() due to missing commit
|
|
|
df4535 |
7db4333dc0b6c ("libxtables: Introduce xtables_fini()")
|
|
|
df4535 |
---
|
|
|
df4535 |
libxtables/xtables.c | 79 ++++++++++++++++++++++++++++++++++++++++++++
|
|
|
df4535 |
1 file changed, 79 insertions(+)
|
|
|
df4535 |
|
|
|
df4535 |
diff --git a/libxtables/xtables.c b/libxtables/xtables.c
|
|
|
df4535 |
index 58dd69440253d..1e1c218df7441 100644
|
|
|
df4535 |
--- a/libxtables/xtables.c
|
|
|
df4535 |
+++ b/libxtables/xtables.c
|
|
|
df4535 |
@@ -48,6 +48,7 @@
|
|
|
df4535 |
#include <linux/netfilter_ipv4/ip_tables.h>
|
|
|
df4535 |
#include <linux/netfilter_ipv6/ip6_tables.h>
|
|
|
df4535 |
#include <libiptc/libxtc.h>
|
|
|
df4535 |
+#include <libiptc/linux_list.h>
|
|
|
df4535 |
|
|
|
df4535 |
#ifndef NO_SHARED_LIBS
|
|
|
df4535 |
#include <dlfcn.h>
|
|
|
df4535 |
@@ -208,6 +209,71 @@ static bool xtables_fully_register_pending_match(struct xtables_match *me,
|
|
|
df4535 |
static bool xtables_fully_register_pending_target(struct xtables_target *me,
|
|
|
df4535 |
struct xtables_target *prev);
|
|
|
df4535 |
|
|
|
df4535 |
+struct notarget {
|
|
|
df4535 |
+ struct hlist_node node;
|
|
|
df4535 |
+ char name[];
|
|
|
df4535 |
+};
|
|
|
df4535 |
+
|
|
|
df4535 |
+#define NOTARGET_HSIZE 512
|
|
|
df4535 |
+static struct hlist_head notargets[NOTARGET_HSIZE];
|
|
|
df4535 |
+
|
|
|
df4535 |
+static void notargets_hlist_init(void)
|
|
|
df4535 |
+{
|
|
|
df4535 |
+ int i;
|
|
|
df4535 |
+
|
|
|
df4535 |
+ for (i = 0; i < NOTARGET_HSIZE; i++)
|
|
|
df4535 |
+ INIT_HLIST_HEAD(¬argets[i]);
|
|
|
df4535 |
+}
|
|
|
df4535 |
+
|
|
|
df4535 |
+static void notargets_hlist_free(void)
|
|
|
df4535 |
+{
|
|
|
df4535 |
+ struct hlist_node *pos, *n;
|
|
|
df4535 |
+ struct notarget *cur;
|
|
|
df4535 |
+ int i;
|
|
|
df4535 |
+
|
|
|
df4535 |
+ for (i = 0; i < NOTARGET_HSIZE; i++) {
|
|
|
df4535 |
+ hlist_for_each_entry_safe(cur, pos, n, ¬argets[i], node) {
|
|
|
df4535 |
+ hlist_del(&cur->node);
|
|
|
df4535 |
+ free(cur);
|
|
|
df4535 |
+ }
|
|
|
df4535 |
+ }
|
|
|
df4535 |
+}
|
|
|
df4535 |
+
|
|
|
df4535 |
+static uint32_t djb_hash(const char *key)
|
|
|
df4535 |
+{
|
|
|
df4535 |
+ uint32_t i, hash = 5381;
|
|
|
df4535 |
+
|
|
|
df4535 |
+ for (i = 0; i < strlen(key); i++)
|
|
|
df4535 |
+ hash = ((hash << 5) + hash) + key[i];
|
|
|
df4535 |
+
|
|
|
df4535 |
+ return hash;
|
|
|
df4535 |
+}
|
|
|
df4535 |
+
|
|
|
df4535 |
+static struct notarget *notargets_hlist_lookup(const char *name)
|
|
|
df4535 |
+{
|
|
|
df4535 |
+ uint32_t key = djb_hash(name) % NOTARGET_HSIZE;
|
|
|
df4535 |
+ struct hlist_node *node;
|
|
|
df4535 |
+ struct notarget *cur;
|
|
|
df4535 |
+
|
|
|
df4535 |
+ hlist_for_each_entry(cur, node, ¬argets[key], node) {
|
|
|
df4535 |
+ if (!strcmp(name, cur->name))
|
|
|
df4535 |
+ return cur;
|
|
|
df4535 |
+ }
|
|
|
df4535 |
+ return NULL;
|
|
|
df4535 |
+}
|
|
|
df4535 |
+
|
|
|
df4535 |
+static void notargets_hlist_insert(const char *name)
|
|
|
df4535 |
+{
|
|
|
df4535 |
+ struct notarget *cur;
|
|
|
df4535 |
+
|
|
|
df4535 |
+ if (!name)
|
|
|
df4535 |
+ return;
|
|
|
df4535 |
+
|
|
|
df4535 |
+ cur = xtables_malloc(sizeof(*cur) + strlen(name) + 1);
|
|
|
df4535 |
+ strcpy(cur->name, name);
|
|
|
df4535 |
+ hlist_add_head(&cur->node, ¬argets[djb_hash(name) % NOTARGET_HSIZE]);
|
|
|
df4535 |
+}
|
|
|
df4535 |
+
|
|
|
df4535 |
void xtables_init(void)
|
|
|
df4535 |
{
|
|
|
df4535 |
xtables_libdir = getenv("XTABLES_LIBDIR");
|
|
|
df4535 |
@@ -233,6 +299,13 @@ void xtables_init(void)
|
|
|
df4535 |
return;
|
|
|
df4535 |
}
|
|
|
df4535 |
xtables_libdir = XTABLES_LIBDIR;
|
|
|
df4535 |
+
|
|
|
df4535 |
+ notargets_hlist_init();
|
|
|
df4535 |
+}
|
|
|
df4535 |
+
|
|
|
df4535 |
+void xtables_fini(void)
|
|
|
df4535 |
+{
|
|
|
df4535 |
+ notargets_hlist_free();
|
|
|
df4535 |
}
|
|
|
df4535 |
|
|
|
df4535 |
void xtables_set_nfproto(uint8_t nfproto)
|
|
|
df4535 |
@@ -750,6 +823,10 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
|
|
|
df4535 |
|| strcmp(name, XTC_LABEL_QUEUE) == 0
|
|
|
df4535 |
|| strcmp(name, XTC_LABEL_RETURN) == 0)
|
|
|
df4535 |
name = "standard";
|
|
|
df4535 |
+ /* known non-target? */
|
|
|
df4535 |
+ else if (notargets_hlist_lookup(name) &&
|
|
|
df4535 |
+ tryload != XTF_LOAD_MUST_SUCCEED)
|
|
|
df4535 |
+ return NULL;
|
|
|
df4535 |
|
|
|
df4535 |
/* Trigger delayed initialization */
|
|
|
df4535 |
for (dptr = &xtables_pending_targets; *dptr; ) {
|
|
|
df4535 |
@@ -813,6 +890,8 @@ xtables_find_target(const char *name, enum xtables_tryload tryload)
|
|
|
df4535 |
|
|
|
df4535 |
if (ptr)
|
|
|
df4535 |
ptr->used = 1;
|
|
|
df4535 |
+ else
|
|
|
df4535 |
+ notargets_hlist_insert(name);
|
|
|
df4535 |
|
|
|
df4535 |
return ptr;
|
|
|
df4535 |
}
|
|
|
df4535 |
--
|
|
|
df4535 |
2.34.1
|
|
|
df4535 |
|