[PATCH nf-next 3/4] netfilter: nf_nat: use skb_drop_reason

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



same as previous patch: extend nftables nat and masquerade functions to
indicate more precise drop locations.

Signed-off-by: Florian Westphal <fw@xxxxxxxxx>
---
 net/netfilter/nf_nat_masquerade.c | 23 ++++++++++++++++-------
 net/netfilter/nft_nat.c           |  8 +++++++-
 2 files changed, 23 insertions(+), 8 deletions(-)

diff --git a/net/netfilter/nf_nat_masquerade.c b/net/netfilter/nf_nat_masquerade.c
index 1a506b0c6511..06f5968dbc15 100644
--- a/net/netfilter/nf_nat_masquerade.c
+++ b/net/netfilter/nf_nat_masquerade.c
@@ -35,6 +35,7 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
 	struct nf_nat_range2 newrange;
 	const struct rtable *rt;
 	__be32 newsrc, nh;
+	int ret;
 
 	WARN_ON(hooknum != NF_INET_POST_ROUTING);
 
@@ -52,10 +53,8 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
 	rt = skb_rtable(skb);
 	nh = rt_nexthop(rt, ip_hdr(skb)->daddr);
 	newsrc = inet_select_addr(out, nh, RT_SCOPE_UNIVERSE);
-	if (!newsrc) {
-		pr_info("%s ate my IP address\n", out->name);
-		return NF_DROP;
-	}
+	if (!newsrc)
+		return NF_DROP_REASON(skb, SKB_DROP_REASON_NETFILTER_DROP, EADDRNOTAVAIL);
 
 	nat = nf_ct_nat_ext_add(ct);
 	if (nat)
@@ -71,7 +70,12 @@ nf_nat_masquerade_ipv4(struct sk_buff *skb, unsigned int hooknum,
 	newrange.max_proto   = range->max_proto;
 
 	/* Hand modified range to generic setup. */
-	return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
+	ret = nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
+	if (ret == NF_DROP)
+		return NF_DROP_REASON(skb, SKB_DROP_REASON_NETFILTER_DROP,
+				      EPERM);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv4);
 
@@ -246,6 +250,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
 	struct in6_addr src;
 	struct nf_conn *ct;
 	struct nf_nat_range2 newrange;
+	int ret;
 
 	ct = nf_ct_get(skb, &ctinfo);
 	WARN_ON(!(ct && (ctinfo == IP_CT_NEW || ctinfo == IP_CT_RELATED ||
@@ -253,7 +258,7 @@ nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
 
 	if (nat_ipv6_dev_get_saddr(nf_ct_net(ct), out,
 				   &ipv6_hdr(skb)->daddr, 0, &src) < 0)
-		return NF_DROP;
+		return NF_DROP_REASON(skb, SKB_DROP_REASON_NETFILTER_DROP, EADDRNOTAVAIL);
 
 	nat = nf_ct_nat_ext_add(ct);
 	if (nat)
@@ -265,7 +270,11 @@ nf_nat_masquerade_ipv6(struct sk_buff *skb, const struct nf_nat_range2 *range,
 	newrange.min_proto	= range->min_proto;
 	newrange.max_proto	= range->max_proto;
 
-	return nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
+	ret = nf_nat_setup_info(ct, &newrange, NF_NAT_MANIP_SRC);
+	if (ret == NF_DROP)
+		return NF_DROP_REASON(skb, SKB_DROP_REASON_NETFILTER_DROP, EPERM);
+
+	return ret;
 }
 EXPORT_SYMBOL_GPL(nf_nat_masquerade_ipv6);
 
diff --git a/net/netfilter/nft_nat.c b/net/netfilter/nft_nat.c
index 6e21f72c5b57..bd2bda5c2b13 100644
--- a/net/netfilter/nft_nat.c
+++ b/net/netfilter/nft_nat.c
@@ -108,6 +108,7 @@ static void nft_nat_eval(const struct nft_expr *expr,
 	enum ip_conntrack_info ctinfo;
 	struct nf_conn *ct = nf_ct_get(pkt->skb, &ctinfo);
 	struct nf_nat_range2 range;
+	int verdict;
 
 	memset(&range, 0, sizeof(range));
 
@@ -122,7 +123,12 @@ static void nft_nat_eval(const struct nft_expr *expr,
 
 	range.flags = priv->flags;
 
-	regs->verdict.code = nf_nat_setup_info(ct, &range, priv->type);
+	verdict = nf_nat_setup_info(ct, &range, priv->type);
+	if (verdict == NF_DROP)
+		verdict = NF_DROP_REASON(pkt->skb,
+					 SKB_DROP_REASON_NETFILTER_DROP,
+					 EPERM);
+	regs->verdict.code = verdict;
 }
 
 static const struct nla_policy nft_nat_policy[NFTA_NAT_MAX + 1] = {
-- 
2.45.2





[Index of Archives]     [Netfitler Users]     [Berkeley Packet Filter]     [LARTC]     [Bugtraq]     [Yosemite Forum]

  Powered by Linux