All of lore.kernel.org
 help / color / mirror / Atom feed
* Backported conntrack-acct/connbytes to 2.4 tree
@ 2004-11-16 22:05 Piotr Chytla
  2004-11-21 16:34 ` Piotr Chytla
  0 siblings, 1 reply; 4+ messages in thread
From: Piotr Chytla @ 2004-11-16 22:05 UTC (permalink / raw)
  To: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 342 bytes --]

Hi ,

I attached two backports from 2.6 tree to 2.4 for patch-o-matic-ng , 

1) Backported conntrack-acct 
2) Backported connbytes with per-connection accounting support , also 
   shared library for iptables is attached . 
   Shared library for iptables works with connbytes from 2.6 tree.

/pch

PS. This is my first two patchs for pom-ng.

[-- Attachment #2: connbytes.patch --]
[-- Type: text/plain, Size: 15256 bytes --]

diff -Nru -x '*.orig' -x '*.rej' a/connbytes/info b/connbytes/info
--- a/connbytes/info	2004-07-22 16:53:13.000000000 +0200
+++ b/connbytes/info	2004-11-15 23:45:29.000000000 +0100
@@ -1,4 +1,4 @@
-Author: Harald Welte <laforge@netfilter.org> / Martin Devera <devik@cdi.cz> 
+Author: Piotr Chytla <pch@fouk.org> / Harald Welte <laforge@netfilter.org> / Martin Devera <devik@cdi.cz> 
 Status: Experimental
 Repository: extra
 Depends: !CONNMARK
diff -Nru -x '*.orig' -x '*.rej' a/connbytes/iptables/extensions/libipt_connbytes.c b/connbytes/iptables/extensions/libipt_connbytes.c
--- a/connbytes/iptables/extensions/libipt_connbytes.c	1970-01-01 01:00:00.000000000 +0100
+++ b/connbytes/iptables/extensions/libipt_connbytes.c	2004-11-15 22:17:46.000000000 +0100
@@ -0,0 +1,256 @@
+/* Shared library add-on to iptables to add byte tracking support. 
+ *
+ * 2004-11-11 - Piotr Chytla <pch@fouk.org>
+ * 	- Some adaptation to backported module with per-conntrack accounting
+ * 	- Added connpkts/connavgpkt/direction ,
+ *
+ */ 
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ipt_connbytes.h>
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+	printf(
+"connbytes v%s options:\n"
+" [!] --connbytes from:[to]\n"
+"				Transfered bytes range to match\n"
+" [!] --connpkts from:[to]\n"
+"				Transfered number of packets range to match\n"
+" [!] --connavgpkt from:[to]\n"
+"				Transfered average packet size range to match\n"
+" --direction original|reply|both\n"
+"				Match only from direction \n"
+"\n", IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{ "connpkts", 1, 0, '1' },
+	{ "connbytes", 1, 0, '2' },
+	{ "connavgpkt", 1, 0, '3' },
+	{ "direction", 1, 0, '4'},
+	{0}
+};
+
+static char *sinfo_names[] = {
+	"connpkts",
+	"connbytes",
+	"connavgpkt",
+	NULL
+};
+
+static char *sinfo_directions[] = {
+	"original",
+	"replay",
+	"both",
+	NULL
+};
+
+#define IPT_CONNBYTES_PKTS	0x1
+#define IPT_CONNBYTES_BYTES	0x2
+#define IPT_CONNBYTES_AVGPKT	0x4
+#define IPT_CONNBYTES_ORIGINAL	0x8
+#define IPT_CONNBYTES_REPLY	0x10
+#define IPT_CONNBYTES_BOTH	0x20
+
+/* Initialize the match. */
+static void
+init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+	/* Can't cache this */
+	*nfcache |= NFC_UNKNOWN;
+} 
+
+static void
+parse_range(const char *arg, struct ipt_connbytes_info *si)
+{
+	char *colon,*p;
+
+	si->count.from = strtoul(arg,&colon,10);
+	if (*colon != ':') 
+		exit_error(PARAMETER_PROBLEM, "Bad range `%s'", arg);
+	si->count.to = strtoul(colon+1,&p,10);
+	if (p == colon+1) {
+		/* second number omited */
+		si->count.to = 0xffffffff;
+	}
+	if (si->count.from > si->count.to)
+		exit_error(PARAMETER_PROBLEM, "%llu should be less than %llu", si->count.from,si->count.to);
+}
+
+static int 
+parse_direction(const char *direction,size_t strlen,struct ipt_connbytes_info *sinfo,unsigned int *flags)
+{
+	if (strncasecmp(direction,"original",strlen) == 0)
+	{
+		sinfo->direction=IPT_CONNBYTES_DIR_ORIGINAL;
+		*flags |= IPT_CONNBYTES_ORIGINAL;
+	} else if (strncasecmp(direction,"both",strlen) == 0) 
+	{
+		sinfo->direction=IPT_CONNBYTES_DIR_BOTH;
+		*flags |= IPT_CONNBYTES_BOTH;
+	} else if (strncasecmp(direction,"replay",strlen) == 0)
+	{
+		sinfo->direction=IPT_CONNBYTES_DIR_REPLY;
+		*flags |= IPT_CONNBYTES_REPLY;
+	} else return 0;
+	return 1;
+}
+	
+
+/* Function which parses command options; returns true if it
+   ate an option */
+static int
+parse(int c, char **argv, int invert, unsigned int *flags,
+      const struct ipt_entry *entry,
+      unsigned int *nfcache,
+      struct ipt_entry_match **match)
+{
+	struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)(*match)->data;
+	unsigned long i;
+	switch (c) {
+	case '2':
+		if (*flags & IPT_CONNBYTES_BYTES)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't specify --connbytes twice");
+		if (*flags & IPT_CONNBYTES_PKTS)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connpkts and --connbytes together");
+		if (*flags & IPT_CONNBYTES_AVGPKT)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connavgpkt and --connbytes together");
+
+		if (check_inverse(optarg, &invert, &optind, 0))
+			optind++;
+
+		parse_range(argv[optind-1], sinfo);
+		if (invert) {
+			i = sinfo->count.from;
+			sinfo->count.from = sinfo->count.to;
+			sinfo->count.to = i;
+		}
+		sinfo->what=IPT_CONNBYTES_WHAT_BYTES;
+		sinfo->direction=IPT_CONNBYTES_DIR_BOTH;
+		*flags |= IPT_CONNBYTES_BYTES;
+		break;
+	case '1':
+		if (*flags & IPT_CONNBYTES_PKTS)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't specify --connpkts twice");
+		if (*flags & IPT_CONNBYTES_BYTES)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connbytes and --connpkts together");
+		if (*flags & IPT_CONNBYTES_AVGPKT)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connavgpkt and --connpkts together");
+		
+		if (check_inverse(optarg,&invert,&optind,0))
+			optind++;
+
+		parse_range(argv[optind-1],sinfo);
+		if (invert) {
+			i = sinfo->count.from;
+			sinfo->count.from = sinfo->count.to;
+			sinfo->count.to = i;
+		}
+		sinfo->what=IPT_CONNBYTES_WHAT_PKTS;
+		sinfo->direction=IPT_CONNBYTES_DIR_BOTH;
+		*flags |= IPT_CONNBYTES_PKTS;
+		break;
+	case '3':
+		if (*flags & IPT_CONNBYTES_AVGPKT)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't specify --connavgpkt twice");
+		if (*flags & IPT_CONNBYTES_PKTS)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connpkts and --connavgpkt together");
+		if (*flags & IPT_CONNBYTES_BYTES)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connbytes and --connavgpkt together");
+		
+		if (check_inverse(optarg,&invert,&optind,0))
+			optind++;
+
+		parse_range(argv[optind-1],sinfo);
+		if (invert) {
+			i = sinfo->count.from;
+			sinfo->count.from = sinfo->count.to;
+			sinfo->count.to = i;
+		}
+		sinfo->what=IPT_CONNBYTES_WHAT_AVGPKT;
+		sinfo->direction=IPT_CONNBYTES_DIR_BOTH;
+		*flags |= IPT_CONNBYTES_AVGPKT;
+		break;
+	case '4':
+		if (*flags & (IPT_CONNBYTES_ORIGINAL|IPT_CONNBYTES_BOTH|IPT_CONNBYTES_REPLY))
+			exit_error(PARAMETER_PROBLEM,
+					"Can't specify --direction twice");
+		if (!parse_direction(argv[optind-1],strlen(argv[optind-1]),sinfo,flags))
+			exit_error(PARAMETER_PROBLEM, "Bad direction '%s'",argv[optind-1]);
+		
+		break;
+	default:	
+		return 0;
+	}
+	return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM, "You must specify `--connbytes or --connpkts or--connavgpkt'");
+}
+
+/* Prints out the matchinfo. */
+static void
+print(const struct ipt_ip *ip,
+      const struct ipt_entry_match *match,
+      int numeric)
+{
+	struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)match->data;
+
+		if (sinfo->count.from > sinfo->count.to) 
+			printf("%s ! %llu:%llu direction:%s",sinfo_names[sinfo->what],sinfo->count.to,sinfo->count.from,sinfo_directions[sinfo->direction]);
+		else
+		printf("%s %llu:%llu direction:%s",sinfo_names[sinfo->what],sinfo->count.from,sinfo->count.to,sinfo_directions[sinfo->direction]);
+}
+
+/* Saves the matchinfo in parsable form to stdout. */
+static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+{
+	struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)match->data;
+
+	if (sinfo->count.from > sinfo->count.to) 
+		printf("! --%s %llu:%llu --direction %s",sinfo_names[sinfo->what],sinfo->count.to,sinfo->count.from,sinfo_directions[sinfo->direction]);
+	else
+		printf("--%s %llu:%llu --direction %s",sinfo_names[sinfo->what],sinfo->count.from,sinfo->count.to,sinfo_directions[sinfo->direction]);
+}
+
+static
+struct iptables_match state
+= { NULL,
+    "connbytes",
+    IPTABLES_VERSION,
+    IPT_ALIGN(sizeof(struct ipt_connbytes_info)),
+    IPT_ALIGN(sizeof(struct ipt_connbytes_info)),
+    &help,
+    &init,
+    &parse,
+    &final_check,
+    &print,
+    &save,
+    opts
+};
+
+void _init(void)
+{
+	register_match(&state);
+}
diff -Nru -x '*.orig' -x '*.rej' a/connbytes/linux-2.4/include/linux/netfilter_ipv4/ipt_connbytes.h b/connbytes/linux-2.4/include/linux/netfilter_ipv4/ipt_connbytes.h
--- a/connbytes/linux-2.4/include/linux/netfilter_ipv4/ipt_connbytes.h	2004-04-07 13:04:28.000000000 +0200
+++ b/connbytes/linux-2.4/include/linux/netfilter_ipv4/ipt_connbytes.h	2004-11-11 21:05:52.000000000 +0100
@@ -1,10 +1,25 @@
 #ifndef _IPT_CONNBYTES_H
 #define _IPT_CONNBYTES_H
+enum ipt_connbytes_what {
+	        IPT_CONNBYTES_WHAT_PKTS,
+	        IPT_CONNBYTES_WHAT_BYTES,
+	        IPT_CONNBYTES_WHAT_AVGPKT,
+};
+
+enum ipt_connbytes_direction {
+	        IPT_CONNBYTES_DIR_ORIGINAL,
+	        IPT_CONNBYTES_DIR_REPLY,
+	        IPT_CONNBYTES_DIR_BOTH,
+};
 
 struct ipt_connbytes_info
 {
-       /* if from <= to then it matches the range; if from > to then
-          inverse range is matched */
-       unsigned long from, to;
+        struct {
+                u_int64_t from; /* count to be matched */
+                u_int64_t to;   /* count to be matched */
+        } count;
+        u_int8_t what;          /* ipt_connbytes_what */
+        u_int8_t direction;     /* ipt_connbytes_direction */
 };
+
 #endif
diff -Nru -x '*.orig' -x '*.rej' a/connbytes/linux-2.4/net/ipv4/netfilter/ipt_connbytes.c b/connbytes/linux-2.4/net/ipv4/netfilter/ipt_connbytes.c
--- a/connbytes/linux-2.4/net/ipv4/netfilter/ipt_connbytes.c	2004-04-07 13:04:28.000000000 +0200
+++ b/connbytes/linux-2.4/net/ipv4/netfilter/ipt_connbytes.c	2004-11-15 22:11:20.000000000 +0100
@@ -1,12 +1,32 @@
 /* Kernel module to match connection tracking byte counter.
  * GPL (C) 2002 Martin Devera (devik@cdi.cz).
+ *
+ * 2004-07-20 Harald Welte <laforge@netfilter.org>
+ *      - reimplemented to use per-connection accounting counters
+ *      - add functionality to match number of packets
+ *      - add functionality to match average packet size
+ *      - add support to match directions seperately
+ *
+ * 2004-10-24 Piotr Chytla <pch@fouk.org>
+ * 	- Connbytes with per-connection accouting backported to 2.4
+ * 	
  */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/types.h>
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ipt_connbytes.h>
 
+#include <asm/div64.h>
+
+static u_int64_t mydiv(u_int64_t arg1,u_int32_t arg2)
+{
+	do_div(arg1,arg2);
+	return arg1;
+}
+
 static int
 match(const struct sk_buff *skb,
       const struct net_device *in,
@@ -17,17 +37,89 @@
       u_int16_t datalen,
       int *hotdrop)
 {
+	static u_int64_t what;
 	const struct ipt_connbytes_info *sinfo = matchinfo;
 	enum ip_conntrack_info ctinfo;
 	struct ip_conntrack *ct;
 
 	if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)))
 		return 0; /* no match */
