From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- .../src/linux/linux/net/ipv4/netfilter/tomato_ct.c | 181 +++++++++++++++++++++ 1 file changed, 181 insertions(+) create mode 100644 release/src/linux/linux/net/ipv4/netfilter/tomato_ct.c (limited to 'release/src/linux/linux/net/ipv4/netfilter/tomato_ct.c') diff --git a/release/src/linux/linux/net/ipv4/netfilter/tomato_ct.c b/release/src/linux/linux/net/ipv4/netfilter/tomato_ct.c new file mode 100644 index 00000000..a84cab09 --- /dev/null +++ b/release/src/linux/linux/net/ipv4/netfilter/tomato_ct.c @@ -0,0 +1,181 @@ +/* + + tomato_ct.c + Copyright (C) 2006 Jonathan Zarate + + Licensed under GNU GPL v2. + +*/ +#include +#include +#include +#include + +// #define TEST_HASHDIST + + +#ifdef TEST_HASHDIST +static int hashdist_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data) +{ + struct list_head *h; + struct list_head *e; + int i; + int n; + int count; + char *buf; + int max; + + // do this the easy way... + max = ip_conntrack_htable_size * sizeof("12345\t12345\n"); + buf = kmalloc(max + 1, GFP_KERNEL); + if (buf == NULL) return 0; + + n = 0; + max -= sizeof("12345\t12345\n"); + + READ_LOCK(&ip_conntrack_lock); + + for (i = 0; i < ip_conntrack_htable_size; ++i) { + count = 0; + h = &ip_conntrack_hash[i]; + if (h) { + e = h; + while (e->next != h) { + ++count; + e = e->next; + } + } + + n += sprintf(buf + n, "%d\t%d\n", i, count); + if (n > max) { + printk("hashdist: %d > %d\n", n, max); + break; + } + } + + READ_UNLOCK(&ip_conntrack_lock); + + if (offset < n) { + n = n - offset; + if (n > length) { + n = length; + *eof = 0; + } + else { + *eof = 1; + } + memcpy(buffer, buf + offset, n); + *start = buffer; + } + else { + n = 0; + *eof = 1; + } + + kfree(buf); + return n; +} +#endif + + +static void interate_all(void (*func)(struct ip_conntrack *, unsigned long), unsigned long data) +{ + int i; + struct list_head *h; + struct list_head *e; + + WRITE_LOCK(&ip_conntrack_lock); + for (i = 0; i < ip_conntrack_htable_size; ++i) { + h = &ip_conntrack_hash[i]; + if (h) { + e = h; + while (e->next != h) { + e = e->next; + func(((struct ip_conntrack_tuple_hash *)e)->ctrack, data); + } + } + } + WRITE_UNLOCK(&ip_conntrack_lock); +} + +static void expireearly(struct ip_conntrack *ct, unsigned long data) +{ + if (ct->timeout.expires > data) { + if (del_timer(&ct->timeout)) { + ct->timeout.expires = data; + add_timer(&ct->timeout); + } + } +} + +static int expireearly_write(struct file *file, const char *buffer, unsigned long length, void *data) +{ + char s[8]; + unsigned long n; + + if ((length > 0) && (length < 6)) { + memcpy(s, buffer, length); + s[length] = 0; + n = simple_strtoul(s, NULL, 10); + if (n < 10) n = 10; + else if (n > 86400) n = 86400; + + interate_all(expireearly, jiffies + (n * HZ)); + } + +/* + if ((length > 0) && (buffer[0] == '1')) { + interate_all(expireearly, jiffies + (20 * HZ)); + } +*/ + + return length; +} + + +static void clearmarks(struct ip_conntrack *ct, unsigned long data) +{ + ct->mark = 0; +} + +static int clearmarks_write(struct file *file, const char *buffer, unsigned long length, void *data) +{ + if ((length > 0) && (buffer[0] == '1')) { + interate_all(clearmarks, 0); + } + return length; +} + +static int __init init(void) +{ + struct proc_dir_entry *p; + + printk(__FILE__ " [" __DATE__ " " __TIME__ "]\n"); + +#ifdef TEST_HASHDIST + p = create_proc_entry("hash_dist", 0400, proc_net); + if (p) p->read_proc = hashdist_read; +#endif + + p = create_proc_entry("expire_early", 0200, proc_net); + if (p) p->write_proc = expireearly_write; + + p = create_proc_entry("clear_marks", 0200, proc_net); + if (p) p->write_proc = clearmarks_write; + + return 0; +} + +static void __exit fini(void) +{ +#ifdef TEST_HASHDIST + remove_proc_entry("hash_dist", proc_net); +#endif + remove_proc_entry("expire_early", proc_net); + remove_proc_entry("clear_marks", proc_net); +} + +module_init(init); +module_exit(fini); + +MODULE_LICENSE("GPL"); -- cgit v1.2.3-54-g00ecf