xt_quota.c 1.9 KB

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