From 3e64341eacf17a0552e83bf4e34f2c3d4f049921 Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 7 Aug 2014 18:59:18 +0000 Subject: [PATCH] kernel: improve ipv4 netfilter optimization patch Signed-off-by: Felix Fietkau SVN-Revision: 42045 --- ...netfilter_match_bypass_default_table.patch | 26 +++--- ...netfilter_match_bypass_default_table.patch | 85 +++++++++++-------- 2 files changed, 62 insertions(+), 49 deletions(-) diff --git a/target/linux/generic/patches-3.10/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/patches-3.10/611-netfilter_match_bypass_default_table.patch index 3cf0e5a32d..2e0324345b 100644 --- a/target/linux/generic/patches-3.10/611-netfilter_match_bypass_default_table.patch +++ b/target/linux/generic/patches-3.10/611-netfilter_match_bypass_default_table.patch @@ -34,33 +34,35 @@ /* Returns one of the generic firewall policies, like NF_ACCEPT. */ unsigned int ipt_do_table(struct sk_buff *skb, -@@ -334,6 +361,25 @@ ipt_do_table(struct sk_buff *skb, - ip = ip_hdr(skb); - indev = in ? in->name : nulldevname; - outdev = out ? out->name : nulldevname; -+ +@@ -331,9 +358,27 @@ ipt_do_table(struct sk_buff *skb, + unsigned int addend; + + /* Initialization */ + IP_NF_ASSERT(table->valid_hooks & (1 << hook)); + local_bh_disable(); -+ addend = xt_write_recseq_begin(); + private = table->private; + cpu = smp_processor_id(); + table_base = private->entries[cpu]; -+ jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; -+ stackptr = per_cpu_ptr(private->stackptr, cpu); -+ origptr = *stackptr; -+ + e = get_entry(table_base, private->hook_entry[hook]); + if (ipt_handle_default_rule(e, &verdict)) { + ADD_COUNTER(e->counters, skb->len, 1); -+ xt_write_recseq_end(addend); + local_bh_enable(); + return verdict; + } ++ + ip = ip_hdr(skb); + indev = in ? in->name : nulldevname; + outdev = out ? out->name : nulldevname; ++ ++ addend = xt_write_recseq_begin(); ++ jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; ++ stackptr = per_cpu_ptr(private->stackptr, cpu); ++ origptr = *stackptr; + /* We handle fragments by dealing with the first fragment as * if it was a normal packet. All other fragments are treated * normally, except that they will NEVER match rules that ask -@@ -348,18 +394,6 @@ ipt_do_table(struct sk_buff *skb, +@@ -348,18 +393,6 @@ ipt_do_table(struct sk_buff *skb, acpar.family = NFPROTO_IPV4; acpar.hooknum = hook; diff --git a/target/linux/generic/patches-3.14/611-netfilter_match_bypass_default_table.patch b/target/linux/generic/patches-3.14/611-netfilter_match_bypass_default_table.patch index f4fa054c2b..ef993c864b 100644 --- a/target/linux/generic/patches-3.14/611-netfilter_match_bypass_default_table.patch +++ b/target/linux/generic/patches-3.14/611-netfilter_match_bypass_default_table.patch @@ -34,50 +34,61 @@ /* Returns one of the generic firewall policies, like NF_ACCEPT. */ unsigned int ipt_do_table(struct sk_buff *skb, -@@ -334,19 +361,6 @@ ipt_do_table(struct sk_buff *skb, - ip = ip_hdr(skb); - indev = in ? in->name : nulldevname; - outdev = out ? out->name : nulldevname; -- /* We handle fragments by dealing with the first fragment as -- * if it was a normal packet. All other fragments are treated -- * normally, except that they will NEVER match rules that ask -- * things we don't know, ie. tcp syn flag or ports). If the -- * rule is also a fragment-specific rule, non-fragments won't -- * match it. */ -- acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -- acpar.thoff = ip_hdrlen(skb); -- acpar.hotdrop = false; -- acpar.in = in; -- acpar.out = out; -- acpar.family = NFPROTO_IPV4; -- acpar.hooknum = hook; +@@ -331,9 +358,33 @@ ipt_do_table(struct sk_buff *skb, + unsigned int addend; - IP_NF_ASSERT(table->valid_hooks & (1 << hook)); - local_bh_disable(); -@@ -364,6 +378,26 @@ ipt_do_table(struct sk_buff *skb, - origptr = *stackptr; - - e = get_entry(table_base, private->hook_entry[hook]); + /* Initialization */ ++ IP_NF_ASSERT(table->valid_hooks & (1 << hook)); ++ local_bh_disable(); ++ private = table->private; ++ cpu = smp_processor_id(); ++ /* ++ * Ensure we load private-> members after we've fetched the base ++ * pointer. ++ */ ++ smp_read_barrier_depends(); ++ table_base = private->entries[cpu]; ++ ++ e = get_entry(table_base, private->hook_entry[hook]); + if (ipt_handle_default_rule(e, &verdict)) { + ADD_COUNTER(e->counters, skb->len, 1); -+ xt_write_recseq_end(addend); + local_bh_enable(); + return verdict; + } + -+ /* We handle fragments by dealing with the first fragment as -+ * if it was a normal packet. All other fragments are treated -+ * normally, except that they will NEVER match rules that ask -+ * things we don't know, ie. tcp syn flag or ports). If the -+ * rule is also a fragment-specific rule, non-fragments won't -+ * match it. */ -+ acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; -+ acpar.thoff = ip_hdrlen(skb); -+ acpar.hotdrop = false; -+ acpar.in = in; -+ acpar.out = out; -+ acpar.family = NFPROTO_IPV4; -+ acpar.hooknum = hook; + ip = ip_hdr(skb); + indev = in ? in->name : nulldevname; + outdev = out ? out->name : nulldevname; ++ ++ addend = xt_write_recseq_begin(); ++ jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; ++ stackptr = per_cpu_ptr(private->stackptr, cpu); ++ origptr = *stackptr; ++ + /* We handle fragments by dealing with the first fragment as + * if it was a normal packet. All other fragments are treated + * normally, except that they will NEVER match rules that ask +@@ -348,23 +399,6 @@ ipt_do_table(struct sk_buff *skb, + acpar.family = NFPROTO_IPV4; + acpar.hooknum = hook; +- IP_NF_ASSERT(table->valid_hooks & (1 << hook)); +- local_bh_disable(); +- addend = xt_write_recseq_begin(); +- private = table->private; +- cpu = smp_processor_id(); +- /* +- * Ensure we load private-> members after we've fetched the base +- * pointer. +- */ +- smp_read_barrier_depends(); +- table_base = private->entries[cpu]; +- jumpstack = (struct ipt_entry **)private->jumpstack[cpu]; +- stackptr = per_cpu_ptr(private->stackptr, cpu); +- origptr = *stackptr; +- +- e = get_entry(table_base, private->hook_entry[hook]); +- pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n", table->name, hook, origptr, + get_entry(table_base, private->underflow[hook])); -- 2.30.2