aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic/backport-4.19/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch
diff options
context:
space:
mode:
authorHauke Mehrtens <hauke@hauke-m.de>2018-11-01 17:57:55 +0100
committerHauke Mehrtens <hauke@hauke-m.de>2018-12-15 12:50:06 +0100
commit52a82ce3dd901a1536c7d7d9d963e9c2d761c816 (patch)
tree79020fb59420fcea7bdc4b12272f7251e101fe64 /target/linux/generic/backport-4.19/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch
parenta272af75cd8c67d265400f96c1e6bb172315c23c (diff)
downloadupstream-52a82ce3dd901a1536c7d7d9d963e9c2d761c816.tar.gz
upstream-52a82ce3dd901a1536c7d7d9d963e9c2d761c816.tar.bz2
upstream-52a82ce3dd901a1536c7d7d9d963e9c2d761c816.zip
kernel: Copy patches from kernel 4.14 to 4.19
This just copies the files from the kernel 4.14 specific folders into the kernel 4.19 specific folder, no changes are done to the files in this commit. Signed-off-by: Hauke Mehrtens <hauke@hauke-m.de>
Diffstat (limited to 'target/linux/generic/backport-4.19/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch')
-rw-r--r--target/linux/generic/backport-4.19/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch146
1 files changed, 146 insertions, 0 deletions
diff --git a/target/linux/generic/backport-4.19/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch b/target/linux/generic/backport-4.19/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch
new file mode 100644
index 0000000000..05888a070e
--- /dev/null
+++ b/target/linux/generic/backport-4.19/301-v4.16-netfilter-core-only-allow-one-nat-hook-per-hook-poin.patch
@@ -0,0 +1,146 @@
+From: Florian Westphal <fw@strlen.de>
+Date: Fri, 8 Dec 2017 17:01:54 +0100
+Subject: [PATCH] netfilter: core: only allow one nat hook per hook point
+
+The netfilter NAT core cannot deal with more than one NAT hook per hook
+location (prerouting, input ...), because the NAT hooks install a NAT null
+binding in case the iptables nat table (iptable_nat hooks) or the
+corresponding nftables chain (nft nat hooks) doesn't specify a nat
+transformation.
+
+Null bindings are needed to detect port collsisions between NAT-ed and
+non-NAT-ed connections.
+
+This causes nftables NAT rules to not work when iptable_nat module is
+loaded, and vice versa because nat binding has already been attached
+when the second nat hook is consulted.
+
+The netfilter core is not really the correct location to handle this
+(hooks are just hooks, the core has no notion of what kinds of side
+ effects a hook implements), but its the only place where we can check
+for conflicts between both iptables hooks and nftables hooks without
+adding dependencies.
+
+So add nat annotation to hook_ops to describe those hooks that will
+add NAT bindings and then make core reject if such a hook already exists.
+The annotation fills a padding hole, in case further restrictions appar
+we might change this to a 'u8 type' instead of bool.
+
+iptables error if nft nat hook active:
+iptables -t nat -A POSTROUTING -j MASQUERADE
+iptables v1.4.21: can't initialize iptables table `nat': File exists
+Perhaps iptables or your kernel needs to be upgraded.
+
+nftables error if iptables nat table present:
+nft -f /etc/nftables/ipv4-nat
+/usr/etc/nftables/ipv4-nat:3:1-2: Error: Could not process rule: File exists
+table nat {
+^^
+
+Signed-off-by: Florian Westphal <fw@strlen.de>
+Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
+---
+
+--- a/include/linux/netfilter.h
++++ b/include/linux/netfilter.h
+@@ -67,6 +67,7 @@ struct nf_hook_ops {
+ struct net_device *dev;
+ void *priv;
+ u_int8_t pf;
++ bool nat_hook;
+ unsigned int hooknum;
+ /* Hooks are ordered in ascending priority. */
+ int priority;
+--- a/net/ipv4/netfilter/iptable_nat.c
++++ b/net/ipv4/netfilter/iptable_nat.c
+@@ -72,6 +72,7 @@ static const struct nf_hook_ops nf_nat_i
+ {
+ .hook = iptable_nat_ipv4_in,
+ .pf = NFPROTO_IPV4,
++ .nat_hook = true,
+ .hooknum = NF_INET_PRE_ROUTING,
+ .priority = NF_IP_PRI_NAT_DST,
+ },
+@@ -79,6 +80,7 @@ static const struct nf_hook_ops nf_nat_i
+ {
+ .hook = iptable_nat_ipv4_out,
+ .pf = NFPROTO_IPV4,
++ .nat_hook = true,
+ .hooknum = NF_INET_POST_ROUTING,
+ .priority = NF_IP_PRI_NAT_SRC,
+ },
+@@ -86,6 +88,7 @@ static const struct nf_hook_ops nf_nat_i
+ {
+ .hook = iptable_nat_ipv4_local_fn,
+ .pf = NFPROTO_IPV4,
++ .nat_hook = true,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = NF_IP_PRI_NAT_DST,
+ },
+@@ -93,6 +96,7 @@ static const struct nf_hook_ops nf_nat_i
+ {
+ .hook = iptable_nat_ipv4_fn,
+ .pf = NFPROTO_IPV4,
++ .nat_hook = true,
+ .hooknum = NF_INET_LOCAL_IN,
+ .priority = NF_IP_PRI_NAT_SRC,
+ },
+--- a/net/ipv6/netfilter/ip6table_nat.c
++++ b/net/ipv6/netfilter/ip6table_nat.c
+@@ -74,6 +74,7 @@ static const struct nf_hook_ops nf_nat_i
+ {
+ .hook = ip6table_nat_in,
+ .pf = NFPROTO_IPV6,
++ .nat_hook = true,
+ .hooknum = NF_INET_PRE_ROUTING,
+ .priority = NF_IP6_PRI_NAT_DST,
+ },
+@@ -81,6 +82,7 @@ static const struct nf_hook_ops nf_nat_i
+ {
+ .hook = ip6table_nat_out,
+ .pf = NFPROTO_IPV6,
++ .nat_hook = true,
+ .hooknum = NF_INET_POST_ROUTING,
+ .priority = NF_IP6_PRI_NAT_SRC,
+ },
+@@ -88,12 +90,14 @@ static const struct nf_hook_ops nf_nat_i
+ {
+ .hook = ip6table_nat_local_fn,
+ .pf = NFPROTO_IPV6,
++ .nat_hook = true,
+ .hooknum = NF_INET_LOCAL_OUT,
+ .priority = NF_IP6_PRI_NAT_DST,
+ },
+ /* After packet filtering, change source */
+ {
+ .hook = ip6table_nat_fn,
++ .nat_hook = true,
+ .pf = NFPROTO_IPV6,
+ .hooknum = NF_INET_LOCAL_IN,
+ .priority = NF_IP6_PRI_NAT_SRC,
+--- a/net/netfilter/core.c
++++ b/net/netfilter/core.c
+@@ -160,6 +160,12 @@ nf_hook_entries_grow(const struct nf_hoo
+ ++i;
+ continue;
+ }
++
++ if (reg->nat_hook && orig_ops[i]->nat_hook) {
++ kvfree(new);
++ return ERR_PTR(-EEXIST);
++ }
++
+ if (inserted || reg->priority > orig_ops[i]->priority) {
+ new_ops[nhooks] = (void *)orig_ops[i];
+ new->hooks[nhooks] = old->hooks[i];
+--- a/net/netfilter/nf_tables_api.c
++++ b/net/netfilter/nf_tables_api.c
+@@ -1431,6 +1431,8 @@ static int nf_tables_addchain(struct nft
+ ops->hook = hookfn;
+ if (afi->hook_ops_init)
+ afi->hook_ops_init(ops, i);
++ if (basechain->type->type == NFT_CHAIN_T_NAT)
++ ops->nat_hook = true;
+ }
+
+ chain->flags |= NFT_BASE_CHAIN;