aboutsummaryrefslogtreecommitdiffstats
path: root/target/linux/generic-2.4/patches/612-netfilter_quota.patch
blob: a0a019c171f51d0ebb5c5b7ef20b99eaeef212e3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
diff -ruN linux-2.4.30-old/Documentation/Configure.help linux-2.4.30-new/Documentation/Configure.help
--- linux-2.4.30-old/Documentation/Configure.help	2005-11-13 22:30:42.000000000 +0100
+++ linux-2.4.30-new/Documentation/Configure.help	2005-11-13 22:31:17.000000000 +0100
@@ -2888,6 +2888,13 @@
   If you want to compile it as a module, say M here and read
   <file:Documentation/modules.txt>.  If unsure, say `N'.
 
+quota match support
+CONFIG_IP_NF_MATCH_QUOTA
+  This match implements network quotas.
+
+  If you want to compile it as a module, say M here and read
+  Documentation/modules.txt.  If unsure, say `N'.
+
 skb->pkt_type packet match support
 CONFIG_IP_NF_MATCH_PKTTYPE
   This patch allows you to match packet in accrodance
diff -ruN linux-2.4.30-old/include/linux/netfilter_ipv4/ipt_quota.h linux-2.4.30-new/include/linux/netfilter_ipv4/ipt_quota.h
--- linux-2.4.30-old/include/linux/netfilter_ipv4/ipt_quota.h	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.30-new/include/linux/netfilter_ipv4/ipt_quota.h	2005-11-13 22:31:17.000000000 +0100
@@ -0,0 +1,12 @@
+#ifndef _IPT_QUOTA_H
+#define _IPT_QUOTA_H
+
+/* print debug info in both kernel/netfilter module & iptable library */
+//#define DEBUG_IPT_QUOTA
+
+struct ipt_quota_info {
+        u_int64_t quota;
+	struct ipt_quota_info *master;
+};
+
+#endif /*_IPT_QUOTA_H*/
diff -ruN linux-2.4.30-old/net/ipv4/netfilter/Config.in linux-2.4.30-new/net/ipv4/netfilter/Config.in
--- linux-2.4.30-old/net/ipv4/netfilter/Config.in	2005-11-13 22:30:42.000000000 +0100
+++ linux-2.4.30-new/net/ipv4/netfilter/Config.in	2005-11-13 22:31:17.000000000 +0100
@@ -24,6 +24,7 @@
 if [ "$CONFIG_IP_NF_IPTABLES" != "n" ]; then
 # The simple matches.
   dep_tristate '  limit match support' CONFIG_IP_NF_MATCH_LIMIT $CONFIG_IP_NF_IPTABLES
+  dep_tristate '  quota match support' CONFIG_IP_NF_MATCH_QUOTA $CONFIG_IP_NF_IPTABLES
 
   dep_tristate '  IP set support' CONFIG_IP_NF_SET $CONFIG_IP_NF_IPTABLES
   if [ "$CONFIG_IP_NF_SET" != "n" ]; then
diff -ruN linux-2.4.30-old/net/ipv4/netfilter/Makefile linux-2.4.30-new/net/ipv4/netfilter/Makefile
--- linux-2.4.30-old/net/ipv4/netfilter/Makefile	2005-11-13 22:30:42.000000000 +0100
+++ linux-2.4.30-new/net/ipv4/netfilter/Makefile	2005-11-13 22:31:17.000000000 +0100
@@ -74,6 +74,7 @@
 # matches
 obj-$(CONFIG_IP_NF_MATCH_HELPER) += ipt_helper.o
 obj-$(CONFIG_IP_NF_MATCH_LIMIT) += ipt_limit.o
+obj-$(CONFIG_IP_NF_MATCH_QUOTA) += ipt_quota.o
 obj-$(CONFIG_IP_NF_MATCH_MARK) += ipt_mark.o
 obj-$(CONFIG_IP_NF_MATCH_SET) += ipt_set.o
 obj-$(CONFIG_IP_NF_TARGET_SET) += ipt_SET.o
diff -ruN linux-2.4.30-old/net/ipv4/netfilter/ipt_quota.c linux-2.4.30-new/net/ipv4/netfilter/ipt_quota.c
--- linux-2.4.30-old/net/ipv4/netfilter/ipt_quota.c	1970-01-01 01:00:00.000000000 +0100
+++ linux-2.4.30-new/net/ipv4/netfilter/ipt_quota.c	2005-11-13 22:31:17.000000000 +0100
@@ -0,0 +1,88 @@
+/* 
+ * netfilter module to enforce network quotas
+ *
+ * Sam Johnston <samj@samj.net>
+ *
+ * 30/01/05: Fixed on SMP --Pablo Neira <pablo@eurodev.net>
+ */
+#include <linux/module.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/interrupt.h>
+
+#include <linux/netfilter_ipv4/ip_tables.h>
+#include <linux/netfilter_ipv4/ipt_quota.h>
+
+MODULE_LICENSE("GPL");
+
+static spinlock_t quota_lock = SPIN_LOCK_UNLOCKED;
+
+static int
+match(const struct sk_buff *skb,
+      const struct net_device *in,
+      const struct net_device *out,
+      const void *matchinfo,
+      int offset, const void *hdr, u_int16_t datalen, int *hotdrop)
+{
+	struct ipt_quota_info *q =
+		((struct ipt_quota_info *) matchinfo)->master;
+
+        spin_lock_bh(&quota_lock);
+
+        if (q->quota >= datalen) {
+                /* we can afford this one */
+                q->quota -= datalen;
+                spin_unlock_bh(&quota_lock);
+
+#ifdef DEBUG_IPT_QUOTA
+                printk("IPT Quota OK: %llu datlen %d \n", q->quota, datalen);
+#endif
+                return 1;
+        }
+
+        /* so we do not allow even small packets from now on */
+        q->quota = 0;
+
+#ifdef DEBUG_IPT_QUOTA
+        printk("IPT Quota Failed: %llu datlen %d \n", q->quota, datalen);
+#endif
+
+        spin_unlock_bh(&quota_lock);
+        return 0;
+}
+
+static int
+checkentry(const char *tablename,
+           const struct ipt_ip *ip,
+           void *matchinfo, unsigned int matchsize, unsigned int hook_mask)
+{
+        /* TODO: spinlocks? sanity checks? */
+	struct ipt_quota_info *q = (struct ipt_quota_info *) matchinfo;
+
+        if (matchsize != IPT_ALIGN(sizeof (struct ipt_quota_info)))
+                return 0;
+	
+	/* For SMP, we only want to use one set of counters. */
+	q->master = q;
+
+        return 1;
+}
+
+static struct ipt_match quota_match
+    = { {NULL, NULL}, "quota", &match, &checkentry, NULL, THIS_MODULE };
+
+static int __init
+init(void)
+{
+        return ipt_register_match(&quota_match);
+}
+
+static void __exit
+fini(void)
+{
+        ipt_unregister_match(&quota_match);
+}
+
+module_init(init);
+module_exit(fini);
+