diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h index b8cd62f..a652136 100644 --- a/include/uapi/linux/netfilter/nf_tables.h +++ b/include/uapi/linux/netfilter/nf_tables.h @@ -538,12 +538,12 @@ enum nft_ct_attributes { * enum nft_limit_attributes - nf_tables limit expression netlink attributes * * @NFTA_LIMIT_RATE: refill rate (NLA_U64) - * @NFTA_LIMIT_DEPTH: bucket depth (NLA_U64) + * @NFTA_LIMIT_UNIT: refill unit (NLA_U64) */ enum nft_limit_attributes { NFTA_LIMIT_UNSPEC, NFTA_LIMIT_RATE, - NFTA_LIMIT_DEPTH, + NFTA_LIMIT_UNIT, __NFTA_LIMIT_MAX }; #define NFTA_LIMIT_MAX (__NFTA_LIMIT_MAX - 1) diff --git a/net/netfilter/nft_limit.c b/net/netfilter/nft_limit.c index a40ccc0..85da5bd 100644 --- a/net/netfilter/nft_limit.c +++ b/net/netfilter/nft_limit.c @@ -21,8 +21,8 @@ static DEFINE_SPINLOCK(limit_lock); struct nft_limit { u64 tokens; - u64 depth; u64 rate; + u64 unit; unsigned long stamp; }; @@ -33,11 +33,9 @@ static void nft_limit_eval(const struct nft_expr *expr, struct nft_limit *priv = nft_expr_priv(expr); spin_lock_bh(&limit_lock); - if (priv->stamp != jiffies) { - priv->tokens += priv->rate * (jiffies - priv->stamp); - if (priv->tokens > priv->depth) - priv->tokens = priv->depth; - priv->stamp = jiffies; + if (time_after_eq(jiffies, priv->stamp)) { + priv->tokens = priv->rate; + priv->stamp = jiffies + priv->unit * HZ; } if (priv->tokens >= 1) { @@ -52,7 +50,7 @@ static void nft_limit_eval(const struct nft_expr *expr, static const struct nla_policy nft_limit_policy[NFTA_LIMIT_MAX + 1] = { [NFTA_LIMIT_RATE] = { .type = NLA_U64 }, - [NFTA_LIMIT_DEPTH] = { .type = NLA_U64 }, + [NFTA_LIMIT_UNIT] = { .type = NLA_U64 }, }; static int nft_limit_init(const struct nft_ctx *ctx, @@ -62,12 +60,13 @@ static int nft_limit_init(const struct nft_ctx *ctx, struct nft_limit *priv = nft_expr_priv(expr); if (tb[NFTA_LIMIT_RATE] == NULL || - tb[NFTA_LIMIT_DEPTH] == NULL) + tb[NFTA_LIMIT_UNIT] == NULL) return -EINVAL; priv->rate = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_RATE])); - priv->depth = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_DEPTH])); - priv->tokens = priv->depth; + priv->unit = be64_to_cpu(nla_get_be64(tb[NFTA_LIMIT_UNIT])); + priv->stamp = jiffies + priv->unit * HZ; + priv->tokens = priv->rate; return 0; } @@ -77,7 +76,7 @@ static int nft_limit_dump(struct sk_buff *skb, const struct nft_expr *expr) if (nla_put_be64(skb, NFTA_LIMIT_RATE, cpu_to_be64(priv->rate))) goto nla_put_failure; - if (nla_put_be64(skb, NFTA_LIMIT_DEPTH, cpu_to_be64(priv->depth))) + if (nla_put_be64(skb, NFTA_LIMIT_UNIT, cpu_to_be64(priv->unit))) goto nla_put_failure; return 0;