Browse Source

kernel: improve ipv4 netfilter optimization patch

Signed-off-by: Felix Fietkau <[email protected]>

SVN-Revision: 42045
Felix Fietkau 11 years ago
parent
commit
3e64341eac

+ 14 - 12
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;
  

+ 48 - 37
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]));