Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a9fea2a3 authored by Pablo Neira Ayuso's avatar Pablo Neira Ayuso
Browse files

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: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 63aea290
Loading
Loading
Loading
Loading
+50 −0
Original line number Diff line number Diff line
@@ -4183,12 +4183,18 @@ static int nf_tables_fill_obj_info(struct sk_buff *skb, struct net *net,
	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 @@ static int nf_tables_dump_obj(struct sk_buff *skb, struct netlink_callback *cb)
	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);
	}