kernel: improve ipv4 netfilter optimization patch
authorFelix Fietkau <nbd@openwrt.org>
Thu, 7 Aug 2014 18:59:18 +0000 (18:59 +0000)
committerFelix Fietkau <nbd@openwrt.org>
Thu, 7 Aug 2014 18:59:18 +0000 (18:59 +0000)
Signed-off-by: Felix Fietkau <nbd@openwrt.org>
SVN-Revision: 42045

target/linux/generic/patches-3.10/611-netfilter_match_bypass_default_table.patch
target/linux/generic/patches-3.14/611-netfilter_match_bypass_default_table.patch

index 3cf0e5a32d9f21a5e5d38da41e5d70e09e918f95..2e0324345be275603f38d67611f60a85740f8556 100644 (file)
  /* 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;
  
index f4fa054c2ba3884d8bba95d41527fdf6fd2a1c7d..ef993c864b0c65b232e41ded5c3bcdc0fc8458fa 100644 (file)
  /* 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]));