From 581d5ac044929de4b970071560d43bc156aadb2d Mon Sep 17 00:00:00 2001 From: Eric Jallot Date: Mon, 4 Nov 2019 21:19:58 +0100 Subject: flowtable: add support for handle attribute Add code to implement NFTA_FLOWTABLE_HANDLE Signed-off-by: Eric Jallot Signed-off-by: Pablo Neira Ayuso --- include/libnftnl/flowtable.h | 3 +++ src/flowtable.c | 36 ++++++++++++++++++++++++++++++++++++ src/libnftnl.map | 2 ++ tests/nft-flowtable-test.c | 20 ++++++++++++-------- 4 files changed, 53 insertions(+), 8 deletions(-) diff --git a/include/libnftnl/flowtable.h b/include/libnftnl/flowtable.h index 028095e..bdff114 100644 --- a/include/libnftnl/flowtable.h +++ b/include/libnftnl/flowtable.h @@ -27,6 +27,7 @@ enum nftnl_flowtable_attr { NFTNL_FLOWTABLE_DEVICES, NFTNL_FLOWTABLE_SIZE, NFTNL_FLOWTABLE_FLAGS, + NFTNL_FLOWTABLE_HANDLE, __NFTNL_FLOWTABLE_MAX }; #define NFTNL_FLOWTABLE_MAX (__NFTNL_FLOWTABLE_MAX - 1) @@ -38,6 +39,7 @@ int nftnl_flowtable_set_data(struct nftnl_flowtable *t, uint16_t attr, const void *data, uint32_t data_len); void nftnl_flowtable_set_u32(struct nftnl_flowtable *t, uint16_t attr, uint32_t data); void nftnl_flowtable_set_s32(struct nftnl_flowtable *t, uint16_t attr, int32_t data); +void nftnl_flowtable_set_u64(struct nftnl_flowtable *t, uint16_t attr, uint64_t data); int nftnl_flowtable_set_str(struct nftnl_flowtable *t, uint16_t attr, const char *str); void nftnl_flowtable_set_array(struct nftnl_flowtable *t, uint16_t attr, const char **data); @@ -47,6 +49,7 @@ const void *nftnl_flowtable_get_data(const struct nftnl_flowtable *c, uint16_t a const char *nftnl_flowtable_get_str(const struct nftnl_flowtable *c, uint16_t attr); uint32_t nftnl_flowtable_get_u32(const struct nftnl_flowtable *c, uint16_t attr); int32_t nftnl_flowtable_get_s32(const struct nftnl_flowtable *c, uint16_t attr); +uint64_t nftnl_flowtable_get_u64(const struct nftnl_flowtable *c, uint16_t attr); const char **nftnl_flowtable_get_array(const struct nftnl_flowtable *t, uint16_t attr); struct nlmsghdr; diff --git a/src/flowtable.c b/src/flowtable.c index ed91357..ec89b95 100644 --- a/src/flowtable.c +++ b/src/flowtable.c @@ -32,6 +32,7 @@ struct nftnl_flowtable { uint32_t ft_flags; uint32_t use; uint32_t flags; + uint64_t handle; }; EXPORT_SYMBOL(nftnl_flowtable_alloc); @@ -84,6 +85,7 @@ void nftnl_flowtable_unset(struct nftnl_flowtable *c, uint16_t attr) case NFTNL_FLOWTABLE_USE: case NFTNL_FLOWTABLE_FAMILY: case NFTNL_FLOWTABLE_FLAGS: + case NFTNL_FLOWTABLE_HANDLE: break; case NFTNL_FLOWTABLE_DEVICES: for (i = 0; i < c->dev_array_len; i++) @@ -102,6 +104,7 @@ static uint32_t nftnl_flowtable_validate[NFTNL_FLOWTABLE_MAX + 1] = { [NFTNL_FLOWTABLE_PRIO] = sizeof(int32_t), [NFTNL_FLOWTABLE_FAMILY] = sizeof(uint32_t), [NFTNL_FLOWTABLE_FLAGS] = sizeof(uint32_t), + [NFTNL_FLOWTABLE_HANDLE] = sizeof(uint64_t), }; EXPORT_SYMBOL(nftnl_flowtable_set_data); @@ -166,6 +169,9 @@ int nftnl_flowtable_set_data(struct nftnl_flowtable *c, uint16_t attr, case NFTNL_FLOWTABLE_FLAGS: memcpy(&c->ft_flags, data, sizeof(c->ft_flags)); break; + case NFTNL_FLOWTABLE_HANDLE: + memcpy(&c->handle, data, sizeof(c->handle)); + break; } c->flags |= (1 << attr); return 0; @@ -195,6 +201,12 @@ int nftnl_flowtable_set_str(struct nftnl_flowtable *c, uint16_t attr, const char return nftnl_flowtable_set_data(c, attr, str, strlen(str) + 1); } +EXPORT_SYMBOL(nftnl_flowtable_set_u64); +void nftnl_flowtable_set_u64(struct nftnl_flowtable *c, uint16_t attr, uint64_t data) +{ + nftnl_flowtable_set_data(c, attr, &data, sizeof(uint64_t)); +} + EXPORT_SYMBOL(nftnl_flowtable_get_data); const void *nftnl_flowtable_get_data(const struct nftnl_flowtable *c, uint16_t attr, uint32_t *data_len) @@ -226,6 +238,9 @@ const void *nftnl_flowtable_get_data(const struct nftnl_flowtable *c, case NFTNL_FLOWTABLE_FLAGS: *data_len = sizeof(int32_t); return &c->ft_flags; + case NFTNL_FLOWTABLE_HANDLE: + *data_len = sizeof(uint64_t); + return &c->handle; } return NULL; } @@ -254,6 +269,17 @@ uint32_t nftnl_flowtable_get_u32(const struct nftnl_flowtable *c, uint16_t attr) return val ? *val : 0; } +EXPORT_SYMBOL(nftnl_flowtable_get_u64); +uint64_t nftnl_flowtable_get_u64(const struct nftnl_flowtable *c, uint16_t attr) +{ + uint32_t data_len = 0; + const uint64_t *val = nftnl_flowtable_get_data(c, attr, &data_len); + + nftnl_assert(val, attr, data_len == sizeof(uint64_t)); + + return val ? *val : 0; +} + EXPORT_SYMBOL(nftnl_flowtable_get_s32); int32_t nftnl_flowtable_get_s32(const struct nftnl_flowtable *c, uint16_t attr) { @@ -300,6 +326,8 @@ void nftnl_flowtable_nlmsg_build_payload(struct nlmsghdr *nlh, mnl_attr_put_u32(nlh, NFTA_FLOWTABLE_USE, htonl(c->use)); if (c->flags & (1 << NFTNL_FLOWTABLE_SIZE)) mnl_attr_put_u32(nlh, NFTA_FLOWTABLE_SIZE, htonl(c->size)); + if (c->flags & (1 << NFTNL_FLOWTABLE_HANDLE)) + mnl_attr_put_u64(nlh, NFTA_FLOWTABLE_HANDLE, htobe64(c->handle)); } static int nftnl_flowtable_parse_attr_cb(const struct nlattr *attr, void *data) @@ -325,6 +353,10 @@ static int nftnl_flowtable_parse_attr_cb(const struct nlattr *attr, void *data) if (mnl_attr_validate(attr, MNL_TYPE_U32) < 0) abi_breakage(); break; + case NFTA_FLOWTABLE_HANDLE: + if (mnl_attr_validate(attr, MNL_TYPE_U64) < 0) + abi_breakage(); + break; } tb[type] = attr; @@ -461,6 +493,10 @@ int nftnl_flowtable_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_flowtab c->size = ntohl(mnl_attr_get_u32(tb[NFTA_FLOWTABLE_SIZE])); c->flags |= (1 << NFTNL_FLOWTABLE_SIZE); } + if (tb[NFTA_FLOWTABLE_HANDLE]) { + c->handle = be64toh(mnl_attr_get_u64(tb[NFTA_FLOWTABLE_HANDLE])); + c->flags |= (1 << NFTNL_FLOWTABLE_HANDLE); + } c->family = nfg->nfgen_family; c->flags |= (1 << NFTNL_FLOWTABLE_FAMILY); diff --git a/src/libnftnl.map b/src/libnftnl.map index e810c4d..8230d15 100644 --- a/src/libnftnl.map +++ b/src/libnftnl.map @@ -314,10 +314,12 @@ global: nftnl_flowtable_set_u32; nftnl_flowtable_set_s32; nftnl_flowtable_set_str; + nftnl_flowtable_set_u64; nftnl_flowtable_get; nftnl_flowtable_get_u32; nftnl_flowtable_get_s32; nftnl_flowtable_get_str; + nftnl_flowtable_get_u64; nftnl_flowtable_parse; nftnl_flowtable_parse_file; nftnl_flowtable_snprintf; diff --git a/tests/nft-flowtable-test.c b/tests/nft-flowtable-test.c index 1311cf2..3edb00d 100644 --- a/tests/nft-flowtable-test.c +++ b/tests/nft-flowtable-test.c @@ -17,28 +17,31 @@ static void cmp_nftnl_flowtable(struct nftnl_flowtable *a, struct nftnl_flowtabl { if (strcmp(nftnl_flowtable_get_str(a, NFTNL_FLOWTABLE_NAME), nftnl_flowtable_get_str(b, NFTNL_FLOWTABLE_NAME)) != 0) - print_err("Chain name mismatches"); + print_err("Flowtable name mismatches"); if (strcmp(nftnl_flowtable_get_str(a, NFTNL_FLOWTABLE_TABLE), nftnl_flowtable_get_str(b, NFTNL_FLOWTABLE_TABLE)) != 0) - print_err("Chain table mismatches"); + print_err("Flowtable table mismatches"); if (nftnl_flowtable_get_u32(a, NFTNL_FLOWTABLE_FAMILY) != nftnl_flowtable_get_u32(b, NFTNL_FLOWTABLE_FAMILY)) - print_err("Chain family mismatches"); + print_err("Flowtable family mismatches"); if (nftnl_flowtable_get_u32(a, NFTNL_FLOWTABLE_HOOKNUM) != nftnl_flowtable_get_u32(b, NFTNL_FLOWTABLE_HOOKNUM)) - print_err("Chain hooknum mismatches"); + print_err("Flowtable hooknum mismatches"); if (nftnl_flowtable_get_s32(a, NFTNL_FLOWTABLE_PRIO) != nftnl_flowtable_get_s32(b, NFTNL_FLOWTABLE_PRIO)) - print_err("Chain Prio mismatches"); + print_err("Flowtable prio mismatches"); if (nftnl_flowtable_get_u32(a, NFTNL_FLOWTABLE_USE) != nftnl_flowtable_get_u32(b, NFTNL_FLOWTABLE_USE)) - print_err("Chain use mismatches"); + print_err("Flowtable use mismatches"); if (nftnl_flowtable_get_u32(a, NFTNL_FLOWTABLE_SIZE) != nftnl_flowtable_get_u32(b, NFTNL_FLOWTABLE_SIZE)) - print_err("Chain use mismatches"); + print_err("Flowtable size mismatches"); if (nftnl_flowtable_get_u32(a, NFTNL_FLOWTABLE_FLAGS) != nftnl_flowtable_get_u32(b, NFTNL_FLOWTABLE_FLAGS)) - print_err("Chain use mismatches"); + print_err("Flowtable flags mismatches"); + if (nftnl_flowtable_get_u64(a, NFTNL_FLOWTABLE_HANDLE) != + nftnl_flowtable_get_u64(b, NFTNL_FLOWTABLE_HANDLE)) + print_err("Flowtable handle mismatches"); } int main(int argc, char *argv[]) @@ -60,6 +63,7 @@ int main(int argc, char *argv[]) nftnl_flowtable_set_u32(a, NFTNL_FLOWTABLE_USE, 0x78123456); nftnl_flowtable_set_u32(a, NFTNL_FLOWTABLE_SIZE, 0x89016745); nftnl_flowtable_set_u32(a, NFTNL_FLOWTABLE_FLAGS, 0x45016723); + nftnl_flowtable_set_u64(a, NFTNL_FLOWTABLE_HANDLE, 0x2345016789); nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_NEWFLOWTABLE, AF_INET, 0, 1234); -- cgit v1.2.3