mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/chenhuacai/linux-loongson
synced 2025-08-29 02:59:13 +00:00
netfilter: nf_tables: add packets conntrack state to debug trace info
Add the minimal relevant info needed for userspace ("nftables monitor trace") to provide the conntrack view of the packet: - state (new, related, established) - direction (original, reply) - status (e.g., if connection is subject to dnat) - id (allows to query ctnetlink for remaining conntrack state info) Example: trace id a62 inet filter PRE_RAW packet: iif "enp0s3" ether [..] [..] trace id a62 inet filter PRE_MANGLE conntrack: ct direction original ct state new ct id 32 trace id a62 inet filter PRE_MANGLE packet: [..] [..] trace id a62 inet filter IN conntrack: ct direction original ct state new ct status dnat-done ct id 32 [..] In this case one can see that while NAT is active, the new connection isn't subject to a translation. Signed-off-by: Florian Westphal <fw@strlen.de> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
90869f43d0
commit
7e5c6aa67e
@ -1841,6 +1841,10 @@ enum nft_xfrm_keys {
|
|||||||
* @NFTA_TRACE_MARK: nfmark (NLA_U32)
|
* @NFTA_TRACE_MARK: nfmark (NLA_U32)
|
||||||
* @NFTA_TRACE_NFPROTO: nf protocol processed (NLA_U32)
|
* @NFTA_TRACE_NFPROTO: nf protocol processed (NLA_U32)
|
||||||
* @NFTA_TRACE_POLICY: policy that decided fate of packet (NLA_U32)
|
* @NFTA_TRACE_POLICY: policy that decided fate of packet (NLA_U32)
|
||||||
|
* @NFTA_TRACE_CT_ID: conntrack id (NLA_U32)
|
||||||
|
* @NFTA_TRACE_CT_DIRECTION: packets direction (NLA_U8)
|
||||||
|
* @NFTA_TRACE_CT_STATUS: conntrack status (NLA_U32)
|
||||||
|
* @NFTA_TRACE_CT_STATE: packet state (new, established, ...) (NLA_U32)
|
||||||
*/
|
*/
|
||||||
enum nft_trace_attributes {
|
enum nft_trace_attributes {
|
||||||
NFTA_TRACE_UNSPEC,
|
NFTA_TRACE_UNSPEC,
|
||||||
@ -1861,6 +1865,10 @@ enum nft_trace_attributes {
|
|||||||
NFTA_TRACE_NFPROTO,
|
NFTA_TRACE_NFPROTO,
|
||||||
NFTA_TRACE_POLICY,
|
NFTA_TRACE_POLICY,
|
||||||
NFTA_TRACE_PAD,
|
NFTA_TRACE_PAD,
|
||||||
|
NFTA_TRACE_CT_ID,
|
||||||
|
NFTA_TRACE_CT_DIRECTION,
|
||||||
|
NFTA_TRACE_CT_STATUS,
|
||||||
|
NFTA_TRACE_CT_STATE,
|
||||||
__NFTA_TRACE_MAX
|
__NFTA_TRACE_MAX
|
||||||
};
|
};
|
||||||
#define NFTA_TRACE_MAX (__NFTA_TRACE_MAX - 1)
|
#define NFTA_TRACE_MAX (__NFTA_TRACE_MAX - 1)
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
#include <linux/netfilter.h>
|
#include <linux/netfilter.h>
|
||||||
#include <linux/netfilter/nfnetlink.h>
|
#include <linux/netfilter/nfnetlink.h>
|
||||||
#include <linux/netfilter/nf_tables.h>
|
#include <linux/netfilter/nf_tables.h>
|
||||||
|
#include <net/netfilter/nf_conntrack.h>
|
||||||
#include <net/netfilter/nf_tables_core.h>
|
#include <net/netfilter/nf_tables_core.h>
|
||||||
#include <net/netfilter/nf_tables.h>
|
#include <net/netfilter/nf_tables.h>
|
||||||
|
|
||||||
@ -90,6 +91,49 @@ static int nf_trace_fill_dev_info(struct sk_buff *nlskb,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int nf_trace_fill_ct_info(struct sk_buff *nlskb,
|
||||||
|
const struct sk_buff *skb)
|
||||||
|
{
|
||||||
|
const struct nf_ct_hook *ct_hook;
|
||||||
|
enum ip_conntrack_info ctinfo;
|
||||||
|
const struct nf_conn *ct;
|
||||||
|
u32 state;
|
||||||
|
|
||||||
|
ct_hook = rcu_dereference(nf_ct_hook);
|
||||||
|
if (!ct_hook)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
ct = nf_ct_get(skb, &ctinfo);
|
||||||
|
if (!ct) {
|
||||||
|
if (ctinfo != IP_CT_UNTRACKED) /* not seen by conntrack or invalid */
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
state = NF_CT_STATE_UNTRACKED_BIT;
|
||||||
|
} else {
|
||||||
|
state = NF_CT_STATE_BIT(ctinfo);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nla_put_be32(nlskb, NFTA_TRACE_CT_STATE, htonl(state)))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (ct) {
|
||||||
|
u32 id = ct_hook->get_id(&ct->ct_general);
|
||||||
|
u32 status = READ_ONCE(ct->status);
|
||||||
|
u8 dir = CTINFO2DIR(ctinfo);
|
||||||
|
|
||||||
|
if (nla_put_u8(nlskb, NFTA_TRACE_CT_DIRECTION, dir))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (nla_put_be32(nlskb, NFTA_TRACE_CT_ID, (__force __be32)id))
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (status && nla_put_be32(nlskb, NFTA_TRACE_CT_STATUS, htonl(status)))
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int nf_trace_fill_pkt_info(struct sk_buff *nlskb,
|
static int nf_trace_fill_pkt_info(struct sk_buff *nlskb,
|
||||||
const struct nft_pktinfo *pkt)
|
const struct nft_pktinfo *pkt)
|
||||||
{
|
{
|
||||||
@ -210,7 +254,11 @@ void nft_trace_notify(const struct nft_pktinfo *pkt,
|
|||||||
nla_total_size(sizeof(__be32)) + /* trace type */
|
nla_total_size(sizeof(__be32)) + /* trace type */
|
||||||
nla_total_size(0) + /* VERDICT, nested */
|
nla_total_size(0) + /* VERDICT, nested */
|
||||||
nla_total_size(sizeof(u32)) + /* verdict code */
|
nla_total_size(sizeof(u32)) + /* verdict code */
|
||||||
nla_total_size(sizeof(u32)) + /* id */
|
nla_total_size(sizeof(u32)) + /* ct id */
|
||||||
|
nla_total_size(sizeof(u8)) + /* ct direction */
|
||||||
|
nla_total_size(sizeof(u32)) + /* ct state */
|
||||||
|
nla_total_size(sizeof(u32)) + /* ct status */
|
||||||
|
nla_total_size(sizeof(u32)) + /* trace id */
|
||||||
nla_total_size(NFT_TRACETYPE_LL_HSIZE) +
|
nla_total_size(NFT_TRACETYPE_LL_HSIZE) +
|
||||||
nla_total_size(NFT_TRACETYPE_NETWORK_HSIZE) +
|
nla_total_size(NFT_TRACETYPE_NETWORK_HSIZE) +
|
||||||
nla_total_size(NFT_TRACETYPE_TRANSPORT_HSIZE) +
|
nla_total_size(NFT_TRACETYPE_TRANSPORT_HSIZE) +
|
||||||
@ -291,6 +339,10 @@ void nft_trace_notify(const struct nft_pktinfo *pkt,
|
|||||||
|
|
||||||
if (nf_trace_fill_pkt_info(skb, pkt))
|
if (nf_trace_fill_pkt_info(skb, pkt))
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
|
if (nf_trace_fill_ct_info(skb, pkt->skb))
|
||||||
|
goto nla_put_failure;
|
||||||
|
|
||||||
info->packet_dumped = true;
|
info->packet_dumped = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user