@@ -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);
@@ -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] = {
same as previous patch: extend nftables nat and masquerade functions to indicate more precise drop locations. Signed-off-by: Florian Westphal <fw@strlen.de> --- net/netfilter/nf_nat_masquerade.c | 23 ++++++++++++++++------- net/netfilter/nft_nat.c | 8 +++++++- 2 files changed, 23 insertions(+), 8 deletions(-)