kernel: generic: Fix nftables inet table breakage
authorBrett Mastbergen <bmastbergen@untangle.com>
Wed, 12 Sep 2018 19:04:55 +0000 (15:04 -0400)
committerJo-Philipp Wich <jo@mein.io>
Tue, 18 Dec 2018 10:28:13 +0000 (11:28 +0100)
Commit b7265c59ab7d ("kernel: backport a series of netfilter cleanup
patches to 4.14") added patch 302-netfilter-nf_tables_inet-don-t-use-
multihook-infrast.patch.  That patch switches the netfilter core in the
kernel to use the new native NFPROTO_INET support.  Unfortunately, the
new native NFPROTO_INET support does not exist in 4.14 and was not
backported along with this patchset.  As such, nftables inet tables never
see any traffic.

As an example the following nft counter rule should increment for every
packet coming into the box, but never will:

nft add table inet foo
nft add chain inet foo bar { type filter hook input priority 0\; }
nft add rule inet foo bar counter

This commit pulls in the required backport patches to add the new
native NFPROTO_INET support, and thus restore nftables inet table
functionality.

Tested on Turris Omnia (mvebu)

Fixes: b7265c59ab7d ("kernel: backport a series of netfilter cleanup ...")
Signed-off-by: Brett Mastbergen <bmastbergen@untangle.com>
(backported from f57806b56e5f6ca7bb9fb66d5b175b5f98ece93c)
(rebased patches)
Signed-off-by: Jo-Philipp Wich <jo@mein.io>
31 files changed:
target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/291-v4.16-netfilter-core-remove-synchronize_net-call-if-nfqueu.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/292-v4.16-netfilter-core-free-hooks-with-call_rcu.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/293-v4.16-netfilter-reduce-size-of-hook-entry-point-locations.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/294-v4.16-netfilter-reduce-hook-array-sizes-to-what-is-needed.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/295-v4.16-netfilter-don-t-allocate-space-for-decnet-hooks-unle.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/296-v4.16-netfilter-don-t-allocate-space-for-arp-bridge-hooks-.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/297-v4.16-netfilter-core-pass-hook-number-family-and-device-to.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/298-v4.16-netfilter-core-add-nf_remove_net_hook.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/298-v4.16-netfilter-core-pass-family-as-parameter-to-nf_remove.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch [new file with mode: 0644]
target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch
target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch
target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch
target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch
target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch
target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch
target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch
target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch
target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch
target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch
target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch
target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch
target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch
target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch
target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch
target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch
target/linux/generic/hack-4.14/250-netfilter_depends.patch
target/linux/generic/hack-4.14/251-sound_kconfig.patch
target/linux/generic/hack-4.14/650-netfilter-add-xt_OFFLOAD-target.patch
target/linux/generic/pending-4.14/640-netfilter-nf_flow_table-add-hardware-offload-support.patch

diff --git a/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch b/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch
new file mode 100644 (file)
index 0000000..35800c4
--- /dev/null
@@ -0,0 +1,91 @@
+From 4e645b47c4f000a503b9c90163ad905786b9bc1d Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Fri, 1 Dec 2017 00:21:02 +0100
+Subject: [PATCH 02/11] netfilter: core: make nf_unregister_net_hooks simple
+ wrapper again
+
+This reverts commit d3ad2c17b4047
+("netfilter: core: batch nf_unregister_net_hooks synchronize_net calls").
+
+Nothing wrong with it.  However, followup patch will delay freeing of hooks
+with call_rcu, so all synchronize_net() calls become obsolete and there
+is no need anymore for this batching.
+
+This revert causes a temporary performance degradation when destroying
+network namespace, but its resolved with the upcoming call_rcu conversion.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ net/netfilter/core.c | 59 +++-------------------------------------------------
+ 1 file changed, 3 insertions(+), 56 deletions(-)
+
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -395,63 +395,10 @@ EXPORT_SYMBOL(nf_register_net_hooks);
+ void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg,
+                            unsigned int hookcount)
+ {
+-      struct nf_hook_entries *to_free[16], *p;
+-      struct nf_hook_entries __rcu **pp;
+-      unsigned int i, j, n;
++      unsigned int i;
+-      mutex_lock(&nf_hook_mutex);
+-      for (i = 0; i < hookcount; i++) {
+-              pp = nf_hook_entry_head(net, &reg[i]);
+-              if (!pp)
+-                      continue;
+-
+-              p = nf_entry_dereference(*pp);
+-              if (WARN_ON_ONCE(!p))
+-                      continue;
+-              __nf_unregister_net_hook(p, &reg[i]);
+-      }
+-      mutex_unlock(&nf_hook_mutex);
+-
+-      do {
+-              n = min_t(unsigned int, hookcount, ARRAY_SIZE(to_free));
+-
+-              mutex_lock(&nf_hook_mutex);
+-
+-              for (i = 0, j = 0; i < hookcount && j < n; i++) {
+-                      pp = nf_hook_entry_head(net, &reg[i]);
+-                      if (!pp)
+-                              continue;
+-
+-                      p = nf_entry_dereference(*pp);
+-                      if (!p)
+-                              continue;
+-
+-                      to_free[j] = __nf_hook_entries_try_shrink(pp);
+-                      if (to_free[j])
+-                              ++j;
+-              }
+-
+-              mutex_unlock(&nf_hook_mutex);
+-
+-              if (j) {
+-                      unsigned int nfq;
+-
+-                      synchronize_net();
+-
+-                      /* need 2nd synchronize_net() if nfqueue is used, skb
+-                       * can get reinjected right before nf_queue_hook_drop()
+-                       */
+-                      nfq = nf_queue_nf_hook_drop(net);
+-                      if (nfq)
+-                              synchronize_net();
+-
+-                      for (i = 0; i < j; i++)
+-                              kvfree(to_free[i]);
+-              }
+-
+-              reg += n;
+-              hookcount -= n;
+-      } while (hookcount > 0);
++      for (i = 0; i < hookcount; i++)
++              nf_unregister_net_hook(net, &reg[i]);
+ }
+ EXPORT_SYMBOL(nf_unregister_net_hooks);
diff --git a/target/linux/generic/backport-4.14/291-v4.16-netfilter-core-remove-synchronize_net-call-if-nfqueu.patch b/target/linux/generic/backport-4.14/291-v4.16-netfilter-core-remove-synchronize_net-call-if-nfqueu.patch
new file mode 100644 (file)
index 0000000..0ac5783
--- /dev/null
@@ -0,0 +1,116 @@
+From 26888dfd7e7454686b8d3ea9ba5045d5f236e4d7 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Fri, 1 Dec 2017 00:21:03 +0100
+Subject: [PATCH 03/11] netfilter: core: remove synchronize_net call if nfqueue
+ is used
+
+since commit 960632ece6949b ("netfilter: convert hook list to an array")
+nfqueue no longer stores a pointer to the hook that caused the packet
+to be queued.  Therefore no extra synchronize_net() call is needed after
+dropping the packets enqueued by the old rule blob.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ include/net/netfilter/nf_queue.h | 2 +-
+ net/netfilter/core.c             | 6 +-----
+ net/netfilter/nf_internals.h     | 2 +-
+ net/netfilter/nf_queue.c         | 7 ++-----
+ net/netfilter/nfnetlink_queue.c  | 9 ++-------
+ 5 files changed, 7 insertions(+), 19 deletions(-)
+
+--- a/include/net/netfilter/nf_queue.h
++++ b/include/net/netfilter/nf_queue.h
+@@ -25,7 +25,7 @@ struct nf_queue_entry {
+ struct nf_queue_handler {
+       int             (*outfn)(struct nf_queue_entry *entry,
+                                unsigned int queuenum);
+-      unsigned int    (*nf_hook_drop)(struct net *net);
++      void            (*nf_hook_drop)(struct net *net);
+ };
+ void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh);
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -341,7 +341,6 @@ void nf_unregister_net_hook(struct net *
+ {
+       struct nf_hook_entries __rcu **pp;
+       struct nf_hook_entries *p;
+-      unsigned int nfq;
+       pp = nf_hook_entry_head(net, reg);
+       if (!pp)
+@@ -364,10 +363,7 @@ void nf_unregister_net_hook(struct net *
+       synchronize_net();
+-      /* other cpu might still process nfqueue verdict that used reg */
+-      nfq = nf_queue_nf_hook_drop(net);
+-      if (nfq)
+-              synchronize_net();
++      nf_queue_nf_hook_drop(net);
+       kvfree(p);
+ }
+ EXPORT_SYMBOL(nf_unregister_net_hook);
+--- a/net/netfilter/nf_internals.h
++++ b/net/netfilter/nf_internals.h
+@@ -10,7 +10,7 @@
+ int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
+            const struct nf_hook_entries *entries, unsigned int index,
+            unsigned int verdict);
+-unsigned int nf_queue_nf_hook_drop(struct net *net);
++void nf_queue_nf_hook_drop(struct net *net);
+ /* nf_log.c */
+ int __init netfilter_log_init(void);
+--- a/net/netfilter/nf_queue.c
++++ b/net/netfilter/nf_queue.c
+@@ -96,18 +96,15 @@ void nf_queue_entry_get_refs(struct nf_q
+ }
+ EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
+-unsigned int nf_queue_nf_hook_drop(struct net *net)
++void nf_queue_nf_hook_drop(struct net *net)
+ {
+       const struct nf_queue_handler *qh;
+-      unsigned int count = 0;
+       rcu_read_lock();
+       qh = rcu_dereference(net->nf.queue_handler);
+       if (qh)
+-              count = qh->nf_hook_drop(net);
++              qh->nf_hook_drop(net);
+       rcu_read_unlock();
+-
+-      return count;
+ }
+ EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop);
+--- a/net/netfilter/nfnetlink_queue.c
++++ b/net/netfilter/nfnetlink_queue.c
+@@ -941,23 +941,18 @@ static struct notifier_block nfqnl_dev_n
+       .notifier_call  = nfqnl_rcv_dev_event,
+ };
+-static unsigned int nfqnl_nf_hook_drop(struct net *net)
++static void nfqnl_nf_hook_drop(struct net *net)
+ {
+       struct nfnl_queue_net *q = nfnl_queue_pernet(net);
+-      unsigned int instances = 0;
+       int i;
+       for (i = 0; i < INSTANCE_BUCKETS; i++) {
+               struct nfqnl_instance *inst;
+               struct hlist_head *head = &q->instance_table[i];
+-              hlist_for_each_entry_rcu(inst, head, hlist) {
++              hlist_for_each_entry_rcu(inst, head, hlist)
+                       nfqnl_flush(inst, NULL, 0);
+-                      instances++;
+-              }
+       }
+-
+-      return instances;
+ }
+ static int
diff --git a/target/linux/generic/backport-4.14/292-v4.16-netfilter-core-free-hooks-with-call_rcu.patch b/target/linux/generic/backport-4.14/292-v4.16-netfilter-core-free-hooks-with-call_rcu.patch
new file mode 100644 (file)
index 0000000..5eca735
--- /dev/null
@@ -0,0 +1,132 @@
+From 8c873e2199700c2de7dbd5eedb9d90d5f109462b Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Fri, 1 Dec 2017 00:21:04 +0100
+Subject: [PATCH 04/11] netfilter: core: free hooks with call_rcu
+
+Giuseppe Scrivano says:
+  "SELinux, if enabled, registers for each new network namespace 6
+    netfilter hooks."
+
+Cost for this is high.  With synchronize_net() removed:
+   "The net benefit on an SMP machine with two cores is that creating a
+   new network namespace takes -40% of the original time."
+
+This patch replaces synchronize_net+kvfree with call_rcu().
+We store rcu_head at the tail of a structure that has no fixed layout,
+i.e. we cannot use offsetof() to compute the start of the original
+allocation.  Thus store this information right after the rcu head.
+
+We could simplify this by just placing the rcu_head at the start
+of struct nf_hook_entries.  However, this structure is used in
+packet processing hotpath, so only place what is needed for that
+at the beginning of the struct.
+
+Reported-by: Giuseppe Scrivano <gscrivan@redhat.com>
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ include/linux/netfilter.h | 19 +++++++++++++++----
+ net/netfilter/core.c      | 34 ++++++++++++++++++++++++++++------
+ 2 files changed, 43 insertions(+), 10 deletions(-)
+
+--- a/include/linux/netfilter.h
++++ b/include/linux/netfilter.h
+@@ -77,17 +77,28 @@ struct nf_hook_entry {
+       void                            *priv;
+ };
++struct nf_hook_entries_rcu_head {
++      struct rcu_head head;
++      void    *allocation;
++};
++
+ struct nf_hook_entries {
+       u16                             num_hook_entries;
+       /* padding */
+       struct nf_hook_entry            hooks[];
+-      /* trailer: pointers to original orig_ops of each hook.
+-       *
+-       * This is not part of struct nf_hook_entry since its only
+-       * needed in slow path (hook register/unregister).
++      /* trailer: pointers to original orig_ops of each hook,
++       * followed by rcu_head and scratch space used for freeing
++       * the structure via call_rcu.
+        *
++       *   This is not part of struct nf_hook_entry since its only
++       *   needed in slow path (hook register/unregister):
+        * const struct nf_hook_ops     *orig_ops[]
++       *
++       *   For the same reason, we store this at end -- its
++       *   only needed when a hook is deleted, not during
++       *   packet path processing:
++       * struct nf_hook_entries_rcu_head     head
+        */
+ };
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -74,7 +74,8 @@ static struct nf_hook_entries *allocate_
+       struct nf_hook_entries *e;
+       size_t alloc = sizeof(*e) +
+                      sizeof(struct nf_hook_entry) * num +
+-                     sizeof(struct nf_hook_ops *) * num;
++                     sizeof(struct nf_hook_ops *) * num +
++                     sizeof(struct nf_hook_entries_rcu_head);
+       if (num == 0)
+               return NULL;
+@@ -85,6 +86,30 @@ static struct nf_hook_entries *allocate_
+       return e;
+ }
++static void __nf_hook_entries_free(struct rcu_head *h)
++{
++      struct nf_hook_entries_rcu_head *head;
++
++      head = container_of(h, struct nf_hook_entries_rcu_head, head);
++      kvfree(head->allocation);
++}
++
++static void nf_hook_entries_free(struct nf_hook_entries *e)
++{
++      struct nf_hook_entries_rcu_head *head;
++      struct nf_hook_ops **ops;
++      unsigned int num;
++
++      if (!e)
++              return;
++
++      num = e->num_hook_entries;
++      ops = nf_hook_entries_get_hook_ops(e);
++      head = (void *)&ops[num];
++      head->allocation = e;
++      call_rcu(&head->head, __nf_hook_entries_free);
++}
++
+ static unsigned int accept_all(void *priv,
+                              struct sk_buff *skb,
+                              const struct nf_hook_state *state)
+@@ -291,9 +316,8 @@ int nf_register_net_hook(struct net *net
+ #ifdef HAVE_JUMP_LABEL
+       static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]);
+ #endif
+-      synchronize_net();
+       BUG_ON(p == new_hooks);
+-      kvfree(p);
++      nf_hook_entries_free(p);
+       return 0;
+ }
+ EXPORT_SYMBOL(nf_register_net_hook);
+@@ -361,10 +385,8 @@ void nf_unregister_net_hook(struct net *
+       if (!p)
+               return;
+-      synchronize_net();
+-
+       nf_queue_nf_hook_drop(net);
+-      kvfree(p);
++      nf_hook_entries_free(p);
+ }
+ EXPORT_SYMBOL(nf_unregister_net_hook);
diff --git a/target/linux/generic/backport-4.14/293-v4.16-netfilter-reduce-size-of-hook-entry-point-locations.patch b/target/linux/generic/backport-4.14/293-v4.16-netfilter-reduce-size-of-hook-entry-point-locations.patch
new file mode 100644 (file)
index 0000000..fcf54e9
--- /dev/null
@@ -0,0 +1,200 @@
+From b0f38338aef2dae5ade3c16acf713737e3b15a73 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Sun, 3 Dec 2017 00:58:47 +0100
+Subject: [PATCH 05/11] netfilter: reduce size of hook entry point locations
+
+struct net contains:
+
+struct nf_hook_entries __rcu *hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
+
+which store the hook entry point locations for the various protocol
+families and the hooks.
+
+Using array results in compact c code when doing accesses, i.e.
+  x = rcu_dereference(net->nf.hooks[pf][hook]);
+
+but its also wasting a lot of memory, as most families are
+not used.
+
+So split the array into those families that are used, which
+are only 5 (instead of 13).  In most cases, the 'pf' argument is
+constant, i.e. gcc removes switch statement.
+
+struct net before:
+ /* size: 5184, cachelines: 81, members: 46 */
+after:
+ /* size: 4672, cachelines: 73, members: 46 */
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ include/linux/netfilter.h       | 24 ++++++++++++++++++++++--
+ include/net/netns/netfilter.h   |  6 +++++-
+ net/bridge/br_netfilter_hooks.c |  2 +-
+ net/netfilter/core.c            | 38 ++++++++++++++++++++++++++++++--------
+ net/netfilter/nf_queue.c        | 21 +++++++++++++++++++--
+ 5 files changed, 77 insertions(+), 14 deletions(-)
+
+--- a/include/linux/netfilter.h
++++ b/include/linux/netfilter.h
+@@ -195,7 +195,7 @@ static inline int nf_hook(u_int8_t pf, u
+                         struct net_device *indev, struct net_device *outdev,
+                         int (*okfn)(struct net *, struct sock *, struct sk_buff *))
+ {
+-      struct nf_hook_entries *hook_head;
++      struct nf_hook_entries *hook_head = NULL;
+       int ret = 1;
+ #ifdef HAVE_JUMP_LABEL
+@@ -206,7 +206,27 @@ static inline int nf_hook(u_int8_t pf, u
+ #endif
+       rcu_read_lock();
+-      hook_head = rcu_dereference(net->nf.hooks[pf][hook]);
++      switch (pf) {
++      case NFPROTO_IPV4:
++              hook_head = rcu_dereference(net->nf.hooks_ipv4[hook]);
++              break;
++      case NFPROTO_IPV6:
++              hook_head = rcu_dereference(net->nf.hooks_ipv6[hook]);
++              break;
++      case NFPROTO_ARP:
++              hook_head = rcu_dereference(net->nf.hooks_arp[hook]);
++              break;
++      case NFPROTO_BRIDGE:
++              hook_head = rcu_dereference(net->nf.hooks_bridge[hook]);
++              break;
++      case NFPROTO_DECNET:
++              hook_head = rcu_dereference(net->nf.hooks_decnet[hook]);
++              break;
++      default:
++              WARN_ON_ONCE(1);
++              break;
++      }
++
+       if (hook_head) {
+               struct nf_hook_state state;
+--- a/include/net/netns/netfilter.h
++++ b/include/net/netns/netfilter.h
+@@ -17,7 +17,11 @@ struct netns_nf {
+ #ifdef CONFIG_SYSCTL
+       struct ctl_table_header *nf_log_dir_header;
+ #endif
+-      struct nf_hook_entries __rcu *hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
++      struct nf_hook_entries __rcu *hooks_ipv4[NF_MAX_HOOKS];
++      struct nf_hook_entries __rcu *hooks_ipv6[NF_MAX_HOOKS];
++      struct nf_hook_entries __rcu *hooks_arp[NF_MAX_HOOKS];
++      struct nf_hook_entries __rcu *hooks_bridge[NF_MAX_HOOKS];
++      struct nf_hook_entries __rcu *hooks_decnet[NF_MAX_HOOKS];
+ #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
+       bool                    defrag_ipv4;
+ #endif
+--- a/net/bridge/br_netfilter_hooks.c
++++ b/net/bridge/br_netfilter_hooks.c
+@@ -992,7 +992,7 @@ int br_nf_hook_thresh(unsigned int hook,
+       unsigned int i;
+       int ret;
+-      e = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]);
++      e = rcu_dereference(net->nf.hooks_bridge[hook]);
+       if (!e)
+               return okfn(net, sk, skb);
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -264,8 +264,23 @@ out_assign:
+ static struct nf_hook_entries __rcu **nf_hook_entry_head(struct net *net, const struct nf_hook_ops *reg)
+ {
+-      if (reg->pf != NFPROTO_NETDEV)
+-              return net->nf.hooks[reg->pf]+reg->hooknum;
++      switch (reg->pf) {
++      case NFPROTO_NETDEV:
++              break;
++      case NFPROTO_ARP:
++              return net->nf.hooks_arp + reg->hooknum;
++      case NFPROTO_BRIDGE:
++              return net->nf.hooks_bridge + reg->hooknum;
++      case NFPROTO_IPV4:
++              return net->nf.hooks_ipv4 + reg->hooknum;
++      case NFPROTO_IPV6:
++              return net->nf.hooks_ipv6 + reg->hooknum;
++      case NFPROTO_DECNET:
++              return net->nf.hooks_decnet + reg->hooknum;
++      default:
++              WARN_ON_ONCE(1);
++              return NULL;
++      }
+ #ifdef CONFIG_NETFILTER_INGRESS
+       if (reg->hooknum == NF_NETDEV_INGRESS) {
+@@ -534,14 +549,21 @@ void (*nf_nat_decode_session_hook)(struc
+ EXPORT_SYMBOL(nf_nat_decode_session_hook);
+ #endif
+-static int __net_init netfilter_net_init(struct net *net)
++static void __net_init __netfilter_net_init(struct nf_hook_entries *e[NF_MAX_HOOKS])
+ {
+-      int i, h;
++      int h;
+-      for (i = 0; i < ARRAY_SIZE(net->nf.hooks); i++) {
+-              for (h = 0; h < NF_MAX_HOOKS; h++)
+-                      RCU_INIT_POINTER(net->nf.hooks[i][h], NULL);
+-      }
++      for (h = 0; h < NF_MAX_HOOKS; h++)
++              RCU_INIT_POINTER(e[h], NULL);
++}
++
++static int __net_init netfilter_net_init(struct net *net)
++{
++      __netfilter_net_init(net->nf.hooks_ipv4);
++      __netfilter_net_init(net->nf.hooks_ipv6);
++      __netfilter_net_init(net->nf.hooks_arp);
++      __netfilter_net_init(net->nf.hooks_bridge);
++      __netfilter_net_init(net->nf.hooks_decnet);
+ #ifdef CONFIG_PROC_FS
+       net->nf.proc_netfilter = proc_net_mkdir(net, "netfilter",
+--- a/net/netfilter/nf_queue.c
++++ b/net/netfilter/nf_queue.c
+@@ -201,6 +201,23 @@ repeat:
+       return NF_ACCEPT;
+ }
++static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum)
++{
++      switch (pf) {
++      case NFPROTO_BRIDGE:
++              return rcu_dereference(net->nf.hooks_bridge[hooknum]);
++      case NFPROTO_IPV4:
++              return rcu_dereference(net->nf.hooks_ipv4[hooknum]);
++      case NFPROTO_IPV6:
++              return rcu_dereference(net->nf.hooks_ipv6[hooknum]);
++      default:
++              WARN_ON_ONCE(1);
++              return NULL;
++      }
++
++      return NULL;
++}
++
+ /* Caller must hold rcu read-side lock */
+ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
+ {
+@@ -216,12 +233,12 @@ void nf_reinject(struct nf_queue_entry *
+       net = entry->state.net;
+       pf = entry->state.pf;
+-      hooks = rcu_dereference(net->nf.hooks[pf][entry->state.hook]);
++      hooks = nf_hook_entries_head(net, pf, entry->state.hook);
+       nf_queue_entry_release_refs(entry);
+       i = entry->hook_index;
+-      if (WARN_ON_ONCE(i >= hooks->num_hook_entries)) {
++      if (WARN_ON_ONCE(!hooks || i >= hooks->num_hook_entries)) {
+               kfree_skb(skb);
+               kfree(entry);
+               return;
diff --git a/target/linux/generic/backport-4.14/294-v4.16-netfilter-reduce-hook-array-sizes-to-what-is-needed.patch b/target/linux/generic/backport-4.14/294-v4.16-netfilter-reduce-hook-array-sizes-to-what-is-needed.patch
new file mode 100644 (file)
index 0000000..d9009b8
--- /dev/null
@@ -0,0 +1,95 @@
+From ef57170bbfdd6958281011332b1fd237712f69f0 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Thu, 7 Dec 2017 16:28:24 +0100
+Subject: [PATCH 06/11] netfilter: reduce hook array sizes to what is needed
+
+Not all families share the same hook count, adjust sizes to what is
+needed.
+
+struct net before:
+/* size: 6592, cachelines: 103, members: 46 */
+after:
+/* size: 5952, cachelines: 93, members: 46 */
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ include/net/netns/netfilter.h | 10 +++++-----
+ net/netfilter/core.c          | 24 +++++++++++++++++-------
+ 2 files changed, 22 insertions(+), 12 deletions(-)
+
+--- a/include/net/netns/netfilter.h
++++ b/include/net/netns/netfilter.h
+@@ -17,11 +17,11 @@ struct netns_nf {
+ #ifdef CONFIG_SYSCTL
+       struct ctl_table_header *nf_log_dir_header;
+ #endif
+-      struct nf_hook_entries __rcu *hooks_ipv4[NF_MAX_HOOKS];
+-      struct nf_hook_entries __rcu *hooks_ipv6[NF_MAX_HOOKS];
+-      struct nf_hook_entries __rcu *hooks_arp[NF_MAX_HOOKS];
+-      struct nf_hook_entries __rcu *hooks_bridge[NF_MAX_HOOKS];
+-      struct nf_hook_entries __rcu *hooks_decnet[NF_MAX_HOOKS];
++      struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS];
++      struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS];
++      struct nf_hook_entries __rcu *hooks_arp[NF_ARP_NUMHOOKS];
++      struct nf_hook_entries __rcu *hooks_bridge[NF_INET_NUMHOOKS];
++      struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS];
+ #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
+       bool                    defrag_ipv4;
+ #endif
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -268,14 +268,24 @@ static struct nf_hook_entries __rcu **nf
+       case NFPROTO_NETDEV:
+               break;
+       case NFPROTO_ARP:
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_arp) <= reg->hooknum))
++                      return NULL;
+               return net->nf.hooks_arp + reg->hooknum;
+       case NFPROTO_BRIDGE:
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_bridge) <= reg->hooknum))
++                      return NULL;
+               return net->nf.hooks_bridge + reg->hooknum;
+       case NFPROTO_IPV4:
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= reg->hooknum))
++                      return NULL;
+               return net->nf.hooks_ipv4 + reg->hooknum;
+       case NFPROTO_IPV6:
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv6) <= reg->hooknum))
++                      return NULL;
+               return net->nf.hooks_ipv6 + reg->hooknum;
+       case NFPROTO_DECNET:
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_decnet) <= reg->hooknum))
++                      return NULL;
+               return net->nf.hooks_decnet + reg->hooknum;
+       default:
+               WARN_ON_ONCE(1);
+@@ -549,21 +559,21 @@ void (*nf_nat_decode_session_hook)(struc
+ EXPORT_SYMBOL(nf_nat_decode_session_hook);
+ #endif
+-static void __net_init __netfilter_net_init(struct nf_hook_entries *e[NF_MAX_HOOKS])
++static void __net_init __netfilter_net_init(struct nf_hook_entries **e, int max)
+ {
+       int h;
+-      for (h = 0; h < NF_MAX_HOOKS; h++)
++      for (h = 0; h < max; h++)
+               RCU_INIT_POINTER(e[h], NULL);
+ }
+ static int __net_init netfilter_net_init(struct net *net)
+ {
+-      __netfilter_net_init(net->nf.hooks_ipv4);
+-      __netfilter_net_init(net->nf.hooks_ipv6);
+-      __netfilter_net_init(net->nf.hooks_arp);
+-      __netfilter_net_init(net->nf.hooks_bridge);
+-      __netfilter_net_init(net->nf.hooks_decnet);
++      __netfilter_net_init(net->nf.hooks_ipv4, ARRAY_SIZE(net->nf.hooks_ipv4));
++      __netfilter_net_init(net->nf.hooks_ipv6, ARRAY_SIZE(net->nf.hooks_ipv6));
++      __netfilter_net_init(net->nf.hooks_arp, ARRAY_SIZE(net->nf.hooks_arp));
++      __netfilter_net_init(net->nf.hooks_bridge, ARRAY_SIZE(net->nf.hooks_bridge));
++      __netfilter_net_init(net->nf.hooks_decnet, ARRAY_SIZE(net->nf.hooks_decnet));
+ #ifdef CONFIG_PROC_FS
+       net->nf.proc_netfilter = proc_net_mkdir(net, "netfilter",
diff --git a/target/linux/generic/backport-4.14/295-v4.16-netfilter-don-t-allocate-space-for-decnet-hooks-unle.patch b/target/linux/generic/backport-4.14/295-v4.16-netfilter-don-t-allocate-space-for-decnet-hooks-unle.patch
new file mode 100644 (file)
index 0000000..26a93c4
--- /dev/null
@@ -0,0 +1,67 @@
+From bb4badf3a3dc81190f7c1c1fa063cdefb18df45f Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Thu, 7 Dec 2017 16:28:25 +0100
+Subject: [PATCH 07/11] netfilter: don't allocate space for decnet hooks unless
+ needed
+
+no need to define hook points if the family isn't supported.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ include/linux/netfilter.h     | 2 ++
+ include/net/netns/netfilter.h | 2 ++
+ net/netfilter/core.c          | 4 ++++
+ 3 files changed, 8 insertions(+)
+
+--- a/include/linux/netfilter.h
++++ b/include/linux/netfilter.h
+@@ -219,9 +219,11 @@ static inline int nf_hook(u_int8_t pf, u
+       case NFPROTO_BRIDGE:
+               hook_head = rcu_dereference(net->nf.hooks_bridge[hook]);
+               break;
++#if IS_ENABLED(CONFIG_DECNET)
+       case NFPROTO_DECNET:
+               hook_head = rcu_dereference(net->nf.hooks_decnet[hook]);
+               break;
++#endif
+       default:
+               WARN_ON_ONCE(1);
+               break;
+--- a/include/net/netns/netfilter.h
++++ b/include/net/netns/netfilter.h
+@@ -21,7 +21,9 @@ struct netns_nf {
+       struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS];
+       struct nf_hook_entries __rcu *hooks_arp[NF_ARP_NUMHOOKS];
+       struct nf_hook_entries __rcu *hooks_bridge[NF_INET_NUMHOOKS];
++#if IS_ENABLED(CONFIG_DECNET)
+       struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS];
++#endif
+ #if IS_ENABLED(CONFIG_NF_DEFRAG_IPV4)
+       bool                    defrag_ipv4;
+ #endif
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -283,10 +283,12 @@ static struct nf_hook_entries __rcu **nf
+               if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv6) <= reg->hooknum))
+                       return NULL;
+               return net->nf.hooks_ipv6 + reg->hooknum;
++#if IS_ENABLED(CONFIG_DECNET)
+       case NFPROTO_DECNET:
+               if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_decnet) <= reg->hooknum))
+                       return NULL;
+               return net->nf.hooks_decnet + reg->hooknum;
++#endif
+       default:
+               WARN_ON_ONCE(1);
+               return NULL;
+@@ -573,7 +575,9 @@ static int __net_init netfilter_net_init
+       __netfilter_net_init(net->nf.hooks_ipv6, ARRAY_SIZE(net->nf.hooks_ipv6));
+       __netfilter_net_init(net->nf.hooks_arp, ARRAY_SIZE(net->nf.hooks_arp));
+       __netfilter_net_init(net->nf.hooks_bridge, ARRAY_SIZE(net->nf.hooks_bridge));
++#if IS_ENABLED(CONFIG_DECNET)
+       __netfilter_net_init(net->nf.hooks_decnet, ARRAY_SIZE(net->nf.hooks_decnet));
++#endif
+ #ifdef CONFIG_PROC_FS
+       net->nf.proc_netfilter = proc_net_mkdir(net, "netfilter",
diff --git a/target/linux/generic/backport-4.14/296-v4.16-netfilter-don-t-allocate-space-for-arp-bridge-hooks-.patch b/target/linux/generic/backport-4.14/296-v4.16-netfilter-don-t-allocate-space-for-arp-bridge-hooks-.patch
new file mode 100644 (file)
index 0000000..9444f6b
--- /dev/null
@@ -0,0 +1,165 @@
+From 2a95183a5e0375df756efb2ca37602d71e8455f9 Mon Sep 17 00:00:00 2001
+From: Florian Westphal <fw@strlen.de>
+Date: Thu, 7 Dec 2017 16:28:26 +0100
+Subject: [PATCH 08/11] netfilter: don't allocate space for arp/bridge hooks
+ unless needed
+
+no need to define hook points if the family isn't supported.
+Because we need these hooks for either nftables, arp/ebtables
+or the 'call-iptables' hack we have in the bridge layer add two
+new dependencies, NETFILTER_FAMILY_{ARP,BRIDGE}, and have the
+users select them.
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ include/linux/netfilter.h     | 4 ++++
+ include/net/netns/netfilter.h | 4 ++++
+ net/Kconfig                   | 1 +
+ net/bridge/netfilter/Kconfig  | 2 ++
+ net/ipv4/netfilter/Kconfig    | 2 ++
+ net/netfilter/Kconfig         | 6 ++++++
+ net/netfilter/core.c          | 8 ++++++++
+ net/netfilter/nf_queue.c      | 2 ++
+ 8 files changed, 29 insertions(+)
+
+--- a/include/linux/netfilter.h
++++ b/include/linux/netfilter.h
+@@ -214,10 +214,14 @@ static inline int nf_hook(u_int8_t pf, u
+               hook_head = rcu_dereference(net->nf.hooks_ipv6[hook]);
+               break;
+       case NFPROTO_ARP:
++#ifdef CONFIG_NETFILTER_FAMILY_ARP
+               hook_head = rcu_dereference(net->nf.hooks_arp[hook]);
++#endif
+               break;
+       case NFPROTO_BRIDGE:
++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
+               hook_head = rcu_dereference(net->nf.hooks_bridge[hook]);
++#endif
+               break;
+ #if IS_ENABLED(CONFIG_DECNET)
+       case NFPROTO_DECNET:
+--- a/include/net/netns/netfilter.h
++++ b/include/net/netns/netfilter.h
+@@ -19,8 +19,12 @@ struct netns_nf {
+ #endif
+       struct nf_hook_entries __rcu *hooks_ipv4[NF_INET_NUMHOOKS];
+       struct nf_hook_entries __rcu *hooks_ipv6[NF_INET_NUMHOOKS];
++#ifdef CONFIG_NETFILTER_FAMILY_ARP
+       struct nf_hook_entries __rcu *hooks_arp[NF_ARP_NUMHOOKS];
++#endif
++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
+       struct nf_hook_entries __rcu *hooks_bridge[NF_INET_NUMHOOKS];
++#endif
+ #if IS_ENABLED(CONFIG_DECNET)
+       struct nf_hook_entries __rcu *hooks_decnet[NF_DN_NUMHOOKS];
+ #endif
+--- a/net/Kconfig
++++ b/net/Kconfig
+@@ -182,6 +182,7 @@ config BRIDGE_NETFILTER
+       depends on BRIDGE
+       depends on NETFILTER && INET
+       depends on NETFILTER_ADVANCED
++      select NETFILTER_FAMILY_BRIDGE
+       default m
+       ---help---
+         Enabling this option will let arptables resp. iptables see bridged
+--- a/net/bridge/netfilter/Kconfig
++++ b/net/bridge/netfilter/Kconfig
+@@ -4,6 +4,7 @@
+ #
+ menuconfig NF_TABLES_BRIDGE
+       depends on BRIDGE && NETFILTER && NF_TABLES
++      select NETFILTER_FAMILY_BRIDGE
+       tristate "Ethernet Bridge nf_tables support"
+ if NF_TABLES_BRIDGE
+@@ -29,6 +30,7 @@ endif # NF_TABLES_BRIDGE
+ menuconfig BRIDGE_NF_EBTABLES
+       tristate "Ethernet Bridge tables (ebtables) support"
+       depends on BRIDGE && NETFILTER && NETFILTER_XTABLES
++      select NETFILTER_FAMILY_BRIDGE
+       help
+         ebtables is a general, extensible frame/packet identification
+         framework. Say 'Y' or 'M' here if you want to do Ethernet
+--- a/net/ipv4/netfilter/Kconfig
++++ b/net/ipv4/netfilter/Kconfig
+@@ -72,6 +72,7 @@ endif # NF_TABLES_IPV4
+ config NF_TABLES_ARP
+       tristate "ARP nf_tables support"
++      select NETFILTER_FAMILY_ARP
+       help
+         This option enables the ARP support for nf_tables.
+@@ -392,6 +393,7 @@ endif # IP_NF_IPTABLES
+ config IP_NF_ARPTABLES
+       tristate "ARP tables support"
+       select NETFILTER_XTABLES
++      select NETFILTER_FAMILY_ARP
+       depends on NETFILTER_ADVANCED
+       help
+         arptables is a general, extensible packet identification framework.
+--- a/net/netfilter/Kconfig
++++ b/net/netfilter/Kconfig
+@@ -12,6 +12,12 @@ config NETFILTER_INGRESS
+ config NETFILTER_NETLINK
+       tristate
++config NETFILTER_FAMILY_BRIDGE
++      bool
++
++config NETFILTER_FAMILY_ARP
++      bool
++
+ config NETFILTER_NETLINK_ACCT
+ tristate "Netfilter NFACCT over NFNETLINK interface"
+       depends on NETFILTER_ADVANCED
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -267,14 +267,18 @@ static struct nf_hook_entries __rcu **nf
+       switch (reg->pf) {
+       case NFPROTO_NETDEV:
+               break;
++#ifdef CONFIG_NETFILTER_FAMILY_ARP
+       case NFPROTO_ARP:
+               if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_arp) <= reg->hooknum))
+                       return NULL;
+               return net->nf.hooks_arp + reg->hooknum;
++#endif
++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
+       case NFPROTO_BRIDGE:
+               if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_bridge) <= reg->hooknum))
+                       return NULL;
+               return net->nf.hooks_bridge + reg->hooknum;
++#endif
+       case NFPROTO_IPV4:
+               if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= reg->hooknum))
+                       return NULL;
+@@ -573,8 +577,12 @@ static int __net_init netfilter_net_init
+ {
+       __netfilter_net_init(net->nf.hooks_ipv4, ARRAY_SIZE(net->nf.hooks_ipv4));
+       __netfilter_net_init(net->nf.hooks_ipv6, ARRAY_SIZE(net->nf.hooks_ipv6));
++#ifdef CONFIG_NETFILTER_FAMILY_ARP
+       __netfilter_net_init(net->nf.hooks_arp, ARRAY_SIZE(net->nf.hooks_arp));
++#endif
++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
+       __netfilter_net_init(net->nf.hooks_bridge, ARRAY_SIZE(net->nf.hooks_bridge));
++#endif
+ #if IS_ENABLED(CONFIG_DECNET)
+       __netfilter_net_init(net->nf.hooks_decnet, ARRAY_SIZE(net->nf.hooks_decnet));
+ #endif
+--- a/net/netfilter/nf_queue.c
++++ b/net/netfilter/nf_queue.c
+@@ -204,8 +204,10 @@ repeat:
+ static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum)
+ {
+       switch (pf) {
++#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
+       case NFPROTO_BRIDGE:
+               return rcu_dereference(net->nf.hooks_bridge[hooknum]);
++#endif
+       case NFPROTO_IPV4:
+               return rcu_dereference(net->nf.hooks_ipv4[hooknum]);
+       case NFPROTO_IPV6:
diff --git a/target/linux/generic/backport-4.14/297-v4.16-netfilter-core-pass-hook-number-family-and-device-to.patch b/target/linux/generic/backport-4.14/297-v4.16-netfilter-core-pass-hook-number-family-and-device-to.patch
new file mode 100644 (file)
index 0000000..7d450f9
--- /dev/null
@@ -0,0 +1,98 @@
+From 62a0fe46e2aaba1812d3cbcae014a41539f9eb09 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Sat, 9 Dec 2017 15:23:51 +0100
+Subject: [PATCH 09/11] netfilter: core: pass hook number, family and device to
+ nf_find_hook_list()
+
+Instead of passing struct nf_hook_ops, this is needed by follow up
+patches to handle NFPROTO_INET from the core.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ net/netfilter/core.c | 36 +++++++++++++++++++-----------------
+ 1 file changed, 19 insertions(+), 17 deletions(-)
+
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -262,36 +262,38 @@ out_assign:
+       return old;
+ }
+-static struct nf_hook_entries __rcu **nf_hook_entry_head(struct net *net, const struct nf_hook_ops *reg)
++static struct nf_hook_entries __rcu **
++nf_hook_entry_head(struct net *net, int pf, unsigned int hooknum,
++                 struct net_device *dev)
+ {
+-      switch (reg->pf) {
++      switch (pf) {
+       case NFPROTO_NETDEV:
+               break;
+ #ifdef CONFIG_NETFILTER_FAMILY_ARP
+       case NFPROTO_ARP:
+-              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_arp) <= reg->hooknum))
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_arp) <= hooknum))
+                       return NULL;
+-              return net->nf.hooks_arp + reg->hooknum;
++              return net->nf.hooks_arp + hooknum;
+ #endif
+ #ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
+       case NFPROTO_BRIDGE:
+-              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_bridge) <= reg->hooknum))
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_bridge) <= hooknum))
+                       return NULL;
+-              return net->nf.hooks_bridge + reg->hooknum;
++              return net->nf.hooks_bridge + hooknum;
+ #endif
+       case NFPROTO_IPV4:
+-              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= reg->hooknum))
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv4) <= hooknum))
+                       return NULL;
+-              return net->nf.hooks_ipv4 + reg->hooknum;
++              return net->nf.hooks_ipv4 + hooknum;
+       case NFPROTO_IPV6:
+-              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv6) <= reg->hooknum))
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_ipv6) <= hooknum))
+                       return NULL;
+-              return net->nf.hooks_ipv6 + reg->hooknum;
++              return net->nf.hooks_ipv6 + hooknum;
+ #if IS_ENABLED(CONFIG_DECNET)
+       case NFPROTO_DECNET:
+-              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_decnet) <= reg->hooknum))
++              if (WARN_ON_ONCE(ARRAY_SIZE(net->nf.hooks_decnet) <= hooknum))
+                       return NULL;
+-              return net->nf.hooks_decnet + reg->hooknum;
++              return net->nf.hooks_decnet + hooknum;
+ #endif
+       default:
+               WARN_ON_ONCE(1);
+@@ -299,9 +301,9 @@ static struct nf_hook_entries __rcu **nf
+       }
+ #ifdef CONFIG_NETFILTER_INGRESS
+-      if (reg->hooknum == NF_NETDEV_INGRESS) {
+-              if (reg->dev && dev_net(reg->dev) == net)
+-                      return &reg->dev->nf_hooks_ingress;
++      if (hooknum == NF_NETDEV_INGRESS) {
++              if (dev && dev_net(dev) == net)
++                      return &dev->nf_hooks_ingress;
+       }
+ #endif
+       WARN_ON_ONCE(1);
+@@ -323,7 +325,7 @@ int nf_register_net_hook(struct net *net
+                       return -EINVAL;
+       }
+-      pp = nf_hook_entry_head(net, reg);
++      pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev);
+       if (!pp)
+               return -EINVAL;
+@@ -397,7 +399,7 @@ void nf_unregister_net_hook(struct net *
+       struct nf_hook_entries __rcu **pp;
+       struct nf_hook_entries *p;
+-      pp = nf_hook_entry_head(net, reg);
++      pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev);
+       if (!pp)
+               return;
diff --git a/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-add-nf_remove_net_hook.patch b/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-add-nf_remove_net_hook.patch
new file mode 100644 (file)
index 0000000..8fea44b
--- /dev/null
@@ -0,0 +1,44 @@
+From 3d3cdc38e8c265a9f9d3825e823e772872bca1b8 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Sat, 9 Dec 2017 15:19:14 +0100
+Subject: [PATCH 01/11] netfilter: core: add nf_remove_net_hook
+
+Just a cleanup, __nf_unregister_net_hook() is used by a follow up patch
+when handling NFPROTO_INET as a real family from the core.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ net/netfilter/core.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -356,7 +356,7 @@ int nf_register_net_hook(struct net *net
+ EXPORT_SYMBOL(nf_register_net_hook);
+ /*
+- * __nf_unregister_net_hook - remove a hook from blob
++ * nf_remove_net_hook - remove a hook from blob
+  *
+  * @oldp: current address of hook blob
+  * @unreg: hook to unregister
+@@ -364,8 +364,8 @@ EXPORT_SYMBOL(nf_register_net_hook);
+  * This cannot fail, hook unregistration must always succeed.
+  * Therefore replace the to-be-removed hook with a dummy hook.
+  */
+-static void __nf_unregister_net_hook(struct nf_hook_entries *old,
+-                                   const struct nf_hook_ops *unreg)
++static void nf_remove_net_hook(struct nf_hook_entries *old,
++                             const struct nf_hook_ops *unreg)
+ {
+       struct nf_hook_ops **orig_ops;
+       bool found = false;
+@@ -411,7 +411,7 @@ void nf_unregister_net_hook(struct net *
+               return;
+       }
+-      __nf_unregister_net_hook(p, reg);
++      nf_remove_net_hook(p, reg);
+       p = __nf_hook_entries_try_shrink(pp);
+       mutex_unlock(&nf_hook_mutex);
diff --git a/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-pass-family-as-parameter-to-nf_remove.patch b/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-pass-family-as-parameter-to-nf_remove.patch
new file mode 100644 (file)
index 0000000..4c52635
--- /dev/null
@@ -0,0 +1,51 @@
+From 30259408118f550f5969fda19c0d67020d21eda8 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Sat, 9 Dec 2017 15:26:37 +0100
+Subject: [PATCH 10/11] netfilter: core: pass family as parameter to
+ nf_remove_net_hook()
+
+So static_key_slow_dec applies to the family behind NFPROTO_INET.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ net/netfilter/core.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -365,7 +365,7 @@ EXPORT_SYMBOL(nf_register_net_hook);
+  * Therefore replace the to-be-removed hook with a dummy hook.
+  */
+ static void nf_remove_net_hook(struct nf_hook_entries *old,
+-                             const struct nf_hook_ops *unreg)
++                             const struct nf_hook_ops *unreg, int pf)
+ {
+       struct nf_hook_ops **orig_ops;
+       bool found = false;
+@@ -383,14 +383,14 @@ static void nf_remove_net_hook(struct nf
+       if (found) {
+ #ifdef CONFIG_NETFILTER_INGRESS
+-              if (unreg->pf == NFPROTO_NETDEV && unreg->hooknum == NF_NETDEV_INGRESS)
++              if (pf == NFPROTO_NETDEV && unreg->hooknum == NF_NETDEV_INGRESS)
+                       net_dec_ingress_queue();
+ #endif
+ #ifdef HAVE_JUMP_LABEL
+-              static_key_slow_dec(&nf_hooks_needed[unreg->pf][unreg->hooknum]);
++              static_key_slow_dec(&nf_hooks_needed[pf][unreg->hooknum]);
+ #endif
+       } else {
+-              WARN_ONCE(1, "hook not found, pf %d num %d", unreg->pf, unreg->hooknum);
++              WARN_ONCE(1, "hook not found, pf %d num %d", pf, unreg->hooknum);
+       }
+ }
+@@ -411,7 +411,7 @@ void nf_unregister_net_hook(struct net *
+               return;
+       }
+-      nf_remove_net_hook(p, reg);
++      nf_remove_net_hook(p, reg, reg->pf);
+       p = __nf_hook_entries_try_shrink(pp);
+       mutex_unlock(&nf_hook_mutex);
diff --git a/target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch b/target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch
new file mode 100644 (file)
index 0000000..b112855
--- /dev/null
@@ -0,0 +1,129 @@
+From cb7ccd835ebb333669e400f99c650e4f3abf11c0 Mon Sep 17 00:00:00 2001
+From: Pablo Neira Ayuso <pablo@netfilter.org>
+Date: Sat, 9 Dec 2017 15:30:26 +0100
+Subject: [PATCH 11/11] netfilter: core: support for NFPROTO_INET hook
+ registration
+
+Expand NFPROTO_INET in two hook registrations, one for NFPROTO_IPV4 and
+another for NFPROTO_IPV6. Hence, we handle NFPROTO_INET from the core.
+
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+ net/netfilter/core.c | 53 +++++++++++++++++++++++++++++++++++++++++++---------
+ 1 file changed, 44 insertions(+), 9 deletions(-)
+
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -310,12 +310,13 @@ nf_hook_entry_head(struct net *net, int
+       return NULL;
+ }
+-int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
++static int __nf_register_net_hook(struct net *net, int pf,
++                                const struct nf_hook_ops *reg)
+ {
+       struct nf_hook_entries *p, *new_hooks;
+       struct nf_hook_entries __rcu **pp;
+-      if (reg->pf == NFPROTO_NETDEV) {
++      if (pf == NFPROTO_NETDEV) {
+ #ifndef CONFIG_NETFILTER_INGRESS
+               if (reg->hooknum == NF_NETDEV_INGRESS)
+                       return -EOPNOTSUPP;
+@@ -325,7 +326,7 @@ int nf_register_net_hook(struct net *net
+                       return -EINVAL;
+       }
+-      pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev);
++      pp = nf_hook_entry_head(net, pf, reg->hooknum, reg->dev);
+       if (!pp)
+               return -EINVAL;
+@@ -343,17 +344,16 @@ int nf_register_net_hook(struct net *net
+       hooks_validate(new_hooks);
+ #ifdef CONFIG_NETFILTER_INGRESS
+-      if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS)
++      if (pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS)
+               net_inc_ingress_queue();
+ #endif
+ #ifdef HAVE_JUMP_LABEL
+-      static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]);
++      static_key_slow_inc(&nf_hooks_needed[pf][reg->hooknum]);
+ #endif
+       BUG_ON(p == new_hooks);
+       nf_hook_entries_free(p);
+       return 0;
+ }
+-EXPORT_SYMBOL(nf_register_net_hook);
+ /*
+  * nf_remove_net_hook - remove a hook from blob
+@@ -394,12 +394,13 @@ static void nf_remove_net_hook(struct nf
+       }
+ }
+-void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
++void __nf_unregister_net_hook(struct net *net, int pf,
++                            const struct nf_hook_ops *reg)
+ {
+       struct nf_hook_entries __rcu **pp;
+       struct nf_hook_entries *p;
+-      pp = nf_hook_entry_head(net, reg->pf, reg->hooknum, reg->dev);
++      pp = nf_hook_entry_head(net, pf, reg->hooknum, reg->dev);
+       if (!pp)
+               return;
+@@ -411,7 +412,7 @@ void nf_unregister_net_hook(struct net *
+               return;
+       }
+-      nf_remove_net_hook(p, reg, reg->pf);
++      nf_remove_net_hook(p, reg, pf);
+       p = __nf_hook_entries_try_shrink(pp);
+       mutex_unlock(&nf_hook_mutex);
+@@ -421,8 +422,42 @@ void nf_unregister_net_hook(struct net *
+       nf_queue_nf_hook_drop(net);
+       nf_hook_entries_free(p);
+ }
++
++void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
++{
++      if (reg->pf == NFPROTO_INET) {
++              __nf_unregister_net_hook(net, NFPROTO_IPV4, reg);
++              __nf_unregister_net_hook(net, NFPROTO_IPV6, reg);
++      } else {
++              __nf_unregister_net_hook(net, reg->pf, reg);
++      }
++}
+ EXPORT_SYMBOL(nf_unregister_net_hook);
++int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
++{
++      int err;
++
++      if (reg->pf == NFPROTO_INET) {
++              err = __nf_register_net_hook(net, NFPROTO_IPV4, reg);
++              if (err < 0)
++                      return err;
++
++              err = __nf_register_net_hook(net, NFPROTO_IPV6, reg);
++              if (err < 0) {
++                      __nf_unregister_net_hook(net, NFPROTO_IPV4, reg);
++                      return err;
++              }
++      } else {
++              err = __nf_register_net_hook(net, reg->pf, reg);
++              if (err < 0)
++                      return err;
++      }
++
++      return 0;
++}
++EXPORT_SYMBOL(nf_register_net_hook);
++
+ int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg,
+                         unsigned int n)
+ {
index 5ae8f8f1ed6566be95b8ac829cc9891150837005..05888a070efe2bfa4481762ed087feb74399d1c2 100644 (file)
@@ -120,7 +120,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
                .priority       = NF_IP6_PRI_NAT_SRC,
 --- a/net/netfilter/core.c
 +++ b/net/netfilter/core.c
-@@ -135,6 +135,12 @@ nf_hook_entries_grow(const struct nf_hoo
+@@ -160,6 +160,12 @@ nf_hook_entries_grow(const struct nf_hoo
                        ++i;
                        continue;
                }
index b122dd55d0f1acbbcc1d3f05ca85419dbd535e8d..458ddd41723e3eb6b71522cf94c8d947c093f9ed 100644 (file)
@@ -18,7 +18,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/include/linux/netfilter.h
 +++ b/include/linux/netfilter.h
-@@ -274,8 +274,6 @@ struct nf_queue_entry;
+@@ -311,8 +311,6 @@ struct nf_queue_entry;
  
  struct nf_afinfo {
        unsigned short  family;
@@ -27,7 +27,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        __sum16         (*checksum_partial)(struct sk_buff *skb,
                                            unsigned int hook,
                                            unsigned int dataoff,
-@@ -296,20 +294,9 @@ static inline const struct nf_afinfo *nf
+@@ -333,20 +331,9 @@ static inline const struct nf_afinfo *nf
        return rcu_dereference(nf_afinfo[family]);
  }
  
index 7c22312c67e3fab587523b48689ccea475dbc7f1..19a0aacb45be55b1b24b125abb09fc2db8a87439 100644 (file)
@@ -18,7 +18,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/include/linux/netfilter.h
 +++ b/include/linux/netfilter.h
-@@ -274,11 +274,6 @@ struct nf_queue_entry;
+@@ -311,11 +311,6 @@ struct nf_queue_entry;
  
  struct nf_afinfo {
        unsigned short  family;
@@ -30,7 +30,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        int             (*route)(struct net *net, struct dst_entry **dst,
                                 struct flowi *fl, bool strict);
        void            (*saveroute)(const struct sk_buff *skb,
-@@ -298,22 +293,9 @@ __sum16 nf_checksum(struct sk_buff *skb,
+@@ -335,22 +330,9 @@ __sum16 nf_checksum(struct sk_buff *skb,
                    unsigned int dataoff, u_int8_t protocol,
                    unsigned short family);
  
index e52f81164e0bc06ba5731cbacfd3d711a5cc784c..75de3c84fef7f6cae7b6e2514521a4d536791de1 100644 (file)
@@ -11,7 +11,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/include/linux/netfilter.h
 +++ b/include/linux/netfilter.h
-@@ -276,8 +276,6 @@ struct nf_afinfo {
+@@ -313,8 +313,6 @@ struct nf_afinfo {
        unsigned short  family;
        int             (*route)(struct net *net, struct dst_entry **dst,
                                 struct flowi *fl, bool strict);
@@ -176,7 +176,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  #include <linux/netfilter_bridge.h>
  #include <linux/seq_file.h>
  #include <linux/rcupdate.h>
-@@ -111,6 +113,35 @@ unsigned int nf_queue_nf_hook_drop(struc
+@@ -108,6 +110,35 @@ void nf_queue_nf_hook_drop(struct net *n
  }
  EXPORT_SYMBOL_GPL(nf_queue_nf_hook_drop);
  
@@ -212,7 +212,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state,
                      const struct nf_hook_entries *entries,
                      unsigned int index, unsigned int queuenum)
-@@ -147,7 +178,16 @@ static int __nf_queue(struct sk_buff *sk
+@@ -144,7 +175,16 @@ static int __nf_queue(struct sk_buff *sk
  
        nf_queue_entry_get_refs(entry);
        skb_dst_force(skb);
index fe60a7903669908e218e0ae3dfef023023e1fa3d..b98aac0fff6533fd7a0b35ae32458d8dac014b5f 100644 (file)
@@ -17,7 +17,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/include/linux/netfilter.h
 +++ b/include/linux/netfilter.h
-@@ -274,8 +274,6 @@ struct nf_queue_entry;
+@@ -311,8 +311,6 @@ struct nf_queue_entry;
  
  struct nf_afinfo {
        unsigned short  family;
@@ -26,7 +26,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        int             (*reroute)(struct net *net, struct sk_buff *skb,
                                   const struct nf_queue_entry *entry);
        int             route_key_size;
-@@ -294,6 +292,8 @@ __sum16 nf_checksum(struct sk_buff *skb,
+@@ -331,6 +329,8 @@ __sum16 nf_checksum(struct sk_buff *skb,
  __sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
                            unsigned int dataoff, unsigned int len,
                            u_int8_t protocol, unsigned short family);
index 2ffb39d9aff255fe838d11c1778a545095acca05..5dbd1a4cea5bc4501d304e7a72d56d60fecd8249 100644 (file)
@@ -17,7 +17,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/include/linux/netfilter.h
 +++ b/include/linux/netfilter.h
-@@ -274,8 +274,6 @@ struct nf_queue_entry;
+@@ -311,8 +311,6 @@ struct nf_queue_entry;
  
  struct nf_afinfo {
        unsigned short  family;
@@ -26,7 +26,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        int             route_key_size;
  };
  
-@@ -294,6 +292,7 @@ __sum16 nf_checksum_partial(struct sk_bu
+@@ -331,6 +329,7 @@ __sum16 nf_checksum_partial(struct sk_bu
                            u_int8_t protocol, unsigned short family);
  int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl,
             bool strict, unsigned short family);
@@ -171,7 +171,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  
 --- a/net/netfilter/nf_queue.c
 +++ b/net/netfilter/nf_queue.c
-@@ -250,7 +250,6 @@ void nf_reinject(struct nf_queue_entry *
+@@ -266,7 +266,6 @@ void nf_reinject(struct nf_queue_entry *
        const struct nf_hook_entry *hook_entry;
        const struct nf_hook_entries *hooks;
        struct sk_buff *skb = entry->skb;
@@ -179,7 +179,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        const struct net *net;
        unsigned int i;
        int err;
-@@ -277,8 +276,7 @@ void nf_reinject(struct nf_queue_entry *
+@@ -293,8 +292,7 @@ void nf_reinject(struct nf_queue_entry *
                verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state);
  
        if (verdict == NF_ACCEPT) {
index 1b571252b5e6bdc301da491fc81f3ea70ebd55cb..21381b7e6b5eec012299e049427e42c870df96ae 100644 (file)
@@ -9,7 +9,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/include/linux/netfilter.h
 +++ b/include/linux/netfilter.h
-@@ -274,7 +274,6 @@ struct nf_queue_entry;
+@@ -311,7 +311,6 @@ struct nf_queue_entry;
  
  struct nf_afinfo {
        unsigned short  family;
@@ -48,7 +48,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  #include <net/protocol.h>
  #include <net/netfilter/nf_queue.h>
  #include <net/dst.h>
-@@ -148,9 +150,9 @@ static int __nf_queue(struct sk_buff *sk
+@@ -145,9 +147,9 @@ static int __nf_queue(struct sk_buff *sk
  {
        int status = -ENOENT;
        struct nf_queue_entry *entry = NULL;
@@ -59,7 +59,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  
        /* QUEUE == DROP if no one is waiting, to be safe. */
        qh = rcu_dereference(net->nf.queue_handler);
-@@ -159,11 +161,19 @@ static int __nf_queue(struct sk_buff *sk
+@@ -156,11 +158,19 @@ static int __nf_queue(struct sk_buff *sk
                goto err;
        }
  
@@ -83,7 +83,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        if (!entry) {
                status = -ENOMEM;
                goto err;
-@@ -173,7 +183,7 @@ static int __nf_queue(struct sk_buff *sk
+@@ -170,7 +180,7 @@ static int __nf_queue(struct sk_buff *sk
                .skb    = skb,
                .state  = *state,
                .hook_index = index,
index 6d19743dfe64edd10b987ae8383ac4bd2234a0f8..0ca58f99885a3df27378a29229bc30d6abb94c12 100644 (file)
@@ -12,7 +12,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/include/linux/netfilter.h
 +++ b/include/linux/netfilter.h
-@@ -272,16 +272,6 @@ int skb_make_writable(struct sk_buff *sk
+@@ -309,16 +309,6 @@ int skb_make_writable(struct sk_buff *sk
  struct flowi;
  struct nf_queue_entry;
  
@@ -29,7 +29,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  __sum16 nf_checksum(struct sk_buff *skb, unsigned int hook,
                    unsigned int dataoff, u_int8_t protocol,
                    unsigned short family);
-@@ -293,9 +283,6 @@ int nf_route(struct net *net, struct dst
+@@ -330,9 +320,6 @@ int nf_route(struct net *net, struct dst
             bool strict, unsigned short family);
  int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry);
  
index d811ef006c4e6c189af8fe5efe0c8def14ae04e6..16de9571a868ac86d293492ba757ae96db3915a7 100644 (file)
@@ -126,7 +126,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  #endif /* _FLOW_OFFLOAD_H */
 --- a/net/netfilter/Kconfig
 +++ b/net/netfilter/Kconfig
-@@ -661,6 +661,13 @@ endif # NF_TABLES_NETDEV
+@@ -667,6 +667,13 @@ endif # NF_TABLES_NETDEV
  
  endif # NF_TABLES
  
index 6f36171605b21836a9457ca54c864194d6e1e985..50d9039c12382e8f04b72f9d006d0139a79d7578 100644 (file)
@@ -19,7 +19,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/net/ipv4/netfilter/Kconfig
 +++ b/net/ipv4/netfilter/Kconfig
-@@ -77,6 +77,14 @@ config NF_TABLES_ARP
+@@ -78,6 +78,14 @@ config NF_TABLES_ARP
  
  endif # NF_TABLES
  
index 9fcb1be982c8217c06bbfde1f0cadb872ac1e99d..04948d88ab1df1cf7554306b769ac919466c2f67 100644 (file)
@@ -63,7 +63,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        .family         = NFPROTO_IPV6,
 --- a/net/netfilter/Kconfig
 +++ b/net/netfilter/Kconfig
-@@ -661,6 +661,14 @@ endif # NF_TABLES_NETDEV
+@@ -667,6 +667,14 @@ endif # NF_TABLES_NETDEV
  
  endif # NF_TABLES
  
index 86f1f8a098cfd3558e7381efb0b0ca07c495691c..0decc341057b673fe1df26146356c6215c36e69f 100644 (file)
@@ -39,7 +39,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        NFT_LIMIT_PKT_BYTES
 --- a/net/netfilter/Kconfig
 +++ b/net/netfilter/Kconfig
-@@ -509,6 +509,13 @@ config NFT_CT
+@@ -515,6 +515,13 @@ config NFT_CT
          This option adds the "ct" expression that you can use to match
          connection tracking information such as the flow state.
  
index 7174723fc97386361f0cb59c8241db83cfd0a834..0d5cd3bb4fdbd0a9e905e580f0d85a71212a7537 100644 (file)
@@ -59,7 +59,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/net/ipv4/netfilter/Kconfig
 +++ b/net/ipv4/netfilter/Kconfig
-@@ -78,8 +78,9 @@ config NF_TABLES_ARP
+@@ -79,8 +79,9 @@ config NF_TABLES_ARP
  endif # NF_TABLES
  
  config NF_FLOW_TABLE_IPV4
@@ -85,7 +85,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  
 --- a/net/netfilter/Kconfig
 +++ b/net/netfilter/Kconfig
-@@ -669,8 +669,9 @@ endif # NF_TABLES_NETDEV
+@@ -675,8 +675,9 @@ endif # NF_TABLES_NETDEV
  endif # NF_TABLES
  
  config NF_FLOW_TABLE_INET
@@ -96,7 +96,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        help
            This option adds the flow table mixed IPv4/IPv6 support.
  
-@@ -678,6 +679,7 @@ config NF_FLOW_TABLE_INET
+@@ -684,6 +685,7 @@ config NF_FLOW_TABLE_INET
  
  config NF_FLOW_TABLE
        tristate "Netfilter flow table module"
index b1b876cf1d6ddf28e754db81e21136bf4dd63a44..5938a9ba5a8e9bb851d8db678971632a1b3ff6fc 100644 (file)
@@ -62,7 +62,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  static struct pernet_operations nfnl_log_net_ops = {
 --- a/net/netfilter/nfnetlink_queue.c
 +++ b/net/netfilter/nfnetlink_queue.c
-@@ -1515,10 +1515,15 @@ static int __net_init nfnl_queue_net_ini
+@@ -1510,10 +1510,15 @@ static int __net_init nfnl_queue_net_ini
  
  static void __net_exit nfnl_queue_net_exit(struct net *net)
  {
index 162086e340ddd347567fb6813d716bdd2c034639..bb8c2d3e5a9673804dda20f27da9901877fe7001 100644 (file)
@@ -25,7 +25,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
 
 --- a/net/ipv4/netfilter/Kconfig
 +++ b/net/ipv4/netfilter/Kconfig
-@@ -79,8 +79,7 @@ endif # NF_TABLES
+@@ -80,8 +80,7 @@ endif # NF_TABLES
  
  config NF_FLOW_TABLE_IPV4
        tristate "Netfilter flow table IPv4 module"
@@ -49,7 +49,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  
 --- a/net/netfilter/Kconfig
 +++ b/net/netfilter/Kconfig
-@@ -670,8 +670,8 @@ endif # NF_TABLES
+@@ -676,8 +676,8 @@ endif # NF_TABLES
  
  config NF_FLOW_TABLE_INET
        tristate "Netfilter flow table mixed IPv4/IPv6 module"
@@ -60,7 +60,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
        help
            This option adds the flow table mixed IPv4/IPv6 support.
  
-@@ -679,7 +679,9 @@ config NF_FLOW_TABLE_INET
+@@ -685,7 +685,9 @@ config NF_FLOW_TABLE_INET
  
  config NF_FLOW_TABLE
        tristate "Netfilter flow table module"
index 7d4bdc6d8dc02a1ef0f955473f0f5218a6cc123a..b5fe25a1d646015c243ad559376f090b69a00f53 100644 (file)
@@ -11,7 +11,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/net/netfilter/Kconfig
 +++ b/net/netfilter/Kconfig
-@@ -670,8 +670,7 @@ endif # NF_TABLES
+@@ -676,8 +676,7 @@ endif # NF_TABLES
  
  config NF_FLOW_TABLE_INET
        tristate "Netfilter flow table mixed IPv4/IPv6 module"
index 264d7661cf6637e64dc415fd2fe8f703fa94b57b..a8fe5d41758c0fdc0e16f2d573a1f1332ec487d0 100644 (file)
@@ -9,7 +9,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/net/netfilter/Kconfig
 +++ b/net/netfilter/Kconfig
-@@ -223,7 +223,6 @@ config NF_CONNTRACK_FTP
+@@ -229,7 +229,6 @@ config NF_CONNTRACK_FTP
  
  config NF_CONNTRACK_H323
        tristate "H.323 protocol support"
@@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        depends on NETFILTER_ADVANCED
        help
          H.323 is a VoIP signalling protocol from ITU-T. As one of the most
-@@ -1046,7 +1045,6 @@ config NETFILTER_XT_TARGET_SECMARK
+@@ -1052,7 +1051,6 @@ config NETFILTER_XT_TARGET_SECMARK
  
  config NETFILTER_XT_TARGET_TCPMSS
        tristate '"TCPMSS" target support'
index e1e48ce5f342b61890e15bd3ebfb905a05a55b92..5bf5c01ad3acd5e972ab1c3fa4ab67090ac5f26c 100644 (file)
@@ -122,8 +122,8 @@ Signed-off-by: John Crispin <john@phrozen.org>
 -      tristate
 +      tristate "Netfilter NFNETLINK interface"
  
- config NETFILTER_NETLINK_ACCT
- tristate "Netfilter NFACCT over NFNETLINK interface"
+ config NETFILTER_FAMILY_BRIDGE
+       bool
 --- a/net/wireless/Kconfig
 +++ b/net/wireless/Kconfig
 @@ -1,5 +1,5 @@
index 308fe0974d20e8b1dc00fd7e2b939831d22c046a..2044bfaeb8a6509eba456bf01d4357fe129686cc 100644 (file)
@@ -8,7 +8,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
 
 --- a/net/ipv4/netfilter/Kconfig
 +++ b/net/ipv4/netfilter/Kconfig
-@@ -75,8 +75,6 @@ config NF_TABLES_ARP
+@@ -76,8 +76,6 @@ config NF_TABLES_ARP
        help
          This option enables the ARP support for nf_tables.
  
@@ -17,7 +17,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  config NF_FLOW_TABLE_IPV4
        tristate "Netfilter flow table IPv4 module"
        depends on NF_FLOW_TABLE
-@@ -85,6 +83,8 @@ config NF_FLOW_TABLE_IPV4
+@@ -86,6 +84,8 @@ config NF_FLOW_TABLE_IPV4
  
          To compile it as a module, choose M here.
  
@@ -47,7 +47,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        depends on !NF_CONNTRACK || NF_CONNTRACK
 --- a/net/netfilter/Kconfig
 +++ b/net/netfilter/Kconfig
-@@ -665,8 +665,6 @@ config NFT_FIB_NETDEV
+@@ -671,8 +671,6 @@ config NFT_FIB_NETDEV
  
  endif # NF_TABLES_NETDEV
  
@@ -56,7 +56,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
  config NF_FLOW_TABLE_INET
        tristate "Netfilter flow table mixed IPv4/IPv6 module"
        depends on NF_FLOW_TABLE
-@@ -675,11 +673,12 @@ config NF_FLOW_TABLE_INET
+@@ -681,11 +679,12 @@ config NF_FLOW_TABLE_INET
  
          To compile it as a module, choose M here.
  
@@ -70,7 +70,7 @@ Signed-off-by: Felix Fietkau <nbd@nbd.name>
        help
          This option adds the flow table core infrastructure.
  
-@@ -968,6 +967,15 @@ config NETFILTER_XT_TARGET_NOTRACK
+@@ -974,6 +973,15 @@ config NETFILTER_XT_TARGET_NOTRACK
        depends on NETFILTER_ADVANCED
        select NETFILTER_XT_TARGET_CT
  
index e4a9ba7d961847843245ad52c5ad50ac00dba5cf..ad78b684a0cc46d4aaffc796b132d6ca206a4dd7 100644 (file)
@@ -128,7 +128,7 @@ Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
  #define NFTA_FLOWTABLE_MAX    (__NFTA_FLOWTABLE_MAX - 1)
 --- a/net/netfilter/Kconfig
 +++ b/net/netfilter/Kconfig
-@@ -686,6 +686,15 @@ config NF_FLOW_TABLE
+@@ -692,6 +692,15 @@ config NF_FLOW_TABLE
  
          To compile it as a module, choose M here.