|
@@ -4183,12 +4183,18 @@ nla_put_failure:
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
+struct nft_obj_filter {
|
|
|
+ char table[NFT_OBJ_MAXNAMELEN];
|
|
|
+ u32 type;
|
|
|
+};
|
|
|
+
|
|
|
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;
|
|
|
unsigned int idx = 0, s_idx = cb->args[0];
|
|
|
+ struct nft_obj_filter *filter = cb->data;
|
|
|
struct net *net = sock_net(skb->sk);
|
|
|
int family = nfmsg->nfgen_family;
|
|
|
struct nft_object *obj;
|
|
@@ -4213,6 +4219,13 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
|
|
|
if (idx > s_idx)
|
|
|
memset(&cb->args[1], 0,
|
|
|
sizeof(cb->args) - sizeof(cb->args[0]));
|
|
|
+ if (filter->table[0] &&
|
|
|
+ strcmp(filter->table, table->name))
|
|
|
+ goto cont;
|
|
|
+ if (filter->type != NFT_OBJECT_UNSPEC &&
|
|
|
+ obj->type->type != filter->type)
|
|
|
+ goto cont;
|
|
|
+
|
|
|
if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
|
|
|
cb->nlh->nlmsg_seq,
|
|
|
NFT_MSG_NEWOBJ,
|
|
@@ -4233,6 +4246,31 @@ done:
|
|
|
return skb->len;
|
|
|
}
|
|
|
|
|
|
+static int nf_tables_dump_obj_done(struct netlink_callback *cb)
|
|
|
+{
|
|
|
+ kfree(cb->data);
|
|
|
+
|
|
|
+ return 0;
|
|
|
+}
|
|
|
+
|
|
|
+static struct nft_obj_filter *
|
|
|
+nft_obj_filter_alloc(const struct nlattr * const nla[])
|
|
|
+{
|
|
|
+ struct nft_obj_filter *filter;
|
|
|
+
|
|
|
+ filter = kzalloc(sizeof(*filter), GFP_KERNEL);
|
|
|
+ if (!filter)
|
|
|
+ return ERR_PTR(-ENOMEM);
|
|
|
+
|
|
|
+ if (nla[NFTA_OBJ_TABLE])
|
|
|
+ nla_strlcpy(filter->table, nla[NFTA_OBJ_TABLE],
|
|
|
+ NFT_TABLE_MAXNAMELEN);
|
|
|
+ if (nla[NFTA_OBJ_TYPE])
|
|
|
+ filter->type = ntohl(nla_get_be32(nla[NFTA_OBJ_TYPE]));
|
|
|
+
|
|
|
+ return filter;
|
|
|
+}
|
|
|
+
|
|
|
static int nf_tables_getobj(struct net *net, struct sock *nlsk,
|
|
|
struct sk_buff *skb, const struct nlmsghdr *nlh,
|
|
|
const struct nlattr * const nla[])
|
|
@@ -4251,7 +4289,19 @@ static int nf_tables_getobj(struct net *net, struct sock *nlsk,
|
|
|
if (nlh->nlmsg_flags & NLM_F_DUMP) {
|
|
|
struct netlink_dump_control c = {
|
|
|
.dump = nf_tables_dump_obj,
|
|
|
+ .done = nf_tables_dump_obj_done,
|
|
|
};
|
|
|
+
|
|
|
+ if (nla[NFTA_OBJ_TABLE] ||
|
|
|
+ nla[NFTA_OBJ_TYPE]) {
|
|
|
+ struct nft_obj_filter *filter;
|
|
|
+
|
|
|
+ filter = nft_obj_filter_alloc(nla);
|
|
|
+ if (IS_ERR(filter))
|
|
|
+ return -ENOMEM;
|
|
|
+
|
|
|
+ c.data = filter;
|
|
|
+ }
|
|
|
return netlink_dump_start(nlsk, skb, nlh, &c);
|
|
|
}
|
|
|
|