Skip to contentSkip to conversation

libnetfilter_conntrack: Packet/byte counters are 64 bit

PATCH In review Philip Craig 2 participants 3 messages Aug 14, 2007 – Sep 3, 2007 netfilter

lore
Share & tools
lore
#0 lore raw

PATCH 1/1 libnetfilter_conntrack: Packet/byte counters are 64 bit

The counters in struct nf_conntrack are 64 bit, so the getter/setter have to access them as such.

src/conntrack/api.c +29 -0
Index: libnetfilter_conntrack/src/conntrack/api.c
===================================================================
@@ -267,6 +267,19 @@
 }
 
 /**
+ * nfct_set_attr_u64 - set the value of a certain conntrack attribute
+ * @ct: pointer to a valid conntrack
+ * @type: attribute type
+ * @value: unsigned 64 bits attribute value
+ */
+void nfct_set_attr_u64(struct nf_conntrack *ct,
+		       const enum nf_conntrack_attr type,
+		       u_int64_t value)
+{
+	nfct_set_attr(ct, type, &value);
+}
+
+/**
  * nfct_get_attr - get a conntrack attribute
  * ct: pointer to a valid conntrack
  * @type: attribute type
@@ -341,6 +354,22 @@
 }
 
 /**
+ * nfct_get_attr_u64 - get attribute of unsigned 64-bits long
+ * @ct: pointer to a valid conntrack
+ * @type: attribute type
+ *
+ * Returns the value of the requested attribute, if the attribute is not
+ * set, 0 is returned. In order to check if the attribute is set or not,
+ * use nfct_attr_is_set.
+ */
+u_int64_t nfct_get_attr_u64(const struct nf_conntrack *ct,
+			    const enum nf_conntrack_attr type)
+{
+	const u_int64_t *ret = nfct_get_attr(ct, type);
+	return ret == NULL ? 0 : *ret;
+}
+
+/**
  * nfct_attr_is_set - check if a certain attribute is set
  * @ct: pointer to a valid conntrack object
  * @type: attribute type
include/libnetfilter_conntrack/libnetfilter_conntrack.h +11 -4
Index: libnetfilter_conntrack/include/libnetfilter_conntrack/libnetfilter_conntrack.h
===================================================================
@@ -91,10 +91,10 @@
 	ATTR_DNAT_PORT,				/* u16 bits */
 	ATTR_TIMEOUT = 24,			/* u32 bits */
 	ATTR_MARK,				/* u32 bits */
-	ATTR_ORIG_COUNTER_PACKETS,		/* u32 bits */
-	ATTR_REPL_COUNTER_PACKETS,		/* u32 bits */
-	ATTR_ORIG_COUNTER_BYTES = 28,		/* u32 bits */
-	ATTR_REPL_COUNTER_BYTES,		/* u32 bits */
+	ATTR_ORIG_COUNTER_PACKETS,		/* u64 bits */
+	ATTR_REPL_COUNTER_PACKETS,		/* u64 bits */
+	ATTR_ORIG_COUNTER_BYTES = 28,		/* u64 bits */
+	ATTR_REPL_COUNTER_BYTES,		/* u64 bits */
 	ATTR_USE,				/* u32 bits */
 	ATTR_ID,				/* u32 bits */
 	ATTR_STATUS = 32,			/* u32 bits  */
@@ -194,6 +194,10 @@
 			      const enum nf_conntrack_attr type,
 			      u_int32_t value);
 
+extern void nfct_set_attr_u64(struct nf_conntrack *ct,
+			      const enum nf_conntrack_attr type,
+			      u_int64_t value);
+
 /* getter */
 extern const void *nfct_get_attr(const struct nf_conntrack *ct,
 				 const enum nf_conntrack_attr type);
@@ -207,6 +211,9 @@
 extern u_int32_t nfct_get_attr_u32(const struct nf_conntrack *ct,
 				   const enum nf_conntrack_attr type);
 
+extern u_int64_t nfct_get_attr_u64(const struct nf_conntrack *ct,
+				   const enum nf_conntrack_attr type);
+
 /* checker */
 extern int nfct_attr_is_set(const struct nf_conntrack *ct,
 			    const enum nf_conntrack_attr type);
#1 lore raw
Quoted 2 lines · Philip Craig

The counters in struct nf_conntrack are 64 bit, so the getter/setter have to access them as such.

Still my kernel has 32 bit counters although I know that there was a patch on the table to recover 64 bits counters. I'm still getting in sync with the development again, did that patch finally hit mainline?

Signature · 2 lines
"Será preciso viajar por los ojos de los idiotas" -- Poeta en Nueva York
-- Federico García Lorca.
#2 lore raw
Quoted 7 lines · Pablo Neira Ayuso
Quoted 2 lines · Philip Craig

The counters in struct nf_conntrack are 64 bit, so the getter/setter have to access them as such.

Still my kernel has 32 bit counters although I know that there was a patch on the table to recover 64 bits counters. I'm still getting in sync with the development again, did that patch finally hit mainline?

The kernel still sends 32 bit from what I can see, but this is problem independent of what the kernel sends. The library handles receiving both 32 and 64 bit counters from the kernel, and stores them in a 64 bit field in a structure. The getter/setter then access that field, but that doesn't work if they access only 32 bits of it, at least for big endian.

An alternative fix is to change the nf_conntrack field to 32 bit, but I would only do that if you never intend for the kernel to send 64 bit counters.