diff options
author | Patrick McHardy <kaber@trash.net> | 2006-05-29 21:20:32 -0400 |
---|---|---|
committer | David S. Miller <davem@sunset.davemloft.net> | 2006-06-18 00:28:49 -0400 |
commit | 62b7743483b402f8fb73545d5d487ca714e82766 (patch) | |
tree | f90e434e85c1f4391ad46310ee128ce25c1dca57 /net | |
parent | 957dc80ac30f3c4d53259fa936df807663ba54fa (diff) |
[NETFILTER]: x_tables: add quota match
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/netfilter/Kconfig | 10 | ||||
-rw-r--r-- | net/netfilter/Makefile | 1 | ||||
-rw-r--r-- | net/netfilter/xt_quota.c | 96 |
3 files changed, 107 insertions, 0 deletions
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index e2893effdfaa..5543c7b74535 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig | |||
@@ -329,6 +329,16 @@ config NETFILTER_XT_MATCH_PKTTYPE | |||
329 | 329 | ||
330 | To compile it as a module, choose M here. If unsure, say N. | 330 | To compile it as a module, choose M here. If unsure, say N. |
331 | 331 | ||
332 | config NETFILTER_XT_MATCH_QUOTA | ||
333 | tristate '"quota" match support' | ||
334 | depends on NETFILTER_XTABLES | ||
335 | help | ||
336 | This option adds a `quota' match, which allows to match on a | ||
337 | byte counter. | ||
338 | |||
339 | If you want to compile it as a module, say M here and read | ||
340 | <file:Documentation/modules.txt>. If unsure, say `N'. | ||
341 | |||
332 | config NETFILTER_XT_MATCH_REALM | 342 | config NETFILTER_XT_MATCH_REALM |
333 | tristate '"realm" match support' | 343 | tristate '"realm" match support' |
334 | depends on NETFILTER_XTABLES | 344 | depends on NETFILTER_XTABLES |
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 95b7e416512d..4b6a6ea07373 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile | |||
@@ -44,6 +44,7 @@ obj-$(CONFIG_NETFILTER_XT_MATCH_MARK) += xt_mark.o | |||
44 | obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o | 44 | obj-$(CONFIG_NETFILTER_XT_MATCH_MULTIPORT) += xt_multiport.o |
45 | obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o | 45 | obj-$(CONFIG_NETFILTER_XT_MATCH_POLICY) += xt_policy.o |
46 | obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o | 46 | obj-$(CONFIG_NETFILTER_XT_MATCH_PKTTYPE) += xt_pkttype.o |
47 | obj-$(CONFIG_NETFILTER_XT_MATCH_QUOTA) += xt_quota.o | ||
47 | obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o | 48 | obj-$(CONFIG_NETFILTER_XT_MATCH_REALM) += xt_realm.o |
48 | obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o | 49 | obj-$(CONFIG_NETFILTER_XT_MATCH_SCTP) += xt_sctp.o |
49 | obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o | 50 | obj-$(CONFIG_NETFILTER_XT_MATCH_STATE) += xt_state.o |
diff --git a/net/netfilter/xt_quota.c b/net/netfilter/xt_quota.c new file mode 100644 index 000000000000..4cdba7469dc4 --- /dev/null +++ b/net/netfilter/xt_quota.c | |||
@@ -0,0 +1,96 @@ | |||
1 | /* | ||
2 | * netfilter module to enforce network quotas | ||
3 | * | ||
4 | * Sam Johnston <samj@samj.net> | ||
5 | */ | ||
6 | #include <linux/skbuff.h> | ||
7 | #include <linux/spinlock.h> | ||
8 | |||
9 | #include <linux/netfilter/x_tables.h> | ||
10 | #include <linux/netfilter/xt_quota.h> | ||
11 | |||
12 | MODULE_LICENSE("GPL"); | ||
13 | MODULE_AUTHOR("Sam Johnston <samj@samj.net>"); | ||
14 | |||
15 | static DEFINE_SPINLOCK(quota_lock); | ||
16 | |||
17 | static int | ||
18 | match(const struct sk_buff *skb, | ||
19 | const struct net_device *in, const struct net_device *out, | ||
20 | const struct xt_match *match, const void *matchinfo, | ||
21 | int offset, unsigned int protoff, int *hotdrop) | ||
22 | { | ||
23 | struct xt_quota_info *q = ((struct xt_quota_info *)matchinfo)->master; | ||
24 | int ret = q->flags & XT_QUOTA_INVERT ? 1 : 0; | ||
25 | |||
26 | spin_lock_bh("a_lock); | ||
27 | if (q->quota >= skb->len) { | ||
28 | q->quota -= skb->len; | ||
29 | ret ^= 1; | ||
30 | } else { | ||
31 | /* we do not allow even small packets from now on */ | ||
32 | q->quota = 0; | ||
33 | } | ||
34 | spin_unlock_bh("a_lock); | ||
35 | |||
36 | return ret; | ||
37 | } | ||
38 | |||
39 | static int | ||
40 | checkentry(const char *tablename, const void *entry, | ||
41 | const struct xt_match *match, void *matchinfo, | ||
42 | unsigned int matchsize, unsigned int hook_mask) | ||
43 | { | ||
44 | struct xt_quota_info *q = (struct xt_quota_info *)matchinfo; | ||
45 | |||
46 | if (q->flags & ~XT_QUOTA_MASK) | ||
47 | return 0; | ||
48 | /* For SMP, we only want to use one set of counters. */ | ||
49 | q->master = q; | ||
50 | return 1; | ||
51 | } | ||
52 | |||
53 | static struct xt_match quota_match = { | ||
54 | .name = "quota", | ||
55 | .family = AF_INET, | ||
56 | .match = match, | ||
57 | .matchsize = sizeof(struct xt_quota_info), | ||
58 | .checkentry = checkentry, | ||
59 | .me = THIS_MODULE | ||
60 | }; | ||
61 | |||
62 | static struct xt_match quota_match6 = { | ||
63 | .name = "quota", | ||
64 | .family = AF_INET6, | ||
65 | .match = match, | ||
66 | .matchsize = sizeof(struct xt_quota_info), | ||
67 | .checkentry = checkentry, | ||
68 | .me = THIS_MODULE | ||
69 | }; | ||
70 | |||
71 | static int __init xt_quota_init(void) | ||
72 | { | ||
73 | int ret; | ||
74 | |||
75 | ret = xt_register_match("a_match); | ||
76 | if (ret) | ||
77 | goto err1; | ||
78 | ret = xt_register_match("a_match6); | ||
79 | if (ret) | ||
80 | goto err2; | ||
81 | return ret; | ||
82 | |||
83 | err2: | ||
84 | xt_unregister_match("a_match); | ||
85 | err1: | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | static void __exit xt_quota_fini(void) | ||
90 | { | ||
91 | xt_unregister_match("a_match6); | ||
92 | xt_unregister_match("a_match); | ||
93 | } | ||
94 | |||
95 | module_init(xt_quota_init); | ||
96 | module_exit(xt_quota_fini); | ||