--- /dev/null
+From stable-bounces@linux.kernel.org Tue Jan 30 16:37:35 2007
+Message-ID: <45BFE271.6000704@trash.net>
+Date: Wed, 31 Jan 2007 01:27:29 +0100
+From: Patrick McHardy <kaber@trash.net>
+To: stable@kernel.org
+Cc: Netfilter Development Mailinglist <netfilter-devel@lists.netfilter.org>, "David S. Miller" <davem@davemloft.net>
+Subject: NETFILTER: xt_connbytes: fix division by zero
+
+When the packet counter of a connection is zero a division by zero
+occurs in div64_64(). Fix that by using zero as average value, which
+is correct as long as the packet counter didn't overflow, at which
+point we have lost anyway.
+
+Additionally we're probably going to go back to 64 bit counters
+in 2.6.21.
+
+Based on patch from Jonas Berlin <xkr47@outerspace.dyndns.org>,
+with suggestions from KOVACS Krisztian <hidden@balabit.hu>.
+
+Signed-off-by: Patrick McHardy <kaber@trash.net>
+Signed-off-by: Chris Wright <chrisw@sous-sol.org>
+---
+ net/netfilter/xt_connbytes.c | 29 ++++++++++++-----------------
+ 1 file changed, 12 insertions(+), 17 deletions(-)
+
+--- linux-2.6.19.2.orig/net/netfilter/xt_connbytes.c
++++ linux-2.6.19.2/net/netfilter/xt_connbytes.c
+@@ -52,6 +52,8 @@ match(const struct sk_buff *skb,
+ {
+ const struct xt_connbytes_info *sinfo = matchinfo;
+ u_int64_t what = 0; /* initialize to make gcc happy */
++ u_int64_t bytes = 0;
++ u_int64_t pkts = 0;
+ const struct ip_conntrack_counter *counters;
+
+ if (!(counters = nf_ct_get_counters(skb)))
+@@ -89,29 +91,22 @@ match(const struct sk_buff *skb,
+ case XT_CONNBYTES_AVGPKT:
+ switch (sinfo->direction) {
+ case XT_CONNBYTES_DIR_ORIGINAL:
+- what = div64_64(counters[IP_CT_DIR_ORIGINAL].bytes,
+- counters[IP_CT_DIR_ORIGINAL].packets);
++ bytes = counters[IP_CT_DIR_ORIGINAL].bytes;
++ pkts = counters[IP_CT_DIR_ORIGINAL].packets;
+ break;
+ case XT_CONNBYTES_DIR_REPLY:
+- what = div64_64(counters[IP_CT_DIR_REPLY].bytes,
+- counters[IP_CT_DIR_REPLY].packets);
++ bytes = counters[IP_CT_DIR_REPLY].bytes;
++ pkts = counters[IP_CT_DIR_REPLY].packets;
+ break;
+ case XT_CONNBYTES_DIR_BOTH:
+- {
+- u_int64_t bytes;
+- u_int64_t pkts;
+- bytes = counters[IP_CT_DIR_ORIGINAL].bytes +
+- counters[IP_CT_DIR_REPLY].bytes;
+- pkts = counters[IP_CT_DIR_ORIGINAL].packets+
+- counters[IP_CT_DIR_REPLY].packets;
+-
+- /* FIXME_THEORETICAL: what to do if sum
+- * overflows ? */
+-
+- what = div64_64(bytes, pkts);
+- }
++ bytes = counters[IP_CT_DIR_ORIGINAL].bytes +
++ counters[IP_CT_DIR_REPLY].bytes;
++ pkts = counters[IP_CT_DIR_ORIGINAL].packets +
++ counters[IP_CT_DIR_REPLY].packets;
+ break;
+ }
++ if (pkts != 0)
++ what = div64_64(bytes, pkts);
+ break;
+ }
+