netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [nf-next RFC] netfilter: nf_tables: Feature ifname-based hook registration
@ 2025-07-02 17:47 Phil Sutter
  2025-07-02 22:39 ` Florian Westphal
  0 siblings, 1 reply; 29+ messages in thread
From: Phil Sutter @ 2025-07-02 17:47 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: Florian Westphal, netfilter-devel

Require user space to set a flag upon flowtable or netdev-family chain
creation explicitly relaxing the hook registration when it comes to
non-existent interfaces. For the sake of simplicity, just restore error
condition if a given hook does not find an interface to bind to, leave
everyting else in place. Therefore:

- A wildcard interface spec is accepted as long as at least a single
  interface matches.
- Dynamic unregistering and re-registering of vanishing/re-appearing
  interfaces is still happening.

Note that this flag is persistent, i.e. included in ruleset dumps. This
effectively makes it "updatable": User space may create a "name-based"
flowtable for a non-existent interface, then update the flowtable to
drop the flag. What should happen then? Right now this is simply
accepted, even though the flowtable still does not bind to an interface.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 include/uapi/linux/netfilter/nf_tables.h |  9 +++++++--
 net/netfilter/nf_tables_api.c            | 15 ++++++++++++---
 2 files changed, 19 insertions(+), 5 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 792836149eca..d08c7fbde1d1 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -219,10 +219,12 @@ enum nft_chain_flags {
 	NFT_CHAIN_BASE		= (1 << 0),
 	NFT_CHAIN_HW_OFFLOAD	= (1 << 1),
 	NFT_CHAIN_BINDING	= (1 << 2),
+	NFT_CHAIN_NAME_BASED	= (1 << 3),
 };
 #define NFT_CHAIN_FLAGS		(NFT_CHAIN_BASE		| \
 				 NFT_CHAIN_HW_OFFLOAD	| \
-				 NFT_CHAIN_BINDING)
+				 NFT_CHAIN_BINDING	| \
+				 NFT_CHAIN_NAME_BASED)
 
 /**
  * enum nft_chain_attributes - nf_tables chain netlink attributes
@@ -1699,12 +1701,15 @@ enum nft_object_attributes {
  *
  * @NFT_FLOWTABLE_HW_OFFLOAD: flowtable hardware offload is enabled
  * @NFT_FLOWTABLE_COUNTER: enable flow counters
+ * @NFT_FLOWTABLE_NAME_BASED: relax interface hooks
  */
 enum nft_flowtable_flags {
 	NFT_FLOWTABLE_HW_OFFLOAD	= 0x1,
 	NFT_FLOWTABLE_COUNTER		= 0x2,
+	NFT_FLOWTABLE_NAME_BASED	= 0x4,
 	NFT_FLOWTABLE_MASK		= (NFT_FLOWTABLE_HW_OFFLOAD |
-					   NFT_FLOWTABLE_COUNTER)
+					   NFT_FLOWTABLE_COUNTER |
+					   NFT_FLOWTABLE_NAME_BASED)
 };
 
 /**
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 8fcc6393be38..5ae736715eec 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -2374,7 +2374,8 @@ static struct nft_hook *nft_hook_list_find(struct list_head *hook_list,
 static int nf_tables_parse_netdev_hooks(struct net *net,
 					const struct nlattr *attr,
 					struct list_head *hook_list,
-					struct netlink_ext_ack *extack)
+					struct netlink_ext_ack *extack,
+					bool relaxed)
 {
 	struct nft_hook *hook, *next;
 	const struct nlattr *tmp;
@@ -2392,6 +2393,12 @@ static int nf_tables_parse_netdev_hooks(struct net *net,
 			err = PTR_ERR(hook);
 			goto err_hook;
 		}
+		if (!relaxed && list_empty(&hook->ops_list)) {
+			NL_SET_BAD_ATTR(extack, tmp);
+			nft_netdev_hook_free(hook);
+			err = -ENOENT;
+			goto err_hook;
+		}
 		if (nft_hook_list_find(hook_list, hook)) {
 			NL_SET_BAD_ATTR(extack, tmp);
 			nft_netdev_hook_free(hook);
@@ -2441,7 +2448,8 @@ static int nft_chain_parse_netdev(struct net *net, struct nlattr *tb[],
 		list_add_tail(&hook->list, hook_list);
 	} else if (tb[NFTA_HOOK_DEVS]) {
 		err = nf_tables_parse_netdev_hooks(net, tb[NFTA_HOOK_DEVS],
-						   hook_list, extack);
+						   hook_list, extack,
+						   flags & NFT_CHAIN_NAME_BASED);
 		if (err < 0)
 			return err;
 
@@ -8847,6 +8855,7 @@ static int nft_flowtable_parse_hook(const struct nft_ctx *ctx,
 				    struct nft_flowtable *flowtable,
 				    struct netlink_ext_ack *extack, bool add)
 {
+	bool relaxed = flowtable->data.flags & NFT_FLOWTABLE_NAME_BASED;
 	struct nlattr *tb[NFTA_FLOWTABLE_HOOK_MAX + 1];
 	struct nf_hook_ops *ops;
 	struct nft_hook *hook;
@@ -8897,7 +8906,7 @@ static int nft_flowtable_parse_hook(const struct nft_ctx *ctx,
 		err = nf_tables_parse_netdev_hooks(ctx->net,
 						   tb[NFTA_FLOWTABLE_HOOK_DEVS],
 						   &flowtable_hook->list,
-						   extack);
+						   extack, relaxed);
 		if (err < 0)
 			return err;
 	}
-- 
2.49.0


^ permalink raw reply related	[flat|nested] 29+ messages in thread

end of thread, other threads:[~2025-07-14 14:02 UTC | newest]

Thread overview: 29+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-07-02 17:47 [nf-next RFC] netfilter: nf_tables: Feature ifname-based hook registration Phil Sutter
2025-07-02 22:39 ` Florian Westphal
2025-07-03 10:21   ` Phil Sutter
2025-07-03 11:35     ` Pablo Neira Ayuso
2025-07-03 12:09       ` Florian Westphal
2025-07-03 12:37         ` Phil Sutter
2025-07-03 12:25       ` Phil Sutter
2025-07-03 12:39         ` Florian Westphal
2025-07-03 12:47           ` Phil Sutter
2025-07-03 12:54             ` Florian Westphal
2025-07-03 13:17               ` Phil Sutter
2025-07-03 14:19                 ` Pablo Neira Ayuso
2025-07-03 14:33                   ` Phil Sutter
2025-07-03 21:32                     ` Pablo Neira Ayuso
2025-07-04 12:41                       ` Phil Sutter
2025-07-04 14:04                         ` Florian Westphal
2025-07-04 15:33                           ` Phil Sutter
2025-07-07 19:25                           ` Pablo Neira Ayuso
2025-07-08 14:38                             ` Phil Sutter
2025-07-09 22:43                               ` Pablo Neira Ayuso
2025-07-10 13:55                                 ` Phil Sutter
2025-07-11 12:19                                 ` Phil Sutter
2025-07-11 13:16                                   ` Florian Westphal
2025-07-11 13:43                                     ` Phil Sutter
2025-07-11 13:48                                       ` Florian Westphal
2025-07-11 14:52                                   ` Pablo Neira Ayuso
2025-07-11 16:39                                     ` Phil Sutter
2025-07-14 14:02                                       ` Pablo Neira Ayuso
2025-07-03 11:55     ` Florian Westphal

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).