netfilter: nf_tables: allow to filter stateful object dumps by type
This patch adds the netlink code to filter out dump of stateful objects, through the NFTA_OBJ_TYPE netlink attribute. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
Родитель
63aea29060
Коммит
a9fea2a3c3
|
@ -4183,12 +4183,18 @@ nla_put_failure:
|
||||||
return -1;
|
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)
|
static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
|
||||||
{
|
{
|
||||||
const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
|
const struct nfgenmsg *nfmsg = nlmsg_data(cb->nlh);
|
||||||
const struct nft_af_info *afi;
|
const struct nft_af_info *afi;
|
||||||
const struct nft_table *table;
|
const struct nft_table *table;
|
||||||
unsigned int idx = 0, s_idx = cb->args[0];
|
unsigned int idx = 0, s_idx = cb->args[0];
|
||||||
|
struct nft_obj_filter *filter = cb->data;
|
||||||
struct net *net = sock_net(skb->sk);
|
struct net *net = sock_net(skb->sk);
|
||||||
int family = nfmsg->nfgen_family;
|
int family = nfmsg->nfgen_family;
|
||||||
struct nft_object *obj;
|
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)
|
if (idx > s_idx)
|
||||||
memset(&cb->args[1], 0,
|
memset(&cb->args[1], 0,
|
||||||
sizeof(cb->args) - sizeof(cb->args[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,
|
if (nf_tables_fill_obj_info(skb, net, NETLINK_CB(cb->skb).portid,
|
||||||
cb->nlh->nlmsg_seq,
|
cb->nlh->nlmsg_seq,
|
||||||
NFT_MSG_NEWOBJ,
|
NFT_MSG_NEWOBJ,
|
||||||
|
@ -4233,6 +4246,31 @@ done:
|
||||||
return skb->len;
|
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,
|
static int nf_tables_getobj(struct net *net, struct sock *nlsk,
|
||||||
struct sk_buff *skb, const struct nlmsghdr *nlh,
|
struct sk_buff *skb, const struct nlmsghdr *nlh,
|
||||||
const struct nlattr * const nla[])
|
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) {
|
if (nlh->nlmsg_flags & NLM_F_DUMP) {
|
||||||
struct netlink_dump_control c = {
|
struct netlink_dump_control c = {
|
||||||
.dump = nf_tables_dump_obj,
|
.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);
|
return netlink_dump_start(nlsk, skb, nlh, &c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче