diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-11-28 00:05:44 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-12-07 12:56:57 +0100 |
commit | 43da04a593d8b2626f1cf4b56efe9402f6b53652 (patch) | |
tree | 9d3885eed99e906866b95af4448e731050fb1b26 /net/netfilter/nft_quota.c | |
parent | 795595f68d6c787028345804bb06f5a633af24a2 (diff) | |
download | linux-43da04a593d8b2626f1cf4b56efe9402f6b53652.tar.gz linux-43da04a593d8b2626f1cf4b56efe9402f6b53652.tar.bz2 linux-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.c | 18 |
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; |