From 7285bf672df47b130e4ff3afd481bf4973cede5e Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 8 May 2024 22:39:41 +0200 Subject: [PATCH] utils: Introduce and use nftnl_set_str_attr() JIRA: https://issues.redhat.com/browse/RHEL-28515 Upstream Status: libnftnl commit bb5e75be9d28c37096c90d9ae9fcc7ad0841f2c2 commit bb5e75be9d28c37096c90d9ae9fcc7ad0841f2c2 Author: Phil Sutter Date: Thu Mar 7 14:07:21 2024 +0100 utils: Introduce and use nftnl_set_str_attr() The function consolidates the necessary code when assigning to string pointer attributes, namely: * Conditional free of the previous value * Allocation of new value * Checking for memory allocation errors * Setting respective flag bit A new feature previously missing in all call sites is respecting data_len in case the buffer up to that point did not contain a NUL-char. Signed-off-by: Phil Sutter Signed-off-by: Phil Sutter --- src/chain.c | 36 ++++++++---------------------------- src/flowtable.c | 17 ++++------------- src/object.c | 13 ++++--------- src/rule.c | 18 ++++-------------- src/set.c | 18 ++++-------------- src/table.c | 9 ++------- src/utils.c | 14 ++++++++++++++ 7 files changed, 40 insertions(+), 85 deletions(-) diff --git a/src/chain.c b/src/chain.c index e0b1eaf..c7026f4 100644 --- a/src/chain.c +++ b/src/chain.c @@ -217,21 +217,11 @@ int nftnl_chain_set_data(struct nftnl_chain *c, uint16_t attr, switch(attr) { case NFTNL_CHAIN_NAME: - if (c->flags & (1 << NFTNL_CHAIN_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_CHAIN_TABLE: - if (c->flags & (1 << NFTNL_CHAIN_TABLE)) - xfree(c->table); - - c->table = strdup(data); - if (!c->table) - return -1; - break; + return nftnl_set_str_attr(&c->table, &c->flags, + attr, data, data_len); case NFTNL_CHAIN_HOOKNUM: memcpy(&c->hooknum, data, sizeof(c->hooknum)); break; @@ -257,21 +247,11 @@ int nftnl_chain_set_data(struct nftnl_chain *c, uint16_t attr, memcpy(&c->family, data, sizeof(c->family)); break; case NFTNL_CHAIN_TYPE: - if (c->flags & (1 << NFTNL_CHAIN_TYPE)) - xfree(c->type); - - c->type = strdup(data); - if (!c->type) - return -1; - break; + return nftnl_set_str_attr(&c->type, &c->flags, + attr, data, data_len); case NFTNL_CHAIN_DEV: - if (c->flags & (1 << NFTNL_CHAIN_DEV)) - xfree(c->dev); - - c->dev = strdup(data); - if (!c->dev) - return -1; - break; + return nftnl_set_str_attr(&c->dev, &c->flags, + attr, data, data_len); case NFTNL_CHAIN_DEVICES: dev_array = (const char **)data; while (dev_array[len] != NULL) diff --git a/src/flowtable.c b/src/flowtable.c index 2f37cd4..41a1456 100644 --- a/src/flowtable.c +++ b/src/flowtable.c @@ -119,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)); diff --git a/src/object.c b/src/object.c index b653732..79b41eb 100644 --- a/src/object.c +++ b/src/object.c @@ -85,17 +85,12 @@ int nftnl_obj_set_data(struct nftnl_obj *obj, uint16_t attr, switch (attr) { case NFTNL_OBJ_TABLE: - xfree(obj->table); - obj->table = strdup(data); - if (!obj->table) - return -1; + return nftnl_set_str_attr(&obj->table, &obj->flags, + attr, data, data_len); break; case NFTNL_OBJ_NAME: - xfree(obj->name); - obj->name = strdup(data); - if (!obj->name) - return -1; - break; + return nftnl_set_str_attr(&obj->name, &obj->flags, + attr, data, data_len); case NFTNL_OBJ_TYPE: obj->ops = nftnl_obj_ops_lookup(*((uint32_t *)data)); if (!obj->ops) diff --git a/src/rule.c b/src/rule.c index a52012b..e16e2c1 100644 --- a/src/rule.c +++ b/src/rule.c @@ -115,21 +115,11 @@ int nftnl_rule_set_data(struct nftnl_rule *r, uint16_t attr, switch(attr) { case NFTNL_RULE_TABLE: - if (r->flags & (1 << NFTNL_RULE_TABLE)) - xfree(r->table); - - r->table = strdup(data); - if (!r->table) - return -1; - break; + return nftnl_set_str_attr(&r->table, &r->flags, + attr, data, data_len); case NFTNL_RULE_CHAIN: - if (r->flags & (1 << NFTNL_RULE_CHAIN)) - xfree(r->chain); - - r->chain = strdup(data); - if (!r->chain) - return -1; - break; + return nftnl_set_str_attr(&r->chain, &r->flags, + attr, data, data_len); case NFTNL_RULE_HANDLE: memcpy(&r->handle, data, sizeof(r->handle)); break; diff --git a/src/set.c b/src/set.c index a732bc0..07e332d 100644 --- a/src/set.c +++ b/src/set.c @@ -146,21 +146,11 @@ int nftnl_set_set_data(struct nftnl_set *s, uint16_t attr, const void *data, switch(attr) { case NFTNL_SET_TABLE: - if (s->flags & (1 << NFTNL_SET_TABLE)) - xfree(s->table); - - s->table = strdup(data); - if (!s->table) - return -1; - break; + return nftnl_set_str_attr(&s->table, &s->flags, + attr, data, data_len); case NFTNL_SET_NAME: - if (s->flags & (1 << NFTNL_SET_NAME)) - xfree(s->name); - - s->name = strdup(data); - if (!s->name) - return -1; - break; + return nftnl_set_str_attr(&s->name, &s->flags, + attr, data, data_len); case NFTNL_SET_HANDLE: memcpy(&s->handle, data, sizeof(s->handle)); break; diff --git a/src/table.c b/src/table.c index 4f48e8c..13f01cf 100644 --- a/src/table.c +++ b/src/table.c @@ -101,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; diff --git a/src/utils.c b/src/utils.c index 3617837..a0f03da 100644 --- a/src/utils.c +++ b/src/utils.c @@ -330,3 +330,17 @@ void __noreturn __abi_breakage(const char *file, int line, const char *reason) "%s:%d reason: %s\n", file, line, reason); exit(EXIT_FAILURE); } + +int nftnl_set_str_attr(const char **dptr, uint32_t *flags, + uint16_t attr, const void *data, uint32_t data_len) +{ + if (*flags & (1 << attr)) + xfree(*dptr); + + *dptr = strndup(data, data_len); + if (!*dptr) + return -1; + + *flags |= (1 << attr); + return 0; +}