* [nft PATCH v5 1/3] mnl: Support simple wildcards in netdev hooks
2025-07-31 22:29 [nft PATCH v5 0/3] Support wildcard netdev hooks Phil Sutter
@ 2025-07-31 22:29 ` Phil Sutter
2025-09-04 15:16 ` Pablo Neira Ayuso
2025-07-31 22:29 ` [nft PATCH v5 2/3] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member Phil Sutter
2025-07-31 22:29 ` [nft PATCH v5 3/3] tests: shell: Test ifname-based hooks Phil Sutter
2 siblings, 1 reply; 10+ messages in thread
From: Phil Sutter @ 2025-07-31 22:29 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
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>
---
Changes since v4:
- Introduce and use NFTA_DEVICE_PREFIX which contains a NUL-terminated
string as well but signals the kernel to interpret it as a prefix to
match interfaces on.
- Do not send wildcards in NFTA_HOOK_DEV: On one hand, the kernel can't
detect them anymore since they are NUL-terminated as well. On the
other, it would defeat the purpose of having NFTA_DEVICE_PREFIX, which
is to not crash old user space.
Changes since v3:
- Use uint16_t for 'attr' parameter and size_t for 'len' variable
- Use mnl_nft_ prefix for the helper function
Changes since v2:
- Introduce mnl_attr_put_ifname() to perform the conditional
mnl_attr_put() parameter adjustment
- Sanity-check array index in above function to avoid out-of-bounds
access
---
include/linux/netfilter/nf_tables.h | 2 ++
src/mnl.c | 26 +++++++++++++++++++++++---
2 files changed, 25 insertions(+), 3 deletions(-)
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index f57963e89fd16..b38d4780ae8c8 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -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)
diff --git a/src/mnl.c b/src/mnl.c
index 43229f2498e55..b532b8ff00c1e 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -795,6 +795,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;
@@ -803,14 +823,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);
}
@@ -2091,7 +2111,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);
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [nft PATCH v5 1/3] mnl: Support simple wildcards in netdev hooks
2025-07-31 22:29 ` [nft PATCH v5 1/3] mnl: Support simple wildcards in " Phil Sutter
@ 2025-09-04 15:16 ` Pablo Neira Ayuso
2025-09-04 22:27 ` Phil Sutter
0 siblings, 1 reply; 10+ messages in thread
From: Pablo Neira Ayuso @ 2025-09-04 15:16 UTC (permalink / raw)
To: Phil Sutter; +Cc: netfilter-devel
Hi Phil,
NFTA_DEVICE_PREFIX is now available in net.git, let's pick up on this.
On Fri, Aug 01, 2025 at 12:29:43AM +0200, Phil Sutter wrote:
> 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>
> ---
> Changes since v4:
> - Introduce and use NFTA_DEVICE_PREFIX which contains a NUL-terminated
> string as well but signals the kernel to interpret it as a prefix to
> match interfaces on.
> - Do not send wildcards in NFTA_HOOK_DEV: On one hand, the kernel can't
> detect them anymore since they are NUL-terminated as well. On the
> other, it would defeat the purpose of having NFTA_DEVICE_PREFIX, which
> is to not crash old user space.
>
> Changes since v3:
> - Use uint16_t for 'attr' parameter and size_t for 'len' variable
> - Use mnl_nft_ prefix for the helper function
>
> Changes since v2:
> - Introduce mnl_attr_put_ifname() to perform the conditional
> mnl_attr_put() parameter adjustment
> - Sanity-check array index in above function to avoid out-of-bounds
> access
> ---
> include/linux/netfilter/nf_tables.h | 2 ++
> src/mnl.c | 26 +++++++++++++++++++++++---
> 2 files changed, 25 insertions(+), 3 deletions(-)
>
> diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
> index f57963e89fd16..b38d4780ae8c8 100644
> --- a/include/linux/netfilter/nf_tables.h
> +++ b/include/linux/netfilter/nf_tables.h
> @@ -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)
> diff --git a/src/mnl.c b/src/mnl.c
> index 43229f2498e55..b532b8ff00c1e 100644
> --- a/src/mnl.c
> +++ b/src/mnl.c
> @@ -795,6 +795,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 */
Is this comment here still valid?
> + 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;
> @@ -803,14 +823,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);
> }
> @@ -2091,7 +2111,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);
> --
> 2.49.0
>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [nft PATCH v5 1/3] mnl: Support simple wildcards in netdev hooks
2025-09-04 15:16 ` Pablo Neira Ayuso
@ 2025-09-04 22:27 ` Phil Sutter
2025-09-05 11:20 ` Pablo Neira Ayuso
0 siblings, 1 reply; 10+ messages in thread
From: Phil Sutter @ 2025-09-04 22:27 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
On Thu, Sep 04, 2025 at 05:16:19PM +0200, Pablo Neira Ayuso wrote:
> Hi Phil,
>
> NFTA_DEVICE_PREFIX is now available in net.git, let's pick up on this.
>
> On Fri, Aug 01, 2025 at 12:29:43AM +0200, Phil Sutter wrote:
> > 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>
> > ---
> > Changes since v4:
> > - Introduce and use NFTA_DEVICE_PREFIX which contains a NUL-terminated
> > string as well but signals the kernel to interpret it as a prefix to
> > match interfaces on.
> > - Do not send wildcards in NFTA_HOOK_DEV: On one hand, the kernel can't
> > detect them anymore since they are NUL-terminated as well. On the
> > other, it would defeat the purpose of having NFTA_DEVICE_PREFIX, which
> > is to not crash old user space.
> >
> > Changes since v3:
> > - Use uint16_t for 'attr' parameter and size_t for 'len' variable
> > - Use mnl_nft_ prefix for the helper function
> >
> > Changes since v2:
> > - Introduce mnl_attr_put_ifname() to perform the conditional
> > mnl_attr_put() parameter adjustment
> > - Sanity-check array index in above function to avoid out-of-bounds
> > access
> > ---
> > include/linux/netfilter/nf_tables.h | 2 ++
> > src/mnl.c | 26 +++++++++++++++++++++++---
> > 2 files changed, 25 insertions(+), 3 deletions(-)
> >
> > diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
> > index f57963e89fd16..b38d4780ae8c8 100644
> > --- a/include/linux/netfilter/nf_tables.h
> > +++ b/include/linux/netfilter/nf_tables.h
> > @@ -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)
> > diff --git a/src/mnl.c b/src/mnl.c
> > index 43229f2498e55..b532b8ff00c1e 100644
> > --- a/src/mnl.c
> > +++ b/src/mnl.c
> > @@ -795,6 +795,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 */
>
> Is this comment here still valid?
Yes, sadly. The above covers for eth* and eth\* but not for eth\\* since
a proper solution didn't quickly come to mind which avoids playing
whack-a-mole. (E.g., does eth\\\\\\* escape the wildcard or not?)
Guess I could just count the number of backslashes immediately preceding
the asterisk and return true if the sum is odd?
Cheers, Phil
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [nft PATCH v5 1/3] mnl: Support simple wildcards in netdev hooks
2025-09-04 22:27 ` Phil Sutter
@ 2025-09-05 11:20 ` Pablo Neira Ayuso
2025-09-30 21:06 ` Phil Sutter
0 siblings, 1 reply; 10+ messages in thread
From: Pablo Neira Ayuso @ 2025-09-05 11:20 UTC (permalink / raw)
To: Phil Sutter, netfilter-devel
On Fri, Sep 05, 2025 at 12:27:28AM +0200, Phil Sutter wrote:
> On Thu, Sep 04, 2025 at 05:16:19PM +0200, Pablo Neira Ayuso wrote:
> > Hi Phil,
> >
> > NFTA_DEVICE_PREFIX is now available in net.git, let's pick up on this.
> >
> > On Fri, Aug 01, 2025 at 12:29:43AM +0200, Phil Sutter wrote:
> > > 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>
> > > ---
> > > Changes since v4:
> > > - Introduce and use NFTA_DEVICE_PREFIX which contains a NUL-terminated
> > > string as well but signals the kernel to interpret it as a prefix to
> > > match interfaces on.
> > > - Do not send wildcards in NFTA_HOOK_DEV: On one hand, the kernel can't
> > > detect them anymore since they are NUL-terminated as well. On the
> > > other, it would defeat the purpose of having NFTA_DEVICE_PREFIX, which
> > > is to not crash old user space.
> > >
> > > Changes since v3:
> > > - Use uint16_t for 'attr' parameter and size_t for 'len' variable
> > > - Use mnl_nft_ prefix for the helper function
> > >
> > > Changes since v2:
> > > - Introduce mnl_attr_put_ifname() to perform the conditional
> > > mnl_attr_put() parameter adjustment
> > > - Sanity-check array index in above function to avoid out-of-bounds
> > > access
> > > ---
> > > include/linux/netfilter/nf_tables.h | 2 ++
> > > src/mnl.c | 26 +++++++++++++++++++++++---
> > > 2 files changed, 25 insertions(+), 3 deletions(-)
> > >
> > > diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
> > > index f57963e89fd16..b38d4780ae8c8 100644
> > > --- a/include/linux/netfilter/nf_tables.h
> > > +++ b/include/linux/netfilter/nf_tables.h
> > > @@ -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)
> > > diff --git a/src/mnl.c b/src/mnl.c
> > > index 43229f2498e55..b532b8ff00c1e 100644
> > > --- a/src/mnl.c
> > > +++ b/src/mnl.c
> > > @@ -795,6 +795,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 */
> >
> > Is this comment here still valid?
>
> Yes, sadly. The above covers for eth* and eth\* but not for eth\\* since
> a proper solution didn't quickly come to mind which avoids playing
> whack-a-mole. (E.g., does eth\\\\\\* escape the wildcard or not?)
>
> Guess I could just count the number of backslashes immediately preceding
> the asterisk and return true if the sum is odd?
Thanks for explaining the comment, this supports eth* and eth\* which
is sufficient at this stage.
For this series:
Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [nft PATCH v5 1/3] mnl: Support simple wildcards in netdev hooks
2025-09-05 11:20 ` Pablo Neira Ayuso
@ 2025-09-30 21:06 ` Phil Sutter
0 siblings, 0 replies; 10+ messages in thread
From: Phil Sutter @ 2025-09-30 21:06 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
On Fri, Sep 05, 2025 at 01:20:49PM +0200, Pablo Neira Ayuso wrote:
> On Fri, Sep 05, 2025 at 12:27:28AM +0200, Phil Sutter wrote:
> > On Thu, Sep 04, 2025 at 05:16:19PM +0200, Pablo Neira Ayuso wrote:
> > > Hi Phil,
> > >
> > > NFTA_DEVICE_PREFIX is now available in net.git, let's pick up on this.
> > >
> > > On Fri, Aug 01, 2025 at 12:29:43AM +0200, Phil Sutter wrote:
> > > > 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>
> > > > ---
> > > > Changes since v4:
> > > > - Introduce and use NFTA_DEVICE_PREFIX which contains a NUL-terminated
> > > > string as well but signals the kernel to interpret it as a prefix to
> > > > match interfaces on.
> > > > - Do not send wildcards in NFTA_HOOK_DEV: On one hand, the kernel can't
> > > > detect them anymore since they are NUL-terminated as well. On the
> > > > other, it would defeat the purpose of having NFTA_DEVICE_PREFIX, which
> > > > is to not crash old user space.
> > > >
> > > > Changes since v3:
> > > > - Use uint16_t for 'attr' parameter and size_t for 'len' variable
> > > > - Use mnl_nft_ prefix for the helper function
> > > >
> > > > Changes since v2:
> > > > - Introduce mnl_attr_put_ifname() to perform the conditional
> > > > mnl_attr_put() parameter adjustment
> > > > - Sanity-check array index in above function to avoid out-of-bounds
> > > > access
> > > > ---
> > > > include/linux/netfilter/nf_tables.h | 2 ++
> > > > src/mnl.c | 26 +++++++++++++++++++++++---
> > > > 2 files changed, 25 insertions(+), 3 deletions(-)
> > > >
> > > > diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
> > > > index f57963e89fd16..b38d4780ae8c8 100644
> > > > --- a/include/linux/netfilter/nf_tables.h
> > > > +++ b/include/linux/netfilter/nf_tables.h
> > > > @@ -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)
> > > > diff --git a/src/mnl.c b/src/mnl.c
> > > > index 43229f2498e55..b532b8ff00c1e 100644
> > > > --- a/src/mnl.c
> > > > +++ b/src/mnl.c
> > > > @@ -795,6 +795,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 */
> > >
> > > Is this comment here still valid?
> >
> > Yes, sadly. The above covers for eth* and eth\* but not for eth\\* since
> > a proper solution didn't quickly come to mind which avoids playing
> > whack-a-mole. (E.g., does eth\\\\\\* escape the wildcard or not?)
> >
> > Guess I could just count the number of backslashes immediately preceding
> > the asterisk and return true if the sum is odd?
>
> Thanks for explaining the comment, this supports eth* and eth\* which
> is sufficient at this stage.
>
> For this series:
>
> Reviewed-by: Pablo Neira Ayuso <pablo@netfilter.org>
Series applied, thanks!
^ permalink raw reply [flat|nested] 10+ messages in thread
* [nft PATCH v5 2/3] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member
2025-07-31 22:29 [nft PATCH v5 0/3] Support wildcard netdev hooks Phil Sutter
2025-07-31 22:29 ` [nft PATCH v5 1/3] mnl: Support simple wildcards in " Phil Sutter
@ 2025-07-31 22:29 ` Phil Sutter
2025-09-04 15:20 ` Pablo Neira Ayuso
2025-07-31 22:29 ` [nft PATCH v5 3/3] tests: shell: Test ifname-based hooks Phil Sutter
2 siblings, 1 reply; 10+ messages in thread
From: Phil Sutter @ 2025-07-31 22:29 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
All clauses are identical, so instead of adding a third one for
ASTERISK_STRING, use a single one for 'string' (which combines all three
variants).
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
Changes since v3:
- Cover interface wildcards in nft.8
---
doc/nft.txt | 30 ++++++++++++++++++++++++++----
src/parser_bison.y | 11 +----------
2 files changed, 27 insertions(+), 14 deletions(-)
diff --git a/doc/nft.txt b/doc/nft.txt
index 8712981943d78..42cdd38a27b67 100644
--- a/doc/nft.txt
+++ b/doc/nft.txt
@@ -387,13 +387,19 @@ add table inet mytable
CHAINS
------
[verse]
-{*add* | *create*} *chain* ['family'] 'table' 'chain' [*{ type* 'type' *hook* 'hook' [*device* 'device'] *priority* 'priority' *;* [*policy* 'policy' *;*] [*comment* 'comment' *;*] *}*]
+____
+{*add* | *create*} *chain* ['family'] 'table' 'chain' [*{ type* 'type' *hook* 'hook' ['DEVICE'] *priority* 'priority' *;* [*policy* 'policy' *;*] [*comment* 'comment' *;*] *}*]
{*delete* | *destroy* | *list* | *flush*} *chain* ['family'] 'table' 'chain'
*list chains* ['family']
*delete chain* ['family'] 'table' *handle* 'handle'
*destroy chain* ['family'] 'table' *handle* 'handle'
*rename chain* ['family'] 'table' 'chain' 'newname'
+'DEVICE' := {*device* 'DEVICE_NAME' | *devices = {* 'DEVICE_LIST' *}*}
+'DEVICE_LIST' := 'DEVICE_NAME' [*,* 'DEVICE_LIST']
+'DEVICE_NAME' := 'string' | 'string'***
+____
+
Chains are containers for rules. They exist in two kinds, base chains and
regular chains. A base chain is an entry point for packets from the networking
stack, a regular chain may be used as jump target and is used for better rule
@@ -436,7 +442,7 @@ Apart from the special cases illustrated above (e.g. *nat* type not supporting
* The netdev family supports merely two combinations, namely *filter* type with
*ingress* hook and *filter* type with *egress* hook. Base chains in this
- family also require the *device* parameter to be present since they exist per
+ family also require the 'DEVICE' parameter to be present since they exist per
interface only.
* The arp family supports only the *input* and *output* hooks, both in chains of type
*filter*.
@@ -449,7 +455,13 @@ Apart from the special cases illustrated above (e.g. *nat* type not supporting
The *device* parameter accepts a network interface name as a string, and is
required when adding a base chain that filters traffic on the ingress or
egress hooks. Any ingress or egress chains will only filter traffic from the
-interface specified in the *device* parameter.
+interface specified in the *device* parameter. The same base chain may be used
+for multiple devices by using the *devices* parameter instead.
+
+With newer kernels there is also basic support for wildcards in 'DEVICE_NAME'
+by specifying an asterisk suffix. The chain will apply to all interfaces
+matching the given prefix. Use the *list hooks* command to see the current
+status.
The *priority* parameter accepts a signed integer value or a standard priority
name which specifies the order in which chains with the same *hook* value are
@@ -763,11 +775,16 @@ per element comment field
FLOWTABLES
-----------
[verse]
-{*add* | *create*} *flowtable* ['family'] 'table' 'flowtable' *{ hook* 'hook' *priority* 'priority' *; devices = {* 'device'[*,* ...] *} ; }*
+____
+{*add* | *create*} *flowtable* ['family'] 'table' 'flowtable' *{ hook* 'hook' *priority* 'priority' *; devices = {* 'DEVICE_LIST' *} ; }*
*list flowtables* ['family'] ['table']
{*delete* | *destroy* | *list*} *flowtable* ['family'] 'table' 'flowtable'
*delete* *flowtable* ['family'] 'table' *handle* 'handle'
+'DEVICE_LIST' := 'DEVICE_NAME' [*,* 'DEVICE_LIST']
+'DEVICE_NAME' := 'string' | 'string'***
+____
+
Flowtables allow you to accelerate packet forwarding in software. Flowtables
entries are represented through a tuple that is composed of the input interface,
source and destination address, source and destination port; and layer 3/4
@@ -786,6 +803,11 @@ The *priority* can be a signed integer or *filter* which stands for 0. Addition
and subtraction can be used to set relative priority, e.g. filter + 5 equals to
5.
+With newer kernels there is basic support for wildcards in 'DEVICE_LIST' by
+specifying an asterisk suffix. The flowtable will apply to all interfaces
+matching the given prefix. Use the *list hooks* command to see the current
+status.
+
[horizontal]
*add*:: Add a new flowtable for the given family with the given name.
*delete*:: Delete the specified flowtable.
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 0b1ea699c6102..d665f2fa8c7c1 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -2473,16 +2473,7 @@ flowtable_list_expr : flowtable_expr_member
| flowtable_list_expr COMMA opt_newline
;
-flowtable_expr_member : QUOTED_STRING
- {
- struct expr *expr = ifname_expr_alloc(&@$, state->msgs, $1);
-
- if (!expr)
- YYERROR;
-
- $$ = expr;
- }
- | STRING
+flowtable_expr_member : string
{
struct expr *expr = ifname_expr_alloc(&@$, state->msgs, $1);
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread* Re: [nft PATCH v5 2/3] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member
2025-07-31 22:29 ` [nft PATCH v5 2/3] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member Phil Sutter
@ 2025-09-04 15:20 ` Pablo Neira Ayuso
2025-09-04 22:29 ` Phil Sutter
0 siblings, 1 reply; 10+ messages in thread
From: Pablo Neira Ayuso @ 2025-09-04 15:20 UTC (permalink / raw)
To: Phil Sutter; +Cc: netfilter-devel
Hi Phil,
On Fri, Aug 01, 2025 at 12:29:44AM +0200, Phil Sutter wrote:
> All clauses are identical, so instead of adding a third one for
> ASTERISK_STRING, use a single one for 'string' (which combines all three
> variants).
>
> Signed-off-by: Phil Sutter <phil@nwl.cc>
> ---
> Changes since v3:
> - Cover interface wildcards in nft.8
> ---
> doc/nft.txt | 30 ++++++++++++++++++++++++++----
> src/parser_bison.y | 11 +----------
> 2 files changed, 27 insertions(+), 14 deletions(-)
>
> diff --git a/doc/nft.txt b/doc/nft.txt
> index 8712981943d78..42cdd38a27b67 100644
> --- a/doc/nft.txt
> +++ b/doc/nft.txt
> @@ -387,13 +387,19 @@ add table inet mytable
> CHAINS
> ------
> [verse]
> -{*add* | *create*} *chain* ['family'] 'table' 'chain' [*{ type* 'type' *hook* 'hook' [*device* 'device'] *priority* 'priority' *;* [*policy* 'policy' *;*] [*comment* 'comment' *;*] *}*]
> +____
> +{*add* | *create*} *chain* ['family'] 'table' 'chain' [*{ type* 'type' *hook* 'hook' ['DEVICE'] *priority* 'priority' *;* [*policy* 'policy' *;*] [*comment* 'comment' *;*] *}*]
> {*delete* | *destroy* | *list* | *flush*} *chain* ['family'] 'table' 'chain'
> *list chains* ['family']
> *delete chain* ['family'] 'table' *handle* 'handle'
> *destroy chain* ['family'] 'table' *handle* 'handle'
> *rename chain* ['family'] 'table' 'chain' 'newname'
>
> +'DEVICE' := {*device* 'DEVICE_NAME' | *devices = {* 'DEVICE_LIST' *}*}
> +'DEVICE_LIST' := 'DEVICE_NAME' [*,* 'DEVICE_LIST']
> +'DEVICE_NAME' := 'string' | 'string'***
> +____
> +
> Chains are containers for rules. They exist in two kinds, base chains and
> regular chains. A base chain is an entry point for packets from the networking
> stack, a regular chain may be used as jump target and is used for better rule
> @@ -436,7 +442,7 @@ Apart from the special cases illustrated above (e.g. *nat* type not supporting
>
> * The netdev family supports merely two combinations, namely *filter* type with
> *ingress* hook and *filter* type with *egress* hook. Base chains in this
> - family also require the *device* parameter to be present since they exist per
> + family also require the 'DEVICE' parameter to be present since they exist per
> interface only.
> * The arp family supports only the *input* and *output* hooks, both in chains of type
> *filter*.
> @@ -449,7 +455,13 @@ Apart from the special cases illustrated above (e.g. *nat* type not supporting
> The *device* parameter accepts a network interface name as a string, and is
> required when adding a base chain that filters traffic on the ingress or
> egress hooks. Any ingress or egress chains will only filter traffic from the
> -interface specified in the *device* parameter.
> +interface specified in the *device* parameter. The same base chain may be used
> +for multiple devices by using the *devices* parameter instead.
> +
> +With newer kernels there is also basic support for wildcards in 'DEVICE_NAME'
> +by specifying an asterisk suffix. The chain will apply to all interfaces
> +matching the given prefix. Use the *list hooks* command to see the current
> +status.
Maybe explain here too that newer kernels also allow to pre-register a
match on unexisting devices (specify version), while old kernel fail
with ENOENT?
> The *priority* parameter accepts a signed integer value or a standard priority
> name which specifies the order in which chains with the same *hook* value are
> @@ -763,11 +775,16 @@ per element comment field
> FLOWTABLES
> -----------
> [verse]
> -{*add* | *create*} *flowtable* ['family'] 'table' 'flowtable' *{ hook* 'hook' *priority* 'priority' *; devices = {* 'device'[*,* ...] *} ; }*
> +____
> +{*add* | *create*} *flowtable* ['family'] 'table' 'flowtable' *{ hook* 'hook' *priority* 'priority' *; devices = {* 'DEVICE_LIST' *} ; }*
> *list flowtables* ['family'] ['table']
> {*delete* | *destroy* | *list*} *flowtable* ['family'] 'table' 'flowtable'
> *delete* *flowtable* ['family'] 'table' *handle* 'handle'
>
> +'DEVICE_LIST' := 'DEVICE_NAME' [*,* 'DEVICE_LIST']
> +'DEVICE_NAME' := 'string' | 'string'***
> +____
> +
> Flowtables allow you to accelerate packet forwarding in software. Flowtables
> entries are represented through a tuple that is composed of the input interface,
> source and destination address, source and destination port; and layer 3/4
> @@ -786,6 +803,11 @@ The *priority* can be a signed integer or *filter* which stands for 0. Addition
> and subtraction can be used to set relative priority, e.g. filter + 5 equals to
> 5.
>
> +With newer kernels there is basic support for wildcards in 'DEVICE_LIST' by
> +specifying an asterisk suffix. The flowtable will apply to all interfaces
> +matching the given prefix. Use the *list hooks* command to see the current
> +status.
... to see the
hooks that are that registered per device that match on the wildcard
device.
^ permalink raw reply [flat|nested] 10+ messages in thread* Re: [nft PATCH v5 2/3] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member
2025-09-04 15:20 ` Pablo Neira Ayuso
@ 2025-09-04 22:29 ` Phil Sutter
0 siblings, 0 replies; 10+ messages in thread
From: Phil Sutter @ 2025-09-04 22:29 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
On Thu, Sep 04, 2025 at 05:20:50PM +0200, Pablo Neira Ayuso wrote:
> Hi Phil,
>
> On Fri, Aug 01, 2025 at 12:29:44AM +0200, Phil Sutter wrote:
> > All clauses are identical, so instead of adding a third one for
> > ASTERISK_STRING, use a single one for 'string' (which combines all three
> > variants).
> >
> > Signed-off-by: Phil Sutter <phil@nwl.cc>
> > ---
> > Changes since v3:
> > - Cover interface wildcards in nft.8
> > ---
> > doc/nft.txt | 30 ++++++++++++++++++++++++++----
> > src/parser_bison.y | 11 +----------
> > 2 files changed, 27 insertions(+), 14 deletions(-)
> >
> > diff --git a/doc/nft.txt b/doc/nft.txt
> > index 8712981943d78..42cdd38a27b67 100644
> > --- a/doc/nft.txt
> > +++ b/doc/nft.txt
> > @@ -387,13 +387,19 @@ add table inet mytable
> > CHAINS
> > ------
> > [verse]
> > -{*add* | *create*} *chain* ['family'] 'table' 'chain' [*{ type* 'type' *hook* 'hook' [*device* 'device'] *priority* 'priority' *;* [*policy* 'policy' *;*] [*comment* 'comment' *;*] *}*]
> > +____
> > +{*add* | *create*} *chain* ['family'] 'table' 'chain' [*{ type* 'type' *hook* 'hook' ['DEVICE'] *priority* 'priority' *;* [*policy* 'policy' *;*] [*comment* 'comment' *;*] *}*]
> > {*delete* | *destroy* | *list* | *flush*} *chain* ['family'] 'table' 'chain'
> > *list chains* ['family']
> > *delete chain* ['family'] 'table' *handle* 'handle'
> > *destroy chain* ['family'] 'table' *handle* 'handle'
> > *rename chain* ['family'] 'table' 'chain' 'newname'
> >
> > +'DEVICE' := {*device* 'DEVICE_NAME' | *devices = {* 'DEVICE_LIST' *}*}
> > +'DEVICE_LIST' := 'DEVICE_NAME' [*,* 'DEVICE_LIST']
> > +'DEVICE_NAME' := 'string' | 'string'***
> > +____
> > +
> > Chains are containers for rules. They exist in two kinds, base chains and
> > regular chains. A base chain is an entry point for packets from the networking
> > stack, a regular chain may be used as jump target and is used for better rule
> > @@ -436,7 +442,7 @@ Apart from the special cases illustrated above (e.g. *nat* type not supporting
> >
> > * The netdev family supports merely two combinations, namely *filter* type with
> > *ingress* hook and *filter* type with *egress* hook. Base chains in this
> > - family also require the *device* parameter to be present since they exist per
> > + family also require the 'DEVICE' parameter to be present since they exist per
> > interface only.
> > * The arp family supports only the *input* and *output* hooks, both in chains of type
> > *filter*.
> > @@ -449,7 +455,13 @@ Apart from the special cases illustrated above (e.g. *nat* type not supporting
> > The *device* parameter accepts a network interface name as a string, and is
> > required when adding a base chain that filters traffic on the ingress or
> > egress hooks. Any ingress or egress chains will only filter traffic from the
> > -interface specified in the *device* parameter.
> > +interface specified in the *device* parameter. The same base chain may be used
> > +for multiple devices by using the *devices* parameter instead.
> > +
> > +With newer kernels there is also basic support for wildcards in 'DEVICE_NAME'
> > +by specifying an asterisk suffix. The chain will apply to all interfaces
> > +matching the given prefix. Use the *list hooks* command to see the current
> > +status.
>
> Maybe explain here too that newer kernels also allow to pre-register a
> match on unexisting devices (specify version), while old kernel fail
> with ENOENT?
ACK, will do!
> > The *priority* parameter accepts a signed integer value or a standard priority
> > name which specifies the order in which chains with the same *hook* value are
> > @@ -763,11 +775,16 @@ per element comment field
> > FLOWTABLES
> > -----------
> > [verse]
> > -{*add* | *create*} *flowtable* ['family'] 'table' 'flowtable' *{ hook* 'hook' *priority* 'priority' *; devices = {* 'device'[*,* ...] *} ; }*
> > +____
> > +{*add* | *create*} *flowtable* ['family'] 'table' 'flowtable' *{ hook* 'hook' *priority* 'priority' *; devices = {* 'DEVICE_LIST' *} ; }*
> > *list flowtables* ['family'] ['table']
> > {*delete* | *destroy* | *list*} *flowtable* ['family'] 'table' 'flowtable'
> > *delete* *flowtable* ['family'] 'table' *handle* 'handle'
> >
> > +'DEVICE_LIST' := 'DEVICE_NAME' [*,* 'DEVICE_LIST']
> > +'DEVICE_NAME' := 'string' | 'string'***
> > +____
> > +
> > Flowtables allow you to accelerate packet forwarding in software. Flowtables
> > entries are represented through a tuple that is composed of the input interface,
> > source and destination address, source and destination port; and layer 3/4
> > @@ -786,6 +803,11 @@ The *priority* can be a signed integer or *filter* which stands for 0. Addition
> > and subtraction can be used to set relative priority, e.g. filter + 5 equals to
> > 5.
> >
> > +With newer kernels there is basic support for wildcards in 'DEVICE_LIST' by
> > +specifying an asterisk suffix. The flowtable will apply to all interfaces
> > +matching the given prefix. Use the *list hooks* command to see the current
> > +status.
>
> ... to see the
> hooks that are that registered per device that match on the wildcard
> device.
LGTM!
Thanks, Phil
^ permalink raw reply [flat|nested] 10+ messages in thread
* [nft PATCH v5 3/3] tests: shell: Test ifname-based hooks
2025-07-31 22:29 [nft PATCH v5 0/3] Support wildcard netdev hooks Phil Sutter
2025-07-31 22:29 ` [nft PATCH v5 1/3] mnl: Support simple wildcards in " Phil Sutter
2025-07-31 22:29 ` [nft PATCH v5 2/3] parser_bison: Accept ASTERISK_STRING in flowtable_expr_member Phil Sutter
@ 2025-07-31 22:29 ` Phil Sutter
2 siblings, 0 replies; 10+ messages in thread
From: Phil Sutter @ 2025-07-31 22:29 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel
Assert that:
- Non-matching interface specs are accepted
- Existing interfaces are hooked into upon flowtable/chain creation
- A new device matching the spec is hooked into immediately
- No stale hooks remain in 'nft list hooks' output
- Wildcard hooks basically work
Signed-off-by: Phil Sutter <phil@nwl.cc>
---
.../features/list_hooks_flowtable_info.sh | 7 +++
.../netdev_chain_name_based_hook_0.json-nft | 34 ++++++++++++++
.../dumps/netdev_chain_name_based_hook_0.nft | 5 +++
.../chains/netdev_chain_name_based_hook_0 | 44 ++++++++++++++++++
.../testcases/flowtable/0016name_based_hook_0 | 45 +++++++++++++++++++
.../dumps/0016name_based_hook_0.json-nft | 32 +++++++++++++
.../flowtable/dumps/0016name_based_hook_0.nft | 6 +++
7 files changed, 173 insertions(+)
create mode 100755 tests/shell/features/list_hooks_flowtable_info.sh
create mode 100644 tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft
create mode 100644 tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft
create mode 100755 tests/shell/testcases/chains/netdev_chain_name_based_hook_0
create mode 100755 tests/shell/testcases/flowtable/0016name_based_hook_0
create mode 100644 tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft
create mode 100644 tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft
diff --git a/tests/shell/features/list_hooks_flowtable_info.sh b/tests/shell/features/list_hooks_flowtable_info.sh
new file mode 100755
index 0000000000000..58bc57e040959
--- /dev/null
+++ b/tests/shell/features/list_hooks_flowtable_info.sh
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# check for flowtable info in 'list hooks' output
+
+unshare -n bash -c " \
+$NFT \"table inet t { flowtable ft { hook ingress priority 0; devices = { lo }; }; }\"; \
+$NFT list hooks netdev device lo | grep -q flowtable\ inet\ t\ ft"
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft
new file mode 100644
index 0000000000000..00706271e96a4
--- /dev/null
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.json-nft
@@ -0,0 +1,34 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "VERSION",
+ "release_name": "RELEASE_NAME",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "table": {
+ "family": "netdev",
+ "name": "t",
+ "handle": 0
+ }
+ },
+ {
+ "chain": {
+ "family": "netdev",
+ "table": "t",
+ "name": "c",
+ "handle": 0,
+ "dev": [
+ "foo*",
+ "lo"
+ ],
+ "type": "filter",
+ "hook": "ingress",
+ "prio": 0,
+ "policy": "accept"
+ }
+ }
+ ]
+}
diff --git a/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft
new file mode 100644
index 0000000000000..ac5acacd12e6d
--- /dev/null
+++ b/tests/shell/testcases/chains/dumps/netdev_chain_name_based_hook_0.nft
@@ -0,0 +1,5 @@
+table netdev t {
+ chain c {
+ type filter hook ingress devices = { "foo*", "lo" } priority filter; policy accept;
+ }
+}
diff --git a/tests/shell/testcases/chains/netdev_chain_name_based_hook_0 b/tests/shell/testcases/chains/netdev_chain_name_based_hook_0
new file mode 100755
index 0000000000000..8a8a601784084
--- /dev/null
+++ b/tests/shell/testcases/chains/netdev_chain_name_based_hook_0
@@ -0,0 +1,44 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_ifname_based_hooks)
+
+cspec=' chain netdev t c '
+$NFT add table netdev t
+$NFT add $cspec '{ type filter hook ingress priority 0; devices = { lo, foo* }; }'
+$NFT list hooks netdev device lo | grep -q "$cspec" || {
+ echo "Existing device lo not hooked into chain as expected"
+ exit 1
+}
+
+[[ $($NFT list hooks | grep -c "$cspec") -eq 1 ]] || {
+ echo "Chain hooks into more than just lo"
+ exit 2
+}
+
+ip link add foo1 type dummy
+$NFT list hooks netdev device foo1 | grep -q "$cspec" || {
+ echo "Chain did not hook into new device foo1"
+ exit 3
+}
+[[ $($NFT list hooks | grep -c "$cspec") -eq 2 ]] || {
+ echo "Chain expected to hook into exactly two devices"
+ exit 4
+}
+
+ip link del foo1
+$NFT list hooks netdev device foo1 | grep -q "$cspec" && {
+ echo "Chain still hooks into removed device foo1"
+ exit 5
+}
+[[ $($NFT list hooks | grep -c "$cspec") -eq 1 ]] || {
+ echo "Chain expected to hook into just lo"
+ exit 6
+}
+
+for ((i = 0; i < 100; i++)); do
+ ip link add foo$i type dummy
+done
+[[ $($NFT list hooks | grep -c "$cspec") -eq 101 ]] || {
+ echo "Chain did not hook into all 100 new devices"
+ exit 7
+}
diff --git a/tests/shell/testcases/flowtable/0016name_based_hook_0 b/tests/shell/testcases/flowtable/0016name_based_hook_0
new file mode 100755
index 0000000000000..9a55596027158
--- /dev/null
+++ b/tests/shell/testcases/flowtable/0016name_based_hook_0
@@ -0,0 +1,45 @@
+#!/bin/bash
+
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_ifname_based_hooks)
+# NFT_TEST_REQUIRES(NFT_TEST_HAVE_list_hooks_flowtable_info)
+
+ftspec=' flowtable ip t ft '
+$NFT add table t
+$NFT add $ftspec '{ hook ingress priority 0; devices = { lo, foo* }; }'
+$NFT list hooks netdev device lo | grep -q "$ftspec" || {
+ echo "Existing device lo not hooked into flowtable as expected"
+ exit 1
+}
+
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 1 ]] || {
+ echo "Flowtable hooks into more than just lo"
+ exit 2
+}
+
+ip link add foo1 type dummy
+$NFT list hooks netdev device foo1 | grep -q "$ftspec" || {
+ echo "Flowtable did not hook into new device foo1"
+ exit 3
+}
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 2 ]] || {
+ echo "Flowtable expected to hook into exactly two devices"
+ exit 4
+}
+
+ip link del foo1
+$NFT list hooks netdev device foo1 | grep -q "$ftspec" && {
+ echo "Flowtable still hooks into removed device foo1"
+ exit 5
+}
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 1 ]] || {
+ echo "Flowtable expected to hook into just lo"
+ exit 6
+}
+
+for ((i = 0; i < 100; i++)); do
+ ip link add foo$i type dummy
+done
+[[ $($NFT list hooks | grep -c "$ftspec") -eq 101 ]] || {
+ echo "Flowtable did not hook into all 100 new devices"
+ exit 7
+}
diff --git a/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft
new file mode 100644
index 0000000000000..93e263323ff95
--- /dev/null
+++ b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.json-nft
@@ -0,0 +1,32 @@
+{
+ "nftables": [
+ {
+ "metainfo": {
+ "version": "VERSION",
+ "release_name": "RELEASE_NAME",
+ "json_schema_version": 1
+ }
+ },
+ {
+ "table": {
+ "family": "ip",
+ "name": "t",
+ "handle": 0
+ }
+ },
+ {
+ "flowtable": {
+ "family": "ip",
+ "name": "ft",
+ "table": "t",
+ "handle": 0,
+ "hook": "ingress",
+ "prio": 0,
+ "dev": [
+ "foo*",
+ "lo"
+ ]
+ }
+ }
+ ]
+}
diff --git a/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft
new file mode 100644
index 0000000000000..b4810664a956f
--- /dev/null
+++ b/tests/shell/testcases/flowtable/dumps/0016name_based_hook_0.nft
@@ -0,0 +1,6 @@
+table ip t {
+ flowtable ft {
+ hook ingress priority filter
+ devices = { "foo*", "lo" }
+ }
+}
--
2.49.0
^ permalink raw reply related [flat|nested] 10+ messages in thread