summaryrefslogtreecommitdiffstats
path: root/src/str_array.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2021-08-30 14:38:27 +0200
committerPhil Sutter <phil@nwl.cc>2024-10-29 23:26:43 +0100
commit0576274ad54a3aae2750e7a49bed1e0f406b61cc (patch)
tree103b004cdb5c58529e253c873c0c47d08afc7aff /src/str_array.c
parentfaab4a300784cc04f35a0cf40b7fdb858a7ece3e (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.c68
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;
+}