K2.6 patches and update.
[tomato.git] / release / src-rt / linux / linux-2.6 / net / ipv4 / netfilter / tomato_ct.c
blobb8f2e4164e2e8565d0f9ff8380be9209eaa51920
1 /*
3 tomato_ct.c
4 Copyright (C) 2006 Jonathan Zarate
6 Licensed under GNU GPL v2.
8 */
9 #include <linux/module.h>
10 #include <linux/skbuff.h>
11 #include <linux/version.h>
12 #include <linux/proc_fs.h>
14 #include <linux/netfilter_ipv4/ip_tables.h>
15 #include <net/netfilter/nf_conntrack.h>
16 #include <net/netfilter/nf_conntrack_core.h>
17 #include <net/netfilter/nf_conntrack_helper.h>
19 // #define TEST_HASHDIST
22 #ifdef TEST_HASHDIST
23 static int hashdist_read(char *buffer, char **start, off_t offset, int length, int *eof, void *data)
25 struct nf_conntrack_tuple_hash *h;
26 int i;
27 int n;
28 int count;
29 char *buf;
30 int max;
32 // do this the easy way...
33 max = nf_conntrack_htable_size * sizeof("12345\t12345\n");
34 buf = kmalloc(max + 1, GFP_KERNEL);
35 if (buf == NULL) return 0;
37 n = 0;
38 max -= sizeof("12345\t12345\n");
40 read_lock_bh(&nf_conntrack_lock);
42 for (i = 0; i < nf_conntrack_htable_size; ++i) {
43 count = 0;
44 list_for_each_entry(h, &nf_conntrack_hash[i], list) {
45 ++count;
47 n += sprintf(buf + n, "%d\t%d\n", i, count);
48 if (n > max) {
49 printk("hashdist: %d > %d\n", n, max);
50 break;
54 read_unlock_bh(&nf_conntrack_lock);
56 if (offset < n) {
57 n = n - offset;
58 if (n > length) {
59 n = length;
60 *eof = 0;
62 else {
63 *eof = 1;
65 memcpy(buffer, buf + offset, n);
66 *start = buffer;
68 else {
69 n = 0;
70 *eof = 1;
73 kfree(buf);
74 return n;
76 #endif
79 static void iterate_all(void (*func)(struct nf_conn *, unsigned long), unsigned long data)
81 unsigned int i;
82 struct nf_conntrack_tuple_hash *h;
84 write_lock_bh(&nf_conntrack_lock);
85 for (i = 0; i < nf_conntrack_htable_size; ++i) {
86 list_for_each_entry(h, &nf_conntrack_hash[i], list) {
87 func(nf_ct_tuplehash_to_ctrack(h), data);
90 write_unlock_bh(&nf_conntrack_lock);
93 static void expireearly(struct nf_conn *ct, unsigned long data)
95 if (ct->timeout.expires > data) {
96 if (del_timer(&ct->timeout)) {
97 ct->timeout.expires = data;
98 add_timer(&ct->timeout);
103 static int expireearly_write(struct file *file, const char *buffer, unsigned long length, void *data)
105 char s[8];
106 unsigned long n;
108 if ((length > 0) && (length < 6)) {
109 memcpy(s, buffer, length);
110 s[length] = 0;
111 n = simple_strtoul(s, NULL, 10);
112 if (n < 10) n = 10;
113 else if (n > 86400) n = 86400;
115 iterate_all(expireearly, jiffies + (n * HZ));
119 if ((length > 0) && (buffer[0] == '1')) {
120 iterate_all(expireearly, jiffies + (20 * HZ));
124 return length;
128 static void clearmarks(struct nf_conn *ct, unsigned long data)
130 ct->mark = 0;
133 static int clearmarks_write(struct file *file, const char *buffer, unsigned long length, void *data)
135 if ((length > 0) && (buffer[0] == '1')) {
136 iterate_all(clearmarks, 0);
138 return length;
141 static int conntrack_clear_write(struct file *file, const char *buffer, unsigned long length, void *data)
143 if ((length > 0) && (buffer[0] == '1')) {
144 i_see_dead_people:
145 nf_conntrack_flush();
146 if (atomic_read(&nf_conntrack_count) != 0) {
147 schedule();
148 goto i_see_dead_people;
151 return length;
154 static int __init init(void)
156 #ifdef CONFIG_PROC_FS
157 struct proc_dir_entry *p;
159 printk(__FILE__ " [" __DATE__ " " __TIME__ "]\n");
161 #ifdef TEST_HASHDIST
162 p = create_proc_entry("hash_dist", 0400, proc_net);
163 if (p) {
164 p->owner = THIS_MODULE;
165 p->read_proc = hashdist_read;
167 #endif
169 p = create_proc_entry("expire_early", 0200, proc_net);
170 if (p) {
171 p->owner = THIS_MODULE;
172 p->write_proc = expireearly_write;
175 p = create_proc_entry("clear_marks", 0200, proc_net);
176 if (p) {
177 p->owner = THIS_MODULE;
178 p->write_proc = clearmarks_write;
181 p = create_proc_entry("conntrack_clear", 0200, proc_net);
182 if (p) {
183 p->owner = THIS_MODULE;
184 p->write_proc = conntrack_clear_write;
186 #endif /* CONFIG_PROC_FS */
188 return 0;
191 static void __exit fini(void)
193 #ifdef CONFIG_PROC_FS
194 #ifdef TEST_HASHDIST
195 remove_proc_entry("hash_dist", proc_net);
196 #endif
197 remove_proc_entry("expire_early", proc_net);
198 remove_proc_entry("clear_marks", proc_net);
199 remove_proc_entry("conntrack_clear", proc_net);
200 #endif /* CONFIG_PROC_FS */
203 module_init(init);
204 module_exit(fini);
206 MODULE_LICENSE("GPL");