[Devel] [PATCH 11/13] net: Mark conntrack users in xtables

Alexander Mikhalitsyn alexander.mikhalitsyn at virtuozzo.com
Tue May 18 20:54:25 MSK 2021


From: Kirill Tkhai <ktkhai at virtuozzo.com>

Allow conntracks to be allocated in case of these
rules are inserted.

https://jira.sw.ru/browse/PSBM-51050

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
Reviewed-by: Andrei Vagin <avagin at virtuozzo.com>

+++
ve/net: Delete allow_conntrack_allocation() from nf_synproxy

Since nf_conntrack_alloc() is not called there anymore,
it's not need to allow CT allocation there.

https://jira.sw.ru/browse/PSBM-54823

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>

+++
ve/net: Allow conntrack allocation if a rule with xt_CT target is inserted

https://jira.sw.ru/browse/PSBM-54823

Signed-off-by: Kirill Tkhai <ktkhai at virtuozzo.com>
(cherry picked from commit 3b277df5b8bc61eed867ed91f9428d6bda703cf1)

+++

see also
a357b3f80bc8d ("netfilter: nat: add dependencies on conntrack module")
84899a2b9adaf ("netfilter: xtables: remove xt_connmark v0")

Modules which require conntrack call:
nf_ct_netns_get(struct net *net, u8 nfproto) in struct xt_entry .checkentry callback.
$ grep -Inr 'nf_ct_netns_get' net/netfilter net/ipv4/netfilter net/ipv6/netfilter
is useful to find all modules

net/netfilter/nf_conncount.c was added

VZ 8 rebase part https://jira.sw.ru/browse/PSBM-127783

Signed-off-by: Alexander Mikhalitsyn <alexander.mikhalitsyn at virtuozzo.com>
---
 net/ipv4/netfilter/ipt_CLUSTERIP.c   |  2 ++
 net/ipv4/netfilter/ipt_MASQUERADE.c  |  6 +++++-
 net/ipv4/netfilter/ipt_SYNPROXY.c    |  2 ++
 net/ipv6/netfilter/ip6t_MASQUERADE.c |  6 +++++-
 net/ipv6/netfilter/ip6t_SYNPROXY.c   |  2 ++
 net/netfilter/nf_conncount.c         |  2 ++
 net/netfilter/nf_synproxy_core.c     |  1 -
 net/netfilter/xt_CONNSECMARK.c       |  2 ++
 net/netfilter/xt_CT.c                |  1 +
 net/netfilter/xt_HMARK.c             |  1 +
 net/netfilter/xt_NETMAP.c            | 14 ++++++++++++--
 net/netfilter/xt_REDIRECT.c          | 13 +++++++++++--
 net/netfilter/xt_cluster.c           |  2 ++
 net/netfilter/xt_connbytes.c         |  2 ++
 net/netfilter/xt_connlabel.c         |  3 ++-
 net/netfilter/xt_connlimit.c         |  2 ++
 net/netfilter/xt_connmark.c          |  2 ++
 net/netfilter/xt_conntrack.c         |  2 ++
 net/netfilter/xt_helper.c            |  1 +
 net/netfilter/xt_ipvs.c              |  1 +
 net/netfilter/xt_nat.c               | 14 ++++++++++++--
 net/netfilter/xt_socket.c            | 10 ++++++++++
 net/netfilter/xt_state.c             |  2 ++
 23 files changed, 83 insertions(+), 10 deletions(-)

diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index 1c6da8ed4702..cfa4e2559aa8 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -507,6 +507,8 @@ static int clusterip_tg_check(const struct xt_tgchk_param *par)
 		return ret;
 	}
 
+	allow_conntrack_allocation(par->net);
+
 	if (!par->net->xt.clusterip_deprecated_warning) {
 		pr_info("ipt_CLUSTERIP is deprecated and it will removed soon, "
 			"use xt_cluster instead\n");
diff --git a/net/ipv4/netfilter/ipt_MASQUERADE.c b/net/ipv4/netfilter/ipt_MASQUERADE.c
index fd3f9e8a74da..5c710a63223c 100644
--- a/net/ipv4/netfilter/ipt_MASQUERADE.c
+++ b/net/ipv4/netfilter/ipt_MASQUERADE.c
@@ -32,6 +32,7 @@ MODULE_DESCRIPTION("Xtables: automatic-address SNAT");
 static int masquerade_tg_check(const struct xt_tgchk_param *par)
 {
 	const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
+	int ret;
 
 	if (mr->range[0].flags & NF_NAT_RANGE_MAP_IPS) {
 		pr_debug("bad MAP_IPS.\n");
@@ -41,7 +42,10 @@ static int masquerade_tg_check(const struct xt_tgchk_param *par)
 		pr_debug("bad rangesize %u\n", mr->rangesize);
 		return -EINVAL;
 	}
-	return nf_ct_netns_get(par->net, par->family);
+	ret = nf_ct_netns_get(par->net, par->family);
+	if (ret == 0)
+		allow_conntrack_allocation(par->net);
+	return ret;
 }
 
 static unsigned int
diff --git a/net/ipv4/netfilter/ipt_SYNPROXY.c b/net/ipv4/netfilter/ipt_SYNPROXY.c
index 270594004e46..b577ec9bafc5 100644
--- a/net/ipv4/netfilter/ipt_SYNPROXY.c
+++ b/net/ipv4/netfilter/ipt_SYNPROXY.c
@@ -464,6 +464,8 @@ static int synproxy_tg4_check(const struct xt_tgchk_param *par)
 	}
 
 	snet->hook_ref4++;
+	if (err == 0)
+		allow_conntrack_allocation(par->net);
 	return err;
 }
 
diff --git a/net/ipv6/netfilter/ip6t_MASQUERADE.c b/net/ipv6/netfilter/ip6t_MASQUERADE.c
index 29c7f1915a96..56635322aed5 100644
--- a/net/ipv6/netfilter/ip6t_MASQUERADE.c
+++ b/net/ipv6/netfilter/ip6t_MASQUERADE.c
@@ -30,10 +30,14 @@ masquerade_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 static int masquerade_tg6_checkentry(const struct xt_tgchk_param *par)
 {
 	const struct nf_nat_range2 *range = par->targinfo;
+	int ret;
 
 	if (range->flags & NF_NAT_RANGE_MAP_IPS)
 		return -EINVAL;
-	return nf_ct_netns_get(par->net, par->family);
+	ret = nf_ct_netns_get(par->net, par->family);
+	if (ret == 0)
+		allow_conntrack_allocation(par->net);
+	return ret;
 }
 
 static void masquerade_tg6_destroy(const struct xt_tgdtor_param *par)
diff --git a/net/ipv6/netfilter/ip6t_SYNPROXY.c b/net/ipv6/netfilter/ip6t_SYNPROXY.c
index f1953527af81..97b26842e6d3 100644
--- a/net/ipv6/netfilter/ip6t_SYNPROXY.c
+++ b/net/ipv6/netfilter/ip6t_SYNPROXY.c
@@ -486,6 +486,8 @@ static int synproxy_tg6_check(const struct xt_tgchk_param *par)
 	}
 
 	snet->hook_ref6++;
+	if (err == 0)
+		allow_conntrack_allocation(par->net);
 	return err;
 }
 
diff --git a/net/netfilter/nf_conncount.c b/net/netfilter/nf_conncount.c
index 7554c56b2e63..b1ebb24ee981 100644
--- a/net/netfilter/nf_conncount.c
+++ b/net/netfilter/nf_conncount.c
@@ -535,6 +535,8 @@ struct nf_conncount_data *nf_conncount_init(struct net *net, unsigned int family
 		return ERR_PTR(ret);
 	}
 
+	allow_conntrack_allocation(net);
+
 	for (i = 0; i < ARRAY_SIZE(data->root); ++i)
 		data->root[i] = RB_ROOT;
 
diff --git a/net/netfilter/nf_synproxy_core.c b/net/netfilter/nf_synproxy_core.c
index eae42e67af47..3996ca086ec2 100644
--- a/net/netfilter/nf_synproxy_core.c
+++ b/net/netfilter/nf_synproxy_core.c
@@ -340,7 +340,6 @@ static int __net_init synproxy_net_init(struct net *net)
 	struct nf_conn *ct;
 	int err = -ENOMEM;
 
-	allow_conntrack_allocation(net);
 	ct = nf_ct_tmpl_alloc(net, &nf_ct_zone_dflt, GFP_KERNEL);
 	if (!ct)
 		goto err1;
diff --git a/net/netfilter/xt_CONNSECMARK.c b/net/netfilter/xt_CONNSECMARK.c
index f3f1caac949b..ad30f5e2aba7 100644
--- a/net/netfilter/xt_CONNSECMARK.c
+++ b/net/netfilter/xt_CONNSECMARK.c
@@ -110,6 +110,8 @@ static int connsecmark_tg_check(const struct xt_tgchk_param *par)
 	if (ret < 0)
 		pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
 				    par->family);
