mirror of https://gitee.com/openkylin/linux.git
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: Carlos Falgueras García <carlosfg@riseup.net> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
eb075954e9
commit
e6d8ecac9e
|
@ -291,6 +291,8 @@ void nft_unregister_set(struct nft_set_ops *ops);
|
||||||
* @timeout: default timeout value in msecs
|
* @timeout: default timeout value in msecs
|
||||||
* @gc_int: garbage collection interval in msecs
|
* @gc_int: garbage collection interval in msecs
|
||||||
* @policy: set parameterization (see enum nft_set_policies)
|
* @policy: set parameterization (see enum nft_set_policies)
|
||||||
|
* @udlen: user data length
|
||||||
|
* @udata: user data
|
||||||
* @ops: set ops
|
* @ops: set ops
|
||||||
* @pnet: network namespace
|
* @pnet: network namespace
|
||||||
* @flags: set flags
|
* @flags: set flags
|
||||||
|
@ -310,6 +312,8 @@ struct nft_set {
|
||||||
u64 timeout;
|
u64 timeout;
|
||||||
u32 gc_int;
|
u32 gc_int;
|
||||||
u16 policy;
|
u16 policy;
|
||||||
|
u16 udlen;
|
||||||
|
unsigned char *udata;
|
||||||
/* runtime data below here */
|
/* runtime data below here */
|
||||||
const struct nft_set_ops *ops ____cacheline_aligned;
|
const struct nft_set_ops *ops ____cacheline_aligned;
|
||||||
possible_net_t pnet;
|
possible_net_t pnet;
|
||||||
|
|
|
@ -291,6 +291,7 @@ enum nft_set_desc_attributes {
|
||||||
* @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
|
* @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
|
||||||
* @NFTA_SET_TIMEOUT: default timeout value (NLA_U64)
|
* @NFTA_SET_TIMEOUT: default timeout value (NLA_U64)
|
||||||
* @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
|
* @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
|
||||||
|
* @NFTA_SET_USERDATA: user data (NLA_BINARY)
|
||||||
*/
|
*/
|
||||||
enum nft_set_attributes {
|
enum nft_set_attributes {
|
||||||
NFTA_SET_UNSPEC,
|
NFTA_SET_UNSPEC,
|
||||||
|
@ -306,6 +307,7 @@ enum nft_set_attributes {
|
||||||
NFTA_SET_ID,
|
NFTA_SET_ID,
|
||||||
NFTA_SET_TIMEOUT,
|
NFTA_SET_TIMEOUT,
|
||||||
NFTA_SET_GC_INTERVAL,
|
NFTA_SET_GC_INTERVAL,
|
||||||
|
NFTA_SET_USERDATA,
|
||||||
__NFTA_SET_MAX
|
__NFTA_SET_MAX
|
||||||
};
|
};
|
||||||
#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
|
#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
|
||||||
|
|
|
@ -2323,6 +2323,8 @@ static const struct nla_policy nft_set_policy[NFTA_SET_MAX + 1] = {
|
||||||
[NFTA_SET_ID] = { .type = NLA_U32 },
|
[NFTA_SET_ID] = { .type = NLA_U32 },
|
||||||
[NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
|
[NFTA_SET_TIMEOUT] = { .type = NLA_U64 },
|
||||||
[NFTA_SET_GC_INTERVAL] = { .type = NLA_U32 },
|
[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] = {
|
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;
|
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);
|
desc = nla_nest_start(skb, NFTA_SET_DESC);
|
||||||
if (desc == NULL)
|
if (desc == NULL)
|
||||||
goto nla_put_failure;
|
goto nla_put_failure;
|
||||||
|
@ -2691,6 +2696,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
||||||
u64 timeout;
|
u64 timeout;
|
||||||
u32 ktype, dtype, flags, policy, gc_int;
|
u32 ktype, dtype, flags, policy, gc_int;
|
||||||
struct nft_set_desc desc;
|
struct nft_set_desc desc;
|
||||||
|
unsigned char *udata;
|
||||||
|
u16 udlen;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (nla[NFTA_SET_TABLE] == NULL ||
|
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))
|
if (IS_ERR(ops))
|
||||||
return PTR_ERR(ops);
|
return PTR_ERR(ops);
|
||||||
|
|
||||||
|
udlen = 0;
|
||||||
|
if (nla[NFTA_SET_USERDATA])
|
||||||
|
udlen = nla_len(nla[NFTA_SET_USERDATA]);
|
||||||
|
|
||||||
size = 0;
|
size = 0;
|
||||||
if (ops->privsize != NULL)
|
if (ops->privsize != NULL)
|
||||||
size = ops->privsize(nla);
|
size = ops->privsize(nla);
|
||||||
|
|
||||||
err = -ENOMEM;
|
err = -ENOMEM;
|
||||||
set = kzalloc(sizeof(*set) + size, GFP_KERNEL);
|
set = kzalloc(sizeof(*set) + size + udlen, GFP_KERNEL);
|
||||||
if (set == NULL)
|
if (set == NULL)
|
||||||
goto err1;
|
goto err1;
|
||||||
|
|
||||||
|
@ -2817,6 +2828,12 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err2;
|
goto err2;
|
||||||
|
|
||||||
|
udata = NULL;
|
||||||
|
if (udlen) {
|
||||||
|
udata = set->data + size;
|
||||||
|
nla_memcpy(udata, nla[NFTA_SET_USERDATA], udlen);
|
||||||
|
}
|
||||||
|
|
||||||
INIT_LIST_HEAD(&set->bindings);
|
INIT_LIST_HEAD(&set->bindings);
|
||||||
write_pnet(&set->pnet, net);
|
write_pnet(&set->pnet, net);
|
||||||
set->ops = ops;
|
set->ops = ops;
|
||||||
|
@ -2827,6 +2844,8 @@ static int nf_tables_newset(struct net *net, struct sock *nlsk,
|
||||||
set->flags = flags;
|
set->flags = flags;
|
||||||
set->size = desc.size;
|
set->size = desc.size;
|
||||||
set->policy = policy;
|
set->policy = policy;
|
||||||
|
set->udlen = udlen;
|
||||||
|
set->udata = udata;
|
||||||
set->timeout = timeout;
|
set->timeout = timeout;
|
||||||
set->gc_int = gc_int;
|
set->gc_int = gc_int;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue