]> git.ipfire.org Git - thirdparty/libnftnl.git/commitdiff
utils: Introduce nftnl_parse_str_attr()
authorPhil Sutter <phil@nwl.cc>
Wed, 2 Oct 2024 14:44:49 +0000 (16:44 +0200)
committerPhil Sutter <phil@nwl.cc>
Sat, 18 Oct 2025 19:11:27 +0000 (21:11 +0200)
Wrap the common parsing of string attributes in a function. Apart from
slightly reducing code size, this unifies callers in conditional freeing
of the field in case it was set before (missing in twelve spots) and
error checking for failing strdup()-calls (missing in four spots).

Signed-off-by: Phil Sutter <phil@nwl.cc>
Acked-by: Florian Westphal <fw@strlen.de>
15 files changed:
include/utils.h
src/chain.c
src/expr/dynset.c
src/expr/flow_offload.c
src/expr/log.c
src/expr/lookup.c
src/expr/objref.c
src/flowtable.c
src/object.c
src/rule.c
src/set.c
src/set_elem.c
src/table.c
src/trace.c
src/utils.c

index 5a3379fb501e11be0183422f75921f4dd85d646b..10492893e3a16203419801dbf6592baadf53fe63 100644 (file)
@@ -88,4 +88,7 @@ struct nlattr;
 void nftnl_attr_put_ifname(struct nlmsghdr *nlh, const char *ifname);
 char *nftnl_attr_get_ifname(const struct nlattr *attr);
 
+int nftnl_parse_str_attr(const struct nlattr *tb, int attr,
+                        const char **field, uint32_t *flags);
+
 #endif
index 8396114439ff7461f95fa9457a9ac33b1cd2b381..8433f7db41263e7feac076b5877c701daf630b6d 100644 (file)
@@ -675,22 +675,12 @@ int nftnl_chain_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_chain *c)
        if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_chain_parse_attr_cb, tb) < 0)
                return -1;
 
-       if (tb[NFTA_CHAIN_NAME]) {
-               if (c->flags & (1 << NFTNL_CHAIN_NAME))
-                       xfree(c->name);
-               c->name = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_NAME]));
-               if (!c->name)
-                       return -1;
-               c->flags |= (1 << NFTNL_CHAIN_NAME);
-       }
-       if (tb[NFTA_CHAIN_TABLE]) {
-               if (c->flags & (1 << NFTNL_CHAIN_TABLE))
-                       xfree(c->table);
-               c->table = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TABLE]));
-               if (!c->table)
-                       return -1;
-               c->flags |= (1 << NFTNL_CHAIN_TABLE);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_CHAIN_NAME], NFTNL_CHAIN_NAME,
+                                &c->name, &c->flags) < 0)
+               return -1;
+       if (nftnl_parse_str_attr(tb[NFTA_CHAIN_TABLE], NFTNL_CHAIN_TABLE,
+                                &c->table, &c->flags) < 0)
+               return -1;
        if (tb[NFTA_CHAIN_HOOK]) {
                ret = nftnl_chain_parse_hook(tb[NFTA_CHAIN_HOOK], c);
                if (ret < 0)
@@ -713,14 +703,9 @@ int nftnl_chain_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_chain *c)
                c->handle = be64toh(mnl_attr_get_u64(tb[NFTA_CHAIN_HANDLE]));
                c->flags |= (1 << NFTNL_CHAIN_HANDLE);
        }
