mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-11 12:28:41 +08:00
netfilter: nft_quota: add quota object update support
Signed-off-by: Fernando Fernandez Mancera <ffmancera@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
d62d0ba97b
commit
85936e56e9
@ -13,7 +13,7 @@
|
||||
#include <net/netfilter/nf_tables.h>
|
||||
|
||||
struct nft_quota {
|
||||
u64 quota;
|
||||
atomic64_t quota;
|
||||
unsigned long flags;
|
||||
atomic64_t consumed;
|
||||
};
|
||||
@ -21,7 +21,8 @@ struct nft_quota {
|
||||
static inline bool nft_overquota(struct nft_quota *priv,
|
||||
const struct sk_buff *skb)
|
||||
{
|
||||
return atomic64_add_return(skb->len, &priv->consumed) >= priv->quota;
|
||||
return atomic64_add_return(skb->len, &priv->consumed) >=
|
||||
atomic64_read(&priv->quota);
|
||||
}
|
||||
|
||||
static inline bool nft_quota_invert(struct nft_quota *priv)
|
||||
@ -89,7 +90,7 @@ static int nft_quota_do_init(const struct nlattr * const tb[],
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
priv->quota = quota;
|
||||
atomic64_set(&priv->quota, quota);
|
||||
priv->flags = flags;
|
||||
atomic64_set(&priv->consumed, consumed);
|
||||
|
||||
@ -105,10 +106,22 @@ static int nft_quota_obj_init(const struct nft_ctx *ctx,
|
||||
return nft_quota_do_init(tb, priv);
|
||||
}
|
||||
|
||||
static void nft_quota_obj_update(struct nft_object *obj,
|
||||
struct nft_object *newobj)
|
||||
{
|
||||
struct nft_quota *newpriv = nft_obj_data(newobj);
|
||||
struct nft_quota *priv = nft_obj_data(obj);
|
||||
u64 newquota;
|
||||
|
||||
newquota = atomic64_read(&newpriv->quota);
|
||||
atomic64_set(&priv->quota, newquota);
|
||||
priv->flags = newpriv->flags;
|
||||
}
|
||||
|
||||
static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
|
||||
bool reset)
|
||||
{
|
||||
u64 consumed, consumed_cap;
|
||||
u64 consumed, consumed_cap, quota;
|
||||
u32 flags = priv->flags;
|
||||
|
||||
/* Since we inconditionally increment consumed quota for each packet
|
||||
@ -116,14 +129,15 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
|
||||
* userspace.
|
||||
*/
|
||||
consumed = atomic64_read(&priv->consumed);
|
||||
if (consumed >= priv->quota) {
|
||||
consumed_cap = priv->quota;
|
||||
quota = atomic64_read(&priv->quota);
|
||||
if (consumed >= quota) {
|
||||
consumed_cap = quota;
|
||||
flags |= NFT_QUOTA_F_DEPLETED;
|
||||
} else {
|
||||
consumed_cap = consumed;
|
||||
}
|
||||
|
||||
if (nla_put_be64(skb, NFTA_QUOTA_BYTES, cpu_to_be64(priv->quota),
|
||||
if (nla_put_be64(skb, NFTA_QUOTA_BYTES, cpu_to_be64(quota),
|
||||
NFTA_QUOTA_PAD) ||
|
||||
nla_put_be64(skb, NFTA_QUOTA_CONSUMED, cpu_to_be64(consumed_cap),
|
||||
NFTA_QUOTA_PAD) ||
|
||||
@ -155,6 +169,7 @@ static const struct nft_object_ops nft_quota_obj_ops = {
|
||||
.init = nft_quota_obj_init,
|
||||
.eval = nft_quota_obj_eval,
|
||||
.dump = nft_quota_obj_dump,
|
||||
.update = nft_quota_obj_update,
|
||||
};
|
||||
|
||||
static struct nft_object_type nft_quota_obj_type __read_mostly = {
|
||||
|
Loading…
Reference in New Issue
Block a user