-	
-	if (sinfo->from > sinfo->to)
-		return (ct->bytes < sinfo->to || ct->bytes > sinfo->from);
-	else
-		return (ct->bytes >= sinfo->from && ct->bytes <= sinfo->to);
+        switch (sinfo->what) {
+        case IPT_CONNBYTES_WHAT_PKTS:
+                switch (sinfo->direction) {
+                case IPT_CONNBYTES_DIR_ORIGINAL:
+                        what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
+                        break;
+                case IPT_CONNBYTES_DIR_REPLY:
+                        what = ct->counters[IP_CT_DIR_REPLY].packets;
+                        break;
+                case IPT_CONNBYTES_DIR_BOTH:
+                        what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
+                        what += ct->counters[IP_CT_DIR_REPLY].packets;
+                        break;
+                }
+                break;
+        case IPT_CONNBYTES_WHAT_BYTES:
+                switch (sinfo->direction) {
+                case IPT_CONNBYTES_DIR_ORIGINAL:
+                        what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
+                        break;
+                case IPT_CONNBYTES_DIR_REPLY:
+                        what = ct->counters[IP_CT_DIR_REPLY].bytes;
+                        break;
+                case IPT_CONNBYTES_DIR_BOTH:
+                        what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
+                        what += ct->counters[IP_CT_DIR_REPLY].bytes;
+                        break;
+                }
+                break;
+        case IPT_CONNBYTES_WHAT_AVGPKT:
+                switch (sinfo->direction) {
+                case IPT_CONNBYTES_DIR_ORIGINAL:
+                        {
+                                u_int32_t pkts32;
+
+                                if (ct->counters[IP_CT_DIR_ORIGINAL].packets > 0xfffffffff)
+                                        pkts32 = 0xffffffff;
+                                else
+                                        pkts32 = ct->counters[IP_CT_DIR_ORIGINAL].packets;
+				what = mydiv(ct->counters[IP_CT_DIR_ORIGINAL].bytes,pkts32);
+                        }
+                        break;
+                case IPT_CONNBYTES_DIR_REPLY:
+                        {
+                                u_int32_t pkts32;
+
+                                if (ct->counters[IP_CT_DIR_REPLY].packets > 0xffffffff)
+                                        pkts32 = 0xffffffff;
+                                else
+                                        pkts32 = ct->counters[IP_CT_DIR_REPLY].packets;
+				what = mydiv(ct->counters[IP_CT_DIR_REPLY].bytes,pkts32);
+                        }
+                        break;
+                case IPT_CONNBYTES_DIR_BOTH:
+                        {
+                                u_int64_t bytes;
+                                u_int64_t pkts;
+                                u_int32_t pkts32;
+                                bytes = ct->counters[IP_CT_DIR_ORIGINAL].bytes +
+                                        ct->counters[IP_CT_DIR_REPLY].bytes;
+                                pkts = ct->counters[IP_CT_DIR_ORIGINAL].packets +
+                                        ct->counters[IP_CT_DIR_REPLY].packets;
+                                if (pkts > 0xffffffff)
+                                        pkts32 =  0xffffffff;
+                                else
+                                        pkts32 = pkts;
+				what = mydiv(bytes,pkts);
+                        }
+                        break;
+                }
+                break;
+        }
+        if (sinfo->count.to)
+                return (what <= sinfo->count.to && what >= sinfo->count.from);
+        else
+                return (what >= sinfo->count.from);
 }
 
 static int check(const char *tablename,
@@ -36,8 +128,19 @@
 		 unsigned int matchsize,
 		 unsigned int hook_mask)
 {
+	const struct ipt_connbytes_info *sinfo = matchinfo;
+
 	if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info)))
 		return 0;
+        if (sinfo->what != IPT_CONNBYTES_WHAT_PKTS &&
+		       sinfo->what != IPT_CONNBYTES_WHAT_BYTES &&
+		       sinfo->what != IPT_CONNBYTES_WHAT_AVGPKT)
+		       return 0;
+
+       if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL &&
+			sinfo->direction != IPT_CONNBYTES_DIR_REPLY &&
+	                sinfo->direction != IPT_CONNBYTES_DIR_BOTH)
+		       return 0;
 
 	return 1;
 }

