diff options
Diffstat (limited to 'src/table.c')
-rw-r--r-- | src/table.c | 74 |
1 files changed, 55 insertions, 19 deletions
diff --git a/src/table.c b/src/table.c index 94d522b..13f01cf 100644 --- a/src/table.c +++ b/src/table.c @@ -34,6 +34,11 @@ struct nftnl_table { uint64_t handle; uint32_t use; uint32_t flags; + uint32_t owner; + struct { + void *data; + uint32_t len; + } user; }; EXPORT_SYMBOL(nftnl_table_alloc); @@ -47,6 +52,8 @@ void nftnl_table_free(const struct nftnl_table *t) { if (t->flags & (1 << NFTNL_TABLE_NAME)) xfree(t->name); + if (t->flags & (1 << NFTNL_TABLE_USERDATA)) + xfree(t->user.data); xfree(t); } @@ -70,8 +77,8 @@ void nftnl_table_unset(struct nftnl_table *t, uint16_t attr) case NFTNL_TABLE_FLAGS: case NFTNL_TABLE_HANDLE: case NFTNL_TABLE_FAMILY: - break; case NFTNL_TABLE_USE: + case NFTNL_TABLE_OWNER: break; } t->flags &= ~(1 << attr); @@ -81,6 +88,8 @@ static uint32_t nftnl_table_validate[NFTNL_TABLE_MAX + 1] = { [NFTNL_TABLE_FLAGS] = sizeof(uint32_t), [NFTNL_TABLE_FAMILY] = sizeof(uint32_t), [NFTNL_TABLE_HANDLE] = sizeof(uint64_t), + [NFTNL_TABLE_USE] = sizeof(uint32_t), + [NFTNL_TABLE_OWNER] = sizeof(uint32_t), }; EXPORT_SYMBOL(nftnl_table_set_data); @@ -92,13 +101,8 @@ int nftnl_table_set_data(struct nftnl_table *t, uint16_t attr, switch (attr) { case NFTNL_TABLE_NAME: - if (t->flags & (1 << NFTNL_TABLE_NAME)) - xfree(t->name); - - t->name = strdup(data); - if (!t->name) - return -1; - break; + return nftnl_set_str_attr(&t->name, &t->flags, + attr, data, data_len); case NFTNL_TABLE_HANDLE: memcpy(&t->handle, data, sizeof(t->handle)); break; @@ -111,6 +115,19 @@ int nftnl_table_set_data(struct nftnl_table *t, uint16_t attr, case NFTNL_TABLE_USE: memcpy(&t->use, data, sizeof(t->use)); break; + case NFTNL_TABLE_USERDATA: + if (t->flags & (1 << NFTNL_TABLE_USERDATA)) + xfree(t->user.data); + + t->user.data = malloc(data_len); + if (!t->user.data) + return -1; + memcpy(t->user.data, data, data_len); + t->user.len = data_len; + break; + case NFTNL_TABLE_OWNER: + memcpy(&t->owner, data, sizeof(t->owner)); + break; } t->flags |= (1 << attr); return 0; @@ -169,6 +186,12 @@ const void *nftnl_table_get_data(const struct nftnl_table *t, uint16_t attr, case NFTNL_TABLE_USE: *data_len = sizeof(uint32_t); return &t->use; + case NFTNL_TABLE_USERDATA: + *data_len = t->user.len; + return t->user.data; + case NFTNL_TABLE_OWNER: + *data_len = sizeof(uint32_t); + return &t->owner; } return NULL; } @@ -216,6 +239,8 @@ void nftnl_table_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_ta mnl_attr_put_u64(nlh, NFTA_TABLE_HANDLE, htobe64(t->handle)); if (t->flags & (1 << NFTNL_TABLE_FLAGS)) mnl_attr_put_u32(nlh, NFTA_TABLE_FLAGS, htonl(t->table_flags)); + if (t->flags & (1 << NFTNL_TABLE_USERDATA)) + mnl_attr_put(nlh, NFTA_TABLE_USERDATA, t->user.len, t->user.data); } static int nftnl_table_parse_attr_cb(const struct nlattr *attr, void *data) @@ -237,9 +262,14 @@ static int nftnl_table_parse_attr_cb(const struct nlattr *attr, void *data) break; case NFTA_TABLE_FLAGS: case NFTA_TABLE_USE: + case NFTA_TABLE_OWNER: if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) abi_breakage(); break; + case NFTA_TABLE_USERDATA: + if (mnl_attr_validate(attr, MNL_TYPE_BINARY) < 0) + abi_breakage(); + break; } tb[type] = attr; @@ -251,6 +281,7 @@ int nftnl_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_table *t) { struct nlattr *tb[NFTA_TABLE_MAX+1] = {}; struct nfgenmsg *nfg = mnl_nlmsg_get_payload(nlh); + int ret; if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_table_parse_attr_cb, tb) < 0) return -1; @@ -275,6 +306,17 @@ int nftnl_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_table *t) t->handle = be64toh(mnl_attr_get_u64(tb[NFTA_TABLE_HANDLE])); t->flags |= (1 << NFTNL_TABLE_HANDLE); } + if (tb[NFTA_TABLE_USERDATA]) { + ret = nftnl_table_set_data(t, NFTNL_TABLE_USERDATA, + mnl_attr_get_payload(tb[NFTA_TABLE_USERDATA]), + mnl_attr_get_payload_len(tb[NFTA_TABLE_USERDATA])); + if (ret < 0) + return ret; + } + if (tb[NFTA_TABLE_OWNER]) { + t->owner = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_OWNER])); + t->flags |= (1 << NFTNL_TABLE_OWNER); + } t->family = nfg->nfgen_family; t->flags |= (1 << NFTNL_TABLE_FAMILY); @@ -322,23 +364,17 @@ static int nftnl_table_snprintf_default(char *buf, size_t size, t->table_flags, t->use, (unsigned long long)t->handle); } -static int nftnl_table_cmd_snprintf(char *buf, size_t size, +static int nftnl_table_cmd_snprintf(char *buf, size_t remain, const struct nftnl_table *t, 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_table_snprintf_default(buf + offset, remain, t); - SNPRINTF_BUFFER_SIZE(ret, remain, offset); - break; - case NFTNL_OUTPUT_XML: - case NFTNL_OUTPUT_JSON: - default: + if (type != NFTNL_OUTPUT_DEFAULT) return -1; - } + ret = nftnl_table_snprintf_default(buf + offset, remain, t); + SNPRINTF_BUFFER_SIZE(ret, remain, offset); return offset; } |