+	else
+		allow_conntrack_allocation(par->net);
 	return ret;
 }
 
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c
index 3ae237da9703..281f9d08f230 100644
--- a/net/netfilter/xt_CT.c
+++ b/net/netfilter/xt_CT.c
@@ -206,6 +206,7 @@ static int xt_ct_tg_check(const struct xt_tgchk_param *par,
 	}
 	__set_bit(IPS_CONFIRMED_BIT, &ct->status);
 	nf_conntrack_get(&ct->ct_general);
+	allow_conntrack_allocation(par->net);
 out:
 	info->ct = ct;
 	return 0;
diff --git a/net/netfilter/xt_HMARK.c b/net/netfilter/xt_HMARK.c
index 4327e70efea2..c7a4442e3fc1 100644
--- a/net/netfilter/xt_HMARK.c
+++ b/net/netfilter/xt_HMARK.c
@@ -330,6 +330,7 @@ static int hmark_tg_check(const struct xt_tgchk_param *par)
 		errmsg = "spi-set and port-set can't be combined";
 		goto err;
 	}
+	allow_conntrack_allocation(par->net);
 	return 0;
 err:
 	pr_info_ratelimited("%s\n", errmsg);
diff --git a/net/netfilter/xt_NETMAP.c b/net/netfilter/xt_NETMAP.c
index 1d437875e15a..b2fde9081c08 100644
--- a/net/netfilter/xt_NETMAP.c
+++ b/net/netfilter/xt_NETMAP.c
@@ -57,10 +57,15 @@ netmap_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 static int netmap_tg6_checkentry(const struct xt_tgchk_param *par)
 {
 	const struct nf_nat_range2 *range = par->targinfo;
+	int ret;
 
 	if (!(range->flags & NF_NAT_RANGE_MAP_IPS))
 		return -EINVAL;
-	return nf_ct_netns_get(par->net, par->family);
+
+	ret = nf_ct_netns_get(par->net, par->family);
+	if (ret == 0)
+		allow_conntrack_allocation(par->net);
+	return ret;
 }
 
 static void netmap_tg_destroy(const struct xt_tgdtor_param *par)
@@ -107,6 +112,7 @@ netmap_tg4(struct sk_buff *skb, const struct xt_action_param *par)
 static int netmap_tg4_check(const struct xt_tgchk_param *par)
 {
 	const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
+	int ret;
 
 	if (!(mr->range[0].flags & NF_NAT_RANGE_MAP_IPS)) {
 		pr_debug("bad MAP_IPS.\n");
@@ -116,7 +122,11 @@ static int netmap_tg4_check(const struct xt_tgchk_param *par)
 		pr_debug("bad rangesize %u.\n", mr->rangesize);
 		return -EINVAL;
 	}
-	return nf_ct_netns_get(par->net, par->family);
+
+	ret = nf_ct_netns_get(par->net, par->family);
+	if (ret == 0)
+		allow_conntrack_allocation(par->net);
+	return ret;
 }
 
 static struct xt_target netmap_tg_reg[] __read_mostly = {
diff --git a/net/netfilter/xt_REDIRECT.c b/net/netfilter/xt_REDIRECT.c
index 5ce9461e979c..f076059f887e 100644
--- a/net/netfilter/xt_REDIRECT.c
+++ b/net/netfilter/xt_REDIRECT.c
@@ -37,11 +37,15 @@ redirect_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 static int redirect_tg6_checkentry(const struct xt_tgchk_param *par)
 {
 	const struct nf_nat_range2 *range = par->targinfo;
+	int ret;
 
 	if (range->flags & NF_NAT_RANGE_MAP_IPS)
 		return -EINVAL;
 
-	return nf_ct_netns_get(par->net, par->family);
+	ret = nf_ct_netns_get(par->net, par->family);
+	if (ret == 0)
+		allow_conntrack_allocation(par->net);
+	return ret;
 }
 
 static void redirect_tg_destroy(const struct xt_tgdtor_param *par)
@@ -53,6 +57,7 @@ static void redirect_tg_destroy(const struct xt_tgdtor_param *par)
 static int redirect_tg4_check(const struct xt_tgchk_param *par)
 {
 	const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
+	int ret;
 
 	if (mr->range[0].flags & NF_NAT_RANGE_MAP_IPS) {
 		pr_debug("bad MAP_IPS.\n");
@@ -62,7 +67,11 @@ static int redirect_tg4_check(const struct xt_tgchk_param *par)
 		pr_debug("bad rangesize %u.\n", mr->rangesize);
 		return -EINVAL;
 	}
-	return nf_ct_netns_get(par->net, par->family);
+
+	ret = nf_ct_netns_get(par->net, par->family);
+	if (ret == 0)
+		allow_conntrack_allocation(par->net);
+	return ret;
 }
 
 static unsigned int
diff --git a/net/netfilter/xt_cluster.c b/net/netfilter/xt_cluster.c
index 51d0c257e7a5..8fac1d57f462 100644
--- a/net/netfilter/xt_cluster.c
+++ b/net/netfilter/xt_cluster.c
@@ -141,6 +141,8 @@ static int xt_cluster_mt_checkentry(const struct xt_mtchk_param *par)
 	if (ret < 0)
 		pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
 				    par->family);
