netfilter: nft_quota: move stateful fields out of expression data
In preparation for the rule blob representation. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
33a24de37e
commit
ed0a0c60f0
|
@ -15,13 +15,13 @@
|
||||||
struct nft_quota {
|
struct nft_quota {
|
||||||
atomic64_t quota;
|
atomic64_t quota;
|
||||||
unsigned long flags;
|
unsigned long flags;
|
||||||
atomic64_t consumed;
|
atomic64_t *consumed;
|
||||||
};
|
};
|
||||||
|
|
||||||
static inline bool nft_overquota(struct nft_quota *priv,
|
static inline bool nft_overquota(struct nft_quota *priv,
|
||||||
const struct sk_buff *skb)
|
const struct sk_buff *skb)
|
||||||
{
|
{
|
||||||
return atomic64_add_return(skb->len, &priv->consumed) >=
|
return atomic64_add_return(skb->len, priv->consumed) >=
|
||||||
atomic64_read(&priv->quota);
|
atomic64_read(&priv->quota);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -90,13 +90,23 @@ static int nft_quota_do_init(const struct nlattr * const tb[],
|
||||||
return -EOPNOTSUPP;
|
return -EOPNOTSUPP;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv->consumed = kmalloc(sizeof(*priv->consumed), GFP_KERNEL);
|
||||||
|
if (!priv->consumed)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
atomic64_set(&priv->quota, quota);
|
atomic64_set(&priv->quota, quota);
|
||||||
priv->flags = flags;
|
priv->flags = flags;
|
||||||
atomic64_set(&priv->consumed, consumed);
|
atomic64_set(priv->consumed, consumed);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nft_quota_do_destroy(const struct nft_ctx *ctx,
|
||||||
|
struct nft_quota *priv)
|
||||||
|
{
|
||||||
|
kfree(priv->consumed);
|
||||||
|
}
|
||||||
|
|
||||||
static int nft_quota_obj_init(const struct nft_ctx *ctx,
|
static int nft_quota_obj_init(const struct nft_ctx *ctx,
|
||||||
const struct nlattr * const tb[],
|
const struct nlattr * const tb[],
|
||||||
struct nft_object *obj)
|
struct nft_object *obj)
|
||||||
|
@ -128,7 +138,7 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
|
||||||
* that we see, don't go over the quota boundary in what we send to
|
* that we see, don't go over the quota boundary in what we send to
|
||||||
* userspace.
|
* userspace.
|
||||||
*/
|
*/
|
||||||
consumed = atomic64_read(&priv->consumed);
|
consumed = atomic64_read(priv->consumed);
|
||||||
quota = atomic64_read(&priv->quota);
|
quota = atomic64_read(&priv->quota);
|
||||||
if (consumed >= quota) {
|
if (consumed >= quota) {
|
||||||
consumed_cap = quota;
|
consumed_cap = quota;
|
||||||
|
@ -145,7 +155,7 @@ static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
|
||||||
if (reset) {
|
if (reset) {
|
||||||
atomic64_sub(consumed, &priv->consumed);
|
atomic64_sub(consumed, priv->consumed);
|
||||||
clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
|
clear_bit(NFT_QUOTA_DEPLETED_BIT, &priv->flags);
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -162,11 +172,20 @@ static int nft_quota_obj_dump(struct sk_buff *skb, struct nft_object *obj,
|
||||||
return nft_quota_do_dump(skb, priv, reset);
|
return nft_quota_do_dump(skb, priv, reset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nft_quota_obj_destroy(const struct nft_ctx *ctx,
|
||||||
|
struct nft_object *obj)
|
||||||
|
{
|
||||||
|
struct nft_quota *priv = nft_obj_data(obj);
|
||||||
|
|
||||||
|
return nft_quota_do_destroy(ctx, priv);
|
||||||
|
}
|
||||||
|
|
||||||
static struct nft_object_type nft_quota_obj_type;
|
static struct nft_object_type nft_quota_obj_type;
|
||||||
static const struct nft_object_ops nft_quota_obj_ops = {
|
static const struct nft_object_ops nft_quota_obj_ops = {
|
||||||
.type = &nft_quota_obj_type,
|
.type = &nft_quota_obj_type,
|
||||||
.size = sizeof(struct nft_quota),
|
.size = sizeof(struct nft_quota),
|
||||||
.init = nft_quota_obj_init,
|
.init = nft_quota_obj_init,
|
||||||
|
.destroy = nft_quota_obj_destroy,
|
||||||
.eval = nft_quota_obj_eval,
|
.eval = nft_quota_obj_eval,
|
||||||
.dump = nft_quota_obj_dump,
|
.dump = nft_quota_obj_dump,
|
||||||
.update = nft_quota_obj_update,
|
.update = nft_quota_obj_update,
|
||||||
|
@ -205,12 +224,35 @@ static int nft_quota_dump(struct sk_buff *skb, const struct nft_expr *expr)
|
||||||
return nft_quota_do_dump(skb, priv, false);
|
return nft_quota_do_dump(skb, priv, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void nft_quota_destroy(const struct nft_ctx *ctx,
|
||||||
|
const struct nft_expr *expr)
|
||||||
|
{
|
||||||
|
struct nft_quota *priv = nft_expr_priv(expr);
|
||||||
|
|
||||||
|
return nft_quota_do_destroy(ctx, priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int nft_quota_clone(struct nft_expr *dst, const struct nft_expr *src)
|
||||||
|
{
|
||||||
|
struct nft_quota *priv_dst = nft_expr_priv(dst);
|
||||||
|
|
||||||
|
priv_dst->consumed = kmalloc(sizeof(*priv_dst->consumed), GFP_ATOMIC);
|
||||||
|
if (priv_dst->consumed)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
atomic64_set(priv_dst->consumed, 0);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static struct nft_expr_type nft_quota_type;
|
static struct nft_expr_type nft_quota_type;
|
||||||
static const struct nft_expr_ops nft_quota_ops = {
|
static const struct nft_expr_ops nft_quota_ops = {
|
||||||
.type = &nft_quota_type,
|
.type = &nft_quota_type,
|
||||||
.size = NFT_EXPR_SIZE(sizeof(struct nft_quota)),
|
.size = NFT_EXPR_SIZE(sizeof(struct nft_quota)),
|
||||||
.eval = nft_quota_eval,
|
.eval = nft_quota_eval,
|
||||||
.init = nft_quota_init,
|
.init = nft_quota_init,
|
||||||
|
.destroy = nft_quota_destroy,
|
||||||
|
.clone = nft_quota_clone,
|
||||||
.dump = nft_quota_dump,
|
.dump = nft_quota_dump,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue