|
15 | 15 | #include <linux/netfilter.h> |
16 | 16 | #include <linux/netfilter/nfnetlink.h> |
17 | 17 | #include <linux/netfilter/nf_tables.h> |
| 18 | +#include <net/netfilter/nf_conntrack.h> |
18 | 19 | #include <net/netfilter/nf_tables_core.h> |
19 | 20 | #include <net/netfilter/nf_tables.h> |
20 | 21 |
|
@@ -90,6 +91,49 @@ static int nf_trace_fill_dev_info(struct sk_buff *nlskb, |
90 | 91 | return 0; |
91 | 92 | } |
92 | 93 |
|
| 94 | +static int nf_trace_fill_ct_info(struct sk_buff *nlskb, |
| 95 | + const struct sk_buff *skb) |
| 96 | +{ |
| 97 | + const struct nf_ct_hook *ct_hook; |
| 98 | + enum ip_conntrack_info ctinfo; |
| 99 | + const struct nf_conn *ct; |
| 100 | + u32 state; |
| 101 | + |
| 102 | + ct_hook = rcu_dereference(nf_ct_hook); |
| 103 | + if (!ct_hook) |
| 104 | + return 0; |
| 105 | + |
| 106 | + ct = nf_ct_get(skb, &ctinfo); |
| 107 | + if (!ct) { |
| 108 | + if (ctinfo != IP_CT_UNTRACKED) /* not seen by conntrack or invalid */ |
| 109 | + return 0; |
| 110 | + |
| 111 | + state = NF_CT_STATE_UNTRACKED_BIT; |
| 112 | + } else { |
| 113 | + state = NF_CT_STATE_BIT(ctinfo); |
| 114 | + } |
| 115 | + |
| 116 | + if (nla_put_be32(nlskb, NFTA_TRACE_CT_STATE, htonl(state))) |
| 117 | + return -1; |
| 118 | + |
| 119 | + if (ct) { |
| 120 | + u32 id = ct_hook->get_id(&ct->ct_general); |
| 121 | + u32 status = READ_ONCE(ct->status); |
| 122 | + u8 dir = CTINFO2DIR(ctinfo); |
| 123 | + |
| 124 | + if (nla_put_u8(nlskb, NFTA_TRACE_CT_DIRECTION, dir)) |
| 125 | + return -1; |
| 126 | + |
| 127 | + if (nla_put_be32(nlskb, NFTA_TRACE_CT_ID, (__force __be32)id)) |
| 128 | + return -1; |
| 129 | + |
| 130 | + if (status && nla_put_be32(nlskb, NFTA_TRACE_CT_STATUS, htonl(status))) |
| 131 | + return -1; |
| 132 | + } |
| 133 | + |
| 134 | + return 0; |
| 135 | +} |
| 136 | + |
93 | 137 | static int nf_trace_fill_pkt_info(struct sk_buff *nlskb, |
94 | 138 | const struct nft_pktinfo *pkt) |
95 | 139 | { |
@@ -210,7 +254,11 @@ void nft_trace_notify(const struct nft_pktinfo *pkt, |
210 | 254 | nla_total_size(sizeof(__be32)) + /* trace type */ |
211 | 255 | nla_total_size(0) + /* VERDICT, nested */ |
212 | 256 | nla_total_size(sizeof(u32)) + /* verdict code */ |
213 | | - nla_total_size(sizeof(u32)) + /* id */ |
| 257 | + nla_total_size(sizeof(u32)) + /* ct id */ |
| 258 | + nla_total_size(sizeof(u8)) + /* ct direction */ |
| 259 | + nla_total_size(sizeof(u32)) + /* ct state */ |
| 260 | + nla_total_size(sizeof(u32)) + /* ct status */ |
| 261 | + nla_total_size(sizeof(u32)) + /* trace id */ |
214 | 262 | nla_total_size(NFT_TRACETYPE_LL_HSIZE) + |
215 | 263 | nla_total_size(NFT_TRACETYPE_NETWORK_HSIZE) + |
216 | 264 | nla_total_size(NFT_TRACETYPE_TRANSPORT_HSIZE) + |
@@ -291,6 +339,10 @@ void nft_trace_notify(const struct nft_pktinfo *pkt, |
291 | 339 |
|
292 | 340 | if (nf_trace_fill_pkt_info(skb, pkt)) |
293 | 341 | goto nla_put_failure; |
| 342 | + |
| 343 | + if (nf_trace_fill_ct_info(skb, pkt->skb)) |
| 344 | + goto nla_put_failure; |
| 345 | + |
294 | 346 | info->packet_dumped = true; |
295 | 347 | } |
296 | 348 |
|
|
0 commit comments