update brcm-2.4 to 2.4.35.4, integrate new broadcom system code, update broadcom...
[openwrt/svn-archive/archive.git] / target / linux / generic-2.4 / patches / 610-netfilter_connbytes.patch
1 Index: linux-2.4.35.4/net/ipv4/netfilter/Config.in
2 ===================================================================
3 --- linux-2.4.35.4.orig/net/ipv4/netfilter/Config.in 2007-12-15 05:20:08.396318720 +0100
4 +++ linux-2.4.35.4/net/ipv4/netfilter/Config.in 2007-12-15 05:20:08.692335591 +0100
5 @@ -11,6 +11,8 @@
6 dep_tristate ' Amanda protocol support' CONFIG_IP_NF_AMANDA $CONFIG_IP_NF_CONNTRACK
7 dep_tristate ' TFTP protocol support' CONFIG_IP_NF_TFTP $CONFIG_IP_NF_CONNTRACK
8 dep_tristate ' IRC protocol support' CONFIG_IP_NF_IRC $CONFIG_IP_NF_CONNTRACK
9 + dep_tristate ' Connection tracking flow accounting' CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK
10 + dep_tristate ' Connection byte counter support' CONFIG_IP_NF_MATCH_CONNBYTES $CONFIG_IP_NF_CT_ACCT $CONFIG_IP_NF_CONNTRACK $CONFIG_IP_NF_IPTABLES
11 dep_tristate ' GRE protocol support' CONFIG_IP_NF_CT_PROTO_GRE $CONFIG_IP_NF_CONNTRACK
12 dep_tristate ' PPTP protocol support' CONFIG_IP_NF_PPTP $CONFIG_IP_NF_CT_PROTO_GRE
13 fi
14 Index: linux-2.4.35.4/net/ipv4/netfilter/Makefile
15 ===================================================================
16 --- linux-2.4.35.4.orig/net/ipv4/netfilter/Makefile 2007-12-15 05:20:08.400318949 +0100
17 +++ linux-2.4.35.4/net/ipv4/netfilter/Makefile 2007-12-15 05:20:08.696335817 +0100
18 @@ -106,6 +106,7 @@
19 obj-$(CONFIG_IP_NF_MATCH_TTL) += ipt_ttl.o
20 obj-$(CONFIG_IP_NF_MATCH_STATE) += ipt_state.o
21 obj-$(CONFIG_IP_NF_MATCH_CONNMARK) += ipt_connmark.o
22 +obj-$(CONFIG_IP_NF_MATCH_CONNBYTES) += ipt_connbytes.o
23 obj-$(CONFIG_IP_NF_MATCH_CONNTRACK) += ipt_conntrack.o
24 obj-$(CONFIG_IP_NF_MATCH_UNCLEAN) += ipt_unclean.o
25 obj-$(CONFIG_IP_NF_MATCH_STRING) += ipt_string.o
26 Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_amanda.c
27 ===================================================================
28 --- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_amanda.c 2007-12-15 05:19:37.650566622 +0100
29 +++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_amanda.c 2007-12-15 05:20:08.700336046 +0100
30 @@ -75,7 +75,7 @@
31
32 /* increase the UDP timeout of the master connection as replies from
33 * Amanda clients to the server can be quite delayed */
34 - ip_ct_refresh(ct, master_timeout * HZ);
35 + ip_ct_refresh_acct(ct,ctinfo,NULL, master_timeout * HZ);
36
37 /* Search for "CONNECT " string */
38 do {
39 Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_tcp.c
40 ===================================================================
41 --- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2007-12-15 05:19:37.658567077 +0100
42 +++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_tcp.c 2007-12-15 05:20:08.700336046 +0100
43 @@ -211,7 +211,7 @@
44 set_bit(IPS_ASSURED_BIT, &conntrack->status);
45
46 WRITE_UNLOCK(&tcp_lock);
47 - ip_ct_refresh(conntrack, *tcp_timeouts[newconntrack]);
48 + ip_ct_refresh_acct(conntrack,ctinfo,iph, *tcp_timeouts[newconntrack]);
49 }
50
51 return NF_ACCEPT;
52 Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_udp.c
53 ===================================================================
54 --- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2007-12-15 05:19:37.666567533 +0100
55 +++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_udp.c 2007-12-15 05:20:08.700336046 +0100
56 @@ -47,16 +47,16 @@
57 /* Returns verdict for packet, and may modify conntracktype */
58 static int udp_packet(struct ip_conntrack *conntrack,
59 struct iphdr *iph, size_t len,
60 - enum ip_conntrack_info conntrackinfo)
61 + enum ip_conntrack_info ctinfo)
62 {
63 /* If we've seen traffic both ways, this is some kind of UDP
64 stream. Extend timeout. */
65 if (test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)) {
66 - ip_ct_refresh(conntrack, ip_ct_udp_timeout_stream);
67 + ip_ct_refresh_acct(conntrack,ctinfo,iph,ip_ct_udp_timeout_stream);
68 /* Also, more likely to be important, and not a probe */
69 set_bit(IPS_ASSURED_BIT, &conntrack->status);
70 } else
71 - ip_ct_refresh(conntrack, ip_ct_udp_timeout);
72 + ip_ct_refresh_acct(conntrack,ctinfo,iph, ip_ct_udp_timeout);
73
74 return NF_ACCEPT;
75 }
76 Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_standalone.c
77 ===================================================================
78 --- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_standalone.c 2007-12-15 05:20:07.568271536 +0100
79 +++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_standalone.c 2007-12-15 05:20:08.700336046 +0100
80 @@ -79,6 +79,18 @@
81 return len;
82 }
83
84 +#if defined(CONFIG_IP_NF_CT_ACCT) || \
85 + defined(CONFIG_IP_NF_CT_ACCT_MODULE)
86 +static unsigned int
87 +print_counters(char *buffer, struct ip_conntrack_counter *counter)
88 +{
89 + return sprintf(buffer, "packets=%llu bytes=%llu ",
90 + counter->packets, counter->bytes);
91 +}
92 +#else
93 +#define print_counters(x, y) 0
94 +#endif
95 +
96 static unsigned int
97 print_conntrack(char *buffer, struct ip_conntrack *conntrack)
98 {
99 @@ -98,11 +110,15 @@
100 len += print_tuple(buffer + len,
101 &conntrack->tuplehash[IP_CT_DIR_ORIGINAL].tuple,
102 proto);
103 + len += print_counters(buffer + len,
104 + &conntrack->counters[IP_CT_DIR_ORIGINAL]);
105 if (!(test_bit(IPS_SEEN_REPLY_BIT, &conntrack->status)))
106 len += sprintf(buffer + len, "[UNREPLIED] ");
107 len += print_tuple(buffer + len,
108 &conntrack->tuplehash[IP_CT_DIR_REPLY].tuple,
109 proto);
110 + len += print_counters(buffer + len,
111 + &conntrack->counters[IP_CT_DIR_REPLY]);
112 if (test_bit(IPS_ASSURED_BIT, &conntrack->status))
113 len += sprintf(buffer + len, "[ASSURED] ");
114 len += sprintf(buffer + len, "use=%u ",
115 @@ -478,7 +494,7 @@
116 EXPORT_SYMBOL(ip_conntrack_helper_register);
117 EXPORT_SYMBOL(ip_conntrack_helper_unregister);
118 EXPORT_SYMBOL(ip_ct_iterate_cleanup);
119 -EXPORT_SYMBOL(ip_ct_refresh);
120 +EXPORT_SYMBOL(ip_ct_refresh_acct);
121 EXPORT_SYMBOL(ip_ct_find_proto);
122 EXPORT_SYMBOL(__ip_ct_find_proto);
123 EXPORT_SYMBOL(ip_ct_find_helper);
124 Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_generic.c
125 ===================================================================
126 --- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_proto_generic.c 2007-12-15 05:19:37.682568446 +0100
127 +++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_generic.c 2007-12-15 05:20:08.700336046 +0100
128 @@ -41,9 +41,9 @@
129 /* Returns verdict for packet, or -1 for invalid. */
130 static int established(struct ip_conntrack *conntrack,
131 struct iphdr *iph, size_t len,
132 - enum ip_conntrack_info conntrackinfo)
133 + enum ip_conntrack_info ctinfo)
134 {
135 - ip_ct_refresh(conntrack, ip_ct_generic_timeout);
136 + ip_ct_refresh_acct(conntrack, ctinfo,iph,ip_ct_generic_timeout);
137 return NF_ACCEPT;
138 }
139
140 Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_icmp.c
141 ===================================================================
142 --- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_proto_icmp.c 2007-12-15 05:19:37.686568672 +0100
143 +++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_icmp.c 2007-12-15 05:20:08.704336275 +0100
144 @@ -82,7 +82,7 @@
145 ct->timeout.function((unsigned long)ct);
146 } else {
147 atomic_inc(&ct->proto.icmp.count);
148 - ip_ct_refresh(ct, ip_ct_icmp_timeout);
149 + ip_ct_refresh_acct(ct,ctinfo,iph, ip_ct_icmp_timeout);
150 }
151
152 return NF_ACCEPT;
153 Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_core.c
154 ===================================================================
155 --- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_core.c 2007-12-15 05:20:07.568271536 +0100
156 +++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_core.c 2007-12-15 05:20:08.704336275 +0100
157 @@ -1196,22 +1196,40 @@
158
159 MOD_DEC_USE_COUNT;
160 }
161 +static inline void ct_add_counters(struct ip_conntrack *ct,
162 + enum ip_conntrack_info ctinfo,
163 + const struct iphdr *iph)
164 +{
165 +#if defined(CONFIG_IP_NF_CT_ACCT) || \
166 + defined(CONFIG_IP_NF_CT_ACCT_MODULE)
167 + if (iph) {
168 + ct->counters[CTINFO2DIR(ctinfo)].packets++;
169 + ct->counters[CTINFO2DIR(ctinfo)].bytes +=
170 + ntohs(iph->tot_len);
171 + }
172 +#endif
173 +}
174
175 /* Refresh conntrack for this many jiffies. */
176 -void ip_ct_refresh(struct ip_conntrack *ct, unsigned long extra_jiffies)
177 +void ip_ct_refresh_acct(struct ip_conntrack *ct,
178 + enum ip_conntrack_info ctinfo,
179 + const struct iphdr *iph,
180 + unsigned long extra_jiffies)
181 {
182 IP_NF_ASSERT(ct->timeout.data == (unsigned long)ct);
183
184 WRITE_LOCK(&ip_conntrack_lock);
185 /* If not in hash table, timer will not be active yet */
186 - if (!is_confirmed(ct))
187 + if (!is_confirmed(ct)) {
188 ct->timeout.expires = extra_jiffies;
189 - else {
190 + ct_add_counters(ct, ctinfo,iph);
191 + } else {
192 /* Need del_timer for race avoidance (may already be dying). */
193 if (del_timer(&ct->timeout)) {
194 ct->timeout.expires = jiffies + extra_jiffies;
195 add_timer(&ct->timeout);
196 }
197 + ct_add_counters(ct, ctinfo, iph);
198 }
199 WRITE_UNLOCK(&ip_conntrack_lock);
200 }
201 Index: linux-2.4.35.4/include/linux/netfilter_ipv4/ip_conntrack.h
202 ===================================================================
203 --- linux-2.4.35.4.orig/include/linux/netfilter_ipv4/ip_conntrack.h 2007-12-15 05:20:07.552270623 +0100
204 +++ linux-2.4.35.4/include/linux/netfilter_ipv4/ip_conntrack.h 2007-12-15 05:20:08.704336275 +0100
205 @@ -164,6 +164,12 @@
206 union ip_conntrack_expect_help help;
207 };
208
209 +struct ip_conntrack_counter
210 +{
211 + u_int64_t packets;
212 + u_int64_t bytes;
213 +};
214 +
215 struct ip_conntrack_helper;
216
217 struct ip_conntrack
218 @@ -181,6 +187,12 @@
219 /* Timer function; drops refcnt when it goes off. */
220 struct timer_list timeout;
221
222 +#if defined(CONFIG_IP_NF_CT_ACCT) || \
223 + defined(CONFIG_IP_NF_CT_ACCT_MODULE)
224 + /* Accounting Information (same cache line as other written members) */
225 + struct ip_conntrack_counter counters[IP_CT_DIR_MAX];
226 +#endif
227 +
228 /* If we're expecting another related connection, this will be
229 in expected linked list */
230 struct list_head sibling_list;
231 @@ -264,8 +276,10 @@
232 const struct ip_conntrack_tuple *orig);
233
234 /* Refresh conntrack for this many jiffies */
235 -extern void ip_ct_refresh(struct ip_conntrack *ct,
236 - unsigned long extra_jiffies);
237 +extern void ip_ct_refresh_acct(struct ip_conntrack *ct,
238 + enum ip_conntrack_info ctinfo,
239 + const struct iphdr *iph,
240 + unsigned long extra_jiffies);
241
242 /* These are for NAT. Icky. */
243 /* Call me when a conntrack is destroyed. */
244 Index: linux-2.4.35.4/net/ipv4/netfilter/ipt_connbytes.c
245 ===================================================================
246 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
247 +++ linux-2.4.35.4/net/ipv4/netfilter/ipt_connbytes.c 2007-12-15 05:20:08.704336275 +0100
248 @@ -0,0 +1,163 @@
249 +/* Kernel module to match connection tracking byte counter.
250 + * GPL (C) 2002 Martin Devera (devik@cdi.cz).
251 + *
252 + * 2004-07-20 Harald Welte <laforge at netfilter.org>
253 + * - reimplemented to use per-connection accounting counters
254 + * - add functionality to match number of packets
255 + * - add functionality to match average packet size
256 + * - add support to match directions seperately
257 + *
258 + * 2004-10-24 Piotr Chytla <pch at fouk.org>
259 + * - Connbytes with per-connection accouting backported to 2.4
260 + *
261 + */
262 +
263 +#include <linux/module.h>
264 +#include <linux/skbuff.h>
265 +#include <linux/types.h>
266 +#include <linux/netfilter_ipv4/ip_conntrack.h>
267 +#include <linux/netfilter_ipv4/ip_tables.h>
268 +#include <linux/netfilter_ipv4/ipt_connbytes.h>
269 +
270 +#include <asm/div64.h>
271 +
272 +static u_int64_t mydiv(u_int64_t arg1,u_int32_t arg2)
273 +{
274 + do_div(arg1,arg2);
275 + return arg1;
276 +}
277 +
278 +static int
279 +match(const struct sk_buff *skb,
280 + const struct net_device *in,
281 + const struct net_device *out,
282 + const void *matchinfo,
283 + int offset,
284 + const void *hdr,
285 + u_int16_t datalen,
286 + int *hotdrop)
287 +{
288 + static u_int64_t what;
289 + const struct ipt_connbytes_info *sinfo = matchinfo;
290 + enum ip_conntrack_info ctinfo;
291 + struct ip_conntrack *ct;
292 +
293 + if (!(ct = ip_conntrack_get((struct sk_buff *)skb, &ctinfo)))
294 + return 0; /* no match */
295 + switch (sinfo->what) {
296 + case IPT_CONNBYTES_PKTS:
297 + switch (sinfo->direction) {
298 + case IPT_CONNBYTES_DIR_ORIGINAL:
299 + what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
300 + break;
301 + case IPT_CONNBYTES_DIR_REPLY:
302 + what = ct->counters[IP_CT_DIR_REPLY].packets;
303 + break;
304 + case IPT_CONNBYTES_DIR_BOTH:
305 + what = ct->counters[IP_CT_DIR_ORIGINAL].packets;
306 + what += ct->counters[IP_CT_DIR_REPLY].packets;
307 + break;
308 + }
309 + break;
310 + case IPT_CONNBYTES_BYTES:
311 + switch (sinfo->direction) {
312 + case IPT_CONNBYTES_DIR_ORIGINAL:
313 + what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
314 + break;
315 + case IPT_CONNBYTES_DIR_REPLY:
316 + what = ct->counters[IP_CT_DIR_REPLY].bytes;
317 + break;
318 + case IPT_CONNBYTES_DIR_BOTH:
319 + what = ct->counters[IP_CT_DIR_ORIGINAL].bytes;
320 + what += ct->counters[IP_CT_DIR_REPLY].bytes;
321 + break;
322 + }
323 + break;
324 + case IPT_CONNBYTES_AVGPKT:
325 + switch (sinfo->direction) {
326 + case IPT_CONNBYTES_DIR_ORIGINAL:
327 + {
328 + u_int32_t pkts32;
329 +
330 + if (ct->counters[IP_CT_DIR_ORIGINAL].packets > 0xfffffffff)
331 + pkts32 = 0xffffffff;
332 + else
333 + pkts32 = ct->counters[IP_CT_DIR_ORIGINAL].packets;
334 + what = mydiv(ct->counters[IP_CT_DIR_ORIGINAL].bytes,pkts32);
335 + }
336 + break;
337 + case IPT_CONNBYTES_DIR_REPLY:
338 + {
339 + u_int32_t pkts32;
340 +
341 + if (ct->counters[IP_CT_DIR_REPLY].packets > 0xffffffff)
342 + pkts32 = 0xffffffff;
343 + else
344 + pkts32 = ct->counters[IP_CT_DIR_REPLY].packets;
345 + what = mydiv(ct->counters[IP_CT_DIR_REPLY].bytes,pkts32);
346 + }
347 + break;
348 + case IPT_CONNBYTES_DIR_BOTH:
349 + {
350 + u_int64_t bytes;
351 + u_int64_t pkts;
352 + u_int32_t pkts32;
353 + bytes = ct->counters[IP_CT_DIR_ORIGINAL].bytes +
354 + ct->counters[IP_CT_DIR_REPLY].bytes;
355 + pkts = ct->counters[IP_CT_DIR_ORIGINAL].packets +
356 + ct->counters[IP_CT_DIR_REPLY].packets;
357 + if (pkts > 0xffffffff)
358 + pkts32 = 0xffffffff;
359 + else
360 + pkts32 = pkts;
361 + what = mydiv(bytes,pkts);
362 + }
363 + break;
364 + }
365 + break;
366 + }
367 + if (sinfo->count.to)
368 + return (what <= sinfo->count.to && what >= sinfo->count.from);
369 + else
370 + return (what >= sinfo->count.from);
371 +}
372 +
373 +static int check(const char *tablename,
374 + const struct ipt_ip *ip,
375 + void *matchinfo,
376 + unsigned int matchsize,
377 + unsigned int hook_mask)
378 +{
379 + const struct ipt_connbytes_info *sinfo = matchinfo;
380 +
381 + if (matchsize != IPT_ALIGN(sizeof(struct ipt_connbytes_info)))
382 + return 0;
383 + if (sinfo->what != IPT_CONNBYTES_PKTS &&
384 + sinfo->what != IPT_CONNBYTES_BYTES &&
385 + sinfo->what != IPT_CONNBYTES_AVGPKT)
386 + return 0;
387 +
388 + if (sinfo->direction != IPT_CONNBYTES_DIR_ORIGINAL &&
389 + sinfo->direction != IPT_CONNBYTES_DIR_REPLY &&
390 + sinfo->direction != IPT_CONNBYTES_DIR_BOTH)
391 + return 0;
392 +
393 + return 1;
394 +}
395 +
396 +static struct ipt_match state_match
397 += { { NULL, NULL }, "connbytes", &match, &check, NULL, THIS_MODULE };
398 +
399 +static int __init init(void)
400 +{
401 + return ipt_register_match(&state_match);
402 +}
403 +
404 +static void __exit fini(void)
405 +{
406 + ipt_unregister_match(&state_match);
407 +}
408 +
409 +module_init(init);
410 +module_exit(fini);
411 +MODULE_LICENSE("GPL");
412 Index: linux-2.4.35.4/include/linux/netfilter_ipv4/ipt_connbytes.h
413 ===================================================================
414 --- /dev/null 1970-01-01 00:00:00.000000000 +0000
415 +++ linux-2.4.35.4/include/linux/netfilter_ipv4/ipt_connbytes.h 2007-12-15 05:20:08.708336505 +0100
416 @@ -0,0 +1,25 @@
417 +#ifndef _IPT_CONNBYTES_H
418 +#define _IPT_CONNBYTES_H
419 +enum ipt_connbytes_what {
420 + IPT_CONNBYTES_PKTS,
421 + IPT_CONNBYTES_BYTES,
422 + IPT_CONNBYTES_AVGPKT,
423 +};
424 +
425 +enum ipt_connbytes_direction {
426 + IPT_CONNBYTES_DIR_ORIGINAL,
427 + IPT_CONNBYTES_DIR_REPLY,
428 + IPT_CONNBYTES_DIR_BOTH,
429 +};
430 +
431 +struct ipt_connbytes_info
432 +{
433 + struct {
434 + u_int64_t from; /* count to be matched */
435 + u_int64_t to; /* count to be matched */
436 + } count;
437 + u_int8_t what; /* ipt_connbytes_what */
438 + u_int8_t direction; /* ipt_connbytes_direction */
439 +};
440 +
441 +#endif
442 Index: linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_gre.c
443 ===================================================================
444 --- linux-2.4.35.4.orig/net/ipv4/netfilter/ip_conntrack_proto_gre.c 2007-12-15 05:20:06.404205198 +0100
445 +++ linux-2.4.35.4/net/ipv4/netfilter/ip_conntrack_proto_gre.c 2007-12-15 05:20:08.708336505 +0100
446 @@ -237,16 +237,16 @@
447 /* Returns verdict for packet, and may modify conntrack */
448 static int gre_packet(struct ip_conntrack *ct,
449 struct iphdr *iph, size_t len,
450 - enum ip_conntrack_info conntrackinfo)
451 + enum ip_conntrack_info ctinfo)
452 {
453 /* If we've seen traffic both ways, this is a GRE connection.
454 * Extend timeout. */
455 if (ct->status & IPS_SEEN_REPLY) {
456 - ip_ct_refresh_acct(ct, ct->proto.gre.stream_timeout);
457 + ip_ct_refresh_acct(ct, ctinfo, iph, ct->proto.gre.stream_timeout);
458 /* Also, more likely to be important, and not a probe. */
459 set_bit(IPS_ASSURED_BIT, &ct->status);
460 } else
461 - ip_ct_refresh_acct(ct, ct->proto.gre.timeout);
462 + ip_ct_refresh_acct(ct, ctinfo, iph, ct->proto.gre.timeout);
463
464 return NF_ACCEPT;
465 }