[-- Attachment #3: conntrack-acct.patch --]
[-- Type: text/plain, Size: 10001 bytes --]

diff -Nru -x '*.orig' -x '*.rej' a/conntrack-acct/info b/conntrack-acct/info
--- a/conntrack-acct/info	2004-07-22 21:22:09.000000000 +0200
+++ b/conntrack-acct/info	2004-11-15 23:45:45.000000000 +0100
@@ -1,3 +1,3 @@
-Author: Harald Welte <laforge@netfilter.org> 
+Author: Piotr Chytla <pch@fouk.org> / Harald Welte <laforge@netfilter.org> 
 Status: Stable
 Repository: pending
diff -Nru -x '*.orig' -x '*.rej' a/conntrack-acct/linux-2.4/net/ipv4/netfilter/Config.in.ladd b/conntrack-acct/linux-2.4/net/ipv4/netfilter/Config.in.ladd
--- a/conntrack-acct/linux-2.4/net/ipv4/netfilter/Config.in.ladd	1970-01-01 01:00:00.000000000 +0100
+++ b/conntrack-acct/linux-2.4/net/ipv4/netfilter/Config.in.ladd	2004-11-15 22:43:12.000000000 +0100
@@ -0,0 +1,3 @@
+    dep_tristate '  IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK             
+    dep_tristate '  Connection tracking flow accounting' CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK
+
diff -Nru -x '*.orig' -x '*.rej' a/conntrack-acct/linux-2.4.patch b/conntrack-acct/linux-2.4.patch
--- a/conntrack-acct/linux-2.4.patch	1970-01-01 01:00:00.000000000 +0100
+++ b/conntrack-acct/linux-2.4.patch	2004-11-15 23:09:20.000000000 +0100
@@ -0,0 +1,210 @@
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
+--- a/include/linux/netfilter_ipv4/ip_conntrack.h	2004-08-08 01:26:06.000000000 +0200
++++ b/include/linux/netfilter_ipv4/ip_conntrack.h	2004-11-14 20:55:47.000000000 +0100
+@@ -156,6 +156,12 @@
+ 	union ip_conntrack_expect_help help;
+ };
+ 
++struct ip_conntrack_counter
++{
++       u_int64_t packets;
++       u_int64_t bytes;
++};
++
+ struct ip_conntrack_helper;
+ 
+ struct ip_conntrack
+@@ -173,6 +179,12 @@
+ 	/* Timer function; drops refcnt when it goes off. */
+ 	struct timer_list timeout;
+ 
++#if defined(CONFIG_IP_NF_CT_ACCT) || \
++	defined(CONFIG_IP_NF_CT_ACCT_MODULE)
++       /* Accounting Information (same cache line as other written members) */
++       struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
++#endif
++
+ 	/* If we're expecting another related connection, this will be
+            in expected linked list */
+ 	struct list_head sibling_list;
+@@ -242,8 +254,10 @@
+ 			  const struct ip_conntrack_tuple *orig);
+ 
+ /* Refresh conntrack for this many jiffies */
+-extern void ip_ct_refresh(struct ip_conntrack *ct,
+-			  unsigned long extra_jiffies);
++extern void ip_ct_refresh_acct(struct ip_conntrack *ct,
++                              enum ip_conntrack_info ctinfo,
++                              const struct iphdr *iph,
++                              unsigned long extra_jiffies);
+ 
+ /* These are for NAT.  Icky. */
+ /* Call me when a conntrack is destroyed. */
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
+--- a/net/ipv4/netfilter/ip_conntrack_amanda.c	2004-02-18 14:36:32.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_amanda.c	2004-11-14 20:29:39.000000000 +0100
+@@ -75,7 +75,7 @@
+ 
+ 	/* increase the UDP timeout of the master connection as replies from
+ 	 * Amanda clients to the server can be quite delayed */
+-	ip_ct_refresh(ct, master_timeout * HZ);
++	ip_ct_refresh_acct(ct,ctinfo,NULL, master_timeout * HZ);
+ 	
+ 	/* Search for "CONNECT " string */
+ 	do {
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
+--- a/net/ipv4/netfilter/ip_conntrack_core.c	2004-08-08 01:26:06.000000000 +0200
++++ b/net/ipv4/netfilter/ip_conntrack_core.c	2004-11-14 20:29:52.000000000 +0100
+@@ -1164,21 +1164,40 @@
+ 	MOD_DEC_USE_COUNT;
+ }
+ 
++static inline void ct_add_counters(struct ip_conntrack *ct,
++                                enum ip_conntrack_info ctinfo,
++                                 const struct iphdr *iph)
++{
++#if defined(CONFIG_IP_NF_CT_ACCT) || \
++	defined(CONFIG_IP_NF_CT_ACCT_MODULE)
++     if (iph) {
++            ct->counters[CTINFO2DIR(ctinfo)].packets++;
++            ct->counters[CTINFO2DIR(ctinfo)].bytes += 
++                                ntohs(iph->tot_len);
++   }
++#endif
++}
++
+ /* Refresh conntrack for this many jiffies. */
+-void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies)
++void ip_ct_refresh_acct(struct ip_conntrack *ct, 
++                       enum ip_conntrack_info ctinfo,
++                       const struct iphdr *iph,
++                       unsigned long extra_jiffies)
+ {
+ 	IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
+ 
+ 	WRITE_LOCK(&ip_conntrack_lock);
+ 	/* If not in hash table, timer will not be active yet */
+-	if (!is_confirmed(ct))
++	if (!is_confirmed(ct)) {
+ 		ct->timeout.expires = extra_jiffies;
+-	else {
++		ct_add_counters(ct, ctinfo,iph);
++	} else {
+ 		/* Need del_timer for race avoidance (may already be dying). */
+ 		if (del_timer(&ct->timeout)) {
+ 			ct->timeout.expires = jiffies + extra_jiffies;
+ 			add_timer(&ct->timeout);
+ 		}
++		ct_add_counters(ct, ctinfo, iph);
+ 	}
+ 	WRITE_UNLOCK(&ip_conntrack_lock);
+ }
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_proto_generic.c b/net/ipv4/netfilter/ip_conntrack_proto_generic.c
+--- a/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2003-11-28 19:26:21.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2004-11-14 20:30:15.000000000 +0100
+@@ -41,9 +41,9 @@
+ /* Returns verdict for packet, or -1 for invalid. */
+ static int established(struct ip_conntrack *conntrack,
+ 		       struct iphdr *iph, size_t len,
+-		       enum ip_conntrack_info conntrackinfo)
++		       enum ip_conntrack_info ctinfo)
+ {
+-	ip_ct_refresh(conntrack, ip_ct_generic_timeout);
++	ip_ct_refresh_acct(conntrack, ctinfo,iph,ip_ct_generic_timeout);
+ 	return NF_ACCEPT;
+ }
+ 
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2003-11-28 19:26:21.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2004-11-14 20:30:18.000000000 +0100
+@@ -82,7 +82,7 @@
+ 			ct->timeout.function((unsigned long)ct);
+ 	} else {
+ 		atomic_inc(&ct->proto.icmp.count);
+-		ip_ct_refresh(ct, ip_ct_icmp_timeout);
++		ip_ct_refresh_acct(ct,ctinfo,iph, ip_ct_icmp_timeout);
+ 	}
+ 
+ 	return NF_ACCEPT;
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2003-11-28 19:26:21.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2004-11-14 20:30:26.000000000 +0100
+@@ -211,7 +211,7 @@
+ 			set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ 
+ 		WRITE_UNLOCK(&tcp_lock);
+-		ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
++		ip_ct_refresh_acct(conntrack,ctinfo,iph, *tcp_timeouts[newconntrack]);
+ 	}
+ 
+ 	return NF_ACCEPT;
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
+--- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2003-11-28 19:26:21.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2004-11-14 20:30:23.000000000 +0100
+@@ -47,16 +47,16 @@
+ /* Returns verdict for packet, and may modify conntracktype */
+ static int udp_packet(struct ip_conntrack *conntrack,
+ 		      struct iphdr *iph, size_t len,
+-		      enum ip_conntrack_info conntrackinfo)
++		      enum ip_conntrack_info ctinfo)
+ {
+ 	/* If we've seen traffic both ways, this is some kind of UDP
+ 	   stream.  Extend timeout. */
+ 	if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
+-		ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
++		ip_ct_refresh_acct(conntrack,ctinfo,iph,ip_ct_udp_timeout_stream);
+ 		/* Also, more likely to be important, and not a probe */
+ 		set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ 	} else
+-		ip_ct_refresh(conntrack, ip_ct_udp_timeout);
++		ip_ct_refresh_acct(conntrack,ctinfo,iph, ip_ct_udp_timeout);
+ 
+ 	return NF_ACCEPT;
+ }
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
+--- a/net/ipv4/netfilter/ip_conntrack_standalone.c	2004-08-08 01:26:06.000000000 +0200
++++ b/net/ipv4/netfilter/ip_conntrack_standalone.c	2004-11-14 20:30:30.000000000 +0100
+@@ -79,6 +79,18 @@
+ 	return len;
+ }
+ 
++#if defined(CONFIG_IP_NF_CT_ACCT) || \
++	defined(CONFIG_IP_NF_CT_ACCT_MODULE)
++static unsigned int
++print_counters(char *buffer, struct ip_conntrack_counter *counter)
++{
++       return sprintf(buffer, "packets=%llu bytes=%llu ", 
++                       counter->packets, counter->bytes);
++}
++#else
++#define print_counters(x, y)   0
++#endif
++
+ static unsigned int
+ print_conntrack(char *buffer, struct ip_conntrack *conntrack)
+ {
+@@ -98,11 +110,15 @@
+ 	len += print_tuple(buffer + len,
+ 			   &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+ 			   proto);
++       len += print_counters(buffer + len, 
++                             &conntrack->counters[IP_CT_DIR_ORIGINAL]);
+ 	if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
+ 		len += sprintf(buffer + len, "[UNREPLIED] ");
+ 	len += print_tuple(buffer + len,
+ 			   &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
+ 			   proto);
++       len += print_counters(buffer + len, 
++                            &conntrack->counters[IP_CT_DIR_REPLY]);
+ 	if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
+ 		len += sprintf(buffer + len, "[ASSURED] ");
+ 	len += sprintf(buffer + len, "use=%u ",
+@@ -467,7 +483,7 @@
+ EXPORT_SYMBOL(ip_conntrack_helper_register);
+ EXPORT_SYMBOL(ip_conntrack_helper_unregister);
+ EXPORT_SYMBOL(ip_ct_selective_cleanup);
+-EXPORT_SYMBOL(ip_ct_refresh);
++EXPORT_SYMBOL(ip_ct_refresh_acct);
+ EXPORT_SYMBOL(ip_ct_find_proto);
+ EXPORT_SYMBOL(__ip_ct_find_proto);
+ EXPORT_SYMBOL(ip_ct_find_helper);

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Backported conntrack-acct/connbytes to 2.4 tree
  2004-11-16 22:05 Backported conntrack-acct/connbytes to 2.4 tree Piotr Chytla
@ 2004-11-21 16:34 ` Piotr Chytla
  2005-04-01 10:02   ` Nikola Ciprich
  0 siblings, 1 reply; 4+ messages in thread
From: Piotr Chytla @ 2004-11-21 16:34 UTC (permalink / raw)
  To: netfilter-devel

[-- Attachment #1: Type: text/plain, Size: 416 bytes --]

On Tue, Nov 16, 2004 at 11:05:02PM +0100, Piotr Chytla wrote:
> 1) Backported conntrack-acct 
> 2) Backported connbytes with per-connection accounting support , also 
>    shared library for iptables is attached . 
>    Shared library for iptables works with connbytes from 2.6 tree.
> 
I've removed myself from pom-ng info file(fixed patches for pomng in attachment). 
I was stupid, sorry for inconvenience.


/pch

[-- Attachment #2: connbytes.patch --]
[-- Type: text/plain, Size: 14743 bytes --]

diff -Nru a/connbytes/iptables/extensions/libipt_connbytes.c b/connbytes/iptables/extensions/libipt_connbytes.c
--- a/connbytes/iptables/extensions/libipt_connbytes.c	1970-01-01 01:00:00.000000000 +0100
+++ b/connbytes/iptables/extensions/libipt_connbytes.c	2004-11-15 22:17:46.000000000 +0100
@@ -0,0 +1,256 @@
+/* Shared library add-on to iptables to add byte tracking support. 
+ *
+ * 2004-11-11 - Piotr Chytla <pch@fouk.org>
+ * 	- Some adaptation to backported module with per-conntrack accounting
+ * 	- Added connpkts/connavgpkt/direction ,
+ *
+ */ 
+
+#include <stdio.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <iptables.h>
+#include <linux/netfilter_ipv4/ip_conntrack.h>
+#include <linux/netfilter_ipv4/ipt_connbytes.h>
+
+/* Function which prints out usage message. */
+static void
+help(void)
+{
+	printf(
+"connbytes v%s options:\n"
+" [!] --connbytes from:[to]\n"
+"				Transfered bytes range to match\n"
+" [!] --connpkts from:[to]\n"
+"				Transfered number of packets range to match\n"
+" [!] --connavgpkt from:[to]\n"
+"				Transfered average packet size range to match\n"
+" --direction original|reply|both\n"
+"				Match only from direction \n"
+"\n", IPTABLES_VERSION);
+}
+
+static struct option opts[] = {
+	{ "connpkts", 1, 0, '1' },
+	{ "connbytes", 1, 0, '2' },
+	{ "connavgpkt", 1, 0, '3' },
+	{ "direction", 1, 0, '4'},
+	{0}
+};
+
+static char *sinfo_names[] = {
+	"connpkts",
+	"connbytes",
+	"connavgpkt",
+	NULL
+};
+
+static char *sinfo_directions[] = {
+	"original",
+	"replay",
+	"both",
+	NULL
+};
+
+#define IPT_CONNBYTES_PKTS	0x1
+#define IPT_CONNBYTES_BYTES	0x2
+#define IPT_CONNBYTES_AVGPKT	0x4
+#define IPT_CONNBYTES_ORIGINAL	0x8
+#define IPT_CONNBYTES_REPLY	0x10
+#define IPT_CONNBYTES_BOTH	0x20
+
+/* Initialize the match. */
+static void
+init(struct ipt_entry_match *m, unsigned int *nfcache)
+{
+	/* Can't cache this */
+	*nfcache |= NFC_UNKNOWN;
+} 
+
+static void
+parse_range(const char *arg, struct ipt_connbytes_info *si)
+{
+	char *colon,*p;
+
+	si->count.from = strtoul(arg,&colon,10);
+	if (*colon != ':') 
+		exit_error(PARAMETER_PROBLEM, "Bad range `%s'", arg);
+	si->count.to = strtoul(colon+1,&p,10);
+	if (p == colon+1) {
+		/* second number omited */
+		si->count.to = 0xffffffff;
+	}
+	if (si->count.from > si->count.to)
+		exit_error(PARAMETER_PROBLEM, "%llu should be less than %llu", si->count.from,si->count.to);
+}
+
+static int 
+parse_direction(const char *direction,size_t strlen,struct ipt_connbytes_info *sinfo,unsigned int *flags)
+{
+	if (strncasecmp(direction,"original",strlen) == 0)
+	{
+		sinfo->direction=IPT_CONNBYTES_DIR_ORIGINAL;
+		*flags |= IPT_CONNBYTES_ORIGINAL;
+	} else if (strncasecmp(direction,"both",strlen) == 0) 
+	{
+		sinfo->direction=IPT_CONNBYTES_DIR_BOTH;
+		*flags |= IPT_CONNBYTES_BOTH;
+	} else if (strncasecmp(direction,"replay",strlen) == 0)
+	{
+		sinfo->direction=IPT_CONNBYTES_DIR_REPLY;
+		*flags |= IPT_CONNBYTES_REPLY;
+	} else return 0;
+	return 1;
+}
+	
+
+/* Function which parses command options; returns true if it
+   ate an option */
+static int
+parse(int c, char **argv, int invert, unsigned int *flags,
+      const struct ipt_entry *entry,
+      unsigned int *nfcache,
+      struct ipt_entry_match **match)
+{
+	struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)(*match)->data;
+	unsigned long i;
+	switch (c) {
+	case '2':
+		if (*flags & IPT_CONNBYTES_BYTES)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't specify --connbytes twice");
+		if (*flags & IPT_CONNBYTES_PKTS)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connpkts and --connbytes together");
+		if (*flags & IPT_CONNBYTES_AVGPKT)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connavgpkt and --connbytes together");
+
+		if (check_inverse(optarg, &invert, &optind, 0))
+			optind++;
+
+		parse_range(argv[optind-1], sinfo);
+		if (invert) {
+			i = sinfo->count.from;
+			sinfo->count.from = sinfo->count.to;
+			sinfo->count.to = i;
+		}
+		sinfo->what=IPT_CONNBYTES_WHAT_BYTES;
+		sinfo->direction=IPT_CONNBYTES_DIR_BOTH;
+		*flags |= IPT_CONNBYTES_BYTES;
+		break;
+	case '1':
+		if (*flags & IPT_CONNBYTES_PKTS)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't specify --connpkts twice");
+		if (*flags & IPT_CONNBYTES_BYTES)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connbytes and --connpkts together");
+		if (*flags & IPT_CONNBYTES_AVGPKT)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connavgpkt and --connpkts together");
+		
+		if (check_inverse(optarg,&invert,&optind,0))
+			optind++;
+
+		parse_range(argv[optind-1],sinfo);
+		if (invert) {
+			i = sinfo->count.from;
+			sinfo->count.from = sinfo->count.to;
+			sinfo->count.to = i;
+		}
+		sinfo->what=IPT_CONNBYTES_WHAT_PKTS;
+		sinfo->direction=IPT_CONNBYTES_DIR_BOTH;
+		*flags |= IPT_CONNBYTES_PKTS;
+		break;
+	case '3':
+		if (*flags & IPT_CONNBYTES_AVGPKT)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't specify --connavgpkt twice");
+		if (*flags & IPT_CONNBYTES_PKTS)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connpkts and --connavgpkt together");
+		if (*flags & IPT_CONNBYTES_BYTES)
+			exit_error(PARAMETER_PROBLEM,
+					"Can't use --connbytes and --connavgpkt together");
+		
+		if (check_inverse(optarg,&invert,&optind,0))
+			optind++;
+
+		parse_range(argv[optind-1],sinfo);
+		if (invert) {
+			i = sinfo->count.from;
+			sinfo->count.from = sinfo->count.to;
+			sinfo->count.to = i;
+		}
+		sinfo->what=IPT_CONNBYTES_WHAT_AVGPKT;
+		sinfo->direction=IPT_CONNBYTES_DIR_BOTH;
+		*flags |= IPT_CONNBYTES_AVGPKT;
+		break;
+	case '4':
+		if (*flags & (IPT_CONNBYTES_ORIGINAL|IPT_CONNBYTES_BOTH|IPT_CONNBYTES_REPLY))
+			exit_error(PARAMETER_PROBLEM,
+					"Can't specify --direction twice");
+		if (!parse_direction(argv[optind-1],strlen(argv[optind-1]),sinfo,flags))
+			exit_error(PARAMETER_PROBLEM, "Bad direction '%s'",argv[optind-1]);
+		
+		break;
+	default:	
+		return 0;
+	}
+	return 1;
+}
+
+static void final_check(unsigned int flags)
+{
+	if (!flags)
+		exit_error(PARAMETER_PROBLEM, "You must specify `--connbytes or --connpkts or--connavgpkt'");
+}
+
+/* Prints out the matchinfo. */
+static void
+print(const struct ipt_ip *ip,
+      const struct ipt_entry_match *match,
+      int numeric)
+{
+	struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)match->data;
+
+		if (sinfo->count.from > sinfo->count.to) 
+			printf("%s ! %llu:%llu direction:%s",sinfo_names[sinfo->what],sinfo->count.to,sinfo->count.from,sinfo_directions[sinfo->direction]);
+		else
+		printf("%s %llu:%llu direction:%s",sinfo_names[sinfo->what],sinfo->count.from,sinfo->count.to,sinfo_directions[sinfo->direction]);
+}
+
+/* Saves the matchinfo in parsable form to stdout. */
+static void save(const struct ipt_ip *ip, const struct ipt_entry_match *match)
+{
+	struct ipt_connbytes_info *sinfo = (struct ipt_connbytes_info *)match->data;
+
+	if (sinfo->count.from > sinfo->count.to) 
+		printf("! --%s %llu:%llu --direction %s",sinfo_names[sinfo->what],sinfo->count.to,sinfo->count.from,sinfo_directions[sinfo->direction]);
+	else
+		printf("--%s %llu:%llu --direction %s",sinfo_names[sinfo->what],sinfo->count.from,sinfo->count.to,sinfo_directions[sinfo->direction]);
+}
+
+static
+struct iptables_match state
+= { NULL,
+    "connbytes",
+    IPTABLES_VERSION,
+    IPT_ALIGN(sizeof(struct ipt_connbytes_info)),
+    IPT_ALIGN(sizeof(struct ipt_connbytes_info)),
+    &help,
+    &init,
+    &parse,
+    &final_check,
+    &print,
+    &save,
+    opts
+};
+
+void _init(void)
+{
+	register_match(&state);
+}
diff -Nru a/connbytes/linux-2.4/include/linux/netfilter_ipv4/ipt_connbytes.h b/connbytes/linux-2.4/include/linux/netfilter_ipv4/ipt_connbytes.h
--- a/connbytes/linux-2.4/include/linux/netfilter_ipv4/ipt_connbytes.h	2004-04-07 13:04:28.000000000 +0200
+++ b/connbytes/linux-2.4/include/linux/netfilter_ipv4/ipt_connbytes.h	2004-11-11 21:05:52.000000000 +0100
@@ -1,10 +1,25 @@
 #ifndef _IPT_CONNBYTES_H
 #define _IPT_CONNBYTES_H
+enum ipt_connbytes_what {
+	        IPT_CONNBYTES_WHAT_PKTS,
+	        IPT_CONNBYTES_WHAT_BYTES,
+	        IPT_CONNBYTES_WHAT_AVGPKT,
+};
+
+enum ipt_connbytes_direction {
+	        IPT_CONNBYTES_DIR_ORIGINAL,
+	        IPT_CONNBYTES_DIR_REPLY,
+	        IPT_CONNBYTES_DIR_BOTH,
+};
 
 struct ipt_connbytes_info
 {
-       /* if from <= to then it matches the range; if from > to then
-          inverse range is matched */
-       unsigned long from, to;
+        struct {
+                u_int64_t from; /* count to be matched */
+                u_int64_t to;   /* count to be matched */
+        } count;
+        u_int8_t what;          /* ipt_connbytes_what */
+        u_int8_t direction;     /* ipt_connbytes_direction */
 };
+
 #endif
diff -Nru a/connbytes/linux-2.4/net/ipv4/netfilter/ipt_connbytes.c b/connbytes/linux-2.4/net/ipv4/netfilter/ipt_connbytes.c
--- a/connbytes/linux-2.4/net/ipv4/netfilter/ipt_connbytes.c	2004-04-07 13:04:28.000000000 +0200
+++ b/connbytes/linux-2.4/net/ipv4/netfilter/ipt_connbytes.c	2004-11-15 22:11:20.000000000 +0100
@@ -1,12 +1,32 @@
 /* Kernel module to match connection tracking byte counter.
  * GPL (C) 2002 Martin Devera (devik@cdi.cz).
+ *
+ * 2004-07-20 Harald Welte <laforge@netfilter.org>
+ *      - reimplemented to use per-connection accounting counters
+ *      - add functionality to match number of packets
+ *      - add functionality to match average packet size
+ *      - add support to match directions seperately
+ *
+ * 2004-10-24 Piotr Chytla <pch@fouk.org>
+ * 	- Connbytes with per-connection accouting backported to 2.4
+ * 	
  */
