summaryrefslogtreecommitdiffstats
path: root/net/netfilter/nf_tables_api.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso2016-11-28 00:05:44 +0100
committerPablo Neira Ayuso2016-12-07 12:56:57 +0100
commit43da04a593d8b2626f1cf4b56efe9402f6b53652 (patch)
tree9d3885eed99e906866b95af4448e731050fb1b26 /net/netfilter/nf_tables_api.c
parentnetfilter: nft_quota: dump consumed quota (diff)
downloadkernel-qcow2-linux-43da04a593d8b2626f1cf4b56efe9402f6b53652.tar.gz
kernel-qcow2-linux-43da04a593d8b2626f1cf4b56efe9402f6b53652.tar.xz
kernel-qcow2-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/nf_tables_api.c')
-rw-r--r--net/netfilter/nf_tables_api.c29
1 files changed, 21 insertions, 8 deletions
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 2ae717c5dcb8..bfc015af366a 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -3972,14 +3972,14 @@ err1:
}
static int nft_object_dump(struct sk_buff *skb, unsigned int attr,
- const struct nft_object *obj)
+ struct nft_object *obj, bool reset)
{
struct nlattr *nest;
nest = nla_nest_start(skb, attr);
if (!nest)
goto nla_put_failure;
- if (obj->type->dump(skb, obj) < 0)
+ if (obj->type->dump(skb, obj, reset) < 0)
goto nla_put_failure;
nla_nest_end(skb, nest);
return 0;
@@ -4096,7 +4096,7 @@ err1:
static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
u32 portid, u32 seq, int event, u32 flags,
int family, const struct nft_table *table,
- const struct nft_object *obj)
+ struct nft_object *obj, bool reset)
{
struct nfgenmsg *nfmsg;
struct nlmsghdr *nlh;
@@ -4115,7 +4115,7 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
nla_put_string(skb, NFTA_OBJ_NAME, obj->name) ||
nla_put_be32(skb, NFTA_OBJ_TYPE, htonl(obj->type->type)) ||
nla_put_be32(skb, NFTA_OBJ_USE, htonl(obj->use)) ||
- nft_object_dump(skb, NFTA_OBJ_DATA, obj))
+ nft_object_dump(skb, NFTA_OBJ_DATA, obj, reset))
goto nla_put_failure;
nlmsg_end(skb, nlh);
@@ -4131,10 +4131,14 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
const struct nft_af_info *afi;
const struct nft_table *table;
- const struct nft_object *obj;
unsigned int idx = 0, s_idx = cb->args[0];
struct net *net = sock_net(skb->sk);
int family = nfmsg->nfgen_family;
+ struct nft_object *obj;
+ bool reset = false;
+
+ if (NFNL_MSG_TYPE(cb->nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
+ reset = true;
rcu_read_lock();
cb->seq = net->nft.base_seq;
@@ -4156,7 +4160,7 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
cb->nlh->nlmsg_seq,
NFT_MSG_NEWOBJ,
NLM_F_MULTI | NLM_F_APPEND,
- afi->family, table, obj) < 0)
+ afi->family, table, obj, reset) < 0)
goto done;
nl_dump_check_consistent(cb, nlmsg_hdr(skb));
@@ -4183,6 +4187,7 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk,
const struct nft_table *table;
struct nft_object *obj;
struct sk_buff *skb2;
+ bool reset = false;
u32 objtype;
int err;
@@ -4214,9 +4219,12 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk,
if (!skb2)
return -ENOMEM;
+ if (NFNL_MSG_TYPE(nlh->nlmsg_type) == NFT_MSG_GETOBJ_RESET)
+ reset = true;
+
err = nf_tables_fill_obj_info(skb2, net, NETLINK_CB(skb).portid,
nlh->nlmsg_seq, NFT_MSG_NEWOBJ, 0,
- family, table, obj);
+ family, table, obj, reset);
if (err < 0)
goto err;
@@ -4291,7 +4299,7 @@ static int nf_tables_obj_notify(const struct nft_ctx *ctx,
err = nf_tables_fill_obj_info(skb, ctx->net, ctx->portid, ctx->seq,
event, 0, ctx->afi->family, ctx->table,
- obj);
+ obj, false);
if (err < 0) {
kfree_skb(skb);
goto err;
@@ -4482,6 +4490,11 @@ static const struct nfnl_callback nf_tables_cb[NFT_MSG_MAX] = {
.attr_count = NFTA_OBJ_MAX,
.policy = nft_obj_policy,
},
+ [NFT_MSG_GETOBJ_RESET] = {
+ .call = nf_tables_getobj,
+ .attr_count = NFTA_OBJ_MAX,
+ .policy = nft_obj_policy,
+ },
};
static void nft_chain_commit_update(struct nft_trans *trans)