]> git.ipfire.org Git - thirdparty/iptables.git/commitdiff
extensions: libxt_quota: Allow setting the remaining quota
authorChenbo Feng <fengc@google.com>
Tue, 2 Oct 2018 01:23:07 +0000 (18:23 -0700)
committerPablo Neira Ayuso <pablo@netfilter.org>
Mon, 8 Oct 2018 23:14:30 +0000 (01:14 +0200)
The current xt_quota module cannot track the current remaining quota
of a specific rule. Everytime an unrelated rule is updated in the same
iptables table, the quota will be reset. This is not a very useful
function for iptables that get changed at run time. This patch fixes the
above problem by adding a new field in the struct that records the
current remaining quota.

Fixed a print out bug in verbose print out wrt. inversion.

Signed-off-by: Chenbo Feng <fengc@google.com>
Suggested-by: Maciej Żenczykowski <maze@google.com>
Reviewed-by: Maciej Żenczykowski <maze@google.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
extensions/libxt_quota.c
include/linux/netfilter/xt_quota.h

index bad77d236e6b8899e35acc94b957d740d885fead..6371aa0f1ffff2ef23a8e2d88bfdb531b49e40b5 100644 (file)
@@ -9,26 +9,36 @@
 
 enum {
        O_QUOTA = 0,
+       O_REMAIN = 1,
 };
 
 static const struct xt_option_entry quota_opts[] = {
        {.name = "quota", .id = O_QUOTA, .type = XTTYPE_UINT64,
         .flags = XTOPT_MAND | XTOPT_INVERT | XTOPT_PUT,
         XTOPT_POINTER(struct xt_quota_info, quota)},
+       {.name = "remain", .id = O_REMAIN, .type = XTTYPE_UINT64,
+        .flags = XTOPT_PUT, XTOPT_POINTER(struct xt_quota_info, remain)},
        XTOPT_TABLEEND,
 };
 
 static void quota_help(void)
 {
        printf("quota match options:\n"
-              "[!] --quota quota               quota (bytes)\n");
+              "[!] --quota quota               quota (bytes)\n"
+              "    --remain remain             remain (bytes)\n");
 }
 
 static void
 quota_print(const void *ip, const struct xt_entry_match *match, int numeric)
 {
        const struct xt_quota_info *q = (const void *)match->data;
+       if (q->flags & XT_QUOTA_INVERT)
+               printf(" !");
        printf(" quota: %llu bytes", (unsigned long long)q->quota);
+       if (q->remain) {
+               printf(" remain: %llu bytes",
+                       (unsigned long long)q->remain - 1);
+       }
 }
 
 static void
@@ -39,6 +49,10 @@ quota_save(const void *ip, const struct xt_entry_match *match)
        if (q->flags & XT_QUOTA_INVERT)
                printf(" !");
        printf(" --quota %llu", (unsigned long long) q->quota);
+       if (q->remain) {
+               printf(" --remain %llu",
+                       (unsigned long long) q->remain - 1);
+       }
 }
 
 static void quota_parse(struct xt_option_call *cb)
@@ -48,6 +62,8 @@ static void quota_parse(struct xt_option_call *cb)
        xtables_option_parse(cb);
        if (cb->invert)
                info->flags |= XT_QUOTA_INVERT;
+       if (cb->entry->id == O_REMAIN)
+               info->remain++;
 }
 
 static int quota_xlate(struct xt_xlate *xl,
@@ -66,7 +82,12 @@ static struct xtables_match quota_match = {
        .name           = "quota",
        .version        = XTABLES_VERSION,
        .size           = XT_ALIGN(sizeof (struct xt_quota_info)),
-       .userspacesize  = offsetof(struct xt_quota_info, master),
+       /*
+        * This size is only used for rule matching purpose when deleting
+        * rules. The real size copied out from new kernel xt_quota module
+        * is the whole struct xt_quota_info.
+        */
+       .userspacesize  = offsetof(struct xt_quota_info, remain),
        .help           = quota_help,
        .print          = quota_print,
        .save           = quota_save,
index 9314723f39ca19bb4f257e60f711ffedaaa52ee1..d817aab282287609a14342b5c76e3a91f46fbe84 100644 (file)
@@ -14,9 +14,11 @@ struct xt_quota_info {
        __u32 flags;
        __u32 pad;
        __aligned_u64 quota;
-
-       /* Used internally by the kernel */
-       struct xt_quota_priv    *master;
+#ifdef __KERNEL__
+       atomic64_t counter;
+#else
+       __aligned_u64 remain;
+#endif
 };
 
 #endif /* _XT_QUOTA_H */