@@ -203,25 +203,18 @@ ctnetlink_dump_helpinfo(struct sk_buff *skb, const struct nf_conn *ct)
203203}
204204
205205static int
206- ctnetlink_dump_counters (struct sk_buff * skb , const struct nf_conn * ct ,
207- enum ip_conntrack_dir dir )
206+ dump_counters (struct sk_buff * skb , u64 pkts , u64 bytes ,
207+ enum ip_conntrack_dir dir )
208208{
209209 enum ctattr_type type = dir ? CTA_COUNTERS_REPLY : CTA_COUNTERS_ORIG ;
210210 struct nlattr * nest_count ;
211- const struct nf_conn_counter * acct ;
212-
213- acct = nf_conn_acct_find (ct );
214- if (!acct )
215- return 0 ;
216211
217212 nest_count = nla_nest_start (skb , type | NLA_F_NESTED );
218213 if (!nest_count )
219214 goto nla_put_failure ;
220215
221- NLA_PUT_BE64 (skb , CTA_COUNTERS_PACKETS ,
222- cpu_to_be64 (atomic64_read (& acct [dir ].packets )));
223- NLA_PUT_BE64 (skb , CTA_COUNTERS_BYTES ,
224- cpu_to_be64 (atomic64_read (& acct [dir ].bytes )));
216+ NLA_PUT_BE64 (skb , CTA_COUNTERS_PACKETS , cpu_to_be64 (pkts ));
217+ NLA_PUT_BE64 (skb , CTA_COUNTERS_BYTES , cpu_to_be64 (bytes ));
225218
226219 nla_nest_end (skb , nest_count );
227220
@@ -231,6 +224,27 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
231224 return -1 ;
232225}
233226
227+ static int
228+ ctnetlink_dump_counters (struct sk_buff * skb , const struct nf_conn * ct ,
229+ enum ip_conntrack_dir dir , int type )
230+ {
231+ struct nf_conn_counter * acct ;
232+ u64 pkts , bytes ;
233+
234+ acct = nf_conn_acct_find (ct );
235+ if (!acct )
236+ return 0 ;
237+
238+ if (type == IPCTNL_MSG_CT_GET_CTRZERO ) {
239+ pkts = atomic64_xchg (& acct [dir ].packets , 0 );
240+ bytes = atomic64_xchg (& acct [dir ].bytes , 0 );
241+ } else {
242+ pkts = atomic64_read (& acct [dir ].packets );
243+ bytes = atomic64_read (& acct [dir ].bytes );
244+ }
245+ return dump_counters (skb , pkts , bytes , dir );
246+ }
247+
234248static int
235249ctnetlink_dump_timestamp (struct sk_buff * skb , const struct nf_conn * ct )
236250{
@@ -393,15 +407,15 @@ ctnetlink_dump_use(struct sk_buff *skb, const struct nf_conn *ct)
393407}
394408
395409static int
396- ctnetlink_fill_info (struct sk_buff * skb , u32 pid , u32 seq ,
397- int event , struct nf_conn * ct )
410+ ctnetlink_fill_info (struct sk_buff * skb , u32 pid , u32 seq , u32 type ,
411+ struct nf_conn * ct )
398412{
399413 struct nlmsghdr * nlh ;
400414 struct nfgenmsg * nfmsg ;
401415 struct nlattr * nest_parms ;
402- unsigned int flags = pid ? NLM_F_MULTI : 0 ;
416+ unsigned int flags = pid ? NLM_F_MULTI : 0 , event ;
403417
404- event |= NFNL_SUBSYS_CTNETLINK << 8 ;
418+ event = ( NFNL_SUBSYS_CTNETLINK << 8 | IPCTNL_MSG_CT_NEW ) ;
405419 nlh = nlmsg_put (skb , pid , seq , event , sizeof (* nfmsg ), flags );
406420 if (nlh == NULL )
407421 goto nlmsg_failure ;
@@ -430,8 +444,8 @@ ctnetlink_fill_info(struct sk_buff *skb, u32 pid, u32 seq,
430444
431445 if (ctnetlink_dump_status (skb , ct ) < 0 ||
432446 ctnetlink_dump_timeout (skb , ct ) < 0 ||
433- ctnetlink_dump_counters (skb , ct , IP_CT_DIR_ORIGINAL ) < 0 ||
434- ctnetlink_dump_counters (skb , ct , IP_CT_DIR_REPLY ) < 0 ||
447+ ctnetlink_dump_counters (skb , ct , IP_CT_DIR_ORIGINAL , type ) < 0 ||
448+ ctnetlink_dump_counters (skb , ct , IP_CT_DIR_REPLY , type ) < 0 ||
435449 ctnetlink_dump_timestamp (skb , ct ) < 0 ||
436450 ctnetlink_dump_protoinfo (skb , ct ) < 0 ||
437451 ctnetlink_dump_helpinfo (skb , ct ) < 0 ||
@@ -612,8 +626,10 @@ ctnetlink_conntrack_event(unsigned int events, struct nf_ct_event *item)
612626 goto nla_put_failure ;
613627
614628 if (events & (1 << IPCT_DESTROY )) {
615- if (ctnetlink_dump_counters (skb , ct , IP_CT_DIR_ORIGINAL ) < 0 ||
616- ctnetlink_dump_counters (skb , ct , IP_CT_DIR_REPLY ) < 0 ||
629+ if (ctnetlink_dump_counters (skb , ct ,
630+ IP_CT_DIR_ORIGINAL , type ) < 0 ||
631+ ctnetlink_dump_counters (skb , ct ,
632+ IP_CT_DIR_REPLY , type ) < 0 ||
617633 ctnetlink_dump_timestamp (skb , ct ) < 0 )
618634 goto nla_put_failure ;
619635 } else {
@@ -709,24 +725,13 @@ ctnetlink_dump_table(struct sk_buff *skb, struct netlink_callback *cb)
709725 }
710726 if (ctnetlink_fill_info (skb , NETLINK_CB (cb -> skb ).pid ,
711727 cb -> nlh -> nlmsg_seq ,
712- IPCTNL_MSG_CT_NEW , ct ) < 0 ) {
728+ NFNL_MSG_TYPE (
729+ cb -> nlh -> nlmsg_type ),
730+ ct ) < 0 ) {
713731 nf_conntrack_get (& ct -> ct_general );
714732 cb -> args [1 ] = (unsigned long )ct ;
715733 goto out ;
716734 }
717-
718- if (NFNL_MSG_TYPE (cb -> nlh -> nlmsg_type ) ==
719- IPCTNL_MSG_CT_GET_CTRZERO ) {
720- struct nf_conn_counter * acct ;
721-
722- acct = nf_conn_acct_find (ct );
723- if (acct ) {
724- atomic64_set (& acct [IP_CT_DIR_ORIGINAL ].bytes , 0 );
725- atomic64_set (& acct [IP_CT_DIR_ORIGINAL ].packets , 0 );
726- atomic64_set (& acct [IP_CT_DIR_REPLY ].bytes , 0 );
727- atomic64_set (& acct [IP_CT_DIR_REPLY ].packets , 0 );
728- }
729- }
730735 }
731736 if (cb -> args [1 ]) {
732737 cb -> args [1 ] = 0 ;
@@ -1005,7 +1010,7 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
10051010
10061011 rcu_read_lock ();
10071012 err = ctnetlink_fill_info (skb2 , NETLINK_CB (skb ).pid , nlh -> nlmsg_seq ,
1008- IPCTNL_MSG_CT_NEW , ct );
1013+ NFNL_MSG_TYPE ( nlh -> nlmsg_type ) , ct );
10091014 rcu_read_unlock ();
10101015 nf_ct_put (ct );
10111016 if (err <= 0 )
@@ -1015,17 +1020,6 @@ ctnetlink_get_conntrack(struct sock *ctnl, struct sk_buff *skb,
10151020 if (err < 0 )
10161021 goto out ;
10171022
1018- if (NFNL_MSG_TYPE (nlh -> nlmsg_type ) == IPCTNL_MSG_CT_GET_CTRZERO ) {
1019- struct nf_conn_counter * acct ;
1020-
1021- acct = nf_conn_acct_find (ct );
1022- if (acct ) {
1023- atomic64_set (& acct [IP_CT_DIR_ORIGINAL ].bytes , 0 );
1024- atomic64_set (& acct [IP_CT_DIR_ORIGINAL ].packets , 0 );
1025- atomic64_set (& acct [IP_CT_DIR_REPLY ].bytes , 0 );
1026- atomic64_set (& acct [IP_CT_DIR_REPLY ].packets , 0 );
1027- }
1028- }
10291023 return 0 ;
10301024
10311025free :
0 commit comments