Commit e0d45931 authored by Florian Westphal's avatar Florian Westphal

netfilter: make nftables drops visible in net dropmonitor

net_dropmonitor blames core.c:nf_hook_slow.
Add NF_DROP_REASON() helper and use it in nft_do_chain().

The helper releases the skb, so exact drop location becomes
available. Calling code will observe the NF_STOLEN verdict
instead.

Adjust nf_hook_slow so we can embed an erro value wih
NF_STOLEN verdicts, just like we do for NF_DROP.

After this, drop in nftables can be pinpointed to a drop due
to a rule or the chain policy.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
parent 35c038b0
...@@ -22,6 +22,16 @@ static inline int NF_DROP_GETERR(int verdict) ...@@ -22,6 +22,16 @@ static inline int NF_DROP_GETERR(int verdict)
return -(verdict >> NF_VERDICT_QBITS); return -(verdict >> NF_VERDICT_QBITS);
} }
static __always_inline int
NF_DROP_REASON(struct sk_buff *skb, enum skb_drop_reason reason, u32 err)
{
BUILD_BUG_ON(err > 0xffff);
kfree_skb_reason(skb, reason);
return ((err << 16) | NF_STOLEN);
}
static inline int nf_inet_addr_cmp(const union nf_inet_addr *a1, static inline int nf_inet_addr_cmp(const union nf_inet_addr *a1,
const union nf_inet_addr *a2) const union nf_inet_addr *a2)
{ {
......
...@@ -639,10 +639,10 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, ...@@ -639,10 +639,10 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
if (ret == 1) if (ret == 1)
continue; continue;
return ret; return ret;
case NF_STOLEN:
return NF_DROP_GETERR(verdict);
default: default:
/* Implicit handling for NF_STOLEN, as well as any other WARN_ON_ONCE(1);
* non conventional verdicts.
*/
return 0; return 0;
} }
} }
......
...@@ -308,10 +308,11 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) ...@@ -308,10 +308,11 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
switch (regs.verdict.code & NF_VERDICT_MASK) { switch (regs.verdict.code & NF_VERDICT_MASK) {
case NF_ACCEPT: case NF_ACCEPT:
case NF_DROP:
case NF_QUEUE: case NF_QUEUE:
case NF_STOLEN: case NF_STOLEN:
return regs.verdict.code; return regs.verdict.code;
case NF_DROP:
return NF_DROP_REASON(pkt->skb, SKB_DROP_REASON_NETFILTER_DROP, EPERM);
} }
switch (regs.verdict.code) { switch (regs.verdict.code) {
...@@ -342,6 +343,9 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv) ...@@ -342,6 +343,9 @@ nft_do_chain(struct nft_pktinfo *pkt, void *priv)
if (static_branch_unlikely(&nft_counters_enabled)) if (static_branch_unlikely(&nft_counters_enabled))
nft_update_chain_stats(basechain, pkt); nft_update_chain_stats(basechain, pkt);
if (nft_base_chain(basechain)->policy == NF_DROP)
return NF_DROP_REASON(pkt->skb, SKB_DROP_REASON_NETFILTER_DROP, EPERM);
return nft_base_chain(basechain)->policy; return nft_base_chain(basechain)->policy;
} }
EXPORT_SYMBOL_GPL(nft_do_chain); EXPORT_SYMBOL_GPL(nft_do_chain);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment