From 4aca87515a5083ae0e31ce3177189fd43b6d05ac Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sat, 3 Jan 2015 13:58:15 +0100 Subject: patch to Vanilla Tomato 1.28 --- .../src/linux/linux/net/ipv4/netfilter/ipt_quota.c | 88 ++++++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 release/src/linux/linux/net/ipv4/netfilter/ipt_quota.c (limited to 'release/src/linux/linux/net/ipv4/netfilter/ipt_quota.c') diff --git a/release/src/linux/linux/net/ipv4/netfilter/ipt_quota.c b/release/src/linux/linux/net/ipv4/netfilter/ipt_quota.c new file mode 100644 index 00000000..d7ab39cf --- /dev/null +++ b/release/src/linux/linux/net/ipv4/netfilter/ipt_quota.c @@ -0,0 +1,88 @@ +/* + * netfilter module to enforce network quotas + * + * Sam Johnston + * + * 30/01/05: Fixed on SMP --Pablo Neira + */ +#include +#include +#include +#include + +#include +#include + +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("a_lock); + + if (q->quota >= datalen) { + /* we can afford this one */ + q->quota -= datalen; + spin_unlock_bh("a_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("a_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("a_match); +} + +static void __exit +fini(void) +{ + ipt_unregister_match("a_match); +} + +module_init(init); +module_exit(fini); + -- cgit v1.2.3-54-g00ecf