diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-02-25 22:30:12 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-02-27 10:35:07 +0100 |
commit | 53c0ff324598ce2926236c32b2b4c858a0b3831a (patch) | |
tree | 1f8d2ce3804d0abf4fdc253bf3d78abc34b3fcd4 /src/set.c | |
parent | 7756d31990cd47673a21cacf6fd6d33227d6270e (diff) |
src: add nft_*_attr_{set|get}_data interface
This patch adds two functions that allows you to validate the size
of the attribute. This new functions provide a replacement for
nft_rule_attr_set and nft_rule_attr_get.
The data_len parameter was already passed to the {_set|_get} funcion
in expressions. For consistency, add nft_rule_expr_{set|get}_data
alias.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/set.c')
-rw-r--r-- | src/set.c | 42 |
1 files changed, 39 insertions, 3 deletions
@@ -96,11 +96,23 @@ void nft_set_attr_unset(struct nft_set *s, uint16_t attr) } EXPORT_SYMBOL(nft_set_attr_unset); -void nft_set_attr_set(struct nft_set *s, uint16_t attr, const void *data) +static uint32_t nft_set_attr_validate[NFT_SET_ATTR_MAX + 1] = { + [NFT_SET_ATTR_FLAGS] = sizeof(uint32_t), + [NFT_SET_ATTR_KEY_TYPE] = sizeof(uint32_t), + [NFT_SET_ATTR_KEY_LEN] = sizeof(uint32_t), + [NFT_SET_ATTR_DATA_TYPE] = sizeof(uint32_t), + [NFT_SET_ATTR_DATA_LEN] = sizeof(uint32_t), + [NFT_SET_ATTR_FAMILY] = sizeof(uint32_t), +}; + +void nft_set_attr_set_data(struct nft_set *s, uint16_t attr, const void *data, + uint32_t data_len) { if (attr > NFT_SET_ATTR_MAX) return; + nft_assert_validate(nft_set_attr_validate, attr, data_len); + switch(attr) { case NFT_SET_ATTR_TABLE: if (s->table) @@ -135,6 +147,12 @@ void nft_set_attr_set(struct nft_set *s, uint16_t attr, const void *data) } s->flags |= (1 << attr); } +EXPORT_SYMBOL(nft_set_attr_set_data); + +void nft_set_attr_set(struct nft_set *s, uint16_t attr, const void *data) +{ + nft_set_attr_set_data(s, attr, data, nft_set_attr_validate[attr]); +} EXPORT_SYMBOL(nft_set_attr_set); void nft_set_attr_set_u32(struct nft_set *s, uint16_t attr, uint32_t val) @@ -149,7 +167,8 @@ void nft_set_attr_set_str(struct nft_set *s, uint16_t attr, const char *str) } EXPORT_SYMBOL(nft_set_attr_set_str); -const void *nft_set_attr_get(struct nft_set *s, uint16_t attr) +const void *nft_set_attr_get_data(struct nft_set *s, uint16_t attr, + uint32_t *data_len) { if (!(s->flags & (1 << attr))) return NULL; @@ -160,20 +179,33 @@ const void *nft_set_attr_get(struct nft_set *s, uint16_t attr) case NFT_SET_ATTR_NAME: return s->name; case NFT_SET_ATTR_FLAGS: + *data_len = sizeof(uint32_t); return &s->set_flags; case NFT_SET_ATTR_KEY_TYPE: + *data_len = sizeof(uint32_t); return &s->key_type; case NFT_SET_ATTR_KEY_LEN: + *data_len = sizeof(uint32_t); return &s->key_len; case NFT_SET_ATTR_DATA_TYPE: + *data_len = sizeof(uint32_t); return &s->data_type; case NFT_SET_ATTR_DATA_LEN: + *data_len = sizeof(uint32_t); return &s->data_len; case NFT_SET_ATTR_FAMILY: + *data_len = sizeof(uint32_t); return &s->family; } return NULL; } +EXPORT_SYMBOL(nft_set_attr_get_data); + +const void *nft_set_attr_get(struct nft_set *s, uint16_t attr) +{ + uint32_t data_len; + return nft_set_attr_get_data(s, attr, &data_len); +} EXPORT_SYMBOL(nft_set_attr_get); const char *nft_set_attr_get_str(struct nft_set *s, uint16_t attr) @@ -184,7 +216,11 @@ EXPORT_SYMBOL(nft_set_attr_get_str); uint32_t nft_set_attr_get_u32(struct nft_set *s, uint16_t attr) { - const uint32_t *val = nft_set_attr_get(s, attr); + uint32_t data_len; + const uint32_t *val = nft_set_attr_get_data(s, attr, &data_len); + + nft_assert(attr, data_len == sizeof(uint32_t)); + return val ? *val : 0; } EXPORT_SYMBOL(nft_set_attr_get_u32); |