aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/xt_repldata.h
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2009-06-17 22:14:54 +0200
committerJan Engelhardt <jengelh@medozas.de>2010-02-10 17:50:47 +0100
commite3eaa9910b380530cfd2c0670fcd3f627674da8a (patch)
tree309e522e78f78149ec3cb99ffc386d1b72415a96 /net/netfilter/xt_repldata.h
parentnetfilter: xtables: use xt_table for hook instantiation (diff)
downloadlinux-dev-e3eaa9910b380530cfd2c0670fcd3f627674da8a.tar.xz
linux-dev-e3eaa9910b380530cfd2c0670fcd3f627674da8a.zip
netfilter: xtables: generate initial table on-demand
The static initial tables are pretty large, and after the net namespace has been instantiated, they just hang around for nothing. This commit removes them and creates tables on-demand at runtime when needed. Size shrinks by 7735 bytes (x86_64). Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Diffstat (limited to 'net/netfilter/xt_repldata.h')
-rw-r--r--net/netfilter/xt_repldata.h35
1 files changed, 35 insertions, 0 deletions
diff --git a/net/netfilter/xt_repldata.h b/net/netfilter/xt_repldata.h
new file mode 100644
index 000000000000..6efe4e5a81c6
--- /dev/null
+++ b/net/netfilter/xt_repldata.h
@@ -0,0 +1,35 @@
+/*
+ * Today's hack: quantum tunneling in structs
+ *
+ * 'entries' and 'term' are never anywhere referenced by word in code. In fact,
+ * they serve as the hanging-off data accessed through repl.data[].
+ */
+
+#define xt_alloc_initial_table(type, typ2) ({ \
+ unsigned int hook_mask = info->valid_hooks; \
+ unsigned int nhooks = hweight32(hook_mask); \
+ unsigned int bytes = 0, hooknum = 0, i = 0; \
+ struct { \
+ struct type##_replace repl; \
+ struct type##_standard entries[nhooks]; \
+ struct type##_error term; \
+ } *tbl = kzalloc(sizeof(*tbl), GFP_KERNEL); \
+ if (tbl == NULL) \
+ return NULL; \
+ strncpy(tbl->repl.name, info->name, sizeof(tbl->repl.name)); \
+ tbl->term = (struct type##_error)typ2##_ERROR_INIT; \
+ tbl->repl.valid_hooks = hook_mask; \
+ tbl->repl.num_entries = nhooks + 1; \
+ tbl->repl.size = nhooks * sizeof(struct type##_standard) + \
+ sizeof(struct type##_error); \
+ for (; hook_mask != 0; hook_mask >>= 1, ++hooknum) { \
+ if (!(hook_mask & 1)) \
+ continue; \
+ tbl->repl.hook_entry[hooknum] = bytes; \
+ tbl->repl.underflow[hooknum] = bytes; \
+ tbl->entries[i++] = (struct type##_standard) \
+ typ2##_STANDARD_INIT(NF_ACCEPT); \
+ bytes += sizeof(struct type##_standard); \
+ } \
+ tbl; \
+})