]> git.ipfire.org Git - thirdparty/nftables.git/commitdiff
mnl: Support simple wildcards in netdev hooks
authorPhil Sutter <phil@nwl.cc>
Tue, 13 Aug 2024 18:26:08 +0000 (20:26 +0200)
committerPhil Sutter <phil@nwl.cc>
Tue, 30 Sep 2025 21:04:35 +0000 (23:04 +0200)
When building NFTA_{FLOWTABLE_,}HOOK_DEVS attributes, detect trailing
asterisks in interface names and transmit the leading part in a
NFTA_DEVICE_PREFIX attribute.

Deserialization (i.e., appending asterisk to interface prefixes returned
in NFTA_DEVICE_PREFIX atributes happens in libnftnl.

Signed-off-by: Phil Sutter <phil@nwl.cc>
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
include/linux/netfilter/nf_tables.h
src/mnl.c

index f57963e89fd168a4a39722e8961ab0207aaee657..b38d4780ae8c84e1897f399d06a78cc83b86989d 100644 (file)
@@ -1774,10 +1774,12 @@ enum nft_synproxy_attributes {
  * enum nft_device_attributes - nf_tables device netlink attributes
  *
  * @NFTA_DEVICE_NAME: name of this device (NLA_STRING)
+ * @NFTA_DEVICE_PREFIX: device name prefix, a simple wildcard (NLA_STRING)
  */
 enum nft_devices_attributes {
        NFTA_DEVICE_UNSPEC,
        NFTA_DEVICE_NAME,
+       NFTA_DEVICE_PREFIX,
        __NFTA_DEVICE_MAX
 };
 #define NFTA_DEVICE_MAX                (__NFTA_DEVICE_MAX - 1)
index d1402c0fcb9f4a644a09f13063de42c5640cfb85..bba34b73a708f15373fda557844f098f399298f4 100644 (file)
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -801,6 +801,26 @@ static void nft_dev_array_free(const struct nft_dev *dev_array)
        free_const(dev_array);
 }
 
+static bool is_wildcard_str(const char *str)
+{
+       size_t len = strlen(str);
+
+       if (len < 1 || str[len - 1] != '*')
+               return false;
+       if (len < 2 || str[len - 2] != '\\')
+               return true;
+       /* XXX: ignore backslash escaping for now */
+       return false;
+}
+
+static void mnl_nft_attr_put_ifname(struct nlmsghdr *nlh, const char *ifname)
+{
+       uint16_t attr = is_wildcard_str(ifname) ?
+                       NFTA_DEVICE_PREFIX : NFTA_DEVICE_NAME;
+
+       mnl_attr_put_strz(nlh, attr, ifname);
+}
+
 static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
 {
        const struct expr *dev_expr = cmd->chain->dev_expr;
@@ -809,14 +829,14 @@ static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
        int i, num_devs = 0;
 
        dev_array = nft_dev_array(dev_expr, &num_devs);
-       if (num_devs == 1) {
+       if (num_devs == 1 && !is_wildcard_str(dev_array[0].ifname)) {
                cmd_add_loc(cmd, nlh, dev_array[0].location);
                mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, dev_array[0].ifname);
        } else {
                nest_dev = mnl_attr_nest_start(nlh, NFTA_HOOK_DEVS);
                for (i = 0; i < num_devs; i++) {
                        cmd_add_loc(cmd, nlh, dev_array[i].location);
-                       mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+                       mnl_nft_attr_put_ifname(nlh, dev_array[i].ifname);
                }
                mnl_attr_nest_end(nlh, nest_dev);
        }
@@ -2234,7 +2254,7 @@ static void mnl_nft_ft_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
        nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS);
        for (i = 0; i < num_devs; i++) {
                cmd_add_loc(cmd, nlh, dev_array[i].location);
-               mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+               mnl_nft_attr_put_ifname(nlh, dev_array[i].ifname);
        }
 
        mnl_attr_nest_end(nlh, nest_dev);