netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Pablo Neira Ayuso <pablo@netfilter.org>
To: netfilter-devel@vger.kernel.org
Cc: davem@davemloft.net, netdev@vger.kernel.org
Subject: [PATCH 20/52] netfilter: core: only allow one nat hook per hook point
Date: Mon,  8 Jan 2018 21:19:28 +0100	[thread overview]
Message-ID: <20180108202000.12989-21-pablo@netfilter.org> (raw)
In-Reply-To: <20180108202000.12989-1-pablo@netfilter.org>

From: Florian Westphal <fw@strlen.de>

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>
---
 include/linux/netfilter.h         | 1 +
 net/ipv4/netfilter/iptable_nat.c  | 4 ++++
 net/ipv6/netfilter/ip6table_nat.c | 4 ++++
 net/netfilter/core.c              | 6 ++++++
 net/netfilter/nf_tables_api.c     | 2 ++
 5 files changed, 17 insertions(+)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index ee7a9cbd8d81..85a0b0d599e6 100644
--- 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;
diff --git a/net/ipv4/netfilter/iptable_nat.c b/net/ipv4/netfilter/iptable_nat.c
index a1a07b338ccf..0f7255cc65ee 100644
--- 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_ipv4_ops[] = {
 	{
 		.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_ipv4_ops[] = {
 	{
 		.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_ipv4_ops[] = {
 	{
 		.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_ipv4_ops[] = {
 	{
 		.hook		= iptable_nat_ipv4_fn,
 		.pf		= NFPROTO_IPV4,
+		.nat_hook	= true,
 		.hooknum	= NF_INET_LOCAL_IN,
 		.priority	= NF_IP_PRI_NAT_SRC,
 	},
diff --git a/net/ipv6/netfilter/ip6table_nat.c b/net/ipv6/netfilter/ip6table_nat.c
index 991512576c8c..47306e45a80a 100644
--- 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_ipv6_ops[] = {
 	{
 		.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_ipv6_ops[] = {
 	{
 		.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_ipv6_ops[] = {
 	{
 		.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,
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index ed8618f4efd7..3508a5c8edbb 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -160,6 +160,12 @@ nf_hook_entries_grow(const struct nf_hook_entries *old,
 			++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];
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 10798b357481..838eb581b5ab 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -1400,6 +1400,8 @@ static int nf_tables_addchain(struct nft_ctx *ctx, u8 family, u8 genmask,
 				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;
-- 
2.11.0


  parent reply	other threads:[~2018-01-08 20:20 UTC|newest]

Thread overview: 55+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2018-01-08 20:19 [PATCH 00/52] Netfilter/IPVS updates for net-next Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 01/52] netfilter: conntrack: remove nlattr_size pointer from l4proto trackers Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 02/52] netfilter: conntrack: constify list of builtin trackers Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 03/52] netfilter: conntrack: l4 protocol trackers can be const Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 04/52] netfilter: mark expected switch fall-throughs Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 05/52] netfilter: conntrack: timeouts can be const Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 06/52] netfilter: ipvs: Remove useless ipvsh param of frag_safe_skb_hp Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 07/52] netfilter: ipset: use nfnl_mutex_is_locked Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 08/52] netfilter: ipset: add resched points during set listing Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 09/52] netfilter: nf_conntrack_h323: Remove unwanted comments Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 10/52] netfilter: core: make nf_unregister_net_hooks simple wrapper again Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 11/52] netfilter: core: remove synchronize_net call if nfqueue is used Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 12/52] netfilter: core: free hooks with call_rcu Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 13/52] netfilter: reduce size of hook entry point locations Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 14/52] netfilter: add defines for arp/decnet max hooks Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 15/52] netfilter: reduce hook array sizes to what is needed Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 16/52] netfilter: don't allocate space for decnet hooks unless needed Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 17/52] netfilter: don't allocate space for arp/bridge " Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 18/52] netfilter: reduce NF_MAX_HOOKS define Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 19/52] netfilter: xtables: add and use xt_request_find_table_lock Pablo Neira Ayuso
2018-01-08 20:19 ` Pablo Neira Ayuso [this message]
2018-01-08 20:19 ` [PATCH 21/52] netfilter: nf_tables: reject nat hook registration if prio is before conntrack Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 22/52] netfilter: nf_tables_arp: don't set forward chain Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 23/52] netfilter: nf_tables: explicit nft_set_pktinfo() call from hook path Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 24/52] netfilter: nf_tables: add nft_set_is_anonymous() helper Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 25/52] netfilter: core: add nf_remove_net_hook Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 26/52] netfilter: core: pass hook number, family and device to nf_find_hook_list() Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 27/52] netfilter: core: pass family as parameter to nf_remove_net_hook() Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 28/52] netfilter: core: support for NFPROTO_INET hook registration Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 29/52] netfilter: nf_tables_inet: don't use multihook infrastructure anymore Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 30/52] netfilter: nf_tables: remove multihook chains and families Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 31/52] netfilter: nf_tables: remove hooks from family definition Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 32/52] netfilter: connlimit: split xt_connlimit into front and backend Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 33/52] netfilter: move checksum indirection to struct nf_ipv6_ops Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 34/52] netfilter: move checksum_partial " Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 35/52] netfilter: remove saveroute indirection in struct nf_afinfo Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 36/52] netfilter: move route indirection to struct nf_ipv6_ops Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 37/52] netfilter: move reroute " Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 38/52] netfilter: remove route_key_size field in struct nf_afinfo Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 39/52] netfilter: remove struct nf_afinfo and its helper functions Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 40/52] netfilter: meta: secpath support Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 41/52] netfilter: remove defensive check on malformed packets from raw sockets Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 42/52] netfilter: nf_tables: remove nft_dereference() Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 43/52] netfilter: nf_conntrack: add IPS_OFFLOAD status bit Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 44/52] netfilter: nf_tables: add flow table netlink frontend Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 45/52] netfilter: add generic flow table infrastructure Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 46/52] netfilter: flow table support for IPv4 Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 47/52] netfilter: flow table support for IPv6 Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 48/52] netfilter: flow table support for the mixed IPv4/IPv6 family Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 49/52] netfilter: nf_tables: flow offload expression Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 50/52] netfilter: ipset: use swap macro instead of _manually_ swapping values Pablo Neira Ayuso
2018-01-08 20:19 ` [PATCH 51/52] netfilter: ipset: Fix "don't update counters" mode when counters used at the matching Pablo Neira Ayuso
2018-01-08 20:20 ` [PATCH 52/52] netfilter: ipset: Missing nfnl_lock()/nfnl_unlock() is added to ip_set_net_exit() Pablo Neira Ayuso
2018-01-09  1:55 ` [PATCH 00/52] Netfilter/IPVS updates for net-next David Miller
2018-01-09 15:43   ` Pablo Neira Ayuso

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20180108202000.12989-21-pablo@netfilter.org \
    --to=pablo@netfilter.org \
    --cc=davem@davemloft.net \
    --cc=netdev@vger.kernel.org \
    --cc=netfilter-devel@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).