diff options
author | Chenbo Feng <fengc@google.com> | 2018-10-01 18:23:07 -0700 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2018-10-09 01:14:30 +0200 |
commit | 0a8f2bcadff157489a737f8cc8846adcb750b91f (patch) | |
tree | ca58c1dca192c6ce765130cd707314ac77d26672 /extensions/libxt_quota.c | |
parent | b373a91b24c4bb1074f304bc74ce2f361c818a5a (diff) |
extensions: libxt_quota: Allow setting the remaining quota
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>
Diffstat (limited to 'extensions/libxt_quota.c')
-rw-r--r-- | extensions/libxt_quota.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/extensions/libxt_quota.c b/extensions/libxt_quota.c index bad77d23..6371aa0f 100644 --- a/extensions/libxt_quota.c +++ b/extensions/libxt_quota.c @@ -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, |