-       if (tb[NFTA_CHAIN_TYPE]) {
-               if (c->flags & (1 << NFTNL_CHAIN_TYPE))
-                       xfree(c->type);
-               c->type = strdup(mnl_attr_get_str(tb[NFTA_CHAIN_TYPE]));
-               if (!c->type)
-                       return -1;
-               c->flags |= (1 << NFTNL_CHAIN_TYPE);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_CHAIN_TYPE], NFTNL_CHAIN_TYPE,
+                                &c->type, &c->flags) < 0)
+               return -1;
        if (tb[NFTA_CHAIN_FLAGS]) {
                c->chain_flags = ntohl(mnl_attr_get_u32(tb[NFTA_CHAIN_FLAGS]));
                c->flags |= (1 << NFTNL_CHAIN_FLAGS);
index 40f9136ab73a291b8c3642f8dfbfe0862d633c03..dc74fbbe75b3c3106c257ed92dda18f997e2b32e 100644 (file)
@@ -245,13 +245,11 @@ nftnl_expr_dynset_parse(struct nftnl_expr *e, struct nlattr *attr)
                dynset->timeout = be64toh(mnl_attr_get_u64(tb[NFTA_DYNSET_TIMEOUT]));
                e->flags |= (1 << NFTNL_EXPR_DYNSET_TIMEOUT);
        }
-       if (tb[NFTA_DYNSET_SET_NAME]) {
-               dynset->set_name =
-                       strdup(mnl_attr_get_str(tb[NFTA_DYNSET_SET_NAME]));
-               if (!dynset->set_name)
-                       return -1;
-               e->flags |= (1 << NFTNL_EXPR_DYNSET_SET_NAME);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_DYNSET_SET_NAME],
+                                NFTNL_EXPR_DYNSET_SET_NAME,
+                                (const char **)&dynset->set_name,
+                                &e->flags) < 0)
+               return -1;
        if (tb[NFTA_DYNSET_SET_ID]) {
                dynset->set_id = ntohl(mnl_attr_get_u32(tb[NFTA_DYNSET_SET_ID]));
                e->flags |= (1 << NFTNL_EXPR_DYNSET_SET_ID);
index 5f209a63fa960911cdb3d17b5ac23e55a17a1af6..ce22ec419a944326e6b726bc16f0a910c53d82b3 100644 (file)
@@ -79,13 +79,11 @@ static int nftnl_expr_flow_parse(struct nftnl_expr *e, struct nlattr *attr)
        if (mnl_attr_parse_nested(attr, nftnl_expr_flow_cb, tb) < 0)
                return -1;
 
-       if (tb[NFTA_FLOW_TABLE_NAME]) {
-               flow->table_name =
-                       strdup(mnl_attr_get_str(tb[NFTA_FLOW_TABLE_NAME]));
-               if (!flow->table_name)
-                       return -1;
-               e->flags |= (1 << NFTNL_EXPR_FLOW_TABLE_NAME);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_FLOW_TABLE_NAME],
+                                NFTNL_EXPR_FLOW_TABLE_NAME,
+                                (const char **)&flow->table_name,
+                                &e->flags) < 0)
+               return -1;
 
        return ret;
 }
index d4b53e6c744dee25d12eafae2bcefac027f1e01c..ead243799863c6e0774df40164b01561e4c75ee5 100644 (file)
@@ -147,15 +147,10 @@ nftnl_expr_log_parse(struct nftnl_expr *e, struct nlattr *attr)
        if (mnl_attr_parse_nested(attr, nftnl_expr_log_cb, tb) < 0)
                return -1;
 
-       if (tb[NFTA_LOG_PREFIX]) {
-               if (log->prefix)
-                       xfree(log->prefix);
-
-               log->prefix = strdup(mnl_attr_get_str(tb[NFTA_LOG_PREFIX]));
-               if (!log->prefix)
-                       return -1;
-               e->flags |= (1 << NFTNL_EXPR_LOG_PREFIX);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_LOG_PREFIX],
+                                NFTNL_EXPR_LOG_PREFIX,
+                                &log->prefix, &e->flags) < 0)
+               return -1;
        if (tb[NFTA_LOG_GROUP]) {
                log->group = ntohs(mnl_attr_get_u16(tb[NFTA_LOG_GROUP]));
                e->flags |= (1 << NFTNL_EXPR_LOG_GROUP);
index 7f85ecca008f5fd395f1ae58b463a0a9cb6d2078..4f76c5b71bb2b4ab9ef2285a570e2ec1c213f4bd 100644 (file)
@@ -141,13 +141,11 @@ nftnl_expr_lookup_parse(struct nftnl_expr *e, struct nlattr *attr)
                lookup->dreg = ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_DREG]));
                e->flags |= (1 << NFTNL_EXPR_LOOKUP_DREG);
        }
-       if (tb[NFTA_LOOKUP_SET]) {
-               lookup->set_name =
-                       strdup(mnl_attr_get_str(tb[NFTA_LOOKUP_SET]));
-               if (!lookup->set_name)
-                       return -1;
-               e->flags |= (1 << NFTNL_EXPR_LOOKUP_SET);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_LOOKUP_SET],
+                                NFTNL_EXPR_LOOKUP_SET,
+                                (const char **)&lookup->set_name,
+                                &e->flags) < 0)
+               return -1;
        if (tb[NFTA_LOOKUP_SET_ID]) {
                lookup->set_id =
                        ntohl(mnl_attr_get_u32(tb[NFTA_LOOKUP_SET_ID]));
index 5fe09c242ef480b4fe2c95d8cde4b11bd883b4ce..1b27e94a6fa2c18fb0517fcf882391e81f40b397 100644 (file)
@@ -144,21 +144,19 @@ static int nftnl_expr_objref_parse(struct nftnl_expr *e, struct nlattr *attr)
                        ntohl(mnl_attr_get_u32(tb[NFTA_OBJREF_IMM_TYPE]));
                e->flags |= (1 << NFTNL_EXPR_OBJREF_IMM_TYPE);
        }
-       if (tb[NFTA_OBJREF_IMM_NAME]) {
-               objref->imm.name =
-                       strdup(mnl_attr_get_str(tb[NFTA_OBJREF_IMM_NAME]));
-               e->flags |= (1 << NFTNL_EXPR_OBJREF_IMM_NAME);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_OBJREF_IMM_NAME],
+                                NFTNL_EXPR_OBJREF_IMM_NAME,
+                                &objref->imm.name, &e->flags) < 0)
+               return -1;
        if (tb[NFTA_OBJREF_SET_SREG]) {
                objref->set.sreg =
                        ntohl(mnl_attr_get_u32(tb[NFTA_OBJREF_SET_SREG]));
                e->flags |= (1 << NFTNL_EXPR_OBJREF_SET_SREG);
        }
-       if (tb[NFTA_OBJREF_SET_NAME]) {
-               objref->set.name =
-                       strdup(mnl_attr_get_str(tb[NFTA_OBJREF_SET_NAME]));
-               e->flags |= (1 << NFTNL_EXPR_OBJREF_SET_NAME);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_OBJREF_SET_NAME],
+                                NFTNL_EXPR_OBJREF_SET_NAME,
+                                &objref->set.name, &e->flags) < 0)
+               return -1;
        if (tb[NFTA_OBJREF_SET_ID]) {
                objref->set.id =
                        ntohl(mnl_attr_get_u32(tb[NFTA_OBJREF_SET_ID]));
index 59991d694f602f4c7024d456eef4cd7f8444645f..27af51c688745bd2994e0c74050467f32d6a41a7 100644 (file)
@@ -408,22 +408,14 @@ int nftnl_flowtable_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_flowtab
        if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_flowtable_parse_attr_cb, tb) < 0)
                return -1;
 
-       if (tb[NFTA_FLOWTABLE_NAME]) {
-               if (c->flags & (1 << NFTNL_FLOWTABLE_NAME))
-                       xfree(c->name);
-               c->name = strdup(mnl_attr_get_str(tb[NFTA_FLOWTABLE_NAME]));
-               if (!c->name)
-                       return -1;
-               c->flags |= (1 << NFTNL_FLOWTABLE_NAME);
-       }
-       if (tb[NFTA_FLOWTABLE_TABLE]) {
-               if (c->flags & (1 << NFTNL_FLOWTABLE_TABLE))
-                       xfree(c->table);
-               c->table = strdup(mnl_attr_get_str(tb[NFTA_FLOWTABLE_TABLE]));
-               if (!c->table)
-                       return -1;
-               c->flags |= (1 << NFTNL_FLOWTABLE_TABLE);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_FLOWTABLE_NAME],
+                                NFTNL_FLOWTABLE_NAME,
+                                &c->name, &c->flags) < 0)
+               return -1;
+       if (nftnl_parse_str_attr(tb[NFTA_FLOWTABLE_TABLE],
+                                NFTNL_FLOWTABLE_TABLE,
+                                &c->table, &c->flags) < 0)
+               return -1;
        if (tb[NFTA_FLOWTABLE_HOOK]) {
                ret = nftnl_flowtable_parse_hook(tb[NFTA_FLOWTABLE_HOOK], c);
                if (ret < 0)
index 275a202e63081db385ede6a162af345ace48b14a..3d358ccf051cbc9c271afa69828058603347bad8 100644 (file)
@@ -344,14 +344,12 @@ int nftnl_obj_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_obj *obj)
        if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_obj_parse_attr_cb, tb) < 0)
                return -1;
 
