@@ -6,6 +6,7 @@
#include <stdint.h>
#include <string.h>
#include <stdlib.h>
+#include <libmnl/libmnl.h>
#include <libnftnl/common.h>
#include "config.h"
@@ -83,4 +84,7 @@ int nftnl_fprintf(FILE *fpconst, const void *obj, uint32_t cmd, uint32_t type,
int nftnl_set_str_attr(const char **dptr, uint32_t *flags,
uint16_t attr, const void *data, uint32_t data_len);
+void mnl_attr_put_ifname(struct nlmsghdr *nlh, int attr, const char *ifname);
+const char *mnl_attr_get_ifname(struct nlattr *attr);
+
#endif
@@ -490,14 +490,14 @@ void nftnl_chain_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nftnl_ch
mnl_attr_put_u32(nlh, NFTA_HOOK_PRIORITY, htonl(c->prio));
if (c->flags & (1 << NFTNL_CHAIN_DEV))
- mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, c->dev);
+ mnl_attr_put_ifname(nlh, NFTA_HOOK_DEV, c->dev);
else if (c->flags & (1 << NFTNL_CHAIN_DEVICES)) {
struct nlattr *nest_dev;
nest_dev = mnl_attr_nest_start(nlh, NFTA_HOOK_DEVS);
for (i = 0; i < c->dev_array_len; i++)
- mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME,
- c->dev_array[i]);
+ mnl_attr_put_ifname(nlh, NFTA_DEVICE_NAME,
+ c->dev_array[i]);
mnl_attr_nest_end(nlh, nest_dev);
}
@@ -677,8 +677,10 @@ static int nftnl_chain_parse_devs(struct nlattr *nest, struct nftnl_chain *c)
mnl_attr_for_each_nested(attr, nest) {
if (mnl_attr_get_type(attr) != NFTA_DEVICE_NAME)
goto err;
- dev_array[len++] = strdup(mnl_attr_get_str(attr));
- if (len >= size) {
+ dev_array[len] = strdup(mnl_attr_get_ifname(attr));
+ if (!dev_array[len])
+ goto err;
+ if (++len >= size) {
tmp = realloc(dev_array, size * 2 * sizeof(char *));
if (!tmp)
goto err;
@@ -717,7 +719,9 @@ static int nftnl_chain_parse_hook(struct nlattr *attr, struct nftnl_chain *c)
c->flags |= (1 << NFTNL_CHAIN_PRIO);
}
if (tb[NFTA_HOOK_DEV]) {
- c->dev = strdup(mnl_attr_get_str(tb[NFTA_HOOK_DEV]));
+ if (c->flags & (1 << NFTNL_CHAIN_DEV))
+ xfree(c->dev);
+ c->dev = strdup(mnl_attr_get_ifname(tb[NFTA_HOOK_DEV]));
if (!c->dev)
return -1;
c->flags |= (1 << NFTNL_CHAIN_DEV);
@@ -328,8 +328,8 @@ void nftnl_flowtable_nlmsg_build_payload(struct nlmsghdr *nlh,
nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS);
for (i = 0; i < c->dev_array_len; i++) {
- mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME,
- c->dev_array[i]);
+ mnl_attr_put_ifname(nlh, NFTA_DEVICE_NAME,
+ c->dev_array[i]);
}
mnl_attr_nest_end(nlh, nest_dev);
}
@@ -416,8 +416,10 @@ static int nftnl_flowtable_parse_devs(struct nlattr *nest,
mnl_attr_for_each_nested(attr, nest) {
if (mnl_attr_get_type(attr) != NFTA_DEVICE_NAME)
goto err;
- dev_array[len++] = strdup(mnl_attr_get_str(attr));
- if (len >= size) {
+ dev_array[len] = strdup(mnl_attr_get_ifname(attr));
+ if (!dev_array[len])
+ goto err;
+ if (++len >= size) {
tmp = realloc(dev_array, size * 2 * sizeof(char *));
if (!tmp)
goto err;
@@ -17,8 +17,11 @@
#include <errno.h>
#include <inttypes.h>
+#include <libmnl/libmnl.h>
+
#include <libnftnl/common.h>
+#include <linux/if.h>
#include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h>
@@ -150,3 +153,30 @@ int nftnl_set_str_attr(const char **dptr, uint32_t *flags,
*flags |= (1 << attr);
return 0;
}
+
+void mnl_attr_put_ifname(struct nlmsghdr *nlh, int attr, const char *ifname)
+{
+ int len = strlen(ifname) + 1;
+
+ if (ifname[len - 2] == '*')
+ len -= 2;
+
+ mnl_attr_put(nlh, attr, len, ifname);
+}
+
+const char *mnl_attr_get_ifname(struct nlattr *attr)
+{
+ size_t slen = mnl_attr_get_payload_len(attr);
+ const char *dev = mnl_attr_get_str(attr);
+ static char buf[IFNAMSIZ];
+
+ if (dev[slen - 1] == '\0')
+ return dev;
+
+ if (slen > IFNAMSIZ - 2)
+ slen = IFNAMSIZ - 2;
+
+ memcpy(buf, dev, slen);
+ memcpy(buf + slen, "*\0", 2);
+ return buf;
+}
Support simple (suffix) wildcards in NFTNL_CHAIN_DEV(ICES) and NFTA_FLOWTABLE_HOOK_DEVS identified by non-NUL-terminated strings. Add helpers converting to and from the human-readable asterisk-suffix notation. Signed-off-by: Phil Sutter <phil@nwl.cc> --- include/utils.h | 4 ++++ src/chain.c | 16 ++++++++++------ src/flowtable.c | 10 ++++++---- src/utils.c | 30 ++++++++++++++++++++++++++++++ 4 files changed, 50 insertions(+), 10 deletions(-)