diff mbox series

[nft,5/9] mnl: Support simple wildcards in netdev hooks

Message ID 20241002193853.13818-6-phil@nwl.cc
State New
Headers show
Series Support wildcard netdev hooks and events | expand

Commit Message

Phil Sutter Oct. 2, 2024, 7:38 p.m. UTC
When building NFTA_FLOWTABLE_HOOK_DEVS, NFTA_HOOK_DEV or NFTA_HOOK_DEVS
attributes, detect trailing asterisks in interface names and reduce
attribute length accordingly. Kernel will use strncmp(), effectively
performing a prefix search this way.

Deserialization (i.e., appending asterisk to interface names which don't
include a trailing nul-char) happens in libnftnl.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 src/mnl.c | 19 ++++++++++++++-----
 1 file changed, 14 insertions(+), 5 deletions(-)
diff mbox series

Patch

diff --git a/src/mnl.c b/src/mnl.c
index db53a60b43cb9..4faf027ce1027 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -787,18 +787,24 @@  static void mnl_nft_chain_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
 {
 	const struct expr *dev_expr = cmd->chain->dev_expr;
 	const struct nft_dev *dev_array;
+	int i, len, num_devs = 0;
 	struct nlattr *nest_dev;
-	int i, num_devs = 0;
 
 	dev_array = nft_dev_array(dev_expr, &num_devs);
 	if (num_devs == 1) {
 		cmd_add_loc(cmd, nlh->nlmsg_len, dev_array[0].location);
-		mnl_attr_put_strz(nlh, NFTA_HOOK_DEV, dev_array[0].ifname);
+		len = strlen(dev_array[0].ifname) + 1;
+		if (dev_array[0].ifname[len - 2] == '*')
+			len -= 2;
+		mnl_attr_put(nlh, NFTA_HOOK_DEV, len, 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->nlmsg_len, dev_array[i].location);
-			mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+			len = strlen(dev_array[i].ifname) + 1;
+			if (dev_array[i].ifname[len - 2] == '*')
+				len -= 2;
+			mnl_attr_put(nlh, NFTA_DEVICE_NAME, len, dev_array[i].ifname);
 			mnl_attr_nest_end(nlh, nest_dev);
 		}
 	}
@@ -1999,14 +2005,17 @@  static void mnl_nft_ft_devs_build(struct nlmsghdr *nlh, struct cmd *cmd)
 {
 	const struct expr *dev_expr = cmd->flowtable->dev_expr;
 	const struct nft_dev *dev_array;
+	int i, len, num_devs = 0;
 	struct nlattr *nest_dev;
-	int i, num_devs= 0;
 
 	dev_array = nft_dev_array(dev_expr, &num_devs);
 	nest_dev = mnl_attr_nest_start(nlh, NFTA_FLOWTABLE_HOOK_DEVS);
 	for (i = 0; i < num_devs; i++) {
 		cmd_add_loc(cmd, nlh->nlmsg_len, dev_array[i].location);
-		mnl_attr_put_strz(nlh, NFTA_DEVICE_NAME, dev_array[i].ifname);
+		len = strlen(dev_array[i].ifname) + 1;
+		if (dev_array[i].ifname[len - 2] == '*')
+			len -= 2;
+		mnl_attr_put(nlh, NFTA_DEVICE_NAME, len, dev_array[i].ifname);
 	}
 
 	mnl_attr_nest_end(nlh, nest_dev);