16
16
#include <linux/netfilter/nf_tables.h>
17
17
#include <net/netfilter/nf_tables.h>
18
18
#include <net/netfilter/nf_conntrack.h>
19
+ #include <net/netfilter/nf_conntrack_acct.h>
19
20
#include <net/netfilter/nf_conntrack_tuple.h>
20
21
#include <net/netfilter/nf_conntrack_helper.h>
21
22
#include <net/netfilter/nf_conntrack_ecache.h>
@@ -30,6 +31,18 @@ struct nft_ct {
30
31
};
31
32
};
32
33
34
+ static u64 nft_ct_get_eval_counter (const struct nf_conn_counter * c ,
35
+ enum nft_ct_keys k ,
36
+ enum ip_conntrack_dir d )
37
+ {
38
+ if (d < IP_CT_DIR_MAX )
39
+ return k == NFT_CT_BYTES ? atomic64_read (& c [d ].bytes ) :
40
+ atomic64_read (& c [d ].packets );
41
+
42
+ return nft_ct_get_eval_counter (c , k , IP_CT_DIR_ORIGINAL ) +
43
+ nft_ct_get_eval_counter (c , k , IP_CT_DIR_REPLY );
44
+ }
45
+
33
46
static void nft_ct_get_eval (const struct nft_expr * expr ,
34
47
struct nft_regs * regs ,
35
48
const struct nft_pktinfo * pkt )
@@ -114,6 +127,17 @@ static void nft_ct_get_eval(const struct nft_expr *expr,
114
127
NF_CT_LABELS_MAX_SIZE - size );
115
128
return ;
116
129
}
130
+ case NFT_CT_BYTES : /* fallthrough */
131
+ case NFT_CT_PKTS : {
132
+ const struct nf_conn_acct * acct = nf_conn_acct_find (ct );
133
+ u64 count = 0 ;
134
+
135
+ if (acct )
136
+ count = nft_ct_get_eval_counter (acct -> counter ,
137
+ priv -> key , priv -> dir );
138
+ memcpy (dest , & count , sizeof (count ));
139
+ return ;
140
+ }
117
141
#endif
118
142
default :
119
143
break ;
@@ -291,6 +315,13 @@ static int nft_ct_get_init(const struct nft_ctx *ctx,
291
315
return - EINVAL ;
292
316
len = FIELD_SIZEOF (struct nf_conntrack_tuple , src .u .all );
293
317
break ;
318
+ case NFT_CT_BYTES :
319
+ case NFT_CT_PKTS :
320
+ /* no direction? return sum of original + reply */
321
+ if (tb [NFTA_CT_DIRECTION ] == NULL )
322
+ priv -> dir = IP_CT_DIR_MAX ;
323
+ len = sizeof (u64 );
324
+ break ;
294
325
default :
295
326
return - EOPNOTSUPP ;
296
327
}
@@ -373,6 +404,13 @@ static int nft_ct_get_dump(struct sk_buff *skb, const struct nft_expr *expr)
373
404
case NFT_CT_PROTO_DST :
374
405
if (nla_put_u8 (skb , NFTA_CT_DIRECTION , priv -> dir ))
375
406
goto nla_put_failure ;
407
+ break ;
408
+ case NFT_CT_BYTES :
409
+ case NFT_CT_PKTS :
410
+ if (priv -> dir < IP_CT_DIR_MAX &&
411
+ nla_put_u8 (skb , NFTA_CT_DIRECTION , priv -> dir ))
412
+ goto nla_put_failure ;
413
+ break ;
376
414
default :
377
415
break ;
378
416
}
0 commit comments