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

Commit e6d8ecac authored by Carlos Falgueras García's avatar Carlos Falgueras García Committed by Pablo Neira Ayuso
Browse files

netfilter: nf_tables: Add new attributes into nft_set to store user data.



User data is stored at after 'nft_set_ops' private data into 'data[]'
flexible array. The field 'udata' points to user data and 'udlen' stores
its length.

Add new flag NFTA_SET_USERDATA.

Signed-off-by: default avatarCarlos Falgueras García <carlosfg@riseup.net>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent eb075954
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -291,6 +291,8 @@ void nft_unregister_set(struct nft_set_ops *ops);
 * 	@timeout: default timeout value in msecs
 * 	@gc_int: garbage collection interval in msecs
 *	@policy: set parameterization (see enum nft_set_policies)
 *	@udlen: user data length
 *	@udata: user data
 * 	@ops: set ops
 * 	@pnet: network namespace
 * 	@flags: set flags
@@ -310,6 +312,8 @@ struct nft_set {
	u64				timeout;
	u32				gc_int;
	u16				policy;
	u16				udlen;
	unsigned char			*udata;
	/* runtime data below here */
	const struct nft_set_ops	*ops ____cacheline_aligned;
	possible_net_t			pnet;
+2 −0
Original line number Diff line number Diff line
@@ -291,6 +291,7 @@ enum nft_set_desc_attributes {
 * @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
 * @NFTA_SET_TIMEOUT: default timeout value (NLA_U64)
 * @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
 * @NFTA_SET_USERDATA: user data (NLA_BINARY)
 */
enum nft_set_attributes {
	NFTA_SET_UNSPEC,
@@ -306,6 +307,7 @@ enum nft_set_attributes {
	NFTA_SET_ID,
	NFTA_SET_TIMEOUT,
	NFTA_SET_GC_INTERVAL,
	NFTA_SET_USERDATA,
	__NFTA_SET_MAX
};
#define NFTA_SET_MAX		(__NFTA_SET_MAX - 1)
+20 −1
Original line number Diff line number Diff line
@@ -2323,6 +2323,8 @@ static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
	[NFTA_SET_ID]			= { .type = NLA_U32 },
	[NFTA_SET_TIMEOUT]		= { .type = NLA_U64 },
	[NFTA_SET_GC_INTERVAL]		= { .type = NLA_U32 },
	[NFTA_SET_USERDATA]		= { .type = NLA_BINARY,
					    .len  = NFT_USERDATA_MAXLEN },
};

static const struct nla_policy nft_set_desc_policy[NFTA_SET_DESC_MAX + 1] = {
@@ -2482,6 +2484,9 @@ static int nf_tables_fill_set(struct sk_buff *skb, const struct nft_ctx *ctx,
			goto nla_put_failure;
	}

	if (nla_put(skb, NFTA_SET_USERDATA, set->udlen, set->udata))
		goto nla_put_failure;

	desc = nla_nest_start(skb, NFTA_SET_DESC);
	if (desc == NULL)
		goto nla_put_failure;
@@ -2691,6 +2696,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
	u64 timeout;
	u32 ktype, dtype, flags, policy, gc_int;
	struct nft_set_desc desc;
	unsigned char *udata;
	u16 udlen;
	int err;

	if (nla[NFTA_SET_TABLE] == NULL ||
@@ -2803,12 +2810,16 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
	if (IS_ERR(ops))
		return PTR_ERR(ops);

	udlen = 0;
	if (nla[NFTA_SET_USERDATA])
		udlen = nla_len(nla[NFTA_SET_USERDATA]);

	size = 0;
	if (ops->privsize != NULL)
		size = ops->privsize(nla);

	err = -ENOMEM;
	set = kzalloc(sizeof(*set) + size, GFP_KERNEL);
	set = kzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
	if (set == NULL)
		goto err1;

@@ -2817,6 +2828,12 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
	if (err < 0)
		goto err2;

	udata = NULL;
	if (udlen) {
		udata = set->data + size;
		nla_memcpy(udata, nla[NFTA_SET_USERDATA], udlen);
	}

	INIT_LIST_HEAD(&set->bindings);
	write_pnet(&set->pnet, net);
	set->ops   = ops;
@@ -2827,6 +2844,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
	set->flags = flags;
	set->size  = desc.size;
	set->policy = policy;
	set->udlen  = udlen;
	set->udata  = udata;
	set->timeout = timeout;
	set->gc_int = gc_int;