connbytes & 64bit counters

Krzysztof Oledzki ole at ans.pl
Sat Jul 21 00:42:53 CEST 2007



On Sat, 21 Jul 2007, Krzysztof Oledzki wrote:

>
>
> On Mon, 15 Jan 2007, Patrick McHardy wrote:
>
>> Krzysztof Oledzki wrote:
>>> On Wed, 10 Jan 2007, Patrick McHardy wrote:
>>> 
>>>>> linux-2.6.19.1-64bitconntrack/net/ipv4/netfilter/ip_conntrack_core.c
>>>>> 2006-12-22 21:13:35.000000000 +0100
>>>>> @@ -1148,9 +1148,6 @@
>>>>>          ct->counters[CTINFO2DIR(ctinfo)].packets++;
>>>>>          ct->counters[CTINFO2DIR(ctinfo)].bytes +=
>>>>>                          ntohs(skb->nh.iph->tot_len);
>>>>> -        if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
>>>>> -            || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
>>>>> -            event |= IPCT_COUNTER_FILLING;
>>>> 
>>>> 
>>>> 
>>>> This was actually broken before, since the counters are not
>>>> reset (they just overflow) an event was generated for every
>>>> packet until the overflow once they reached 2^31. Anyway,
>>>> I'm not sure how ulogd2 uses these counters, Harald, is it
>>>> necessary to receive period updates?
>>> 
>>> 
>>> If we remove IPCT_COUNTER_FILLING there is no other solution than also
>>> drop this part of the code.
>> 
>> Let's wait what Harald says about ulogd2, I'm not sure whether we need
>> to keep this.
>> 
>>> BTW: what about CTA_COUNTERS32_*? Should we also drop that attributes?
>> 
>> They should be kept to make sure the value are not reused. Please just
>> add a comment stating that they are not used anymore.
>> 
>
> Getting back to this old thread... How about attached (and inlined) patch?
>
> - for 2.6.22 and current linux-2.6.git kernels with ip_conntrack removed
> - removes IPCT_COUNTER_FILLING
> - comments CTA_COUNTERS32_*

Errr, incomplete patch, sorry... This one should work.

[NETFILTER]: Reimplementation of 64bit counters for bytes/packets accounting

Initially netfilter has had 64bit counters for conntrack-based accounting, but
it was changed in 2.6.14 to save memory. Unfortunately in-kernel 64bit counters are
still required, for example for the "connbytes" extension.

Signed-off-by: Krzysztof Piotr Oledzki <ole at ans.pl>

diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
index 9e0dae0..7a29936 100644
--- a/include/linux/netfilter/nf_conntrack_common.h
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -122,10 +122,6 @@ enum ip_conntrack_events
  	IPCT_NATINFO_BIT = 10,
  	IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),

-	/* Counter highest bit has been set */
-	IPCT_COUNTER_FILLING_BIT = 11,
-	IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
-
  	/* Mark is set */
  	IPCT_MARK_BIT = 12,
  	IPCT_MARK = (1 << IPCT_MARK_BIT),
@@ -139,8 +135,8 @@ enum ip_conntrack_expect_events {
  #ifdef __KERNEL__
  struct ip_conntrack_counter
  {
-	u_int32_t packets;
-	u_int32_t bytes;
+	u_int64_t packets;
+	u_int64_t bytes;
  };

  struct ip_conntrack_stat
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index d7c3503..75f3df8 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -93,10 +93,10 @@ enum ctattr_protoinfo_tcp {

  enum ctattr_counters {
  	CTA_COUNTERS_UNSPEC,
-	CTA_COUNTERS_PACKETS,		/* old 64bit counters */
-	CTA_COUNTERS_BYTES,		/* old 64bit counters */
-	CTA_COUNTERS32_PACKETS,
-	CTA_COUNTERS32_BYTES,
+	CTA_COUNTERS_PACKETS,		/* 64bit counters */
+	CTA_COUNTERS_BYTES,		/* 64bit counters */
+	CTA_COUNTERS32_PACKETS,		/* 32bit counters, unused */
+	CTA_COUNTERS32_BYTES,		/* 32bit counters, unused */
  	__CTA_COUNTERS_MAX
  };
  #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index aa086c8..25e027f 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -806,9 +806,6 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
  		ct->counters[CTINFO2DIR(ctinfo)].bytes +=
  			skb->len - skb_network_offset(skb);

-		if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
-		    || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
-			event |= IPCT_COUNTER_FILLING;
  	}
  #endif

diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 6f89b10..b53284f 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -204,13 +204,13 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
  {
  	enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
  	struct nfattr *nest_count = NFA_NEST(skb, type);
-	__be32 tmp;
+	__be64 tmp;

-	tmp = htonl(ct->counters[dir].packets);
-	NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
+	tmp = cpu_to_be64(ct->counters[dir].packets);
+	NFA_PUT(skb, CTA_COUNTERS_PACKETS, sizeof(__be64), &tmp);

-	tmp = htonl(ct->counters[dir].bytes);
-	NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
+	tmp = cpu_to_be64(ct->counters[dir].bytes);
+	NFA_PUT(skb, CTA_COUNTERS_BYTES, sizeof(__be64), &tmp);

  	NFA_NEST_END(skb, nest_count);

@@ -397,10 +397,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
  			goto nfattr_failure;
  #endif

-		if (events & IPCT_COUNTER_FILLING &&
-		    (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
-		     ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0))
-			goto nfattr_failure;
  	}

  	nlh->nlmsg_len = skb->tail - b;


Best regards,

 				Krzysztof Olędzki
-------------- next part --------------
[NETFILTER]: Reimplementation of 64bit counters for bytes/packets accounting

Initially netfilter has had 64bit counters for conntrack-based accounting, but
it was changed in 2.6.14 to save memory. Unfortunately in-kernel 64bit counters are
still required, for example for the "connbytes" extension.

Signed-off-by: Krzysztof Piotr Oledzki <ole at ans.pl>

diff --git a/include/linux/netfilter/nf_conntrack_common.h b/include/linux/netfilter/nf_conntrack_common.h
index 9e0dae0..7a29936 100644
--- a/include/linux/netfilter/nf_conntrack_common.h
+++ b/include/linux/netfilter/nf_conntrack_common.h
@@ -122,10 +122,6 @@ enum ip_conntrack_events
 	IPCT_NATINFO_BIT = 10,
 	IPCT_NATINFO = (1 << IPCT_NATINFO_BIT),
 
-	/* Counter highest bit has been set */
-	IPCT_COUNTER_FILLING_BIT = 11,
-	IPCT_COUNTER_FILLING = (1 << IPCT_COUNTER_FILLING_BIT),
-
 	/* Mark is set */
 	IPCT_MARK_BIT = 12,
 	IPCT_MARK = (1 << IPCT_MARK_BIT),
@@ -139,8 +135,8 @@ enum ip_conntrack_expect_events {
 #ifdef __KERNEL__
 struct ip_conntrack_counter
 {
-	u_int32_t packets;
-	u_int32_t bytes;
+	u_int64_t packets;
+	u_int64_t bytes;
 };
 
 struct ip_conntrack_stat
diff --git a/include/linux/netfilter/nfnetlink_conntrack.h b/include/linux/netfilter/nfnetlink_conntrack.h
index d7c3503..75f3df8 100644
--- a/include/linux/netfilter/nfnetlink_conntrack.h
+++ b/include/linux/netfilter/nfnetlink_conntrack.h
@@ -93,10 +93,10 @@ enum ctattr_protoinfo_tcp {
 
 enum ctattr_counters {
 	CTA_COUNTERS_UNSPEC,
-	CTA_COUNTERS_PACKETS,		/* old 64bit counters */
-	CTA_COUNTERS_BYTES,		/* old 64bit counters */
-	CTA_COUNTERS32_PACKETS,
-	CTA_COUNTERS32_BYTES,
+	CTA_COUNTERS_PACKETS,		/* 64bit counters */
+	CTA_COUNTERS_BYTES,		/* 64bit counters */
+	CTA_COUNTERS32_PACKETS,		/* 32bit counters, unused */
+	CTA_COUNTERS32_BYTES,		/* 32bit counters, unused */
 	__CTA_COUNTERS_MAX
 };
 #define CTA_COUNTERS_MAX (__CTA_COUNTERS_MAX - 1)
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index aa086c8..25e027f 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -806,9 +806,6 @@ void __nf_ct_refresh_acct(struct nf_conn *ct,
 		ct->counters[CTINFO2DIR(ctinfo)].bytes +=
 			skb->len - skb_network_offset(skb);
 
-		if ((ct->counters[CTINFO2DIR(ctinfo)].packets & 0x80000000)
-		    || (ct->counters[CTINFO2DIR(ctinfo)].bytes & 0x80000000))
-			event |= IPCT_COUNTER_FILLING;
 	}
 #endif
 
diff --git a/net/netfilter/nf_conntrack_netlink.c b/net/netfilter/nf_conntrack_netlink.c
index 6f89b10..b53284f 100644
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -204,13 +204,13 @@ ctnetlink_dump_counters(struct sk_buff *skb, const struct nf_conn *ct,
 {
 	enum ctattr_type type = dir ? CTA_COUNTERS_REPLY: CTA_COUNTERS_ORIG;
 	struct nfattr *nest_count = NFA_NEST(skb, type);
-	__be32 tmp;
+	__be64 tmp;
 
-	tmp = htonl(ct->counters[dir].packets);
-	NFA_PUT(skb, CTA_COUNTERS32_PACKETS, sizeof(u_int32_t), &tmp);
+	tmp = cpu_to_be64(ct->counters[dir].packets);
+	NFA_PUT(skb, CTA_COUNTERS_PACKETS, sizeof(__be64), &tmp);
 
-	tmp = htonl(ct->counters[dir].bytes);
-	NFA_PUT(skb, CTA_COUNTERS32_BYTES, sizeof(u_int32_t), &tmp);
+	tmp = cpu_to_be64(ct->counters[dir].bytes);
+	NFA_PUT(skb, CTA_COUNTERS_BYTES, sizeof(__be64), &tmp);
 
 	NFA_NEST_END(skb, nest_count);
 
@@ -397,10 +397,6 @@ static int ctnetlink_conntrack_event(struct notifier_block *this,
 			goto nfattr_failure;
 #endif
 
-		if (events & IPCT_COUNTER_FILLING &&
-		    (ctnetlink_dump_counters(skb, ct, IP_CT_DIR_ORIGINAL) < 0 ||
-		     ctnetlink_dump_counters(skb, ct, IP_CT_DIR_REPLY) < 0))
-			goto nfattr_failure;
 	}
 
 	nlh->nlmsg_len = skb->tail - b;


More information about the netfilter-devel mailing list