xt_quota.c revision 601e68e100b6bf8ba13a32db8faf92d43acaa997
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 12MODULE_LICENSE("GPL"); 13MODULE_AUTHOR("Sam Johnston <samj@samj.net>"); 14MODULE_ALIAS("ipt_quota"); 15MODULE_ALIAS("ip6t_quota"); 16 17static DEFINE_SPINLOCK(quota_lock); 18 19static int 20match(const struct sk_buff *skb, 21 const struct net_device *in, const struct net_device *out, 22 const struct xt_match *match, const void *matchinfo, 23 int offset, unsigned int protoff, int *hotdrop) 24{ 25 struct xt_quota_info *q = ((struct xt_quota_info *)matchinfo)->master; 26 int ret = q->flags & XT_QUOTA_INVERT ? 1 : 0; 27 28 spin_lock_bh("a_lock); 29 if (q->quota >= skb->len) { 30 q->quota -= skb->len; 31 ret ^= 1; 32 } else { 33 /* we do not allow even small packets from now on */ 34 q->quota = 0; 35 } 36 spin_unlock_bh("a_lock); 37 38 return ret; 39} 40 41static int 42checkentry(const char *tablename, const void *entry, 43 const struct xt_match *match, void *matchinfo, 44 unsigned int hook_mask) 45{ 46 struct xt_quota_info *q = (struct xt_quota_info *)matchinfo; 47 48 if (q->flags & ~XT_QUOTA_MASK) 49 return 0; 50 /* For SMP, we only want to use one set of counters. */ 51 q->master = q; 52 return 1; 53} 54 55static struct xt_match xt_quota_match[] = { 56 { 57 .name = "quota", 58 .family = AF_INET, 59 .checkentry = checkentry, 60 .match = match, 61 .matchsize = sizeof(struct xt_quota_info), 62 .me = THIS_MODULE 63 }, 64 { 65 .name = "quota", 66 .family = AF_INET6, 67 .checkentry = checkentry, 68 .match = match, 69 .matchsize = sizeof(struct xt_quota_info), 70 .me = THIS_MODULE 71 }, 72}; 73 74static int __init xt_quota_init(void) 75{ 76 return xt_register_matches(xt_quota_match, ARRAY_SIZE(xt_quota_match)); 77} 78 79static void __exit xt_quota_fini(void) 80{ 81 xt_unregister_matches(xt_quota_match, ARRAY_SIZE(xt_quota_match)); 82} 83 84module_init(xt_quota_init); 85module_exit(xt_quota_fini); 86