+
 #include <linux/module.h>
 #include <linux/skbuff.h>
+#include <linux/types.h>
 #include <linux/netfilter_ipv4/ip_conntrack.h>
 #include <linux/netfilter_ipv4/ip_tables.h>
 #include <linux/netfilter_ipv4/ipt_connbytes.h>
 
+#include <asm/div64.h>
+
+static u_int64_t mydiv(u_int64_t arg1,u_int32_t arg2)
+{
+	do_div(arg1,arg2);
+	return arg1;
+}
+
 static int
 match(const struct sk_buff *skb,
       const struct net_device *in,
@@ -17,17 +37,89 @@
       u_int16_t datalen,
       int *hotdrop)
 {
+	static u_int64_t what;
 	const struct ipt_connbytes_info *sinfo = matchinfo;
 	enum ip_conntrack_info ctinfo;
 	struct ip_conntrack *ct;
 
 	if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)))
 		return 0; /* no match */
-	
-	if (sinfo->from > sinfo->to)
-		return (ct->bytes < sinfo->to || ct->bytes > sinfo->from);
-	else
-		return (ct->bytes >= sinfo->from && ct->bytes <= sinfo->to);
+        switch (sinfo->what) {
+        case IPT_CONNBYTES_WHAT_PKTS:
+                switch (sinfo->direction) {
+                case IPT_CONNBYTES_DIR_ORIGINAL:
+                        what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
+                        break;
+                case IPT_CONNBYTES_DIR_REPLY:
+                        what = ct->counters[IP_CT_DIR_REPLY].packets;
+                        break;
+                case IPT_CONNBYTES_DIR_BOTH:
+                        what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
+                        what += ct->counters[IP_CT_DIR_REPLY].packets;
+                        break;
+                }
+                break;
+        case IPT_CONNBYTES_WHAT_BYTES:
+                switch (sinfo->direction) {
+                case IPT_CONNBYTES_DIR_ORIGINAL:
+                        what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
+                        break;
+                case IPT_CONNBYTES_DIR_REPLY:
+                        what = ct->counters[IP_CT_DIR_REPLY].bytes;
+                        break;
+                case IPT_CONNBYTES_DIR_BOTH:
+                        what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
+                        what += ct->counters[IP_CT_DIR_REPLY].bytes;
+                        break;
+                }
+                break;
+        case IPT_CONNBYTES_WHAT_AVGPKT:
+                switch (sinfo->direction) {
+                case IPT_CONNBYTES_DIR_ORIGINAL:
+                        {
+                                u_int32_t pkts32;
+
+                                if (ct->counters[IP_CT_DIR_ORIGINAL].packets > 0xfffffffff)
+                                        pkts32 = 0xffffffff;
+                                else
+                                        pkts32 = ct->counters[IP_CT_DIR_ORIGINAL].packets;
+				what = mydiv(ct->counters[IP_CT_DIR_ORIGINAL].bytes,pkts32);
+                        }
+                        break;
+                case IPT_CONNBYTES_DIR_REPLY:
+                        {
+                                u_int32_t pkts32;
+
+                                if (ct->counters[IP_CT_DIR_REPLY].packets > 0xffffffff)
+                                        pkts32 = 0xffffffff;
+                                else
+                                        pkts32 = ct->counters[IP_CT_DIR_REPLY].packets;
+				what = mydiv(ct->counters[IP_CT_DIR_REPLY].bytes,pkts32);
+                        }
+                        break;
+                case IPT_CONNBYTES_DIR_BOTH:
+                        {
+                                u_int64_t bytes;
+                                u_int64_t pkts;
+                                u_int32_t pkts32;
+                                bytes = ct->counters[IP_CT_DIR_ORIGINAL].bytes +
+                                        ct->counters[IP_CT_DIR_REPLY].bytes;
+                                pkts = ct->counters[IP_CT_DIR_ORIGINAL].packets +
+                                        ct->counters[IP_CT_DIR_REPLY].packets;
+                                if (pkts > 0xffffffff)
+                                        pkts32 =  0xffffffff;
+                                else
+                                        pkts32 = pkts;
+				what = mydiv(bytes,pkts);
+                        }
+                        break;
+                }
+                break;
+        }
+        if (sinfo->count.to)
+                return (what <= sinfo->count.to && what >= sinfo->count.from);
+        else
+                return (what >= sinfo->count.from);
 }
 
 static int check(const char *tablename,
@@ -36,8 +128,19 @@
 		 unsigned int matchsize,
 		 unsigned int hook_mask)
 {
+	const struct ipt_connbytes_info *sinfo = matchinfo;
+
 	if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info)))
 		return 0;