+	else
+		allow_conntrack_allocation(par->net);
 	return ret;
 }
 
diff --git a/net/netfilter/xt_connbytes.c b/net/netfilter/xt_connbytes.c
index 93cb018c3055..ffb3b6b420cb 100644
--- a/net/netfilter/xt_connbytes.c
+++ b/net/netfilter/xt_connbytes.c
@@ -114,6 +114,8 @@ static int connbytes_mt_check(const struct xt_mtchk_param *par)
 	if (ret < 0)
 		pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
 				    par->family);
+	else
+		allow_conntrack_allocation(par->net);
 
 	/*
 	 * This filter cannot function correctly unless connection tracking
diff --git a/net/netfilter/xt_connlabel.c b/net/netfilter/xt_connlabel.c
index 4fa4efd24353..3e8e36176ac8 100644
--- a/net/netfilter/xt_connlabel.c
+++ b/net/netfilter/xt_connlabel.c
@@ -67,7 +67,8 @@ static int connlabel_mt_check(const struct xt_mtchk_param *par)
 		pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
 				    par->family);
 		return ret;
-	}
+	} else
+		allow_conntrack_allocation(par->net);
 
 	ret = nf_connlabels_get(par->net, info->bit);
 	if (ret < 0)
diff --git a/net/netfilter/xt_connlimit.c b/net/netfilter/xt_connlimit.c
index baf23fd71923..136c3b7af0e1 100644
--- a/net/netfilter/xt_connlimit.c
+++ b/net/netfilter/xt_connlimit.c
@@ -98,6 +98,8 @@ static int connlimit_mt_check(const struct xt_mtchk_param *par)
 	if (IS_ERR(info->data))
 		return PTR_ERR(info->data);
 
+	allow_conntrack_allocation(par->net);
+
 	return 0;
 }
 
diff --git a/net/netfilter/xt_connmark.c b/net/netfilter/xt_connmark.c
index 29c38aa7f726..8ac6ee052543 100644
--- a/net/netfilter/xt_connmark.c
+++ b/net/netfilter/xt_connmark.c
@@ -149,6 +149,8 @@ static int connmark_mt_check(const struct xt_mtchk_param *par)
 	if (ret < 0)
 		pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
 				    par->family);
+	else
+		allow_conntrack_allocation(par->net);
 	return ret;
 }
 
diff --git a/net/netfilter/xt_conntrack.c b/net/netfilter/xt_conntrack.c
index df80fe7d391c..c9ee5096f695 100644
--- a/net/netfilter/xt_conntrack.c
+++ b/net/netfilter/xt_conntrack.c
@@ -274,6 +274,8 @@ static int conntrack_mt_check(const struct xt_mtchk_param *par)
 	if (ret < 0)
 		pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
 				    par->family);
+	else
+		allow_conntrack_allocation(par->net);
 	return ret;
 }
 
diff --git a/net/netfilter/xt_helper.c b/net/netfilter/xt_helper.c
index fd077aeaaed9..51d1c088b74a 100644
--- a/net/netfilter/xt_helper.c
+++ b/net/netfilter/xt_helper.c
@@ -66,6 +66,7 @@ static int helper_mt_check(const struct xt_mtchk_param *par)
 		return ret;
 	}
 	info->name[sizeof(info->name) - 1] = '\0';
+	allow_conntrack_allocation(par->net);
 	return 0;
 }
 
diff --git a/net/netfilter/xt_ipvs.c b/net/netfilter/xt_ipvs.c
index 1d950a6100af..c6f145b15e65 100644
--- a/net/netfilter/xt_ipvs.c
+++ b/net/netfilter/xt_ipvs.c
@@ -163,6 +163,7 @@ static int ipvs_mt_check(const struct xt_mtchk_param *par)
 		return -EINVAL;
 	}
 
+	allow_conntrack_allocation(par->net);
 	return 0;
 }
 
diff --git a/net/netfilter/xt_nat.c b/net/netfilter/xt_nat.c
index 61eabd171186..cea8fb83eccc 100644
--- a/net/netfilter/xt_nat.c
+++ b/net/netfilter/xt_nat.c
@@ -19,17 +19,27 @@
 static int xt_nat_checkentry_v0(const struct xt_tgchk_param *par)
 {
 	const struct nf_nat_ipv4_multi_range_compat *mr = par->targinfo;
+	int ret;
 
 	if (mr->rangesize != 1) {
 		pr_info_ratelimited("multiple ranges no longer supported\n");
 		return -EINVAL;
 	}
-	return nf_ct_netns_get(par->net, par->family);
+
+	ret = nf_ct_netns_get(par->net, par->family);
+	if (ret == 0)
+		allow_conntrack_allocation(par->net);
+	return ret;
 }
 
 static int xt_nat_checkentry(const struct xt_tgchk_param *par)
 {
-	return nf_ct_netns_get(par->net, par->family);
+	int ret;
+
+	ret = nf_ct_netns_get(par->net, par->family);
+	if (ret == 0)
+		allow_conntrack_allocation(par->net);
+	return ret;
 }
 
 static void xt_nat_destroy(const struct xt_tgdtor_param *par)
diff --git a/net/netfilter/xt_socket.c b/net/netfilter/xt_socket.c
index ada144e5645b..cb57ccdcb1b0 100644
--- a/net/netfilter/xt_socket.c
+++ b/net/netfilter/xt_socket.c
@@ -169,6 +169,12 @@ static int socket_mt_enable_defrag(struct net *net, int family)
 	return 0;
 }
 
+static int socket_mt_v0_check(const struct xt_mtchk_param *par)
+{
+	allow_conntrack_allocation(par->net);
+	return 0;
+}
+
 static int socket_mt_v1_check(const struct xt_mtchk_param *par)
 {
 	const struct xt_socket_mtinfo1 *info = (struct xt_socket_mtinfo1 *) par->matchinfo;
@@ -183,6 +189,7 @@ static int socket_mt_v1_check(const struct xt_mtchk_param *par)
 				    info->flags & ~XT_SOCKET_FLAGS_V1);
 		return -EINVAL;
 	}
+	allow_conntrack_allocation(par->net);
 	return 0;
 }
 
@@ -200,6 +207,7 @@ static int socket_mt_v2_check(const struct xt_mtchk_param *par)
 				    info->flags & ~XT_SOCKET_FLAGS_V2);
 		return -EINVAL;
 	}
+	allow_conntrack_allocation(par->net);
 	return 0;
 }
 
@@ -217,6 +225,7 @@ static int socket_mt_v3_check(const struct xt_mtchk_param *par)
 				    info->flags & ~XT_SOCKET_FLAGS_V3);
 		return -EINVAL;
 	}
+	allow_conntrack_allocation(par->net);
 	return 0;
 }
 
@@ -226,6 +235,7 @@ static struct xt_match socket_mt_reg[] __read_mostly = {
 		.revision	= 0,
 		.family		= NFPROTO_IPV4,
 		.match		= socket_mt4_v0,
+		.checkentry	= socket_mt_v0_check,
 		.hooks		= (1 << NF_INET_PRE_ROUTING) |
 				  (1 << NF_INET_LOCAL_IN),
 		.me		= THIS_MODULE,
diff --git a/net/netfilter/xt_state.c b/net/netfilter/xt_state.c
index 0b41c0befe3c..f6f1c7668210 100644
--- a/net/netfilter/xt_state.c
+++ b/net/netfilter/xt_state.c
@@ -46,6 +46,8 @@ static int state_mt_check(const struct xt_mtchk_param *par)
 	if (ret < 0)
 		pr_info_ratelimited("cannot load conntrack support for proto=%u\n",
 				    par->family);
+	else
+		allow_conntrack_allocation(par->net);
 	return ret;
 }
 
-- 
2.28.0



More information about the Devel mailing list