]> git.ipfire.org Git - thirdparty/xtables-addons.git/commitdiff
xt_quota2: support packet counting; add manpage
authorJan Engelhardt <jengelh@medozas.de>
Sun, 6 Jul 2008 23:19:10 +0000 (01:19 +0200)
committerJan Engelhardt <jengelh@medozas.de>
Sun, 6 Jul 2008 23:19:10 +0000 (01:19 +0200)
extensions/libxt_quota2.c
extensions/libxt_quota2.man [new file with mode: 0644]
extensions/xt_quota2.c
extensions/xt_quota2.h

index 47193d28357b1e181c45b2f6c9bd6a7f12d728cb..71ee70c5c90c091f5aad08e43fb21a0a1df93947 100644 (file)
 #include "xt_quota2.h"
 
 enum {
-       FL_QUOTA = 1 << 0,
-       FL_NAME  = 1 << 1,
-       FL_GROW  = 1 << 2,
+       FL_QUOTA  = 1 << 0,
+       FL_NAME   = 1 << 1,
+       FL_GROW   = 1 << 2,
+       FL_PACKET = 1 << 3,
 };
 
 static const struct option quota_mt2_opts[] = {
-       {.name = "grow",  .has_arg = false, .val = 'g'},
-       {.name = "name",  .has_arg = true,  .val = 'n'},
-       {.name = "quota", .has_arg = true,  .val = 'q'},
+       {.name = "grow",    .has_arg = false, .val = 'g'},
+       {.name = "name",    .has_arg = true,  .val = 'n'},
+       {.name = "quota",   .has_arg = true,  .val = 'q'},
+       {.name = "packets", .has_arg = true,  .val = 'p'},
        {NULL},
 };
 
@@ -31,7 +33,8 @@ static void quota_mt2_help(void)
        "quota match options:\n"
        "    --grow           provide an increasing counter\n"
        "    --name name      name for the file in sysfs\n"
-       "[!] --quota quota    quota (bytes)\n"
+       "[!] --quota quota    initial quota (bytes or packets)\n"
+       "    --packets        count packets instead of bytes\n"
        );
 }
 
@@ -56,6 +59,12 @@ quota_mt2_parse(int c, char **argv, int invert, unsigned int *flags,
                strncpy(info->name, optarg, sizeof(info->name));
                *flags |= FL_NAME;
                return true;
+       case 'p':
+               param_act(P_ONLY_ONCE, "quota", "--packets", *flags & FL_PACKETS);
+               param_act(P_NO_INVERT, "quota", "--packets", invert);
+               info->flags |= XT_QUOTA_PACKET;
+               *flags |= FL_PACKET;
+               return true;
        case 'q':
                param_act(P_ONLY_ONCE, "quota", "--quota", *flags & FL_QUOTA);
                if (invert)
@@ -79,6 +88,8 @@ quota_mt2_save(const void *ip, const struct xt_entry_match *match)
                printf("! ");
        if (q->flags & XT_QUOTA_GROW)
                printf("--grow ");
+       if (q->flags & XT_QUOTA_PACKET)
+               printf("--packets ");
        if (*q->name != '\0')
                printf("--name %s ", q->name);
        printf("--quota %llu ", (unsigned long long)q->quota);
@@ -97,7 +108,11 @@ static void quota_mt2_print(const void *ip, const struct xt_entry_match *match,
                printf("quota");
        if (*q->name != '\0')
                printf(" %s:", q->name);
-       printf(" %llu bytes", (unsigned long long)q->quota);
+       printf(" %llu ", (unsigned long long)q->quota);
+       if (q->flags & XT_QUOTA_PACKET)
+               printf("packets ");
+       else
+               printf("bytes ");
 }
 
 static struct xtables_match quota_mt2_reg = {
diff --git a/extensions/libxt_quota2.man b/extensions/libxt_quota2.man
new file mode 100644 (file)
index 0000000..e18c681
--- /dev/null
@@ -0,0 +1,31 @@
+The "quota2" implements a named counter which can be increased or decreased
+on a per-match basis. Available modes are packet counting or byte counting.
+The value of the counter can be read and reset through procfs, thereby making
+this match a minimalist accounting tool.
+.PP
+When counting down from the initial quota, the counter will stop at 0 and
+the match will return false, just like the original "quota" match. In growing
+(upcounting) mode, it will always return true.
+.TP
+\fB--grow\fP
+Count upwards instead of downwards.
+.TP
+\fB--name\fP \fIname\fP
+Assign the counter a specific name. This option must be present, as an empty
+name is not allowed. Names starting with a dot or names containing a slash are
+prohibited.
+.TP
+[\fB!\fP] \fB--quota\fP \fIiq\fP
+Specify the initial quota for this counter. If the counter already exists,
+it is not reset. An "!" may be used to invert the result of the match. The
+negation has no effect when \fB--grow\fP is used.
+.TP
+\fB--packets\fP
+Count packets instead of bytes that passed the quota2 match.
+.PP
+Because counters in quota2 can be shared, you can combine them for various
+purposes, for example, a bytebucket filter that only lets as much traffic go
+out as has come in:
+.PP
+-A INPUT -p tcp --dport 6881 -m quota --name bt --grow
+-A OUTPUT -p tcp --sport 6881 -m quota --name bt
index 2e719fff6327a0553b89b857c30ca03a3c77b317..78dc6774833e3495a8f21a8cb66604229246791a 100644 (file)
@@ -1,7 +1,11 @@
 /*
- * netfilter module to enforce network quotas
+ * xt_quota2 - enhanced xt_quota that can count upwards and in packets
+ * as a minimal accounting match.
+ * by Jan Engelhardt <jengelh@medozas.de>, 2008
  *
- * Sam Johnston <samj@samj.net>
+ * Originally based on xt_quota.c:
+ *     netfilter module to enforce network quotas
+ *     Sam Johnston <samj@samj.net>
  */
 #include <linux/list.h>
 #include <linux/proc_fs.h>
@@ -167,14 +171,14 @@ quota_mt2(const struct sk_buff *skb, const struct net_device *in,
 
        if (q->flags & XT_QUOTA_GROW) {
                spin_lock_bh(&e->lock);
-               e->quota += skb->len;
+               e->quota += (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
                q->quota = e->quota;
                spin_unlock_bh(&e->lock);
                ret = true;
        } else {
                spin_lock_bh(&e->lock);
                if (e->quota >= skb->len) {
-                       e->quota -= skb->len;
+                       e->quota -= (q->flags & XT_QUOTA_PACKET) ? 1 : skb->len;
                        ret = !ret;
                } else {
                        /* we do not allow even small packets from now on */
index 1b68ae2ac44e9a7326e272b481d66219e43940bd..cb13c790491b4658960723a574addd8832dc2dfc 100644 (file)
@@ -2,9 +2,10 @@
 #define _XT_QUOTA_H
 
 enum xt_quota_flags {
-       XT_QUOTA_INVERT = 0x1,
-       XT_QUOTA_GROW   = 0x2,
-       XT_QUOTA_MASK   = 0x3,
+       XT_QUOTA_INVERT = 1 << 0,
+       XT_QUOTA_GROW   = 1 << 1,
+       XT_QUOTA_PACKET = 1 << 2,
+       XT_QUOTA_MASK   = 0x7,
 
        XT_QUOTA_COUNTER_NAME_LENGTH = 31,
 };