aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-4.14
diff options
context:
space:
mode:
authorBrett Mastbergen <bmastbergen@untangle.com>2018-09-12 15:04:55 -0400
committerJo-Philipp Wich <jo@mein.io>2018-12-18 11:28:13 +0100
commit69d6da1de601eb94285752b0bea44ad4f2381dfe (patch)
tree62e535d0fd3456c13508ed4a7e7ce09deb3675f7 /target/linux/generic/backport-4.14
parentbbc0c4d9cbfe4f93b759bbf4bb845ad4b72588f1 (diff)
downloadupstream-69d6da1de601eb94285752b0bea44ad4f2381dfe.tar.gz
upstream-69d6da1de601eb94285752b0bea44ad4f2381dfe.tar.bz2
upstream-69d6da1de601eb94285752b0bea44ad4f2381dfe.zip
kernel: generic: Fix nftables inet table breakage
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>
Diffstat (limited to 'target/linux/generic/backport-4.14')
-rw-r--r--target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch91
-rw-r--r--target/linux/generic/backport-4.14/291-v4.16-netfilter-core-remove-synchronize_net-call-if-nfqueu.patch116
-rw-r--r--target/linux/generic/backport-4.14/292-v4.16-netfilter-core-free-hooks-with-call_rcu.patch132
-rw-r--r--target/linux/generic/backport-4.14/293-v4.16-netfilter-reduce-size-of-hook-entry-point-locations.patch200
-rw-r--r--target/linux/generic/backport-4.14/294-v4.16-netfilter-reduce-hook-array-sizes-to-what-is-needed.patch95
-rw-r--r--target/linux/generic/backport-4.14/295-v4.16-netfilter-don-t-allocate-space-for-decnet-hooks-unle.patch67
-rw-r--r--target/linux/generic/backport-4.14/296-v4.16-netfilter-don-t-allocate-space-for-arp-bridge-hooks-.patch165
-rw-r--r--target/linux/generic/backport-4.14/297-v4.16-netfilter-core-pass-hook-number-family-and-device-to.patch98
-rw-r--r--target/linux/generic/backport-4.14/298-v4.16-netfilter-core-add-nf_remove_net_hook.patch44
-rw-r--r--target/linux/generic/backport-4.14/298-v4.16-netfilter-core-pass-family-as-parameter-to-nf_remove.patch51
-rw-r--r--target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch129
-rw-r--r--target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch2
-rw-r--r--target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch4
-rw-r--r--target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch4
-rw-r--r--target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch6
-rw-r--r--target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch4
-rw-r--r--target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch8
-rw-r--r--target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch8
-rw-r--r--target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch4
-rw-r--r--target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch2
-rw-r--r--target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch2
-rw-r--r--target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch2
-rw-r--r--target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch2
-rw-r--r--target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch6
-rw-r--r--target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch2
-rw-r--r--target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch6
-rw-r--r--target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch2
27 files changed, 1220 insertions, 32 deletions
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
index 0000000000..35800c4acf
--- /dev/null
+++ b/target/linux/generic/backport-4.14/290-v4.16-netfilter-core-make-nf_unregister_net_hooks-simple-w.patch
@@ -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
index 0000000000..0ac5783624
--- /dev/null
+++ b/target/linux/generic/backport-4.14/291-v4.16-netfilter-core-remove-synchronize_net-call-if-nfqueu.patch
@@ -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
index 0000000000..5eca73552b
--- /dev/null
+++ b/target/linux/generic/backport-4.14/292-v4.16-netfilter-core-free-hooks-with-call_rcu.patch
@@ -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
index 0000000000..fcf54e9858
--- /dev/null
+++ b/target/linux/generic/backport-4.14/293-v4.16-netfilter-reduce-size-of-hook-entry-point-locations.patch
@@ -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
index 0000000000..d9009b8e1f
--- /dev/null
+++ b/target/linux/generic/backport-4.14/294-v4.16-netfilter-reduce-hook-array-sizes-to-what-is-needed.patch
@@ -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
index 0000000000..26a93c40ae
--- /dev/null
+++ b/target/linux/generic/backport-4.14/295-v4.16-netfilter-don-t-allocate-space-for-decnet-hooks-unle.patch
@@ -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
index 0000000000..9444f6bb48
--- /dev/null
+++ b/target/linux/generic/backport-4.14/296-v4.16-netfilter-don-t-allocate-space-for-arp-bridge-hooks-.patch
@@ -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
index 0000000000..7d450f95f0
--- /dev/null
+++ b/target/linux/generic/backport-4.14/297-v4.16-netfilter-core-pass-hook-number-family-and-device-to.patch
@@ -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
index 0000000000..8fea44b359
--- /dev/null
+++ b/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-add-nf_remove_net_hook.patch
@@ -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
index 0000000000..4c52635c13
--- /dev/null
+++ b/target/linux/generic/backport-4.14/298-v4.16-netfilter-core-pass-family-as-parameter-to-nf_remove.patch
@@ -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
index 0000000000..b112855132
--- /dev/null
+++ b/target/linux/generic/backport-4.14/299-v4.16-netfilter-core-support-for-NFPROTO_INET-hook-registr.patch
@@ -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)
+ {
diff --git a/target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch b/target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch
index 5ae8f8f1ed..05888a070e 100644
--- a/target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch
+++ b/target/linux/generic/backport-4.14/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch
@@ -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;
}
diff --git a/target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch b/target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch
index b122dd55d0..458ddd4172 100644
--- a/target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch
+++ b/target/linux/generic/backport-4.14/304-v4.16-netfilter-move-checksum-indirection-to-struct-nf_ipv.patch
@@ -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]);
}
diff --git a/target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch b/target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch
index 7c22312c67..19a0aacb45 100644
--- a/target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch
+++ b/target/linux/generic/backport-4.14/305-v4.16-netfilter-move-checksum_partial-indirection-to-struc.patch
@@ -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);
diff --git a/target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch b/target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch
index e52f81164e..75de3c84fe 100644
--- a/target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch
+++ b/target/linux/generic/backport-4.14/306-v4.16-netfilter-remove-saveroute-indirection-in-struct-nf_.patch
@@ -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);
diff --git a/target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch b/target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch
index fe60a79036..b98aac0fff 100644
--- a/target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch
+++ b/target/linux/generic/backport-4.14/307-v4.16-netfilter-move-route-indirection-to-struct-nf_ipv6_o.patch
@@ -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);
diff --git a/target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch b/target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch
index 2ffb39d9af..5dbd1a4cea 100644
--- a/target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch
+++ b/target/linux/generic/backport-4.14/308-v4.16-netfilter-move-reroute-indirection-to-struct-nf_ipv6.patch
@@ -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) {
diff --git a/target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch b/target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch
index 1b571252b5..21381b7e6b 100644
--- a/target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch
+++ b/target/linux/generic/backport-4.14/309-v4.16-netfilter-remove-route_key_size-field-in-struct-nf_a.patch
@@ -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,
diff --git a/target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch b/target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch
index 6d19743dfe..0ca58f9988 100644
--- a/target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch
+++ b/target/linux/generic/backport-4.14/310-v4.16-netfilter-remove-struct-nf_afinfo-and-its-helper-fun.patch
@@ -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);
diff --git a/target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch b/target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch
index d811ef006c..16de9571a8 100644
--- a/target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch
+++ b/target/linux/generic/backport-4.14/322-v4.16-netfilter-add-generic-flow-table-infrastructure.patch
@@ -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
diff --git a/target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch b/target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch
index 6f36171605..50d9039c12 100644
--- a/target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch
+++ b/target/linux/generic/backport-4.14/323-v4.16-netfilter-flow-table-support-for-IPv4.patch
@@ -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
diff --git a/target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch b/target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch
index 9fcb1be982..04948d88ab 100644
--- a/target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch
+++ b/target/linux/generic/backport-4.14/325-v4.16-netfilter-flow-table-support-for-the-mixed-IPv4-IPv6.patch
@@ -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
diff --git a/target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch b/target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch
index 86f1f8a098..0decc34105 100644
--- a/target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch
+++ b/target/linux/generic/backport-4.14/326-v4.16-netfilter-nf_tables-flow-offload-expression.patch
@@ -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.
diff --git a/target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch b/target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch
index 7174723fc9..0d5cd3bb4f 100644
--- a/target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch
+++ b/target/linux/generic/backport-4.14/329-v4.16-netfilter-improve-flow-table-Kconfig-dependencies.patch
@@ -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"
diff --git a/target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch b/target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch
index b1b876cf1d..5938a9ba5a 100644
--- a/target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch
+++ b/target/linux/generic/backport-4.14/336-v4.15-netfilter-exit_net-cleanup-check-added.patch
@@ -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)
{
diff --git a/target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch b/target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch
index 162086e340..bb8c2d3e5a 100644
--- a/target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch
+++ b/target/linux/generic/backport-4.14/346-v4.16-netfilter-flowtable-infrastructure-depends-on-NETFIL.patch
@@ -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"
diff --git a/target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch b/target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch
index 7d4bdc6d8d..b5fe25a1d6 100644
--- a/target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch
+++ b/target/linux/generic/backport-4.14/356-v4.18-netfilter-nf_flow_table-relax-mixed-ipv4-ipv6-flowta.patch
@@ -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"