summaryrefslogtreecommitdiffstats
path: root/src/flowtable.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/flowtable.c')
-rw-r--r--src/flowtable.c89
1 files changed, 50 insertions, 39 deletions
diff --git a/src/flowtable.c b/src/flowtable.c
index 1e235d0..41a1456 100644
--- a/src/flowtable.c
+++ b/src/flowtable.c
@@ -102,6 +102,7 @@ static uint32_t nftnl_flowtable_validate[NFTNL_FLOWTABLE_MAX + 1] = {
[NFTNL_FLOWTABLE_HOOKNUM] = sizeof(uint32_t),
[NFTNL_FLOWTABLE_PRIO] = sizeof(int32_t),
[NFTNL_FLOWTABLE_FAMILY] = sizeof(uint32_t),
+ [NFTNL_FLOWTABLE_SIZE] = sizeof(uint32_t),
[NFTNL_FLOWTABLE_FLAGS] = sizeof(uint32_t),
[NFTNL_FLOWTABLE_HANDLE] = sizeof(uint64_t),
};
@@ -118,20 +119,11 @@ int nftnl_flowtable_set_data(struct nftnl_flowtable *c, uint16_t attr,
switch(attr) {
case NFTNL_FLOWTABLE_NAME:
- if (c->flags & (1 << NFTNL_FLOWTABLE_NAME))
- xfree(c->name);
-
- c->name = strdup(data);
- if (!c->name)
- return -1;
- break;
+ return nftnl_set_str_attr(&c->name, &c->flags,
+ attr, data, data_len);
case NFTNL_FLOWTABLE_TABLE:
- if (c->flags & (1 << NFTNL_FLOWTABLE_TABLE))
- xfree(c->table);
-
- c->table = strdup(data);
- if (!c->table)
- return -1;
+ return nftnl_set_str_attr(&c->table, &c->flags,
+ attr, data, data_len);
break;
case NFTNL_FLOWTABLE_HOOKNUM:
memcpy(&c->hooknum, data, sizeof(c->hooknum));
@@ -206,6 +198,13 @@ void nftnl_flowtable_set_u64(struct nftnl_flowtable *c, uint16_t attr, uint64_t
nftnl_flowtable_set_data(c, attr, &data, sizeof(uint64_t));
}
+EXPORT_SYMBOL(nftnl_flowtable_set_array);
+int nftnl_flowtable_set_array(struct nftnl_flowtable *c, uint16_t attr,
+ const char **data)
+{
+ return nftnl_flowtable_set_data(c, attr, data, 0);
+}
+
EXPORT_SYMBOL(nftnl_flowtable_get_data);
const void *nftnl_flowtable_get_data(const struct nftnl_flowtable *c,
uint16_t attr, uint32_t *data_len)
@@ -230,6 +229,7 @@ const void *nftnl_flowtable_get_data(const struct nftnl_flowtable *c,
*data_len = sizeof(int32_t);
return &c->family;
case NFTNL_FLOWTABLE_DEVICES:
+ *data_len = 0;
return &c->dev_array[0];
case NFTNL_FLOWTABLE_SIZE:
*data_len = sizeof(int32_t);
@@ -290,35 +290,53 @@ int32_t nftnl_flowtable_get_s32(const struct nftnl_flowtable *c, uint16_t attr)
return val ? *val : 0;
}
+EXPORT_SYMBOL(nftnl_flowtable_get_array);
+const char *const *nftnl_flowtable_get_array(const struct nftnl_flowtable *c, uint16_t attr)
+{
+ uint32_t data_len;
+ const char * const *val = nftnl_flowtable_get_data(c, attr, &data_len);
+
+ nftnl_assert(val, attr, attr == NFTNL_FLOWTABLE_DEVICES);
+
+ return val;
+}
+
EXPORT_SYMBOL(nftnl_flowtable_nlmsg_build_payload);
void nftnl_flowtable_nlmsg_build_payload(struct nlmsghdr *nlh,
const struct nftnl_flowtable *c)
{
+ struct nlattr *nest = NULL;
int i;
if (c->flags & (1 << NFTNL_FLOWTABLE_TABLE))
mnl_attr_put_strz(nlh, NFTA_FLOWTABLE_TABLE, c->table);
if (c->flags & (1 << NFTNL_FLOWTABLE_NAME))
mnl_attr_put_strz(nlh, NFTA_FLOWTABLE_NAME, c->name);
- if ((c->flags & (1 << NFTNL_FLOWTABLE_HOOKNUM)) &&
- (c->flags & (1 << NFTNL_FLOWTABLE_PRIO))) {
- struct nlattr *nest;
+ if (c->flags & (1 << NFTNL_FLOWTABLE_HOOKNUM) ||
+ c->flags & (1 << NFTNL_FLOWTABLE_PRIO) ||
+ c->flags & (1 << NFTNL_FLOWTABLE_DEVICES))
nest = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK);
+
+ if (c->flags & (1 << NFTNL_FLOWTABLE_HOOKNUM))
mnl_attr_put_u32(nlh, NFTA_FLOWTABLE_HOOK_NUM, htonl(c->hooknum));
+ if (c->flags & (1 << NFTNL_FLOWTABLE_PRIO))
mnl_attr_put_u32(nlh, NFTA_FLOWTABLE_HOOK_PRIORITY, htonl(c->prio));
- if (c->flags & (1 << NFTNL_FLOWTABLE_DEVICES)) {
- struct nlattr *nest_dev;
- nest_dev = mnl_attr_nest_start(nlh,
- NFTA_FLOWTABLE_HOOK_DEVS);
- for (i = 0; i < c->dev_array_len; i++)
- mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME,
- c->dev_array[i]);
- mnl_attr_nest_end(nlh, nest_dev);
+ if (c->flags & (1 << NFTNL_FLOWTABLE_DEVICES)) {
+ struct nlattr *nest_dev;
+
+ nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS);
+ for (i = 0; i < c->dev_array_len; i++) {
+ mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME,
+ c->dev_array[i]);
}
- mnl_attr_nest_end(nlh, nest);
+ mnl_attr_nest_end(nlh, nest_dev);
}
+
+ if (nest)
+ mnl_attr_nest_end(nlh, nest);
+
if (c->flags & (1 << NFTNL_FLOWTABLE_FLAGS))
mnl_attr_put_u32(nlh, NFTA_FLOWTABLE_FLAGS, htonl(c->ft_flags));
if (c->flags & (1 << NFTNL_FLOWTABLE_USE))
@@ -565,10 +583,10 @@ int nftnl_flowtable_parse_file(struct nftnl_flowtable *c,
return -1;
}
-static int nftnl_flowtable_snprintf_default(char *buf, size_t size,
+static int nftnl_flowtable_snprintf_default(char *buf, size_t remain,
const struct nftnl_flowtable *c)
{
- int ret, remain = size, offset = 0, i;
+ int ret, offset = 0, i;
ret = snprintf(buf, remain, "flow table %s %s use %u size %u flags %x",
c->table, c->name, c->use, c->size, c->ft_flags);
@@ -597,25 +615,18 @@ static int nftnl_flowtable_snprintf_default(char *buf, size_t size,
return offset;
}
-static int nftnl_flowtable_cmd_snprintf(char *buf, size_t size,
+static int nftnl_flowtable_cmd_snprintf(char *buf, size_t remain,
const struct nftnl_flowtable *c,
uint32_t cmd, uint32_t type,
uint32_t flags)
{
- int ret, remain = size, offset = 0;
+ int ret, offset = 0;
- switch (type) {
- case NFTNL_OUTPUT_DEFAULT:
- ret = nftnl_flowtable_snprintf_default(buf + offset, remain, c);
- SNPRINTF_BUFFER_SIZE(ret, remain, offset);
- break;
- case NFTNL_OUTPUT_XML:
- case NFTNL_OUTPUT_JSON:
- break;
- default:
+ if (type != NFTNL_OUTPUT_DEFAULT)
return -1;
- }
+ ret = nftnl_flowtable_snprintf_default(buf + offset, remain, c);
+ SNPRINTF_BUFFER_SIZE(ret, remain, offset);
return offset;
}