* [PATCH 1/3 nf-next] netfilter: default CONFIG_NETFILTER_INGRESS to y
2015-05-25 12:46 [PATCH 0/3 nf-next] nf_tables support at ingress Pablo Neira Ayuso
@ 2015-05-25 12:46 ` Pablo Neira Ayuso
2015-05-26 0:44 ` Simon Horman
2015-05-25 12:46 ` [PATCH 2/3 nf-next] netfilter: nf_tables: allow to bind table to net_device Pablo Neira Ayuso
` (3 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-25 12:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, netdev
Useful to compile-test all options.
Suggested-by: by Alexei Stavoroitov <ast@plumgrid.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
net/netfilter/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index db1c674..9a89e7c 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -3,6 +3,7 @@ menu "Core Netfilter Configuration"
config NETFILTER_INGRESS
bool "Netfilter ingress support"
+ default y
select NET_INGRESS
help
This allows you to classify packets from ingress using the Netfilter
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3 nf-next] netfilter: default CONFIG_NETFILTER_INGRESS to y
2015-05-25 12:46 ` [PATCH 1/3 nf-next] netfilter: default CONFIG_NETFILTER_INGRESS to y Pablo Neira Ayuso
@ 2015-05-26 0:44 ` Simon Horman
2015-05-26 9:41 ` Pablo Neira Ayuso
0 siblings, 1 reply; 13+ messages in thread
From: Simon Horman @ 2015-05-26 0:44 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, kaber, netdev
Hi Pablo,
On Mon, May 25, 2015 at 02:46:40PM +0200, Pablo Neira Ayuso wrote:
> Useful to compile-test all options.
>
> Suggested-by: by Alexei Stavoroitov <ast@plumgrid.com>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
There seems to be a stray "by" between ':' and Alexi's name.
> ---
> net/netfilter/Kconfig | 1 +
> 1 file changed, 1 insertion(+)
>
> diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
> index db1c674..9a89e7c 100644
> --- a/net/netfilter/Kconfig
> +++ b/net/netfilter/Kconfig
> @@ -3,6 +3,7 @@ menu "Core Netfilter Configuration"
>
> config NETFILTER_INGRESS
> bool "Netfilter ingress support"
> + default y
> select NET_INGRESS
> help
> This allows you to classify packets from ingress using the Netfilter
> --
> 1.7.10.4
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 1/3 nf-next] netfilter: default CONFIG_NETFILTER_INGRESS to y
2015-05-26 0:44 ` Simon Horman
@ 2015-05-26 9:41 ` Pablo Neira Ayuso
0 siblings, 0 replies; 13+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-26 9:41 UTC (permalink / raw)
To: Simon Horman; +Cc: netfilter-devel, kaber, netdev
On Tue, May 26, 2015 at 09:44:44AM +0900, Simon Horman wrote:
> Hi Pablo,
>
> On Mon, May 25, 2015 at 02:46:40PM +0200, Pablo Neira Ayuso wrote:
> > Useful to compile-test all options.
> >
> > Suggested-by: by Alexei Stavoroitov <ast@plumgrid.com>
> > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
>
> There seems to be a stray "by" between ':' and Alexi's name.
Will fix that nit here, thanks Simon.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 2/3 nf-next] netfilter: nf_tables: allow to bind table to net_device
2015-05-25 12:46 [PATCH 0/3 nf-next] nf_tables support at ingress Pablo Neira Ayuso
2015-05-25 12:46 ` [PATCH 1/3 nf-next] netfilter: default CONFIG_NETFILTER_INGRESS to y Pablo Neira Ayuso
@ 2015-05-25 12:46 ` Pablo Neira Ayuso
2015-05-26 0:48 ` Simon Horman
2015-05-25 12:46 ` [PATCH 3/3 nf-next] netfilter: nf_tables: add netdev table to filter from ingress Pablo Neira Ayuso
` (2 subsequent siblings)
4 siblings, 1 reply; 13+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-25 12:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, netdev
This patch adds the internal NFT_AF_NEEDS_DEV flag to indicate that you must
attach this table to a net_device.
This change is required by the follow up patch that introduces the new netdev
table.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netfilter/nf_tables.h | 8 ++++++
include/uapi/linux/netfilter/nf_tables.h | 2 ++
net/netfilter/nf_tables_api.c | 46 ++++++++++++++++++++++++++----
3 files changed, 51 insertions(+), 5 deletions(-)
diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index e6bcf55..3d6f48c 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -819,6 +819,7 @@ unsigned int nft_do_chain(struct nft_pktinfo *pkt,
* @use: number of chain references to this table
* @flags: table flag (see enum nft_table_flags)
* @name: name of the table
+ * @dev: this table is bound to this device (if any)
*/
struct nft_table {
struct list_head list;
@@ -828,6 +829,11 @@ struct nft_table {
u32 use;
u16 flags;
char name[NFT_TABLE_MAXNAMELEN];
+ struct net_device *dev;
+};
+
+enum nft_af_flags {
+ NFT_AF_NEEDS_DEV = (1 << 0),
};
/**
@@ -838,6 +844,7 @@ struct nft_table {
* @nhooks: number of hooks in this family
* @owner: module owner
* @tables: used internally
+ * @flags: family flags
* @nops: number of hook ops in this family
* @hook_ops_init: initialization function for chain hook ops
* @hooks: hookfn overrides for packet validation
@@ -848,6 +855,7 @@ struct nft_af_info {
unsigned int nhooks;
struct module *owner;
struct list_head tables;
+ u32 flags;
unsigned int nops;
void (*hook_ops_init)(struct nf_hook_ops *,
unsigned int);
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 5fa1cd0..89a671e 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -146,12 +146,14 @@ enum nft_table_flags {
* @NFTA_TABLE_NAME: name of the table (NLA_STRING)
* @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32)
* @NFTA_TABLE_USE: number of chains in this table (NLA_U32)
+ * @NFTA_TABLE_DEV: net device name (NLA_STRING)
*/
enum nft_table_attributes {
NFTA_TABLE_UNSPEC,
NFTA_TABLE_NAME,
NFTA_TABLE_FLAGS,
NFTA_TABLE_USE,
+ NFTA_TABLE_DEV,
__NFTA_TABLE_MAX
};
#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index ad9d11f..2fd4e99 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -399,6 +399,8 @@ static const struct nla_policy nft_table_policy[NFTA_TABLE_MAX + 1] = {
[NFTA_TABLE_NAME] = { .type = NLA_STRING,
.len = NFT_TABLE_MAXNAMELEN - 1 },
[NFTA_TABLE_FLAGS] = { .type = NLA_U32 },
+ [NFTA_TABLE_DEV] = { .type = NLA_STRING,
+ .len = IFNAMSIZ - 1 },
};
static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
@@ -423,6 +425,10 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)))
goto nla_put_failure;
+ if (table->dev &&
+ nla_put_string(skb, NFTA_TABLE_DEV, table->dev->name))
+ goto nla_put_failure;
+
nlmsg_end(skb, nlh);
return 0;
@@ -608,6 +614,11 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
if (flags == ctx->table->flags)
return 0;
+ if ((ctx->afi->flags & NFT_AF_NEEDS_DEV) &&
+ ctx->nla[NFTA_TABLE_DEV] &&
+ nla_strcmp(ctx->nla[NFTA_TABLE_DEV], ctx->table->dev->name))
+ return -EOPNOTSUPP;
+
trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
sizeof(struct nft_trans_table));
if (trans == NULL)
@@ -645,6 +656,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
struct nft_table *table;
struct net *net = sock_net(skb->sk);
int family = nfmsg->nfgen_family;
+ struct net_device *dev = NULL;
u32 flags = 0;
struct nft_ctx ctx;
int err;
@@ -679,30 +691,50 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
return -EINVAL;
}
+ if (afi->flags & NFT_AF_NEEDS_DEV) {
+ char ifname[IFNAMSIZ];
+
+ if (!nla[NFTA_TABLE_DEV])
+ return -EOPNOTSUPP;
+
+ nla_strlcpy(ifname, nla[NFTA_TABLE_DEV], IFNAMSIZ);
+ dev = dev_get_by_name(net, ifname);
+ if (!dev)
+ return -ENOENT;
+ } else if (nla[NFTA_TABLE_DEV]) {
+ return -EOPNOTSUPP;
+ }
+
+ err = -EAFNOSUPPORT;
if (!try_module_get(afi->owner))
- return -EAFNOSUPPORT;
+ goto err1;
err = -ENOMEM;
table = kzalloc(sizeof(*table), GFP_KERNEL);
if (table == NULL)
- goto err1;
+ goto err2;
nla_strlcpy(table->name, name, NFT_TABLE_MAXNAMELEN);
INIT_LIST_HEAD(&table->chains);
INIT_LIST_HEAD(&table->sets);
table->flags = flags;
+ table->dev = dev;
nft_ctx_init(&ctx, skb, nlh, afi, table, NULL, nla);
err = nft_trans_table_add(&ctx, NFT_MSG_NEWTABLE);
if (err < 0)
- goto err2;
+ goto err3;
list_add_tail_rcu(&table->list, &afi->tables);
return 0;
-err2:
+err3:
kfree(table);
-err1:
+err2:
module_put(afi->owner);
+err1:
+ if (dev != NULL)
+ dev_put(dev);
+
return err;
}
@@ -806,6 +838,9 @@ static void nf_tables_table_destroy(struct nft_ctx *ctx)
{
BUG_ON(ctx->table->use > 0);
+ if (ctx->table->dev)
+ dev_put(ctx->table->dev);
+
kfree(ctx->table);
module_put(ctx->afi->owner);
}
@@ -1361,6 +1396,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
ops->priority = priority;
ops->priv = chain;
ops->hook = afi->hooks[ops->hooknum];
+ ops->dev = table->dev;
if (hookfn)
ops->hook = hookfn;
if (afi->hook_ops_init)
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3 nf-next] netfilter: nf_tables: allow to bind table to net_device
2015-05-25 12:46 ` [PATCH 2/3 nf-next] netfilter: nf_tables: allow to bind table to net_device Pablo Neira Ayuso
@ 2015-05-26 0:48 ` Simon Horman
2015-05-26 9:58 ` Pablo Neira Ayuso
0 siblings, 1 reply; 13+ messages in thread
From: Simon Horman @ 2015-05-26 0:48 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, kaber, netdev
Hi Pablo,
On Mon, May 25, 2015 at 02:46:41PM +0200, Pablo Neira Ayuso wrote:
> This patch adds the internal NFT_AF_NEEDS_DEV flag to indicate that you must
> attach this table to a net_device.
>
> This change is required by the follow up patch that introduces the new netdev
> table.
>
> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> ---
> include/net/netfilter/nf_tables.h | 8 ++++++
> include/uapi/linux/netfilter/nf_tables.h | 2 ++
> net/netfilter/nf_tables_api.c | 46 ++++++++++++++++++++++++++----
> 3 files changed, 51 insertions(+), 5 deletions(-)
[snip]
> diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> index 5fa1cd0..89a671e 100644
> --- a/include/uapi/linux/netfilter/nf_tables.h
> +++ b/include/uapi/linux/netfilter/nf_tables.h
[snip]
> @@ -423,6 +425,10 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
> nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)))
> goto nla_put_failure;
>
> + if (table->dev &&
> + nla_put_string(skb, NFTA_TABLE_DEV, table->dev->name))
> + goto nla_put_failure;
> +
> nlmsg_end(skb, nlh);
> return 0;
>
> @@ -608,6 +614,11 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
> if (flags == ctx->table->flags)
> return 0;
>
> + if ((ctx->afi->flags & NFT_AF_NEEDS_DEV) &&
> + ctx->nla[NFTA_TABLE_DEV] &&
> + nla_strcmp(ctx->nla[NFTA_TABLE_DEV], ctx->table->dev->name))
> + return -EOPNOTSUPP;
> +
> trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
> sizeof(struct nft_trans_table));
> if (trans == NULL)
I'm a little unsure of the above logic.
Is it ok for NFT_AF_NEEDS_DEV to be set but ctx->nla[NFTA_TABLE_DEV] to
be absent?
> @@ -645,6 +656,7 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
> struct nft_table *table;
> struct net *net = sock_net(skb->sk);
> int family = nfmsg->nfgen_family;
> + struct net_device *dev = NULL;
> u32 flags = 0;
> struct nft_ctx ctx;
> int err;
> @@ -679,30 +691,50 @@ static int nf_tables_newtable(struct sock *nlsk, struct sk_buff *skb,
> return -EINVAL;
> }
>
> + if (afi->flags & NFT_AF_NEEDS_DEV) {
> + char ifname[IFNAMSIZ];
> +
> + if (!nla[NFTA_TABLE_DEV])
> + return -EOPNOTSUPP;
> +
> + nla_strlcpy(ifname, nla[NFTA_TABLE_DEV], IFNAMSIZ);
> + dev = dev_get_by_name(net, ifname);
> + if (!dev)
> + return -ENOENT;
> + } else if (nla[NFTA_TABLE_DEV]) {
> + return -EOPNOTSUPP;
> + }
> +
> + err = -EAFNOSUPPORT;
> if (!try_module_get(afi->owner))
> - return -EAFNOSUPPORT;
> + goto err1;
>
[snip]
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3 nf-next] netfilter: nf_tables: allow to bind table to net_device
2015-05-26 0:48 ` Simon Horman
@ 2015-05-26 9:58 ` Pablo Neira Ayuso
2015-05-27 1:08 ` Simon Horman
0 siblings, 1 reply; 13+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-26 9:58 UTC (permalink / raw)
To: Simon Horman; +Cc: netfilter-devel, kaber, netdev
On Tue, May 26, 2015 at 09:48:41AM +0900, Simon Horman wrote:
> Hi Pablo,
>
> On Mon, May 25, 2015 at 02:46:41PM +0200, Pablo Neira Ayuso wrote:
> > This patch adds the internal NFT_AF_NEEDS_DEV flag to indicate that you must
> > attach this table to a net_device.
> >
> > This change is required by the follow up patch that introduces the new netdev
> > table.
> >
> > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> > ---
> > include/net/netfilter/nf_tables.h | 8 ++++++
> > include/uapi/linux/netfilter/nf_tables.h | 2 ++
> > net/netfilter/nf_tables_api.c | 46 ++++++++++++++++++++++++++----
> > 3 files changed, 51 insertions(+), 5 deletions(-)
>
> [snip]
>
> > diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> > index 5fa1cd0..89a671e 100644
> > --- a/include/uapi/linux/netfilter/nf_tables.h
> > +++ b/include/uapi/linux/netfilter/nf_tables.h
>
> [snip]
>
> > @@ -423,6 +425,10 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
> > nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)))
> > goto nla_put_failure;
> >
> > + if (table->dev &&
> > + nla_put_string(skb, NFTA_TABLE_DEV, table->dev->name))
> > + goto nla_put_failure;
> > +
> > nlmsg_end(skb, nlh);
> > return 0;
> >
> > @@ -608,6 +614,11 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
> > if (flags == ctx->table->flags)
> > return 0;
> >
> > + if ((ctx->afi->flags & NFT_AF_NEEDS_DEV) &&
> > + ctx->nla[NFTA_TABLE_DEV] &&
> > + nla_strcmp(ctx->nla[NFTA_TABLE_DEV], ctx->table->dev->name))
> > + return -EOPNOTSUPP;
> > +
> > trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
> > sizeof(struct nft_trans_table));
> > if (trans == NULL)
>
> I'm a little unsure of the above logic.
>
> Is it ok for NFT_AF_NEEDS_DEV to be set but ctx->nla[NFTA_TABLE_DEV] to
> be absent?
This path is only run if the table already exists.
So it basically checks if we're trying to update the binding, in that
case we hit -EOPNOTSUPP.
If we don't pass any NFTA_TABLE_DEV, then we assume we stick to the
existing binding.
This allows us to update the table flags without indicating the
binding, eg.
nft add table netdev filter { flags dormant\; }
which basically disables the entire table content.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH 2/3 nf-next] netfilter: nf_tables: allow to bind table to net_device
2015-05-26 9:58 ` Pablo Neira Ayuso
@ 2015-05-27 1:08 ` Simon Horman
0 siblings, 0 replies; 13+ messages in thread
From: Simon Horman @ 2015-05-27 1:08 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, kaber, netdev
On Tue, May 26, 2015 at 11:58:24AM +0200, Pablo Neira Ayuso wrote:
> On Tue, May 26, 2015 at 09:48:41AM +0900, Simon Horman wrote:
> > Hi Pablo,
> >
> > On Mon, May 25, 2015 at 02:46:41PM +0200, Pablo Neira Ayuso wrote:
> > > This patch adds the internal NFT_AF_NEEDS_DEV flag to indicate that you must
> > > attach this table to a net_device.
> > >
> > > This change is required by the follow up patch that introduces the new netdev
> > > table.
> > >
> > > Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
> > > ---
> > > include/net/netfilter/nf_tables.h | 8 ++++++
> > > include/uapi/linux/netfilter/nf_tables.h | 2 ++
> > > net/netfilter/nf_tables_api.c | 46 ++++++++++++++++++++++++++----
> > > 3 files changed, 51 insertions(+), 5 deletions(-)
> >
> > [snip]
> >
> > > diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
> > > index 5fa1cd0..89a671e 100644
> > > --- a/include/uapi/linux/netfilter/nf_tables.h
> > > +++ b/include/uapi/linux/netfilter/nf_tables.h
> >
> > [snip]
> >
> > > @@ -423,6 +425,10 @@ static int nf_tables_fill_table_info(struct sk_buff *skb, struct net *net,
> > > nla_put_be32(skb, NFTA_TABLE_USE, htonl(table->use)))
> > > goto nla_put_failure;
> > >
> > > + if (table->dev &&
> > > + nla_put_string(skb, NFTA_TABLE_DEV, table->dev->name))
> > > + goto nla_put_failure;
> > > +
> > > nlmsg_end(skb, nlh);
> > > return 0;
> > >
> > > @@ -608,6 +614,11 @@ static int nf_tables_updtable(struct nft_ctx *ctx)
> > > if (flags == ctx->table->flags)
> > > return 0;
> > >
> > > + if ((ctx->afi->flags & NFT_AF_NEEDS_DEV) &&
> > > + ctx->nla[NFTA_TABLE_DEV] &&
> > > + nla_strcmp(ctx->nla[NFTA_TABLE_DEV], ctx->table->dev->name))
> > > + return -EOPNOTSUPP;
> > > +
> > > trans = nft_trans_alloc(ctx, NFT_MSG_NEWTABLE,
> > > sizeof(struct nft_trans_table));
> > > if (trans == NULL)
> >
> > I'm a little unsure of the above logic.
> >
> > Is it ok for NFT_AF_NEEDS_DEV to be set but ctx->nla[NFTA_TABLE_DEV] to
> > be absent?
>
> This path is only run if the table already exists.
>
> So it basically checks if we're trying to update the binding, in that
> case we hit -EOPNOTSUPP.
>
> If we don't pass any NFTA_TABLE_DEV, then we assume we stick to the
> existing binding.
>
> This allows us to update the table flags without indicating the
> binding, eg.
>
> nft add table netdev filter { flags dormant\; }
>
> which basically disables the entire table content.
Thanks Pablo, that is clear to me now.
I have no objections.
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PATCH 3/3 nf-next] netfilter: nf_tables: add netdev table to filter from ingress
2015-05-25 12:46 [PATCH 0/3 nf-next] nf_tables support at ingress Pablo Neira Ayuso
2015-05-25 12:46 ` [PATCH 1/3 nf-next] netfilter: default CONFIG_NETFILTER_INGRESS to y Pablo Neira Ayuso
2015-05-25 12:46 ` [PATCH 2/3 nf-next] netfilter: nf_tables: allow to bind table to net_device Pablo Neira Ayuso
@ 2015-05-25 12:46 ` Pablo Neira Ayuso
2015-05-25 12:46 ` [PATCH libnftnl] table: add netdev family support Pablo Neira Ayuso
2015-05-25 12:46 ` [PATCH nft] src: " Pablo Neira Ayuso
4 siblings, 0 replies; 13+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-25 12:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, netdev
This allows us to create netdev tables that contain ingress chains. Use
skb_header_pointer() as we may see shared sk_buffs at this stage.
This change provides access to the existing nf_tables features from the ingress
hook.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/net/netns/nftables.h | 1 +
net/netfilter/Kconfig | 5 ++
net/netfilter/Makefile | 1 +
net/netfilter/nf_tables_netdev.c | 183 ++++++++++++++++++++++++++++++++++++++
4 files changed, 190 insertions(+)
create mode 100644 net/netfilter/nf_tables_netdev.c
diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h
index eee608b..c807811 100644
--- a/include/net/netns/nftables.h
+++ b/include/net/netns/nftables.h
@@ -13,6 +13,7 @@ struct netns_nftables {
struct nft_af_info *inet;
struct nft_af_info *arp;
struct nft_af_info *bridge;
+ struct nft_af_info *netdev;
unsigned int base_seq;
u8 gencursor;
};
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index 9a89e7c..bd5aaeb 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -456,6 +456,11 @@ config NF_TABLES_INET
help
This option enables support for a mixed IPv4/IPv6 "inet" table.
+config NF_TABLES_NETDEV
+ tristate "Netfilter nf_tables netdev tables support"
+ help
+ This option enables support for the "netdev" table.
+
config NFT_EXTHDR
tristate "Netfilter nf_tables IPv6 exthdr module"
help
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index a87d8b8..70d026d 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -75,6 +75,7 @@ nf_tables-objs += nft_bitwise.o nft_byteorder.o nft_payload.o
obj-$(CONFIG_NF_TABLES) += nf_tables.o
obj-$(CONFIG_NF_TABLES_INET) += nf_tables_inet.o
+obj-$(CONFIG_NF_TABLES_NETDEV) += nf_tables_netdev.o
obj-$(CONFIG_NFT_COMPAT) += nft_compat.o
obj-$(CONFIG_NFT_EXTHDR) += nft_exthdr.o
obj-$(CONFIG_NFT_META) += nft_meta.o
diff --git a/net/netfilter/nf_tables_netdev.c b/net/netfilter/nf_tables_netdev.c
new file mode 100644
index 0000000..04cb170
--- /dev/null
+++ b/net/netfilter/nf_tables_netdev.c
@@ -0,0 +1,183 @@
+/*
+ * Copyright (c) 2015 Pablo Neira Ayuso <pablo@netfilter.org>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <net/netfilter/nf_tables.h>
+#include <linux/ip.h>
+#include <linux/ipv6.h>
+#include <net/netfilter/nf_tables_ipv4.h>
+#include <net/netfilter/nf_tables_ipv6.h>
+
+static inline void
+nft_netdev_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
+ const struct nf_hook_ops *ops, struct sk_buff *skb,
+ const struct nf_hook_state *state)
+{
+ struct iphdr *iph, _iph;
+ u32 len, thoff;
+
+ nft_set_pktinfo(pkt, ops, skb, state);
+
+ iph = skb_header_pointer(skb, skb_network_offset(skb), sizeof(*iph),
+ &_iph);
+ if (!iph)
+ return;
+
+ iph = ip_hdr(skb);
+ if (iph->ihl < 5 || iph->version != 4)
+ return;
+
+ len = ntohs(iph->tot_len);
+ thoff = iph->ihl * 4;
+ if (skb->len < len)
+ return;
+ else if (len < thoff)
+ return;
+
+ pkt->tprot = iph->protocol;
+ pkt->xt.thoff = thoff;
+ pkt->xt.fragoff = ntohs(iph->frag_off) & IP_OFFSET;
+}
+
+static inline void
+__nft_netdev_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
+ const struct nf_hook_ops *ops,
+ struct sk_buff *skb,
+ const struct nf_hook_state *state)
+{
+#if IS_ENABLED(CONFIG_IPV6)
+ struct ipv6hdr *ip6h, _ip6h;
+ unsigned int thoff = 0;
+ unsigned short frag_off;
+ int protohdr;
+ u32 pkt_len;
+
+ ip6h = skb_header_pointer(skb, skb_network_offset(skb), sizeof(*ip6h),
+ &_ip6h);
+ if (!ip6h)
+ return;
+
+ if (ip6h->version != 6)
+ return;
+
+ pkt_len = ntohs(ip6h->payload_len);
+ if (pkt_len + sizeof(*ip6h) > skb->len)
+ return;
+
+ protohdr = ipv6_find_hdr(pkt->skb, &thoff, -1, &frag_off, NULL);
+ if (protohdr < 0)
+ return;
+
+ pkt->tprot = protohdr;
+ pkt->xt.thoff = thoff;
+ pkt->xt.fragoff = frag_off;
+#endif
+}
+
+static inline void nft_netdev_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
+ const struct nf_hook_ops *ops,
+ struct sk_buff *skb,
+ const struct nf_hook_state *state)
+{
+ nft_set_pktinfo(pkt, ops, skb, state);
+ __nft_netdev_set_pktinfo_ipv6(pkt, ops, skb, state);
+}
+
+static unsigned int
+nft_do_chain_netdev(const struct nf_hook_ops *ops, struct sk_buff *skb,
+ const struct nf_hook_state *state)
+{
+ struct nft_pktinfo pkt;
+
+ switch (eth_hdr(skb)->h_proto) {
+ case htons(ETH_P_IP):
+ nft_netdev_set_pktinfo_ipv4(&pkt, ops, skb, state);
+ break;
+ case htons(ETH_P_IPV6):
+ nft_netdev_set_pktinfo_ipv6(&pkt, ops, skb, state);
+ break;
+ default:
+ nft_set_pktinfo(&pkt, ops, skb, state);
+ break;
+ }
+
+ return nft_do_chain(&pkt, ops);
+}
+
+static struct nft_af_info nft_af_netdev __read_mostly = {
+ .family = NFPROTO_NETDEV,
+ .nhooks = NF_NETDEV_NUMHOOKS,
+ .owner = THIS_MODULE,
+ .flags = NFT_AF_NEEDS_DEV,
+ .nops = 1,
+ .hooks = {
+ [NF_NETDEV_INGRESS] = nft_do_chain_netdev,
+ },
+};
+
+static int nf_tables_netdev_init_net(struct net *net)
+{
+ net->nft.netdev = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
+ if (net->nft.netdev == NULL)
+ return -ENOMEM;
+
+ memcpy(net->nft.netdev, &nft_af_netdev, sizeof(nft_af_netdev));
+
+ if (nft_register_afinfo(net, net->nft.netdev) < 0)
+ goto err;
+
+ return 0;
+err:
+ kfree(net->nft.netdev);
+ return -ENOMEM;
+}
+
+static void nf_tables_netdev_exit_net(struct net *net)
+{
+ nft_unregister_afinfo(net->nft.netdev);
+ kfree(net->nft.netdev);
+}
+
+static struct pernet_operations nf_tables_netdev_net_ops = {
+ .init = nf_tables_netdev_init_net,
+ .exit = nf_tables_netdev_exit_net,
+};
+
+static const struct nf_chain_type nft_filter_chain_netdev = {
+ .name = "filter",
+ .type = NFT_CHAIN_T_DEFAULT,
+ .family = NFPROTO_NETDEV,
+ .owner = THIS_MODULE,
+ .hook_mask = (1 << NF_NETDEV_INGRESS),
+};
+
+static int __init nf_tables_netdev_init(void)
+{
+ int ret;
+
+ nft_register_chain_type(&nft_filter_chain_netdev);
+ ret = register_pernet_subsys(&nf_tables_netdev_net_ops);
+ if (ret < 0)
+ nft_unregister_chain_type(&nft_filter_chain_netdev);
+
+ return ret;
+}
+
+static void __exit nf_tables_netdev_exit(void)
+{
+ unregister_pernet_subsys(&nf_tables_netdev_net_ops);
+ nft_unregister_chain_type(&nft_filter_chain_netdev);
+}
+
+module_init(nf_tables_netdev_init);
+module_exit(nf_tables_netdev_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Pablo Neira Ayuso <pablo@netfilter.org>");
+MODULE_ALIAS_NFT_FAMILY(5); /* NFPROTO_NETDEV */
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH libnftnl] table: add netdev family support
2015-05-25 12:46 [PATCH 0/3 nf-next] nf_tables support at ingress Pablo Neira Ayuso
` (2 preceding siblings ...)
2015-05-25 12:46 ` [PATCH 3/3 nf-next] netfilter: nf_tables: add netdev table to filter from ingress Pablo Neira Ayuso
@ 2015-05-25 12:46 ` Pablo Neira Ayuso
2015-05-25 12:46 ` [PATCH nft] src: " Pablo Neira Ayuso
4 siblings, 0 replies; 13+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-25 12:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, netdev
This adds support for the new 'netdev' family tables.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
include/buffer.h | 1 +
include/libnftnl/table.h | 1 +
include/linux/netfilter.h | 8 ++++++++
include/linux/netfilter/nf_tables.h | 2 ++
src/chain.c | 6 ++++++
src/table.c | 37 +++++++++++++++++++++++++++++++++--
6 files changed, 53 insertions(+), 2 deletions(-)
diff --git a/include/buffer.h b/include/buffer.h
index 52942ed..38b6136 100644
--- a/include/buffer.h
+++ b/include/buffer.h
@@ -41,6 +41,7 @@ int nft_buf_reg(struct nft_buf *b, int type, union nft_data_reg *reg,
#define CHAIN "chain"
#define CODE "code"
#define DATA "data"
+#define DEVICE "device"
#define DIR "dir"
#define DREG "dreg"
#define EXTHDR_TYPE "exthdr_type"
diff --git a/include/libnftnl/table.h b/include/libnftnl/table.h
index fac79e7..16df5fa 100644
--- a/include/libnftnl/table.h
+++ b/include/libnftnl/table.h
@@ -22,6 +22,7 @@ enum {
NFT_TABLE_ATTR_FAMILY,
NFT_TABLE_ATTR_FLAGS,
NFT_TABLE_ATTR_USE,
+ NFT_TABLE_ATTR_DEV,
__NFT_TABLE_ATTR_MAX
};
#define NFT_TABLE_ATTR_MAX (__NFT_TABLE_ATTR_MAX - 1)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index be0bc18..18075f9 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -32,6 +32,7 @@
#define NF_DROP_ERR(x) (((-x) << 16) | NF_DROP)
/* only for userspace compatibility */
+#ifndef __KERNEL__
/* Generic cache responses from hook functions.
<= 0x2000 is used for protocol-flags. */
#define NFC_UNKNOWN 0x4000
@@ -39,6 +40,7 @@
/* NF_VERDICT_BITS should be 8 now, but userspace might break if this changes */
#define NF_VERDICT_BITS 16
+#endif
enum nf_inet_hooks {
NF_INET_PRE_ROUTING,
@@ -49,11 +51,17 @@ enum nf_inet_hooks {
NF_INET_NUMHOOKS
};
+enum nf_dev_hooks {
+ NF_NETDEV_INGRESS,
+ NF_NETDEV_NUMHOOKS
+};
+
enum {
NFPROTO_UNSPEC = 0,
NFPROTO_INET = 1,
NFPROTO_IPV4 = 2,
NFPROTO_ARP = 3,
+ NFPROTO_NETDEV = 5,
NFPROTO_BRIDGE = 7,
NFPROTO_IPV6 = 10,
NFPROTO_DECNET = 12,
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 5fa1cd0..89a671e 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -146,12 +146,14 @@ enum nft_table_flags {
* @NFTA_TABLE_NAME: name of the table (NLA_STRING)
* @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32)
* @NFTA_TABLE_USE: number of chains in this table (NLA_U32)
+ * @NFTA_TABLE_DEV: net device name (NLA_STRING)
*/
enum nft_table_attributes {
NFTA_TABLE_UNSPEC,
NFTA_TABLE_NAME,
NFTA_TABLE_FLAGS,
NFTA_TABLE_USE,
+ NFTA_TABLE_DEV,
__NFTA_TABLE_MAX
};
#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
diff --git a/src/chain.c b/src/chain.c
index 84851e0..74e5925 100644
--- a/src/chain.c
+++ b/src/chain.c
@@ -76,6 +76,12 @@ static const char *nft_hooknum2str(int family, int hooknum)
return "forward";
}
break;
+ case NFPROTO_NETDEV:
+ switch (hooknum) {
+ case NF_NETDEV_INGRESS:
+ return "ingress";
+ }
+ break;
}
return "unknown";
}
diff --git a/src/table.c b/src/table.c
index ab0a8ea..f748d6d 100644
--- a/src/table.c
+++ b/src/table.c
@@ -32,6 +32,7 @@ struct nft_table {
const char *name;
uint32_t family;
uint32_t table_flags;
+ const char *dev;
uint32_t use;
uint32_t flags;
};
@@ -74,6 +75,12 @@ void nft_table_attr_unset(struct nft_table *t, uint16_t attr)
break;
case NFT_TABLE_ATTR_USE:
break;
+ case NFT_TABLE_ATTR_DEV:
+ if (t->dev) {
+ xfree(t->dev);
+ t->dev = NULL;
+ }
+ break;
}
t->flags &= ~(1 << attr);
}
@@ -108,6 +115,12 @@ void nft_table_attr_set_data(struct nft_table *t, uint16_t attr,
case NFT_TABLE_ATTR_USE:
t->use = *((uint32_t *)data);
break;
+ case NFT_TABLE_ATTR_DEV:
+ if (t->dev)
+ xfree(t->dev);
+
+ t->dev = strdup(data);
+ break;
}
t->flags |= (1 << attr);
}
@@ -155,6 +168,8 @@ const void *nft_table_attr_get_data(struct nft_table *t, uint16_t attr,
case NFT_TABLE_ATTR_USE:
*data_len = sizeof(uint32_t);
return &t->use;
+ case NFT_TABLE_ATTR_DEV:
+ return t->dev;
}
return NULL;
}
@@ -193,6 +208,8 @@ void nft_table_nlmsg_build_payload(struct nlmsghdr *nlh, const struct nft_table
mnl_attr_put_strz(nlh, NFTA_TABLE_NAME, t->name);
if (t->flags & (1 << NFT_TABLE_ATTR_FLAGS))
mnl_attr_put_u32(nlh, NFTA_TABLE_FLAGS, htonl(t->table_flags));
+ if (t->flags & (1 << NFT_TABLE_ATTR_DEV))
+ mnl_attr_put_str(nlh, NFTA_TABLE_DEV, t->dev);
}
EXPORT_SYMBOL(nft_table_nlmsg_build_payload);
@@ -206,6 +223,7 @@ static int nft_table_parse_attr_cb(const struct nlattr *attr, void *data)
switch(type) {
case NFTA_TABLE_NAME:
+ case NFTA_TABLE_DEV:
if (mnl_attr_validate(attr, MNL_TYPE_STRING) < 0)
abi_breakage();
break;
@@ -240,6 +258,10 @@ int nft_table_nlmsg_parse(const struct nlmsghdr *nlh, struct nft_table *t)
t->use = ntohl(mnl_attr_get_u32(tb[NFTA_TABLE_USE]));
t->flags |= (1 << NFT_TABLE_ATTR_USE);
}
+ if (tb[NFTA_TABLE_DEV]) {
+ t->dev = strdup(mnl_attr_get_str(tb[NFTA_TABLE_DEV]));
+ t->flags |= (1 << NFT_TABLE_ATTR_DEV);
+ }
t->family = nfg->nfgen_family;
t->flags |= (1 << NFT_TABLE_ATTR_FAMILY);
@@ -252,7 +274,7 @@ EXPORT_SYMBOL(nft_table_nlmsg_parse);
int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t,
struct nft_parse_err *err)
{
- const char *name;
+ const char *name, *dev;
int family;
uint32_t flags, use;
@@ -270,6 +292,11 @@ int nft_mxml_table_parse(mxml_node_t *tree, struct nft_table *t,
&flags, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, flags);
+ dev = nft_mxml_str_parse(tree, "device", MXML_DESCEND_FIRST,
+ NFT_XML_MAND, err);
+ if (dev != NULL)
+ nft_table_attr_set_str(t, NFT_TABLE_ATTR_DEV, dev);
+
if (nft_mxml_num_parse(tree, "use", MXML_DESCEND, BASE_DEC,
&use, NFT_TYPE_U32, NFT_XML_MAND, err) == 0)
nft_table_attr_set_u32(t, NFT_TABLE_ATTR_USE, use);
@@ -303,7 +330,7 @@ int nft_jansson_parse_table(struct nft_table *t, json_t *tree,
{
json_t *root;
uint32_t flags, use;
- const char *str;
+ const char *str, *dev;
int family;
root = nft_jansson_get_node(tree, "table", err);
@@ -321,6 +348,10 @@ int nft_jansson_parse_table(struct nft_table *t, json_t *tree,
err) == 0)
nft_table_attr_set_u32(t, NFT_TABLE_ATTR_FLAGS, flags);
+ dev = nft_jansson_parse_str(root, "device", err);
+ if (dev != NULL)
+ nft_table_attr_set_str(t, NFT_TABLE_ATTR_DEV, dev);
+
if (nft_jansson_parse_val(root, "use", NFT_TYPE_U32, &use, err) == 0)
nft_table_attr_set_u32(t, NFT_TABLE_ATTR_USE, use);
@@ -404,6 +435,8 @@ static int nft_table_export(char *buf, size_t size, struct nft_table *t,
nft_buf_str(&b, type, nft_family2str(t->family), FAMILY);
if (t->flags & (1 << NFT_TABLE_ATTR_FLAGS))
nft_buf_u32(&b, type, t->table_flags, FLAGS);
+ if (t->flags & (1 << NFT_TABLE_ATTR_DEV))
+ nft_buf_str(&b, type, t->dev, DEVICE);
if (t->flags & (1 << NFT_TABLE_ATTR_USE))
nft_buf_u32(&b, type, t->use, USE);
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PATCH nft] src: add netdev family support
2015-05-25 12:46 [PATCH 0/3 nf-next] nf_tables support at ingress Pablo Neira Ayuso
` (3 preceding siblings ...)
2015-05-25 12:46 ` [PATCH libnftnl] table: add netdev family support Pablo Neira Ayuso
@ 2015-05-25 12:46 ` Pablo Neira Ayuso
2015-05-26 16:52 ` Patrick McHardy
4 siblings, 1 reply; 13+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-25 12:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, netdev
This patch adds support for the new 'netdev' table. So far, this table allows
you to create filter chains from ingress.
The following example shows a very simple base configuration with one table that
is bound to device 'eth0' with a single ingress chain:
# nft list table netdev eth0
table netdev eth0 {
device eth0;
chain ingress {
type filter hook ingress priority 0; policy accept;
}
}
The selected table name is 'eth0' but you could have selected any name.
You can test that this works by adding a simple rule with counters:
# nft add rule netdev eth0 ingress counter
or a bit more elaborated test like:
http://people.netfilter.org/pablo/nft-ingress.ruleset
More information will be available at the nftables documentation site [1].
[1] http://wiki.nftables.org/
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
doc/nft.xml | 41 +++++++++++++++++++++++++++++++++++++++++
include/linux/netfilter.h | 8 ++++++++
include/rule.h | 2 ++
src/evaluate.c | 4 ++++
src/netlink.c | 11 +++++++++--
src/parser_bison.y | 7 +++++++
src/payload.c | 1 +
src/proto.c | 1 +
src/rule.c | 23 +++++++++++++++++++++++
src/scanner.l | 2 ++
10 files changed, 98 insertions(+), 2 deletions(-)
diff --git a/doc/nft.xml b/doc/nft.xml
index 8d79016..1172c43 100644
--- a/doc/nft.xml
+++ b/doc/nft.xml
@@ -267,6 +267,14 @@ filter input iif $int_ifs accept
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term><option>netdev</option></term>
+ <listitem>
+ <para>
+ Netdev address family, handling packets from ingress.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
</para>
<para>
@@ -373,6 +381,38 @@ filter input iif $int_ifs accept
The bridge address family handles ethernet packets traversing bridge devices.
</para>
</refsect2>
+ <refsect2>
+ <title>Netdev address family</title>
+ <para>
+ The Netdev address family handles packets from ingress.
+ </para>
+ <para>
+ <table frame="all">
+ <title>Netdev address family hooks</title>
+ <tgroup cols='2' align='left' colsep='1' rowsep='1' pgwide="1">
+ <colspec colname='c1' colwidth="1*"/>
+ <colspec colname='c2' colwidth="5*"/>
+ <thead>
+ <row>
+ <entry>Hook</entry>
+ <entry>Description</entry>
+ </row>
+ </thead>
+ <tbody>
+ <row>
+ <entry>ingress</entry>
+ <entry>
+ All packets entering the system are processed by this hook. It is invoked
+ before layer 3 protocol handlers and it can be used for early filtering and
+ policing.
+ </entry>
+ </row>
+ </tbody>
+ </tgroup>
+ </table>
+ </para>
+ </refsect2>
+
</refsect1>
<refsect1>
@@ -401,6 +441,7 @@ filter input iif $int_ifs accept
<member><literal>inet</literal></member>
<member><literal>arp</literal></member>
<member><literal>bridge</literal></member>
+ <member><literal>netdev</literal></member>
</simplelist>.
The <literal>inet</literal> address family is a dummy family which is used to create
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index be0bc18..18075f9 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -32,6 +32,7 @@
#define NF_DROP_ERR(x) (((-x) << 16) | NF_DROP)
/* only for userspace compatibility */
+#ifndef __KERNEL__
/* Generic cache responses from hook functions.
<= 0x2000 is used for protocol-flags. */
#define NFC_UNKNOWN 0x4000
@@ -39,6 +40,7 @@
/* NF_VERDICT_BITS should be 8 now, but userspace might break if this changes */
#define NF_VERDICT_BITS 16
+#endif
enum nf_inet_hooks {
NF_INET_PRE_ROUTING,
@@ -49,11 +51,17 @@ enum nf_inet_hooks {
NF_INET_NUMHOOKS
};
+enum nf_dev_hooks {
+ NF_NETDEV_INGRESS,
+ NF_NETDEV_NUMHOOKS
+};
+
enum {
NFPROTO_UNSPEC = 0,
NFPROTO_INET = 1,
NFPROTO_IPV4 = 2,
NFPROTO_ARP = 3,
+ NFPROTO_NETDEV = 5,
NFPROTO_BRIDGE = 7,
NFPROTO_IPV6 = 10,
NFPROTO_DECNET = 12,
diff --git a/include/rule.h b/include/rule.h
index 97959f7..06ec2ff 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -72,6 +72,7 @@ enum table_flags {
*
* @list: list node
* @handle: table handle
+ * @dev: network device name (only for netdev family)
* @location: location the table was defined at
* @chains: chains contained in the table
* @sets: sets contained in the table
@@ -80,6 +81,7 @@ enum table_flags {
struct table {
struct list_head list;
struct handle handle;
+ const char *dev;
struct location location;
struct scope scope;
struct list_head chains;
diff --git a/src/evaluate.c b/src/evaluate.c
index 7ecb793..a0344de 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1795,6 +1795,10 @@ static uint32_t str2hooknum(uint32_t family, const char *hook)
else if (!strcmp(hook, "output"))
return NF_ARP_OUT;
break;
+ case NFPROTO_NETDEV:
+ if (!strcmp(hook, "ingress"))
+ return NF_NETDEV_INGRESS;
+ break;
default:
break;
}
diff --git a/src/netlink.c b/src/netlink.c
index 343d8be..bb1cd7d 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -816,10 +816,14 @@ static int netlink_add_table_batch(struct netlink_ctx *ctx,
int err;
nlt = alloc_nft_table(h);
- if (table != NULL)
+ if (table != NULL) {
nft_table_attr_set_u32(nlt, NFT_TABLE_ATTR_FLAGS, table->flags);
- else
+ if (table->dev != NULL)
+ nft_table_attr_set_str(nlt, NFT_TABLE_ATTR_DEV,
+ table->dev);
+ } else {
nft_table_attr_set_u32(nlt, NFT_TABLE_ATTR_FLAGS, 0);
+ }
err = mnl_nft_table_batch_add(nlt, excl ? NLM_F_EXCL : 0,
ctx->seqnum);
@@ -910,6 +914,8 @@ static struct table *netlink_delinearize_table(struct netlink_ctx *ctx,
xstrdup(nft_table_attr_get_str(nlt, NFT_TABLE_ATTR_NAME));
table->flags =
nft_table_attr_get_u32(nlt, NFT_TABLE_ATTR_FLAGS);
+ if (nft_table_attr_is_set(nlt, NFT_TABLE_ATTR_DEV))
+ table->dev = xstrdup(nft_table_attr_get_str(nlt, NFT_TABLE_ATTR_DEV));
return table;
}
@@ -963,6 +969,7 @@ int netlink_get_table(struct netlink_ctx *ctx, const struct handle *h,
ntable = netlink_delinearize_table(ctx, nlt);
table->flags = ntable->flags;
+ table->dev = ntable->dev;
xfree(ntable);
out:
nft_table_free(nlt);
diff --git a/src/parser_bison.y b/src/parser_bison.y
index b86381d..18034ce 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -165,6 +165,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token DEFINE "define"
%token HOOK "hook"
+%token DEVICE "device"
%token TABLE "table"
%token TABLES "tables"
%token CHAIN "chain"
@@ -179,6 +180,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token RULESET "ruleset"
%token INET "inet"
+%token NETDEV "netdev"
%token ADD "add"
%token CREATE "create"
@@ -863,6 +865,10 @@ table_options : FLAGS STRING
YYERROR;
}
}
+ | DEVICE string
+ {
+ $<table>0->dev = $2;
+ }
;
table_block : /* empty */ { $$ = $<table>-1; }
@@ -1102,6 +1108,7 @@ family_spec_explicit : IP { $$ = NFPROTO_IPV4; }
| INET { $$ = NFPROTO_INET; }
| ARP { $$ = NFPROTO_ARP; }
| BRIDGE { $$ = NFPROTO_BRIDGE; }
+ | NETDEV { $$ = NFPROTO_NETDEV; }
;
table_spec : family_spec identifier
diff --git a/src/payload.c b/src/payload.c
index 08578fd..1a9d491 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -215,6 +215,7 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
}
break;
case NFPROTO_BRIDGE:
+ case NFPROTO_NETDEV:
switch (expr->payload.base) {
case PROTO_BASE_LL_HDR:
desc = &proto_eth;
diff --git a/src/proto.c b/src/proto.c
index 7dc7b3e..dc671bd 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -123,6 +123,7 @@ const struct proto_desc *proto_dev_desc(uint16_t type)
const struct hook_proto_desc hook_proto_desc[] = {
[NFPROTO_BRIDGE] = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR, &proto_eth),
+ [NFPROTO_NETDEV] = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR, &proto_eth),
[NFPROTO_INET] = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR, &proto_inet),
[NFPROTO_IPV4] = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_ip),
[NFPROTO_IPV6] = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_ip6),
diff --git a/src/rule.c b/src/rule.c
index 7114380..5e91bf2 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -312,6 +312,7 @@ static const char *chain_hookname_str_array[] = {
"forward",
"postrouting",
"output",
+ "ingress",
NULL,
};
@@ -377,6 +378,8 @@ const char *family2str(unsigned int family)
return "ip6";
case NFPROTO_INET:
return "inet";
+ case NFPROTO_NETDEV:
+ return "netdev";
case NFPROTO_ARP:
return "arp";
case NFPROTO_BRIDGE:
@@ -420,6 +423,13 @@ static const char *hooknum2str(unsigned int family, unsigned int hooknum)
default:
break;
}
+ break;
+ case NFPROTO_NETDEV:
+ switch (hooknum) {
+ case NF_NETDEV_INGRESS:
+ return "ingress";
+ }
+ break;
default:
break;
};
@@ -525,6 +535,7 @@ const char *table_flags_name[TABLE_FLAGS_MAX] = {
static void table_print_options(const struct table *table, const char **delim)
{
uint32_t flags = table->flags;
+ bool newline = false;
int i;
if (flags) {
@@ -537,6 +548,18 @@ static void table_print_options(const struct table *table, const char **delim)
if (flags)
printf(",");
}
+ newline = true;
+ }
+ if (table->dev) {
+ if (!newline)
+ printf("\t");
+ else
+ printf(" ");
+
+ printf("device %s;", table->dev);
+ newline = true;
+ }
+ if (newline) {
printf("\n");
*delim = "\n";
}
diff --git a/src/scanner.l b/src/scanner.l
index 73c4f8b..2de9cbc 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -231,6 +231,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"describe" { return DESCRIBE; }
"hook" { return HOOK; }
+"device" { return DEVICE; }
"table" { return TABLE; }
"tables" { return TABLES; }
"chain" { return CHAIN; }
@@ -253,6 +254,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"to" { return TO; }
"inet" { return INET; }
+"netdev" { return NETDEV; }
"add" { return ADD; }
"create" { return CREATE; }
--
1.7.10.4
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PATCH nft] src: add netdev family support
2015-05-25 12:46 ` [PATCH nft] src: " Pablo Neira Ayuso
@ 2015-05-26 16:52 ` Patrick McHardy
2015-05-26 17:17 ` Pablo Neira Ayuso
0 siblings, 1 reply; 13+ messages in thread
From: Patrick McHardy @ 2015-05-26 16:52 UTC (permalink / raw)
To: Pablo Neira Ayuso; +Cc: netfilter-devel, netdev
On 25.05, Pablo Neira Ayuso wrote:
> diff --git a/include/rule.h b/include/rule.h
> index 97959f7..06ec2ff 100644
> --- a/include/rule.h
> +++ b/include/rule.h
> @@ -72,6 +72,7 @@ enum table_flags {
> *
> * @list: list node
> * @handle: table handle
> + * @dev: network device name (only for netdev family)
> * @location: location the table was defined at
> * @chains: chains contained in the table
> * @sets: sets contained in the table
> @@ -80,6 +81,7 @@ enum table_flags {
> struct table {
> struct list_head list;
> struct handle handle;
> + const char *dev;
I think this logically belongs into struct handle itself.
^ permalink raw reply [flat|nested] 13+ messages in thread
* Re: [PATCH nft] src: add netdev family support
2015-05-26 16:52 ` Patrick McHardy
@ 2015-05-26 17:17 ` Pablo Neira Ayuso
0 siblings, 0 replies; 13+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-26 17:17 UTC (permalink / raw)
To: Patrick McHardy; +Cc: netfilter-devel, netdev
On Tue, May 26, 2015 at 06:52:04PM +0200, Patrick McHardy wrote:
> On 25.05, Pablo Neira Ayuso wrote:
> > diff --git a/include/rule.h b/include/rule.h
> > index 97959f7..06ec2ff 100644
> > --- a/include/rule.h
> > +++ b/include/rule.h
> > @@ -72,6 +72,7 @@ enum table_flags {
> > *
> > * @list: list node
> > * @handle: table handle
> > + * @dev: network device name (only for netdev family)
> > * @location: location the table was defined at
> > * @chains: chains contained in the table
> > * @sets: sets contained in the table
> > @@ -80,6 +81,7 @@ enum table_flags {
> > struct table {
> > struct list_head list;
> > struct handle handle;
> > + const char *dev;
>
> I think this logically belongs into struct handle itself.
Thanks Patrick, I'll move this to the handle.
^ permalink raw reply [flat|nested] 13+ messages in thread