diff options
| author | Phil Sutter <phil@nwl.cc> | 2021-08-30 14:38:27 +0200 |
|---|---|---|
| committer | Phil Sutter <phil@nwl.cc> | 2024-10-29 23:26:43 +0100 |
| commit | 0576274ad54a3aae2750e7a49bed1e0f406b61cc (patch) | |
| tree | 103b004cdb5c58529e253c873c0c47d08afc7aff /src/str_array.c | |
| parent | faab4a300784cc04f35a0cf40b7fdb858a7ece3e (diff) | |
Introduce struct nftnl_str_array
This data structure holds an array of allocated strings for use in
nftnl_chain and nftnl_flowtable structs. For convenience, implement
functions to clear, populate and iterate over contents.
While at it, extend chain and flowtable tests to cover these attributes,
too.
Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/str_array.c')
| -rw-r--r-- | src/str_array.c | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/src/str_array.c b/src/str_array.c new file mode 100644 index 0000000..63471bd --- /dev/null +++ b/src/str_array.c @@ -0,0 +1,68 @@ +/* + * (C) 2024 Red Hat GmbH + * Author: Phil Sutter <phil@nwl.cc> + * + * SPDX-License-Identifier: GPL-2.0-or-later + */ +#include <libmnl/libmnl.h> +#include <linux/netfilter/nf_tables.h> + +#include "str_array.h" +#include "utils.h" + +void nftnl_str_array_clear(struct nftnl_str_array *sa) +{ + while (sa->len > 0) + free(sa->array[--sa->len]); + free(sa->array); +} + +int nftnl_str_array_set(struct nftnl_str_array *sa, const char * const *array) +{ + int len = 0; + + while (array[len]) + len++; + + nftnl_str_array_clear(sa); + sa->array = calloc(len + 1, sizeof(char *)); + if (!sa->array) + return -1; + + while (sa->len < len) { + sa->array[sa->len] = strdup(array[sa->len]); + if (!sa->array[sa->len]) { + nftnl_str_array_clear(sa); + return -1; + } + sa->len++; + } + return 0; +} + +int nftnl_parse_devs(struct nftnl_str_array *sa, const struct nlattr *nest) +{ + struct nlattr *attr; + int len = 0; + + mnl_attr_for_each_nested(attr, nest) { + if (mnl_attr_get_type(attr) != NFTA_DEVICE_NAME) + return -1; + len++; + } + + nftnl_str_array_clear(sa); + sa->array = calloc(len + 1, sizeof(char *)); + if (!sa->array) + return -1; + + mnl_attr_for_each_nested(attr, nest) { + sa->array[sa->len] = strdup(mnl_attr_get_str(attr)); + if (!sa->array[sa->len]) { + nftnl_str_array_clear(sa); + return -1; + } + sa->len++; + } + return 0; +} |
