* [PATCH 0/3 nf-next] nf_tables support at ingress
@ 2015-05-25 12:46 Pablo Neira Ayuso
2015-05-25 12:46 ` [PATCH 1/3 nf-next] netfilter: default CONFIG_NETFILTER_INGRESS to y Pablo Neira Ayuso
` (4 more replies)
0 siblings, 5 replies; 13+ messages in thread
From: Pablo Neira Ayuso @ 2015-05-25 12:46 UTC (permalink / raw)
To: netfilter-devel; +Cc: kaber, netdev
Hi,
This is the follow-up patchset to add nf_tables on top of the Netfilter ingress
hook [1] now available in the net-next tree:
1) default CONFIG_NETFILTER_INGRESS to y for easier compile-testing of all
options.
2) Allow to bind a table to net_device. This introduces the internal
NFT_AF_NEEDS_DEV flag to perform a mandatory check for this binding.
This patch is required by the next patch.
3) Add the 'netdev' table family, this new table allows you to create ingress
filter basechains. This provides access to the existing nf_tables features
from ingress.
After this, I'll prepare more patches to revisit our existing limit expression
and to add support for the tee expression.
If no objections, I'll enqueue this patchset to the nf-next tree.
Thanks.
[1] https://lwn.net/Articles/644937/
Pablo Neira Ayuso (3):
netfilter: default CONFIG_NETFILTER_INGRESS to y
netfilter: nf_tables: allow to bind table to net_device
netfilter: nf_tables: add netdev table to filter from ingress
include/net/netfilter/nf_tables.h | 8 ++
include/net/netns/nftables.h | 1 +
include/uapi/linux/netfilter/nf_tables.h | 2 +
net/netfilter/Kconfig | 6 +
net/netfilter/Makefile | 1 +
net/netfilter/nf_tables_api.c | 46 +++++++-
net/netfilter/nf_tables_netdev.c | 183 ++++++++++++++++++++++++++++++
7 files changed, 242 insertions(+), 5 deletions(-)
create mode 100644 net/netfilter/nf_tables_netdev.c
--
1.7.10.4
^ permalink raw reply [flat|nested] 13+ messages in thread
* [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
* [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
* [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 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 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 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
* 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 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
* 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
end of thread, other threads:[~2015-05-27 1:08 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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-26 0:44 ` Simon Horman
2015-05-26 9:41 ` 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-26 0:48 ` Simon Horman
2015-05-26 9:58 ` Pablo Neira Ayuso
2015-05-27 1:08 ` 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
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
2015-05-26 16:52 ` Patrick McHardy
2015-05-26 17:17 ` Pablo Neira Ayuso
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).