summaryrefslogtreecommitdiffstats
path: root/src/set.c
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2014-02-25 22:30:12 +0100
committerPablo Neira Ayuso <pablo@netfilter.org>2014-02-27 10:35:07 +0100
commit53c0ff324598ce2926236c32b2b4c858a0b3831a (patch)
tree1f8d2ce3804d0abf4fdc253bf3d78abc34b3fcd4 /src/set.c
parent7756d31990cd47673a21cacf6fd6d33227d6270e (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.c42
1 files changed, 39 insertions, 3 deletions
diff --git a/src/set.c b/src/set.c
index c8b5ccf..ef10af5 100644
--- a/src/set.c
+++ b/src/set.c
@@ -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);