aboutsummaryrefslogtreecommitdiffstats
path: root/net/netfilter/nft_quota.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-11-28 00:05:44 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2016-12-07 12:56:57 +0100
commit43da04a593d8b2626f1cf4b56efe9402f6b53652 (patch)
tree9d3885eed99e906866b95af4448e731050fb1b26 /net/netfilter/nft_quota.c
parentnetfilter: nft_quota: dump consumed quota (diff)
downloadlinux-dev-43da04a593d8b2626f1cf4b56efe9402f6b53652.tar.xz
linux-dev-43da04a593d8b2626f1cf4b56efe9402f6b53652.zip
netfilter: nf_tables: atomic dump and reset for stateful objects
This patch adds a new NFT_MSG_GETOBJ_RESET command perform an atomic dump-and-reset of the stateful object. This also comes with add support for atomic dump and reset for counter and quota objects. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter/nft_quota.c')
-rw-r--r--net/netfilter/nft_quota.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/net/netfilter/nft_quota.c b/net/netfilter/nft_quota.c
index 0d344209803a..5d25f57497cb 100644
--- a/net/netfilter/nft_quota.c
+++ b/net/netfilter/nft_quota.c
@@ -83,12 +83,17 @@ static int nft_quota_obj_init(const struct nlattr * const tb[],
return nft_quota_do_init(tb, priv);
}
-static int nft_quota_do_dump(struct sk_buff *skb, const struct nft_quota *priv)
+static int nft_quota_do_dump(struct sk_buff *skb, struct nft_quota *priv,
+ bool reset)
{
u32 flags = priv->invert ? NFT_QUOTA_F_INV : 0;
u64 consumed;
- consumed = atomic64_read(&priv->consumed);
+ if (reset)
+ consumed = atomic64_xchg(&priv->consumed, 0);
+ else
+ consumed = atomic64_read(&priv->consumed);
+
/* Since we inconditionally increment consumed quota for each packet
* that we see, don't go over the quota boundary in what we send to
* userspace.
@@ -108,11 +113,12 @@ nla_put_failure:
return -1;
}
-static int nft_quota_obj_dump(struct sk_buff *skb, const struct nft_object *obj)
+static int nft_quota_obj_dump(struct sk_buff *skb, struct nft_object *obj,
+ bool reset)
{
struct nft_quota *priv = nft_obj_data(obj);
- return nft_quota_do_dump(skb, priv);
+ return nft_quota_do_dump(skb, priv, reset);
}
static struct nft_object_type nft_quota_obj __read_mostly = {
@@ -146,9 +152,9 @@ static int nft_quota_init(const struct nft_ctx *ctx,
static int nft_quota_dump(struct sk_buff *skb, const struct nft_expr *expr)
{
- const struct nft_quota *priv = nft_expr_priv(expr);
+ struct nft_quota *priv = nft_expr_priv(expr);
- return nft_quota_do_dump(skb, priv);
+ return nft_quota_do_dump(skb, priv, false);
}
static struct nft_expr_type nft_quota_type;