+        if (sinfo->what != IPT_CONNBYTES_WHAT_PKTS &&
+		       sinfo->what != IPT_CONNBYTES_WHAT_BYTES &&
+		       sinfo->what != IPT_CONNBYTES_WHAT_AVGPKT)
+		       return 0;
+
+       if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL &&
+			sinfo->direction != IPT_CONNBYTES_DIR_REPLY &&
+	                sinfo->direction != IPT_CONNBYTES_DIR_BOTH)
+		       return 0;
 
 	return 1;
 }

[-- Attachment #3: conntrack-acct.patch --]
[-- Type: text/plain, Size: 9577 bytes --]

diff -Nru a/conntrack-acct/linux-2.4/net/ipv4/netfilter/Config.in.ladd b/conntrack-acct/linux-2.4/net/ipv4/netfilter/Config.in.ladd
--- a/conntrack-acct/linux-2.4/net/ipv4/netfilter/Config.in.ladd	1970-01-01 01:00:00.000000000 +0100
+++ b/conntrack-acct/linux-2.4/net/ipv4/netfilter/Config.in.ladd	2004-11-15 22:43:12.000000000 +0100
@@ -0,0 +1,3 @@
+    dep_tristate '  IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK             
+    dep_tristate '  Connection tracking flow accounting' CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK
+
diff -Nru a/conntrack-acct/linux-2.4.patch b/conntrack-acct/linux-2.4.patch
--- a/conntrack-acct/linux-2.4.patch	1970-01-01 01:00:00.000000000 +0100
+++ b/conntrack-acct/linux-2.4.patch	2004-11-15 23:09:20.000000000 +0100
@@ -0,0 +1,210 @@
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
+--- a/include/linux/netfilter_ipv4/ip_conntrack.h	2004-08-08 01:26:06.000000000 +0200
++++ b/include/linux/netfilter_ipv4/ip_conntrack.h	2004-11-14 20:55:47.000000000 +0100
+@@ -156,6 +156,12 @@
+ 	union ip_conntrack_expect_help help;
+ };
+ 
++struct ip_conntrack_counter
++{
++       u_int64_t packets;
++       u_int64_t bytes;
++};
++
+ struct ip_conntrack_helper;
+ 
+ struct ip_conntrack
+@@ -173,6 +179,12 @@
+ 	/* Timer function; drops refcnt when it goes off. */
+ 	struct timer_list timeout;
+ 
++#if defined(CONFIG_IP_NF_CT_ACCT) || \
++	defined(CONFIG_IP_NF_CT_ACCT_MODULE)
++       /* Accounting Information (same cache line as other written members) */
++       struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
++#endif
++
+ 	/* If we're expecting another related connection, this will be
+            in expected linked list */
+ 	struct list_head sibling_list;
+@@ -242,8 +254,10 @@
+ 			  const struct ip_conntrack_tuple *orig);
+ 
+ /* Refresh conntrack for this many jiffies */
+-extern void ip_ct_refresh(struct ip_conntrack *ct,
+-			  unsigned long extra_jiffies);
++extern void ip_ct_refresh_acct(struct ip_conntrack *ct,
++                              enum ip_conntrack_info ctinfo,
++                              const struct iphdr *iph,
++                              unsigned long extra_jiffies);
+ 
+ /* These are for NAT.  Icky. */
+ /* Call me when a conntrack is destroyed. */
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_amanda.c b/net/ipv4/netfilter/ip_conntrack_amanda.c
+--- a/net/ipv4/netfilter/ip_conntrack_amanda.c	2004-02-18 14:36:32.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_amanda.c	2004-11-14 20:29:39.000000000 +0100
+@@ -75,7 +75,7 @@
+ 
+ 	/* increase the UDP timeout of the master connection as replies from
+ 	 * Amanda clients to the server can be quite delayed */
+-	ip_ct_refresh(ct, master_timeout * HZ);
++	ip_ct_refresh_acct(ct,ctinfo,NULL, master_timeout * HZ);
+ 	
+ 	/* Search for "CONNECT " string */
+ 	do {
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_core.c b/net/ipv4/netfilter/ip_conntrack_core.c
+--- a/net/ipv4/netfilter/ip_conntrack_core.c	2004-08-08 01:26:06.000000000 +0200
++++ b/net/ipv4/netfilter/ip_conntrack_core.c	2004-11-14 20:29:52.000000000 +0100
+@@ -1164,21 +1164,40 @@
+ 	MOD_DEC_USE_COUNT;
+ }
+ 
++static inline void ct_add_counters(struct ip_conntrack *ct,
++                                enum ip_conntrack_info ctinfo,
++                                 const struct iphdr *iph)
++{
++#if defined(CONFIG_IP_NF_CT_ACCT) || \
++	defined(CONFIG_IP_NF_CT_ACCT_MODULE)
++     if (iph) {
++            ct->counters[CTINFO2DIR(ctinfo)].packets++;
++            ct->counters[CTINFO2DIR(ctinfo)].bytes += 
++                                ntohs(iph->tot_len);
++   }
++#endif
++}
++
+ /* Refresh conntrack for this many jiffies. */
+-void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies)
++void ip_ct_refresh_acct(struct ip_conntrack *ct, 
++                       enum ip_conntrack_info ctinfo,
++                       const struct iphdr *iph,
++                       unsigned long extra_jiffies)
+ {
+ 	IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
+ 
+ 	WRITE_LOCK(&ip_conntrack_lock);
+ 	/* If not in hash table, timer will not be active yet */
+-	if (!is_confirmed(ct))
++	if (!is_confirmed(ct)) {
+ 		ct->timeout.expires = extra_jiffies;
+-	else {
++		ct_add_counters(ct, ctinfo,iph);
++	} else {
+ 		/* Need del_timer for race avoidance (may already be dying). */
+ 		if (del_timer(&ct->timeout)) {
+ 			ct->timeout.expires = jiffies + extra_jiffies;
+ 			add_timer(&ct->timeout);
+ 		}
++		ct_add_counters(ct, ctinfo, iph);
+ 	}
+ 	WRITE_UNLOCK(&ip_conntrack_lock);
+ }
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_proto_generic.c b/net/ipv4/netfilter/ip_conntrack_proto_generic.c
+--- a/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2003-11-28 19:26:21.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_proto_generic.c	2004-11-14 20:30:15.000000000 +0100
+@@ -41,9 +41,9 @@
+ /* Returns verdict for packet, or -1 for invalid. */
+ static int established(struct ip_conntrack *conntrack,
+ 		       struct iphdr *iph, size_t len,
+-		       enum ip_conntrack_info conntrackinfo)
++		       enum ip_conntrack_info ctinfo)
+ {
+-	ip_ct_refresh(conntrack, ip_ct_generic_timeout);
++	ip_ct_refresh_acct(conntrack, ctinfo,iph,ip_ct_generic_timeout);
+ 	return NF_ACCEPT;
+ }
+ 
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
+--- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2003-11-28 19:26:21.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c	2004-11-14 20:30:18.000000000 +0100
+@@ -82,7 +82,7 @@
+ 			ct->timeout.function((unsigned long)ct);
+ 	} else {
+ 		atomic_inc(&ct->proto.icmp.count);
+-		ip_ct_refresh(ct, ip_ct_icmp_timeout);
++		ip_ct_refresh_acct(ct,ctinfo,iph, ip_ct_icmp_timeout);
+ 	}
+ 
+ 	return NF_ACCEPT;
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
+--- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2003-11-28 19:26:21.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c	2004-11-14 20:30:26.000000000 +0100
+@@ -211,7 +211,7 @@
+ 			set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ 
+ 		WRITE_UNLOCK(&tcp_lock);
+-		ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
++		ip_ct_refresh_acct(conntrack,ctinfo,iph, *tcp_timeouts[newconntrack]);
+ 	}
+ 
+ 	return NF_ACCEPT;
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c
+--- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2003-11-28 19:26:21.000000000 +0100
++++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c	2004-11-14 20:30:23.000000000 +0100
+@@ -47,16 +47,16 @@
+ /* Returns verdict for packet, and may modify conntracktype */
+ static int udp_packet(struct ip_conntrack *conntrack,
+ 		      struct iphdr *iph, size_t len,
+-		      enum ip_conntrack_info conntrackinfo)
++		      enum ip_conntrack_info ctinfo)
+ {
+ 	/* If we've seen traffic both ways, this is some kind of UDP
+ 	   stream.  Extend timeout. */
+ 	if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
+-		ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
++		ip_ct_refresh_acct(conntrack,ctinfo,iph,ip_ct_udp_timeout_stream);
+ 		/* Also, more likely to be important, and not a probe */
+ 		set_bit(IPS_ASSURED_BIT, &conntrack->status);
+ 	} else
+-		ip_ct_refresh(conntrack, ip_ct_udp_timeout);
++		ip_ct_refresh_acct(conntrack,ctinfo,iph, ip_ct_udp_timeout);
+ 
+ 	return NF_ACCEPT;
+ }
+diff -Nru -x '*.orig' -x '*.rej' -x '*.in' a/net/ipv4/netfilter/ip_conntrack_standalone.c b/net/ipv4/netfilter/ip_conntrack_standalone.c
+--- a/net/ipv4/netfilter/ip_conntrack_standalone.c	2004-08-08 01:26:06.000000000 +0200
++++ b/net/ipv4/netfilter/ip_conntrack_standalone.c	2004-11-14 20:30:30.000000000 +0100
+@@ -79,6 +79,18 @@
+ 	return len;
+ }
+ 
++#if defined(CONFIG_IP_NF_CT_ACCT) || \
++	defined(CONFIG_IP_NF_CT_ACCT_MODULE)
++static unsigned int
++print_counters(char *buffer, struct ip_conntrack_counter *counter)
++{
++       return sprintf(buffer, "packets=%llu bytes=%llu ", 
++                       counter->packets, counter->bytes);
++}
++#else
++#define print_counters(x, y)   0
++#endif
++
+ static unsigned int
+ print_conntrack(char *buffer, struct ip_conntrack *conntrack)
+ {
+@@ -98,11 +110,15 @@
+ 	len += print_tuple(buffer + len,
+ 			   &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
+ 			   proto);
++       len += print_counters(buffer + len, 
++                             &conntrack->counters[IP_CT_DIR_ORIGINAL]);
+ 	if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
+ 		len += sprintf(buffer + len, "[UNREPLIED] ");
+ 	len += print_tuple(buffer + len,
+ 			   &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
+ 			   proto);
++       len += print_counters(buffer + len, 
++                            &conntrack->counters[IP_CT_DIR_REPLY]);
+ 	if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
+ 		len += sprintf(buffer + len, "[ASSURED] ");
+ 	len += sprintf(buffer + len, "use=%u ",
+@@ -467,7 +483,7 @@
+ EXPORT_SYMBOL(ip_conntrack_helper_register);
+ EXPORT_SYMBOL(ip_conntrack_helper_unregister);
+ EXPORT_SYMBOL(ip_ct_selective_cleanup);
+-EXPORT_SYMBOL(ip_ct_refresh);
++EXPORT_SYMBOL(ip_ct_refresh_acct);
+ EXPORT_SYMBOL(ip_ct_find_proto);
+ EXPORT_SYMBOL(__ip_ct_find_proto);
+ EXPORT_SYMBOL(ip_ct_find_helper);

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Backported conntrack-acct/connbytes to 2.4 tree
  2004-11-21 16:34 ` Piotr Chytla
@ 2005-04-01 10:02   ` Nikola Ciprich
  2005-04-03 22:47     ` Piotr Chytla
  0 siblings, 1 reply; 4+ messages in thread
From: Nikola Ciprich @ 2005-04-01 10:02 UTC (permalink / raw)
  To: Piotr Chytla; +Cc: netfilter-devel

Hi all, I'd like to ask, what is state of this patch? Is it going to
main tree? I'm not able to build iptables-1.3.1 without it, but it
breaks (at least) conntrack_{gre,mppe}
Can I do somethink to help?
Thanks!

Piotr Chytla píše v Ne 21. 11. 2004 v 17:34 +0100:
> On Tue, Nov 16, 2004 at 11:05:02PM +0100, Piotr Chytla wrote:
> > 1) Backported conntrack-acct 
> > 2) Backported connbytes with per-connection accounting support , also 
> >    shared library for iptables is attached . 
> >    Shared library for iptables works with connbytes from 2.6 tree.
> > 
> I've removed myself from pom-ng info file(fixed patches for pomng in attachment). 
> I was stupid, sorry for inconvenience.
> 
> 
> /pch

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: Backported conntrack-acct/connbytes to 2.4 tree
  2005-04-01 10:02   ` Nikola Ciprich
@ 2005-04-03 22:47     ` Piotr Chytla
  0 siblings, 0 replies; 4+ messages in thread
From: Piotr Chytla @ 2005-04-03 22:47 UTC (permalink / raw)
  To: Nikola Ciprich; +Cc: netfilter-devel

On Fri, Apr 01, 2005 at 12:02:06PM +0200, Nikola Ciprich wrote:
> Hi all, I'd like to ask, what is state of this patch? Is it going to
> main tree? 
conntrack-acct is in 2.6 main tree but Herald wrote this patch not me , my patch is 
only dirty backport :>

>I'm not able to build iptables-1.3.1 without it, but it
> breaks (at least) conntrack_{gre,mppe}
What kernel version? maybe you have old kernel headers.

/pch

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2005-04-03 22:47 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2004-11-16 22:05 Backported conntrack-acct/connbytes to 2.4 tree Piotr Chytla
2004-11-21 16:34 ` Piotr Chytla
2005-04-01 10:02   ` Nikola Ciprich
2005-04-03 22:47     ` Piotr Chytla

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.