-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[NETFILTER]: x_tables: add quota match
Signed-off-by: Patrick McHardy <kaber@trash.net> Signed-off-by: David S. Miller <davem@davemloft.net>
- Loading branch information
Patrick McHardy
authored and
David S. Miller
committed
Jun 18, 2006
1 parent
957dc80
commit 62b7743
Showing
4 changed files
with
123 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
#ifndef _XT_QUOTA_H | ||
#define _XT_QUOTA_H | ||
|
||
enum xt_quota_flags { | ||
XT_QUOTA_INVERT = 0x1, | ||
}; | ||
#define XT_QUOTA_MASK 0x1 | ||
|
||
struct xt_quota_info { | ||
u_int32_t flags; | ||
u_int32_t pad; | ||
aligned_u64 quota; | ||
struct xt_quota_info *master; | ||
}; | ||
|
||
#endif /* _XT_QUOTA_H */ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
/* | ||
* netfilter module to enforce network quotas | ||
* | ||
* Sam Johnston <samj@samj.net> | ||
*/ | ||
#include <linux/skbuff.h> | ||
#include <linux/spinlock.h> | ||
|
||
#include <linux/netfilter/x_tables.h> | ||
#include <linux/netfilter/xt_quota.h> | ||
|
||
MODULE_LICENSE("GPL"); | ||
MODULE_AUTHOR("Sam Johnston <samj@samj.net>"); | ||
|
||
static DEFINE_SPINLOCK(quota_lock); | ||
|
||
static int | ||
match(const struct sk_buff *skb, | ||
const struct net_device *in, const struct net_device *out, | ||
const struct xt_match *match, const void *matchinfo, | ||
int offset, unsigned int protoff, int *hotdrop) | ||
{ | ||
struct xt_quota_info *q = ((struct xt_quota_info *)matchinfo)->master; | ||
int ret = q->flags & XT_QUOTA_INVERT ? 1 : 0; | ||
|
||
spin_lock_bh("a_lock); | ||
if (q->quota >= skb->len) { | ||
q->quota -= skb->len; | ||
ret ^= 1; | ||
} else { | ||
/* we do not allow even small packets from now on */ | ||
q->quota = 0; | ||
} | ||
spin_unlock_bh("a_lock); | ||
|
||
return ret; | ||
} | ||
|
||
static int | ||
checkentry(const char *tablename, const void *entry, | ||
const struct xt_match *match, void *matchinfo, | ||
unsigned int matchsize, unsigned int hook_mask) | ||
{ | ||
struct xt_quota_info *q = (struct xt_quota_info *)matchinfo; | ||
|
||
if (q->flags & ~XT_QUOTA_MASK) | ||
return 0; | ||
/* For SMP, we only want to use one set of counters. */ | ||
q->master = q; | ||
return 1; | ||
} | ||
|
||
static struct xt_match quota_match = { | ||
.name = "quota", | ||
.family = AF_INET, | ||
.match = match, | ||
.matchsize = sizeof(struct xt_quota_info), | ||
.checkentry = checkentry, | ||
.me = THIS_MODULE | ||
}; | ||
|
||
static struct xt_match quota_match6 = { | ||
.name = "quota", | ||
.family = AF_INET6, | ||
.match = match, | ||
.matchsize = sizeof(struct xt_quota_info), | ||
.checkentry = checkentry, | ||
.me = THIS_MODULE | ||
}; | ||
|
||
static int __init xt_quota_init(void) | ||
{ | ||
int ret; | ||
|
||
ret = xt_register_match("a_match); | ||
if (ret) | ||
goto err1; | ||
ret = xt_register_match("a_match6); | ||
if (ret) | ||
goto err2; | ||
return ret; | ||
|
||
err2: | ||
xt_unregister_match("a_match); | ||
err1: | ||
return ret; | ||
} | ||
|
||
static void __exit xt_quota_fini(void) | ||
{ | ||
xt_unregister_match("a_match6); | ||
xt_unregister_match("a_match); | ||
} | ||
|
||
module_init(xt_quota_init); | ||
module_exit(xt_quota_fini); |