-       if (tb[NFTA_OBJ_TABLE]) {
-               obj->table = strdup(mnl_attr_get_str(tb[NFTA_OBJ_TABLE]));
-               obj->flags |= (1 << NFTNL_OBJ_TABLE);
-       }
-       if (tb[NFTA_OBJ_NAME]) {
-               obj->name = strdup(mnl_attr_get_str(tb[NFTA_OBJ_NAME]));
-               obj->flags |= (1 << NFTNL_OBJ_NAME);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_OBJ_TABLE], NFTNL_OBJ_TABLE,
+                                &obj->table, &obj->flags) < 0)
+               return -1;
+       if (nftnl_parse_str_attr(tb[NFTA_OBJ_NAME], NFTNL_OBJ_NAME,
+                                &obj->name, &obj->flags) < 0)
+               return -1;
        if (tb[NFTA_OBJ_TYPE]) {
                uint32_t type = ntohl(mnl_attr_get_u32(tb[NFTA_OBJ_TYPE]));
 
index 3948a74098fe74170ff3cc6e4e00030afcb5d23f..cd3041e5a399a9d4b36feccdaa578bac2ca6f53e 100644 (file)
@@ -431,22 +431,12 @@ int nftnl_rule_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_rule *r)
        if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_rule_parse_attr_cb, tb) < 0)
                return -1;
 
-       if (tb[NFTA_RULE_TABLE]) {
-               if (r->flags & (1 << NFTNL_RULE_TABLE))
-                       xfree(r->table);
-               r->table = strdup(mnl_attr_get_str(tb[NFTA_RULE_TABLE]));
-               if (!r->table)
-                       return -1;
-               r->flags |= (1 << NFTNL_RULE_TABLE);
-       }
-       if (tb[NFTA_RULE_CHAIN]) {
-               if (r->flags & (1 << NFTNL_RULE_CHAIN))
-                       xfree(r->chain);
-               r->chain = strdup(mnl_attr_get_str(tb[NFTA_RULE_CHAIN]));
-               if (!r->chain)
-                       return -1;
-               r->flags |= (1 << NFTNL_RULE_CHAIN);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_RULE_TABLE], NFTNL_RULE_TABLE,
+                                &r->table, &r->flags) < 0)
+               return -1;
+       if (nftnl_parse_str_attr(tb[NFTA_RULE_CHAIN], NFTNL_RULE_CHAIN,
+                                &r->chain, &r->flags) < 0)
+               return -1;
        if (tb[NFTA_RULE_HANDLE]) {
                r->handle = be64toh(mnl_attr_get_u64(tb[NFTA_RULE_HANDLE]));
                r->flags |= (1 << NFTNL_RULE_HANDLE);
index 412bdac627d3123aeac34396bf54257a3d5ce64a..54674bca709fdd0c64c6d89773f2287a8989e43d 100644 (file)
--- a/src/set.c
+++ b/src/set.c
@@ -657,22 +657,12 @@ int nftnl_set_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_set *s)
        if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_set_parse_attr_cb, tb) < 0)
                return -1;
 
-       if (tb[NFTA_SET_TABLE]) {
-               if (s->flags & (1 << NFTNL_SET_TABLE))
-                       xfree(s->table);
-               s->table = strdup(mnl_attr_get_str(tb[NFTA_SET_TABLE]));
-               if (!s->table)
-                       return -1;
-               s->flags |= (1 << NFTNL_SET_TABLE);
-       }
-       if (tb[NFTA_SET_NAME]) {
-               if (s->flags & (1 << NFTNL_SET_NAME))
-                       xfree(s->name);
-               s->name = strdup(mnl_attr_get_str(tb[NFTA_SET_NAME]));
-               if (!s->name)
-                       return -1;
-               s->flags |= (1 << NFTNL_SET_NAME);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_SET_TABLE], NFTNL_SET_TABLE,
+                                &s->table, &s->flags) < 0)
+               return -1;
+       if (nftnl_parse_str_attr(tb[NFTA_SET_NAME], NFTNL_SET_NAME,
+                                &s->name, &s->flags) < 0)
+               return -1;
        if (tb[NFTA_SET_HANDLE]) {
                s->handle = be64toh(mnl_attr_get_u64(tb[NFTA_SET_HANDLE]));
                s->flags |= (1 << NFTNL_SET_HANDLE);
index 848adf1d179bf75f6bc6fa4ed641a8c1d1671676..05220e7933242d3201a209eb1b67e2fbcfcec438 100644 (file)
@@ -576,13 +576,11 @@ static int nftnl_set_elems_parse2(struct nftnl_set *s, const struct nlattr *nest
                memcpy(e->user.data, udata, e->user.len);
                e->flags |= (1 << NFTNL_RULE_USERDATA);
        }
-       if (tb[NFTA_SET_ELEM_OBJREF]) {
-               e->objref = strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_OBJREF]));
-               if (e->objref == NULL) {
-                       ret = -1;
-                       goto out_set_elem;
-               }
-               e->flags |= (1 << NFTNL_SET_ELEM_OBJREF);
+       if (nftnl_parse_str_attr(tb[NFTA_SET_ELEM_OBJREF],
+                                NFTNL_SET_ELEM_OBJREF,
+                                &e->objref, &e->flags) < 0) {
+               ret = -1;
+               goto out_set_elem;
        }
 
        /* Add this new element to this set */
@@ -646,24 +644,14 @@ int nftnl_set_elems_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_set *s)
                           nftnl_set_elem_list_parse_attr_cb, tb) < 0)
                return -1;
 
-       if (tb[NFTA_SET_ELEM_LIST_TABLE]) {
-               if (s->flags & (1 << NFTNL_SET_TABLE))
-                       xfree(s->table);
-               s->table =
-                       strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_LIST_TABLE]));
-               if (!s->table)
-                       return -1;
-               s->flags |= (1 << NFTNL_SET_TABLE);
-       }
-       if (tb[NFTA_SET_ELEM_LIST_SET]) {
-               if (s->flags & (1 << NFTNL_SET_NAME))
-                       xfree(s->name);
-               s->name =
-                       strdup(mnl_attr_get_str(tb[NFTA_SET_ELEM_LIST_SET]));
-               if (!s->name)
-                       return -1;
-               s->flags |= (1 << NFTNL_SET_NAME);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_SET_ELEM_LIST_TABLE],
+                                NFTNL_SET_TABLE,
+                                &s->table, &s->flags) < 0)
+               return -1;
+       if (nftnl_parse_str_attr(tb[NFTA_SET_ELEM_LIST_SET],
+                                NFTNL_SET_NAME,
+                                &s->name, &s->flags) < 0)
+               return -1;
        if (tb[NFTA_SET_ELEM_LIST_SET_ID]) {
                s->id = ntohl(mnl_attr_get_u32(tb[NFTA_SET_ELEM_LIST_SET_ID]));
                s->flags |= (1 << NFTNL_SET_ID);
index 9870dcafb4ef65134b3b69913a772eca29671659..61382838ae1c57fd6519dff3f0220ff2434f1e41 100644 (file)
@@ -285,14 +285,9 @@ int nftnl_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_table *t)
        if (mnl_attr_parse(nlh, sizeof(*nfg), nftnl_table_parse_attr_cb, tb) < 0)
                return -1;
 
-       if (tb[NFTA_TABLE_NAME]) {
-               if (t->flags & (1 << NFTNL_TABLE_NAME))
-                       xfree(t->name);
-               t->name = strdup(mnl_attr_get_str(tb[NFTA_TABLE_NAME]));
-               if (!t->name)
-                       return -1;
-               t->flags |= (1 << NFTNL_TABLE_NAME);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_TABLE_NAME], NFTNL_TABLE_NAME,
+                                &t->name, &t->flags) < 0)
+               return -1;
        if (tb[NFTA_TABLE_FLAGS]) {
                t->table_flags = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_FLAGS]));
                t->flags |= (1 << NFTNL_TABLE_FLAGS);
index d67e114082665d2e1b88a29e6fd0a307ba8194b3..5dc4cfabc4a82f33eeb892bd67b64d094ac15fc8 100644 (file)
@@ -336,11 +336,11 @@ static int nftnl_trace_parse_verdict(const struct nlattr *attr,
        case NFT_JUMP:
                if (!tb[NFTA_VERDICT_CHAIN])
                        abi_breakage();
-               t->jump_target = strdup(mnl_attr_get_str(tb[NFTA_VERDICT_CHAIN]));
-               if (!t->jump_target)
+               if (nftnl_parse_str_attr(tb[NFTA_VERDICT_CHAIN],
+                                        NFTNL_TRACE_JUMP_TARGET,
+                                        (const char **)&t->jump_target,
+                                        &t->flags) < 0)
                        return -1;
-
-               t->flags |= (1 << NFTNL_TRACE_JUMP_TARGET);
                break;
        }
        return 0;
@@ -370,21 +370,13 @@ int nftnl_trace_nlmsg_parse(const struct nlmsghdr *nlh, struct nftnl_trace *t)
        t->id = ntohl(mnl_attr_get_u32(tb[NFTA_TRACE_ID]));
        t->flags |= (1 << NFTNL_TRACE_ID);
 
-       if (tb[NFTA_TRACE_TABLE]) {
-               t->table = strdup(mnl_attr_get_str(tb[NFTA_TRACE_TABLE]));
-               if (!t->table)
-                       return -1;
-
-               t->flags |= (1 << NFTNL_TRACE_TABLE);
-       }
-
-       if (tb[NFTA_TRACE_CHAIN]) {
-               t->chain = strdup(mnl_attr_get_str(tb[NFTA_TRACE_CHAIN]));
-               if (!t->chain)
-                       return -1;
+       if (nftnl_parse_str_attr(tb[NFTA_TRACE_TABLE], NFTNL_TRACE_TABLE,
+                                (const char **)&t->table, &t->flags) < 0)
+               return -1;
 
-               t->flags |= (1 << NFTNL_TRACE_CHAIN);
-       }
+       if (nftnl_parse_str_attr(tb[NFTA_TRACE_CHAIN], NFTNL_TRACE_CHAIN,
+                                (const char **)&t->chain, &t->flags) < 0)
+               return -1;
 
        if (tb[NFTA_TRACE_IIFTYPE]) {
                t->iiftype = ntohs(mnl_attr_get_u16(tb[NFTA_TRACE_IIFTYPE]));
index d73c5f6175802141715d4c92e9b3b3d0ef42b36b..bbe44b4d532dce6d01f238b7caf758b17353d46c 100644 (file)
@@ -192,3 +192,18 @@ char *nftnl_attr_get_ifname(const struct nlattr *attr)
                return NULL;
        }
 }
+
+int nftnl_parse_str_attr(const struct nlattr *tb, int attr,
+                        const char **field, uint32_t *flags)
+{
+       if (!tb)
+               return 0;
+
+       if (*flags & (1 << attr))
+               xfree(*field);
+       *field = strdup(mnl_attr_get_str(tb));
+       if (!*field)
+               return -1;
+       *flags |= (1 << attr);
+       return 0;
+}