netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support
@ 2014-01-03 12:16 Patrick McHardy
  2014-01-03 12:16 ` [PATCH 1/6] netfilter: nf_tables: make chain types override the default AF functions Patrick McHardy
                   ` (8 more replies)
  0 siblings, 9 replies; 12+ messages in thread
From: Patrick McHardy @ 2014-01-03 12:16 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

The following patches add support for mixed IPv4/IPv6 tables to nftables.

The first patch fixes the chain type override logic so chain types override
the AF defaults instead of the other way around. The second patch adds a
pointer to the nf_hook_ops struct to nft_pktinfo for a later patch which
uses ops->pf to match the actual AF of the packet instead of the dummy
NFPROTO_INET value. The third patch changes the chain and hook registration
logic to support multiple hook registrations. The nf_tables AF modules can
provide a callback function to override defaults. The fourth patch finally
adds a new "inet" family, which basically only initializes the hook
functions to the IPv4 and IPv6 specific ones and registers a dummy filter
chain type for NFPROTO_INET. Patches 5 and 6 add support for matching on
the netfilter hook family and the L4 protocol number to the meta match.

With all this in place, we can create AF-specific rules and AF-independant
rules that only match on the L4 protocol header and above in the inet table:

table inet filter {
        chain input {
                 type filter hook input priority 0;
        }

	chain forward {
                 type filter hook forward priority 0;
        }

	chain output {
                 type filter hook output priority 0;
                 ip protocol tcp tcp dport 1234 counter packets 2 bytes 120
                 ip6 nexthdr tcp tcp dport 1234 counter packets 2 bytes 160
                 tcp dport 1234 counter packets 4 bytes 280
	}
}

Userspace needs a bit of polishing but will most likely follow in a few
hours.

Comments welcome.


Patrick McHardy (6):
      netfilter: nf_tables: make chain types override the default AF functions
      netfilter: nf_tables: add hook ops to struct nft_pktinfo
      netfilter: nf_tables: add support for multi family tables
      netfilter: nf_tables: add "inet" table for IPv4/IPv6
      netfilter: nf_tables: add nfproto support to meta expression
      netfilter: nft_meta: add l4proto support

 include/net/netfilter/nf_tables.h        | 15 ++++-
 include/net/netfilter/nf_tables_ipv4.h   |  5 +-
 include/net/netfilter/nf_tables_ipv6.h   |  3 +
 include/net/netns/nftables.h             |  1 +
 include/uapi/linux/netfilter.h           |  1 +
 include/uapi/linux/netfilter/nf_tables.h |  4 ++
 net/bridge/netfilter/nf_tables_bridge.c  | 39 ++++++-------
 net/ipv4/netfilter/nf_tables_arp.c       | 39 ++++++-------
 net/ipv4/netfilter/nf_tables_ipv4.c      | 47 +++++++---------
 net/ipv6/netfilter/nf_tables_ipv6.c      | 52 ++++++++---------
 net/netfilter/Kconfig                    |  8 +++
 net/netfilter/Makefile                   |  1 +
 net/netfilter/nf_tables_api.c            | 53 +++++++++--------
 net/netfilter/nf_tables_core.c           |  2 +-
 net/netfilter/nf_tables_inet.c           | 97 ++++++++++++++++++++++++++++++++
 net/netfilter/nft_compat.c               |  8 +--
 net/netfilter/nft_log.c                  |  2 +-
 net/netfilter/nft_meta.c                 |  8 +++
 18 files changed, 260 insertions(+), 125 deletions(-)


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

* [PATCH 1/6] netfilter: nf_tables: make chain types override the default AF functions
  2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
@ 2014-01-03 12:16 ` Patrick McHardy
  2014-01-03 12:16 ` [PATCH 2/6] netfilter: nf_tables: add hook ops to struct nft_pktinfo Patrick McHardy
                   ` (7 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2014-01-03 12:16 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Currently the AF-specific hook functions override the chain-type specific
hook functions. That doesn't make too much sense since the chain types
are a special case of the AF-specific hooks.

Make the AF-specific hook functions the default and make the optional
chain type hooks override them.

As a side effect, the necessary code restructuring reduces the code size,
f.i. in case of nf_tables_ipv4.o:

  nf_tables_ipv4_init_net   |  -24
  nft_do_chain_ipv4         | -113
 2 functions changed, 137 bytes removed, diff: -137

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 net/bridge/netfilter/nf_tables_bridge.c | 38 +++++++++++++-------------
 net/ipv4/netfilter/nf_tables_arp.c      | 38 +++++++++++++-------------
 net/ipv4/netfilter/nf_tables_ipv4.c     | 43 +++++++++++++----------------
 net/ipv6/netfilter/nf_tables_ipv6.c     | 48 ++++++++++++++-------------------
 net/netfilter/nf_tables_api.c           | 10 +++----
 5 files changed, 81 insertions(+), 96 deletions(-)

diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index cf54b22..c5fdd9a 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -14,10 +14,29 @@
 #include <linux/netfilter_bridge.h>
 #include <net/netfilter/nf_tables.h>
 
+static unsigned int
+nft_do_chain_bridge(const struct nf_hook_ops *ops,
+		    struct sk_buff *skb,
+		    const struct net_device *in,
+		    const struct net_device *out,
+		    int (*okfn)(struct sk_buff *))
+{
+	struct nft_pktinfo pkt;
+
+	nft_set_pktinfo(&pkt, ops, skb, in, out);
+
+	return nft_do_chain_pktinfo(&pkt, ops);
+}
+
 static struct nft_af_info nft_af_bridge __read_mostly = {
 	.family		= NFPROTO_BRIDGE,
 	.nhooks		= NF_BR_NUMHOOKS,
 	.owner		= THIS_MODULE,
+	.hooks		= {
+		[NF_BR_LOCAL_IN]	= nft_do_chain_bridge,
+		[NF_BR_FORWARD]		= nft_do_chain_bridge,
+		[NF_BR_LOCAL_OUT]	= nft_do_chain_bridge,
+	},
 };
 
 static int nf_tables_bridge_init_net(struct net *net)
@@ -48,20 +67,6 @@ static struct pernet_operations nf_tables_bridge_net_ops = {
 	.exit	= nf_tables_bridge_exit_net,
 };
 
-static unsigned int
-nft_do_chain_bridge(const struct nf_hook_ops *ops,
-		    struct sk_buff *skb,
-		    const struct net_device *in,
-		    const struct net_device *out,
-		    int (*okfn)(struct sk_buff *))
-{
-	struct nft_pktinfo pkt;
-
-	nft_set_pktinfo(&pkt, ops, skb, in, out);
-
-	return nft_do_chain_pktinfo(&pkt, ops);
-}
-
 static struct nf_chain_type filter_bridge = {
 	.family		= NFPROTO_BRIDGE,
 	.name		= "filter",
@@ -69,11 +74,6 @@ static struct nf_chain_type filter_bridge = {
 	.hook_mask	= (1 << NF_BR_LOCAL_IN) |
 			  (1 << NF_BR_FORWARD) |
 			  (1 << NF_BR_LOCAL_OUT),
-	.fn		= {
-		[NF_BR_LOCAL_IN]	= nft_do_chain_bridge,
-		[NF_BR_FORWARD]		= nft_do_chain_bridge,
-		[NF_BR_LOCAL_OUT]	= nft_do_chain_bridge,
-	},
 };
 
 static int __init nf_tables_bridge_init(void)
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index 3e67ef1..31bb778 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -14,10 +14,29 @@
 #include <linux/netfilter_arp.h>
 #include <net/netfilter/nf_tables.h>
 
+static unsigned int
+nft_do_chain_arp(const struct nf_hook_ops *ops,
+		  struct sk_buff *skb,
+		  const struct net_device *in,
+		  const struct net_device *out,
+		  int (*okfn)(struct sk_buff *))
+{
+	struct nft_pktinfo pkt;
+
+	nft_set_pktinfo(&pkt, ops, skb, in, out);
+
+	return nft_do_chain_pktinfo(&pkt, ops);
+}
+
 static struct nft_af_info nft_af_arp __read_mostly = {
 	.family		= NFPROTO_ARP,
 	.nhooks		= NF_ARP_NUMHOOKS,
 	.owner		= THIS_MODULE,
+	.hooks		= {
+		[NF_ARP_IN]		= nft_do_chain_arp,
+		[NF_ARP_OUT]		= nft_do_chain_arp,
+		[NF_ARP_FORWARD]	= nft_do_chain_arp,
+	},
 };
 
 static int nf_tables_arp_init_net(struct net *net)
@@ -48,20 +67,6 @@ static struct pernet_operations nf_tables_arp_net_ops = {
 	.exit   = nf_tables_arp_exit_net,
 };
 
-static unsigned int
-nft_do_chain_arp(const struct nf_hook_ops *ops,
-		  struct sk_buff *skb,
-		  const struct net_device *in,
-		  const struct net_device *out,
-		  int (*okfn)(struct sk_buff *))
-{
-	struct nft_pktinfo pkt;
-
-	nft_set_pktinfo(&pkt, ops, skb, in, out);
-
-	return nft_do_chain_pktinfo(&pkt, ops);
-}
-
 static struct nf_chain_type filter_arp = {
 	.family		= NFPROTO_ARP,
 	.name		= "filter",
@@ -69,11 +74,6 @@ static struct nf_chain_type filter_arp = {
 	.hook_mask	= (1 << NF_ARP_IN) |
 			  (1 << NF_ARP_OUT) |
 			  (1 << NF_ARP_FORWARD),
-	.fn		= {
-		[NF_ARP_IN]		= nft_do_chain_arp,
-		[NF_ARP_OUT]		= nft_do_chain_arp,
-		[NF_ARP_FORWARD]	= nft_do_chain_arp,
-	},
 };
 
 static int __init nf_tables_arp_init(void)
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index 0f4cbfe..ed7e15a 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -18,14 +18,25 @@
 #include <net/ip.h>
 #include <net/netfilter/nf_tables_ipv4.h>
 
+static unsigned int nft_do_chain_ipv4(const struct nf_hook_ops *ops,
+				      struct sk_buff *skb,
+				      const struct net_device *in,
+				      const struct net_device *out,
+				      int (*okfn)(struct sk_buff *))
+{
+	struct nft_pktinfo pkt;
+
+	nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
+
+	return nft_do_chain_pktinfo(&pkt, ops);
+}
+
 static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
 				    struct sk_buff *skb,
 				    const struct net_device *in,
 				    const struct net_device *out,
 				    int (*okfn)(struct sk_buff *))
 {
-	struct nft_pktinfo pkt;
-
 	if (unlikely(skb->len < sizeof(struct iphdr) ||
 		     ip_hdr(skb)->ihl < sizeof(struct iphdr) / 4)) {
 		if (net_ratelimit())
@@ -33,9 +44,8 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
 				"packet\n");
 		return NF_ACCEPT;
 	}
-	nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
 
-	return nft_do_chain_pktinfo(&pkt, ops);
+	return nft_do_chain_ipv4(ops, skb, in, out, okfn);
 }
 
 static struct nft_af_info nft_af_ipv4 __read_mostly = {
@@ -43,7 +53,11 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = {
 	.nhooks		= NF_INET_NUMHOOKS,
 	.owner		= THIS_MODULE,
 	.hooks		= {
+		[NF_INET_LOCAL_IN]	= nft_do_chain_ipv4,
 		[NF_INET_LOCAL_OUT]	= nft_ipv4_output,
+		[NF_INET_FORWARD]	= nft_do_chain_ipv4,
+		[NF_INET_PRE_ROUTING]	= nft_do_chain_ipv4,
+		[NF_INET_POST_ROUTING]	= nft_do_chain_ipv4,
 	},
 };
 
@@ -75,20 +89,6 @@ static struct pernet_operations nf_tables_ipv4_net_ops = {
 	.exit	= nf_tables_ipv4_exit_net,
 };
 
-static unsigned int
-nft_do_chain_ipv4(const struct nf_hook_ops *ops,
-		  struct sk_buff *skb,
-		  const struct net_device *in,
-		  const struct net_device *out,
-		  int (*okfn)(struct sk_buff *))
-{
-	struct nft_pktinfo pkt;
-
-	nft_set_pktinfo_ipv4(&pkt, ops, skb, in, out);
-
-	return nft_do_chain_pktinfo(&pkt, ops);
-}
-
 static struct nf_chain_type filter_ipv4 = {
 	.family		= NFPROTO_IPV4,
 	.name		= "filter",
@@ -98,13 +98,6 @@ static struct nf_chain_type filter_ipv4 = {
 			  (1 << NF_INET_FORWARD) |
 			  (1 << NF_INET_PRE_ROUTING) |
 			  (1 << NF_INET_POST_ROUTING),
-	.fn		= {
-		[NF_INET_LOCAL_IN]	= nft_do_chain_ipv4,
-		[NF_INET_LOCAL_OUT]	= nft_ipv4_output,
-		[NF_INET_FORWARD]	= nft_do_chain_ipv4,
-		[NF_INET_PRE_ROUTING]	= nft_do_chain_ipv4,
-		[NF_INET_POST_ROUTING]	= nft_do_chain_ipv4,
-	},
 };
 
 static int __init nf_tables_ipv4_init(void)
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index d77db8a..54a2bcd 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -16,24 +16,35 @@
 #include <net/netfilter/nf_tables.h>
 #include <net/netfilter/nf_tables_ipv6.h>
 
+static unsigned int nft_do_chain_ipv6(const struct nf_hook_ops *ops,
+				      struct sk_buff *skb,
+				      const struct net_device *in,
+				      const struct net_device *out,
+				      int (*okfn)(struct sk_buff *))
+{
+	struct nft_pktinfo pkt;
+
+	/* malformed packet, drop it */
+	if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
+		return NF_DROP;
+
+	return nft_do_chain_pktinfo(&pkt, ops);
+}
+
 static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops,
 				    struct sk_buff *skb,
 				    const struct net_device *in,
 				    const struct net_device *out,
 				    int (*okfn)(struct sk_buff *))
 {
-	struct nft_pktinfo pkt;
-
 	if (unlikely(skb->len < sizeof(struct ipv6hdr))) {
 		if (net_ratelimit())
 			pr_info("nf_tables_ipv6: ignoring short SOCK_RAW "
 				"packet\n");
 		return NF_ACCEPT;
 	}
-	if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
-		return NF_DROP;
 
-	return nft_do_chain_pktinfo(&pkt, ops);
+	return nft_do_chain_ipv6(ops, skb, in, out, okfn);
 }
 
 static struct nft_af_info nft_af_ipv6 __read_mostly = {
@@ -41,7 +52,11 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = {
 	.nhooks		= NF_INET_NUMHOOKS,
 	.owner		= THIS_MODULE,
 	.hooks		= {
+		[NF_INET_LOCAL_IN]	= nft_do_chain_ipv6,
 		[NF_INET_LOCAL_OUT]	= nft_ipv6_output,
+		[NF_INET_FORWARD]	= nft_do_chain_ipv6,
+		[NF_INET_PRE_ROUTING]	= nft_do_chain_ipv6,
+		[NF_INET_POST_ROUTING]	= nft_do_chain_ipv6,
 	},
 };
 
@@ -73,22 +88,6 @@ static struct pernet_operations nf_tables_ipv6_net_ops = {
 	.exit	= nf_tables_ipv6_exit_net,
 };
 
-static unsigned int
-nft_do_chain_ipv6(const struct nf_hook_ops *ops,
-		  struct sk_buff *skb,
-		  const struct net_device *in,
-		  const struct net_device *out,
-		  int (*okfn)(struct sk_buff *))
-{
-	struct nft_pktinfo pkt;
-
-	/* malformed packet, drop it */
-	if (nft_set_pktinfo_ipv6(&pkt, ops, skb, in, out) < 0)
-		return NF_DROP;
-
-	return nft_do_chain_pktinfo(&pkt, ops);
-}
-
 static struct nf_chain_type filter_ipv6 = {
 	.family		= NFPROTO_IPV6,
 	.name		= "filter",
@@ -98,13 +97,6 @@ static struct nf_chain_type filter_ipv6 = {
 			  (1 << NF_INET_FORWARD) |
 			  (1 << NF_INET_PRE_ROUTING) |
 			  (1 << NF_INET_POST_ROUTING),
-	.fn		= {
-		[NF_INET_LOCAL_IN]	= nft_do_chain_ipv6,
-		[NF_INET_LOCAL_OUT]	= nft_ipv6_output,
-		[NF_INET_FORWARD]	= nft_do_chain_ipv6,
-		[NF_INET_PRE_ROUTING]	= nft_do_chain_ipv6,
-		[NF_INET_POST_ROUTING]	= nft_do_chain_ipv6,
-	},
 };
 
 static int __init nf_tables_ipv6_init(void)
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 71a9f49..0dda328 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -926,9 +926,9 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
 		if (hooknum >= afi->nhooks)
 			return -EINVAL;
 
-		hookfn = chain_type[family][type]->fn[hooknum];
-		if (hookfn == NULL)
+		if (!(chain_type[family][type]->hook_mask & (1 << hooknum)))
 			return -EOPNOTSUPP;
+		hookfn = chain_type[family][type]->fn[hooknum];
 
 		basechain = kzalloc(sizeof(*basechain), GFP_KERNEL);
 		if (basechain == NULL)
@@ -943,9 +943,9 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
 		ops->hooknum	= ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
 		ops->priority	= ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
 		ops->priv	= chain;
-		ops->hook       = hookfn;
-		if (afi->hooks[ops->hooknum])
-			ops->hook = afi->hooks[ops->hooknum];
+		ops->hook	= afi->hooks[ops->hooknum];
+		if (hookfn)
+			ops->hook = hookfn;
 
 		chain->flags |= NFT_BASE_CHAIN;
 
-- 
1.8.4.2


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

* [PATCH 2/6] netfilter: nf_tables: add hook ops to struct nft_pktinfo
  2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
  2014-01-03 12:16 ` [PATCH 1/6] netfilter: nf_tables: make chain types override the default AF functions Patrick McHardy
@ 2014-01-03 12:16 ` Patrick McHardy
  2014-01-03 12:16 ` [PATCH 3/6] netfilter: nf_tables: add support for multi family tables Patrick McHardy
                   ` (6 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2014-01-03 12:16 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Multi-family tables need the AF from the hook ops. Add a pointer to the
hook ops and replace usage of the hooknum member in struct nft_pktinfo.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/net/netfilter/nf_tables.h | 5 +++--
 net/netfilter/nf_tables_core.c    | 2 +-
 net/netfilter/nft_log.c           | 2 +-
 3 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index 5a91abf..c9e6316 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -13,7 +13,7 @@ struct nft_pktinfo {
 	struct sk_buff			*skb;
 	const struct net_device		*in;
 	const struct net_device		*out;
-	u8				hooknum;
+	const struct nf_hook_ops	*ops;
 	u8				nhoff;
 	u8				thoff;
 	/* for x_tables compatibility */
@@ -29,7 +29,8 @@ static inline void nft_set_pktinfo(struct nft_pktinfo *pkt,
 	pkt->skb = skb;
 	pkt->in = pkt->xt.in = in;
 	pkt->out = pkt->xt.out = out;
-	pkt->hooknum = pkt->xt.hooknum = ops->hooknum;
+	pkt->ops = ops;
+	pkt->xt.hooknum = ops->hooknum;
 	pkt->xt.family = ops->pf;
 }
 
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index cb9e685..eb6a157 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -109,7 +109,7 @@ static inline void nft_trace_packet(const struct nft_pktinfo *pkt,
 {
 	struct net *net = dev_net(pkt->in ? pkt->in : pkt->out);
 
-	nf_log_packet(net, pkt->xt.family, pkt->hooknum, pkt->skb, pkt->in,
+	nf_log_packet(net, pkt->xt.family, pkt->ops->hooknum, pkt->skb, pkt->in,
 		      pkt->out, &trace_loginfo, "TRACE: %s:%s:%s:%u ",
 		      chain->table->name, chain->name, comments[type],
 		      rulenum);
diff --git a/net/netfilter/nft_log.c b/net/netfilter/nft_log.c
index 57cad07..5af7901 100644
--- a/net/netfilter/nft_log.c
+++ b/net/netfilter/nft_log.c
@@ -33,7 +33,7 @@ static void nft_log_eval(const struct nft_expr *expr,
 	const struct nft_log *priv = nft_expr_priv(expr);
 	struct net *net = dev_net(pkt->in ? pkt->in : pkt->out);
 
-	nf_log_packet(net, priv->family, pkt->hooknum, pkt->skb, pkt->in,
+	nf_log_packet(net, priv->family, pkt->ops->hooknum, pkt->skb, pkt->in,
 		      pkt->out, &priv->loginfo, "%s", priv->prefix);
 }
 
-- 
1.8.4.2


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

* [PATCH 3/6] netfilter: nf_tables: add support for multi family tables
  2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
  2014-01-03 12:16 ` [PATCH 1/6] netfilter: nf_tables: make chain types override the default AF functions Patrick McHardy
  2014-01-03 12:16 ` [PATCH 2/6] netfilter: nf_tables: add hook ops to struct nft_pktinfo Patrick McHardy
@ 2014-01-03 12:16 ` Patrick McHardy
  2014-01-03 12:16 ` [PATCH 4/6] netfilter: nf_tables: add "inet" table for IPv4/IPv6 Patrick McHardy
                   ` (5 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2014-01-03 12:16 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Add support to register chains to multiple hooks for different address
families for mixed IPv4/IPv6 tables.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/net/netfilter/nf_tables.h       |  9 +++++-
 net/bridge/netfilter/nf_tables_bridge.c |  1 +
 net/ipv4/netfilter/nf_tables_arp.c      |  1 +
 net/ipv4/netfilter/nf_tables_ipv4.c     |  1 +
 net/ipv6/netfilter/nf_tables_ipv6.c     |  1 +
 net/netfilter/nf_tables_api.c           | 49 +++++++++++++++++++--------------
 net/netfilter/nft_compat.c              |  8 +++---
 7 files changed, 45 insertions(+), 25 deletions(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index c9e6316..f066f25 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -422,6 +422,8 @@ struct nft_stats {
 	u64 pkts;
 };
 
+#define NFT_HOOK_OPS_MAX		2
+
 /**
  *	struct nft_base_chain - nf_tables base chain
  *
@@ -432,7 +434,7 @@ struct nft_stats {
  *	@chain: the chain
  */
 struct nft_base_chain {
-	struct nf_hook_ops		ops;
+	struct nf_hook_ops		ops[NFT_HOOK_OPS_MAX];
 	enum nft_chain_type		type;
 	u8				policy;
 	struct nft_stats __percpu	*stats;
@@ -476,6 +478,8 @@ struct nft_table {
  *	@nhooks: number of hooks in this family
  *	@owner: module owner
  *	@tables: used internally
+ *	@nops: number of hook ops in this family
+ *	@hook_ops_init: initialization function for chain hook ops
  *	@hooks: hookfn overrides for packet validation
  */
 struct nft_af_info {
@@ -484,6 +488,9 @@ struct nft_af_info {
 	unsigned int			nhooks;
 	struct module			*owner;
 	struct list_head		tables;
+	unsigned int			nops;
+	void				(*hook_ops_init)(struct nf_hook_ops *,
+							 unsigned int);
 	nf_hookfn			*hooks[NF_MAX_HOOKS];
 };
 
diff --git a/net/bridge/netfilter/nf_tables_bridge.c b/net/bridge/netfilter/nf_tables_bridge.c
index c5fdd9a..003c1e9 100644
--- a/net/bridge/netfilter/nf_tables_bridge.c
+++ b/net/bridge/netfilter/nf_tables_bridge.c
@@ -32,6 +32,7 @@ static struct nft_af_info nft_af_bridge __read_mostly = {
 	.family		= NFPROTO_BRIDGE,
 	.nhooks		= NF_BR_NUMHOOKS,
 	.owner		= THIS_MODULE,
+	.nops		= 1,
 	.hooks		= {
 		[NF_BR_LOCAL_IN]	= nft_do_chain_bridge,
 		[NF_BR_FORWARD]		= nft_do_chain_bridge,
diff --git a/net/ipv4/netfilter/nf_tables_arp.c b/net/ipv4/netfilter/nf_tables_arp.c
index 31bb778..36d27fc 100644
--- a/net/ipv4/netfilter/nf_tables_arp.c
+++ b/net/ipv4/netfilter/nf_tables_arp.c
@@ -32,6 +32,7 @@ static struct nft_af_info nft_af_arp __read_mostly = {
 	.family		= NFPROTO_ARP,
 	.nhooks		= NF_ARP_NUMHOOKS,
 	.owner		= THIS_MODULE,
+	.nops		= 1,
 	.hooks		= {
 		[NF_ARP_IN]		= nft_do_chain_arp,
 		[NF_ARP_OUT]		= nft_do_chain_arp,
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index ed7e15a..177c3bc 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -52,6 +52,7 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = {
 	.family		= NFPROTO_IPV4,
 	.nhooks		= NF_INET_NUMHOOKS,
 	.owner		= THIS_MODULE,
+	.nops		= 1,
 	.hooks		= {
 		[NF_INET_LOCAL_IN]	= nft_do_chain_ipv4,
 		[NF_INET_LOCAL_OUT]	= nft_ipv4_output,
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 54a2bcd..642280e 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -51,6 +51,7 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = {
 	.family		= NFPROTO_IPV6,
 	.nhooks		= NF_INET_NUMHOOKS,
 	.owner		= THIS_MODULE,
+	.nops		= 1,
 	.hooks		= {
 		[NF_INET_LOCAL_IN]	= nft_do_chain_ipv6,
 		[NF_INET_LOCAL_OUT]	= nft_ipv6_output,
diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index 0dda328..e4c4089 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -306,7 +306,8 @@ err:
 	return err;
 }
 
-static int nf_tables_table_enable(struct nft_table *table)
+static int nf_tables_table_enable(const struct nft_af_info *afi,
+				  struct nft_table *table)
 {
 	struct nft_chain *chain;
 	int err, i = 0;
@@ -315,7 +316,7 @@ static int nf_tables_table_enable(struct nft_table *table)
 		if (!(chain->flags & NFT_BASE_CHAIN))
 			continue;
 
-		err = nf_register_hook(&nft_base_chain(chain)->ops);
+		err = nf_register_hooks(nft_base_chain(chain)->ops, afi->nops);
 		if (err < 0)
 			goto err;
 
@@ -330,18 +331,20 @@ err:
 		if (i-- <= 0)
 			break;
 
-		nf_unregister_hook(&nft_base_chain(chain)->ops);
+		nf_unregister_hooks(nft_base_chain(chain)->ops, afi->nops);
 	}
 	return err;
 }
 
-static int nf_tables_table_disable(struct nft_table *table)
+static int nf_tables_table_disable(const struct nft_af_info *afi,
+				   struct nft_table *table)
 {
 	struct nft_chain *chain;
 
 	list_for_each_entry(chain, &table->chains, list) {
 		if (chain->flags & NFT_BASE_CHAIN)
-			nf_unregister_hook(&nft_base_chain(chain)->ops);
+			nf_unregister_hooks(nft_base_chain(chain)->ops,
+					    afi->nops);
 	}
 
 	return 0;
@@ -364,12 +367,12 @@ static int nf_tables_updtable(struct sock *nlsk, struct sk_buff *skb,
 
 		if ((flags & NFT_TABLE_F_DORMANT) &&
 		    !(table->flags & NFT_TABLE_F_DORMANT)) {
-			ret = nf_tables_table_disable(table);
+			ret = nf_tables_table_disable(afi, table);
 			if (ret >= 0)
 				table->flags |= NFT_TABLE_F_DORMANT;
 		} else if (!(flags & NFT_TABLE_F_DORMANT) &&
 			   table->flags & NFT_TABLE_F_DORMANT) {
-			ret = nf_tables_table_enable(table);
+			ret = nf_tables_table_enable(afi, table);
 			if (ret >= 0)
 				table->flags &= ~NFT_TABLE_F_DORMANT;
 		}
@@ -597,7 +600,7 @@ static int nf_tables_fill_chain_info(struct sk_buff *skb, u32 portid, u32 seq,
 
 	if (chain->flags & NFT_BASE_CHAIN) {
 		const struct nft_base_chain *basechain = nft_base_chain(chain);
-		const struct nf_hook_ops *ops = &basechain->ops;
+		const struct nf_hook_ops *ops = &basechain->ops[0];
 		struct nlattr *nest;
 
 		nest = nla_nest_start(skb, NFTA_CHAIN_HOOK);
@@ -831,6 +834,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
 	struct net *net = sock_net(skb->sk);
 	int family = nfmsg->nfgen_family;
 	u64 handle = 0;
+	unsigned int i;
 	int err;
 	bool create;
 
@@ -903,7 +907,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
 	if (nla[NFTA_CHAIN_HOOK]) {
 		struct nf_hook_ops *ops;
 		nf_hookfn *hookfn;
-		u32 hooknum;
+		u32 hooknum, priority;
 		int type = NFT_CHAIN_T_DEFAULT;
 
 		if (nla[NFTA_CHAIN_TYPE]) {
@@ -925,6 +929,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
 		hooknum = ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
 		if (hooknum >= afi->nhooks)
 			return -EINVAL;
+		priority = ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
 
 		if (!(chain_type[family][type]->hook_mask & (1 << hooknum)))
 			return -EOPNOTSUPP;
@@ -937,15 +942,19 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
 		basechain->type = type;
 		chain = &basechain->chain;
 
-		ops = &basechain->ops;
-		ops->pf		= family;
-		ops->owner	= afi->owner;
-		ops->hooknum	= ntohl(nla_get_be32(ha[NFTA_HOOK_HOOKNUM]));
-		ops->priority	= ntohl(nla_get_be32(ha[NFTA_HOOK_PRIORITY]));
-		ops->priv	= chain;
-		ops->hook	= afi->hooks[ops->hooknum];
-		if (hookfn)
-			ops->hook = hookfn;
+		for (i = 0; i < afi->nops; i++) {
+			ops = &basechain->ops[i];
+			ops->pf		= family;
+			ops->owner	= afi->owner;
+			ops->hooknum	= hooknum;
+			ops->priority	= priority;
+			ops->priv	= chain;
+			ops->hook	= afi->hooks[ops->hooknum];
+			if (hookfn)
+				ops->hook = hookfn;
+			if (afi->hook_ops_init)
+				afi->hook_ops_init(ops, i);
+		}
 
 		chain->flags |= NFT_BASE_CHAIN;
 
@@ -992,7 +1001,7 @@ static int nf_tables_newchain(struct sock *nlsk, struct sk_buff *skb,
 
 	if (!(table->flags & NFT_TABLE_F_DORMANT) &&
 	    chain->flags & NFT_BASE_CHAIN) {
-		err = nf_register_hook(&nft_base_chain(chain)->ops);
+		err = nf_register_hooks(nft_base_chain(chain)->ops, afi->nops);
 		if (err < 0) {
 			free_percpu(basechain->stats);
 			kfree(basechain);
@@ -1051,7 +1060,7 @@ static int nf_tables_delchain(struct sock *nlsk, struct sk_buff *skb,
 
 	if (!(table->flags & NFT_TABLE_F_DORMANT) &&
 	    chain->flags & NFT_BASE_CHAIN)
-		nf_unregister_hook(&nft_base_chain(chain)->ops);
+		nf_unregister_hooks(nft_base_chain(chain)->ops, afi->nops);
 
 	nf_tables_chain_notify(skb, nlh, table, chain, NFT_MSG_DELCHAIN,
 			       family);
diff --git a/net/netfilter/nft_compat.c b/net/netfilter/nft_compat.c
index da0c1f4..82cb823 100644
--- a/net/netfilter/nft_compat.c
+++ b/net/netfilter/nft_compat.c
@@ -92,7 +92,7 @@ nft_target_set_tgchk_param(struct xt_tgchk_param *par,
 	if (ctx->chain->flags & NFT_BASE_CHAIN) {
 		const struct nft_base_chain *basechain =
 						nft_base_chain(ctx->chain);
-		const struct nf_hook_ops *ops = &basechain->ops;
+		const struct nf_hook_ops *ops = &basechain->ops[0];
 
 		par->hook_mask = 1 << ops->hooknum;
 	}
@@ -253,7 +253,7 @@ static int nft_target_validate(const struct nft_ctx *ctx,
 	if (ctx->chain->flags & NFT_BASE_CHAIN) {
 		const struct nft_base_chain *basechain =
 						nft_base_chain(ctx->chain);
-		const struct nf_hook_ops *ops = &basechain->ops;
+		const struct nf_hook_ops *ops = &basechain->ops[0];
 
 		hook_mask = 1 << ops->hooknum;
 		if (hook_mask & target->hooks)
@@ -323,7 +323,7 @@ nft_match_set_mtchk_param(struct xt_mtchk_param *par, const struct nft_ctx *ctx,
 	if (ctx->chain->flags & NFT_BASE_CHAIN) {
 		const struct nft_base_chain *basechain =
 						nft_base_chain(ctx->chain);
-		const struct nf_hook_ops *ops = &basechain->ops;
+		const struct nf_hook_ops *ops = &basechain->ops[0];
 
 		par->hook_mask = 1 << ops->hooknum;
 	}
@@ -449,7 +449,7 @@ static int nft_match_validate(const struct nft_ctx *ctx,
 	if (ctx->chain->flags & NFT_BASE_CHAIN) {
 		const struct nft_base_chain *basechain =
 						nft_base_chain(ctx->chain);
-		const struct nf_hook_ops *ops = &basechain->ops;
+		const struct nf_hook_ops *ops = &basechain->ops[0];
 
 		hook_mask = 1 << ops->hooknum;
 		if (hook_mask & match->hooks)
-- 
1.8.4.2


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

* [PATCH 4/6] netfilter: nf_tables: add "inet" table for IPv4/IPv6
  2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
                   ` (2 preceding siblings ...)
  2014-01-03 12:16 ` [PATCH 3/6] netfilter: nf_tables: add support for multi family tables Patrick McHardy
@ 2014-01-03 12:16 ` Patrick McHardy
  2014-01-03 12:16 ` [PATCH 5/6] netfilter: nf_tables: add nfproto support to meta expression Patrick McHardy
                   ` (4 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2014-01-03 12:16 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/net/netfilter/nf_tables_ipv4.h |  2 +
 include/net/netfilter/nf_tables_ipv6.h |  2 +
 include/net/netns/nftables.h           |  1 +
 include/uapi/linux/netfilter.h         |  1 +
 net/ipv4/netfilter/nf_tables_ipv4.c    |  3 +-
 net/ipv6/netfilter/nf_tables_ipv6.c    |  3 +-
 net/netfilter/Kconfig                  |  8 +++
 net/netfilter/Makefile                 |  1 +
 net/netfilter/nf_tables_inet.c         | 97 ++++++++++++++++++++++++++++++++++
 9 files changed, 116 insertions(+), 2 deletions(-)
 create mode 100644 net/netfilter/nf_tables_inet.c

diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h
index 1be1c2c..f7b3a66 100644
--- a/include/net/netfilter/nf_tables_ipv4.h
+++ b/include/net/netfilter/nf_tables_ipv4.h
@@ -20,4 +20,6 @@ nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
 	pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
 }
 
+extern struct nft_af_info nft_af_ipv4;
+
 #endif
diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h
index 4a9b88a..3d8ae48 100644
--- a/include/net/netfilter/nf_tables_ipv6.h
+++ b/include/net/netfilter/nf_tables_ipv6.h
@@ -27,4 +27,6 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
 	return 0;
 }
 
+extern struct nft_af_info nft_af_ipv6;
+
 #endif
diff --git a/include/net/netns/nftables.h b/include/net/netns/nftables.h
index 15d056d..26a394c 100644
--- a/include/net/netns/nftables.h
+++ b/include/net/netns/nftables.h
@@ -10,6 +10,7 @@ struct netns_nftables {
 	struct list_head	commit_list;
 	struct nft_af_info	*ipv4;
 	struct nft_af_info	*ipv6;
+	struct nft_af_info	*inet;
 	struct nft_af_info	*arp;
 	struct nft_af_info	*bridge;
 	u8			gencursor;
diff --git a/include/uapi/linux/netfilter.h b/include/uapi/linux/netfilter.h
index f7dc0eb..ef1b1f8 100644
--- a/include/uapi/linux/netfilter.h
+++ b/include/uapi/linux/netfilter.h
@@ -53,6 +53,7 @@ enum nf_inet_hooks {
 
 enum {
 	NFPROTO_UNSPEC =  0,
+	NFPROTO_INET   =  1,
 	NFPROTO_IPV4   =  2,
 	NFPROTO_ARP    =  3,
 	NFPROTO_BRIDGE =  7,
diff --git a/net/ipv4/netfilter/nf_tables_ipv4.c b/net/ipv4/netfilter/nf_tables_ipv4.c
index 177c3bc..da927dc 100644
--- a/net/ipv4/netfilter/nf_tables_ipv4.c
+++ b/net/ipv4/netfilter/nf_tables_ipv4.c
@@ -48,7 +48,7 @@ static unsigned int nft_ipv4_output(const struct nf_hook_ops *ops,
 	return nft_do_chain_ipv4(ops, skb, in, out, okfn);
 }
 
-static struct nft_af_info nft_af_ipv4 __read_mostly = {
+struct nft_af_info nft_af_ipv4 __read_mostly = {
 	.family		= NFPROTO_IPV4,
 	.nhooks		= NF_INET_NUMHOOKS,
 	.owner		= THIS_MODULE,
@@ -61,6 +61,7 @@ static struct nft_af_info nft_af_ipv4 __read_mostly = {
 		[NF_INET_POST_ROUTING]	= nft_do_chain_ipv4,
 	},
 };
+EXPORT_SYMBOL_GPL(nft_af_ipv4);
 
 static int nf_tables_ipv4_init_net(struct net *net)
 {
diff --git a/net/ipv6/netfilter/nf_tables_ipv6.c b/net/ipv6/netfilter/nf_tables_ipv6.c
index 642280e..025e7f4 100644
--- a/net/ipv6/netfilter/nf_tables_ipv6.c
+++ b/net/ipv6/netfilter/nf_tables_ipv6.c
@@ -47,7 +47,7 @@ static unsigned int nft_ipv6_output(const struct nf_hook_ops *ops,
 	return nft_do_chain_ipv6(ops, skb, in, out, okfn);
 }
 
-static struct nft_af_info nft_af_ipv6 __read_mostly = {
+struct nft_af_info nft_af_ipv6 __read_mostly = {
 	.family		= NFPROTO_IPV6,
 	.nhooks		= NF_INET_NUMHOOKS,
 	.owner		= THIS_MODULE,
@@ -60,6 +60,7 @@ static struct nft_af_info nft_af_ipv6 __read_mostly = {
 		[NF_INET_POST_ROUTING]	= nft_do_chain_ipv6,
 	},
 };
+EXPORT_SYMBOL_GPL(nft_af_ipv6);
 
 static int nf_tables_ipv6_init_net(struct net *net)
 {
diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig
index c3398cd..bd93136 100644
--- a/net/netfilter/Kconfig
+++ b/net/netfilter/Kconfig
@@ -417,6 +417,14 @@ config NF_TABLES
 	depends on NETFILTER_NETLINK
 	tristate "Netfilter nf_tables support"
 
+config NF_TABLES_INET
+	depends on NF_TABLES
+	select NF_TABLES_IPV4
+	select NF_TABLES_IPV6
+	tristate "Netfilter nf_tables mixed IPv4/IPv6 tables support"
+	help
+	  This option enables support for a mixed IPv4/IPv6 "inet" table.
+
 config NFT_EXTHDR
 	depends on NF_TABLES
 	tristate "Netfilter nf_tables IPv6 exthdr module"
diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile
index 394483b..017da0b 100644
--- a/net/netfilter/Makefile
+++ b/net/netfilter/Makefile
@@ -70,6 +70,7 @@ nf_tables-objs += nft_immediate.o nft_cmp.o nft_lookup.o
 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_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_inet.c b/net/netfilter/nf_tables_inet.c
new file mode 100644
index 0000000..ac0edcb
--- /dev/null
+++ b/net/netfilter/nf_tables_inet.c
@@ -0,0 +1,97 @@
+/*
+ * Copyright (c) 2012-2014 Patrick McHardy <kaber@trash.net>
+ *
+ * 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 <linux/ip.h>
+#include <linux/netfilter_ipv4.h>
+#include <linux/netfilter_ipv6.h>
+#include <net/netfilter/nf_tables.h>
+#include <net/netfilter/nf_tables_ipv4.h>
+#include <net/netfilter/nf_tables_ipv6.h>
+#include <net/ip.h>
+
+static void nft_inet_hook_ops_init(struct nf_hook_ops *ops, unsigned int n)
+{
+	struct nft_af_info *afi;
+
+	if (n == 1)
+		afi = &nft_af_ipv4;
+	else
+		afi = &nft_af_ipv6;
+
+	ops->pf = afi->family;
+	if (afi->hooks[ops->hooknum])
+		ops->hook = afi->hooks[ops->hooknum];
+}
+
+static struct nft_af_info nft_af_inet __read_mostly = {
+	.family		= NFPROTO_INET,
+	.nhooks		= NF_INET_NUMHOOKS,
+	.owner		= THIS_MODULE,
+	.nops		= 2,
+	.hook_ops_init	= nft_inet_hook_ops_init,
+};
+
+static int __net_init nf_tables_inet_init_net(struct net *net)
+{
+	net->nft.inet = kmalloc(sizeof(struct nft_af_info), GFP_KERNEL);
+	if (net->nft.inet == NULL)
+		return -ENOMEM;
+	memcpy(net->nft.inet, &nft_af_inet, sizeof(nft_af_inet));
+
+	if (nft_register_afinfo(net, net->nft.inet) < 0)
+		goto err;
+
+	return 0;
+
+err:
+	kfree(net->nft.inet);
+	return -ENOMEM;
+}
+
+static void __net_exit nf_tables_inet_exit_net(struct net *net)
+{
+	nft_unregister_afinfo(net->nft.inet);
+	kfree(net->nft.inet);
+}
+
+static struct pernet_operations nf_tables_inet_net_ops = {
+	.init	= nf_tables_inet_init_net,
+	.exit	= nf_tables_inet_exit_net,
+};
+
+static struct nf_chain_type filter_inet = {
+	.family		= NFPROTO_INET,
+	.name		= "filter",
+	.type		= NFT_CHAIN_T_DEFAULT,
+	.hook_mask	= (1 << NF_INET_LOCAL_IN) |
+			  (1 << NF_INET_LOCAL_OUT) |
+			  (1 << NF_INET_FORWARD) |
+			  (1 << NF_INET_PRE_ROUTING) |
+			  (1 << NF_INET_POST_ROUTING),
+};
+
+static int __init nf_tables_inet_init(void)
+{
+	nft_register_chain_type(&filter_inet);
+	return register_pernet_subsys(&nf_tables_inet_net_ops);
+}
+
+static void __exit nf_tables_inet_exit(void)
+{
+	unregister_pernet_subsys(&nf_tables_inet_net_ops);
+	nft_unregister_chain_type(&filter_inet);
+}
+
+module_init(nf_tables_inet_init);
+module_exit(nf_tables_inet_exit);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
+MODULE_ALIAS_NFT_FAMILY(1);
-- 
1.8.4.2


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

* [PATCH 5/6] netfilter: nf_tables: add nfproto support to meta expression
  2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
                   ` (3 preceding siblings ...)
  2014-01-03 12:16 ` [PATCH 4/6] netfilter: nf_tables: add "inet" table for IPv4/IPv6 Patrick McHardy
@ 2014-01-03 12:16 ` Patrick McHardy
  2014-01-03 12:16 ` [PATCH 6/6] netfilter: nft_meta: add l4proto support Patrick McHardy
                   ` (3 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2014-01-03 12:16 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

Needed by multi-family tables to distinguish IPv4 and IPv6 packets.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/uapi/linux/netfilter/nf_tables.h | 2 ++
 net/netfilter/nft_meta.c                 | 4 ++++
 2 files changed, 6 insertions(+)

diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index fbfd229..7ec92a9 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -529,6 +529,7 @@ enum nft_exthdr_attributes {
  * @NFT_META_NFTRACE: packet nftrace bit
  * @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid)
  * @NFT_META_SECMARK: packet secmark (skb->secmark)
+ * @NFT_META_NFPROTO: netfilter protocol
  */
 enum nft_meta_keys {
 	NFT_META_LEN,
@@ -546,6 +547,7 @@ enum nft_meta_keys {
 	NFT_META_NFTRACE,
 	NFT_META_RTCLASSID,
 	NFT_META_SECMARK,
+	NFT_META_NFPROTO,
 };
 
 /**
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 8c28220..06a4f30 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -40,6 +40,9 @@ static void nft_meta_eval(const struct nft_expr *expr,
 	case NFT_META_PROTOCOL:
 		*(__be16 *)dest->data = skb->protocol;
 		break;
+	case NFT_META_NFPROTO:
+		dest->data[0] = pkt->ops->pf;
+		break;
 	case NFT_META_PRIORITY:
 		dest->data[0] = skb->priority;
 		break;
@@ -151,6 +154,7 @@ static int nft_meta_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 	switch (priv->key) {
 	case NFT_META_LEN:
 	case NFT_META_PROTOCOL:
+	case NFT_META_NFPROTO:
 	case NFT_META_PRIORITY:
 	case NFT_META_MARK:
 	case NFT_META_IIF:
-- 
1.8.4.2


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

* [PATCH 6/6] netfilter: nft_meta: add l4proto support
  2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
                   ` (4 preceding siblings ...)
  2014-01-03 12:16 ` [PATCH 5/6] netfilter: nf_tables: add nfproto support to meta expression Patrick McHardy
@ 2014-01-03 12:16 ` Patrick McHardy
  2014-01-05 20:39 ` [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  8 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2014-01-03 12:16 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

For L3-proto independant rules we need to get at the L4 protocol value
directly. Add it to the nft_pktinfo struct and use the meta expression
to retrieve it.

Signed-off-by: Patrick McHardy <kaber@trash.net>
---
 include/net/netfilter/nf_tables.h        | 1 +
 include/net/netfilter/nf_tables_ipv4.h   | 3 ++-
 include/net/netfilter/nf_tables_ipv6.h   | 1 +
 include/uapi/linux/netfilter/nf_tables.h | 2 ++
 net/netfilter/nft_meta.c                 | 4 ++++
 5 files changed, 10 insertions(+), 1 deletion(-)

diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h
index f066f25..5d2b703 100644
--- a/include/net/netfilter/nf_tables.h
+++ b/include/net/netfilter/nf_tables.h
@@ -16,6 +16,7 @@ struct nft_pktinfo {
 	const struct nf_hook_ops	*ops;
 	u8				nhoff;
 	u8				thoff;
+	u8				tprot;
 	/* for x_tables compatibility */
 	struct xt_action_param		xt;
 };
diff --git a/include/net/netfilter/nf_tables_ipv4.h b/include/net/netfilter/nf_tables_ipv4.h
index f7b3a66..cba143f 100644
--- a/include/net/netfilter/nf_tables_ipv4.h
+++ b/include/net/netfilter/nf_tables_ipv4.h
@@ -15,8 +15,9 @@ nft_set_pktinfo_ipv4(struct nft_pktinfo *pkt,
 
 	nft_set_pktinfo(pkt, ops, skb, in, out);
 
-	pkt->xt.thoff = ip_hdrlen(pkt->skb);
 	ip = ip_hdr(pkt->skb);
+	pkt->tprot = ip->protocol;
+	pkt->xt.thoff = ip_hdrlen(pkt->skb);
 	pkt->xt.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
 }
 
diff --git a/include/net/netfilter/nf_tables_ipv6.h b/include/net/netfilter/nf_tables_ipv6.h
index 3d8ae48..74d9761 100644
--- a/include/net/netfilter/nf_tables_ipv6.h
+++ b/include/net/netfilter/nf_tables_ipv6.h
@@ -21,6 +21,7 @@ nft_set_pktinfo_ipv6(struct nft_pktinfo *pkt,
 	if (protohdr < 0)
 		return -1;
 
+	pkt->tprot = protohdr;
 	pkt->xt.thoff = thoff;
 	pkt->xt.fragoff = frag_off;
 
diff --git a/include/uapi/linux/netfilter/nf_tables.h b/include/uapi/linux/netfilter/nf_tables.h
index 7ec92a9..d557a2c 100644
--- a/include/uapi/linux/netfilter/nf_tables.h
+++ b/include/uapi/linux/netfilter/nf_tables.h
@@ -530,6 +530,7 @@ enum nft_exthdr_attributes {
  * @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid)
  * @NFT_META_SECMARK: packet secmark (skb->secmark)
  * @NFT_META_NFPROTO: netfilter protocol
+ * @NFT_META_L4PROTO: layer 4 protocol number
  */
 enum nft_meta_keys {
 	NFT_META_LEN,
@@ -548,6 +549,7 @@ enum nft_meta_keys {
 	NFT_META_RTCLASSID,
 	NFT_META_SECMARK,
 	NFT_META_NFPROTO,
+	NFT_META_L4PROTO,
 };
 
 /**
diff --git a/net/netfilter/nft_meta.c b/net/netfilter/nft_meta.c
index 06a4f30..62d8de3 100644
--- a/net/netfilter/nft_meta.c
+++ b/net/netfilter/nft_meta.c
@@ -43,6 +43,9 @@ static void nft_meta_eval(const struct nft_expr *expr,
 	case NFT_META_NFPROTO:
 		dest->data[0] = pkt->ops->pf;
 		break;
+	case NFT_META_L4PROTO:
+		dest->data[0] = pkt->tprot;
+		break;
 	case NFT_META_PRIORITY:
 		dest->data[0] = skb->priority;
 		break;
@@ -155,6 +158,7 @@ static int nft_meta_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 	case NFT_META_LEN:
 	case NFT_META_PROTOCOL:
 	case NFT_META_NFPROTO:
+	case NFT_META_L4PROTO:
 	case NFT_META_PRIORITY:
 	case NFT_META_MARK:
 	case NFT_META_IIF:
-- 
1.8.4.2


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

* Re: [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support
  2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
                   ` (5 preceding siblings ...)
  2014-01-03 12:16 ` [PATCH 6/6] netfilter: nft_meta: add l4proto support Patrick McHardy
@ 2014-01-05 20:39 ` Pablo Neira Ayuso
  2014-01-05 21:02   ` Patrick McHardy
  2014-01-06 18:09 ` [PATCH 7/6] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET Patrick McHardy
  2014-01-07 23:03 ` [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Pablo Neira Ayuso
  8 siblings, 1 reply; 12+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-05 20:39 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel

Hi Patrick!

On Fri, Jan 03, 2014 at 12:16:12PM +0000, Patrick McHardy wrote:
> The following patches add support for mixed IPv4/IPv6 tables to nftables.
> 
> The first patch fixes the chain type override logic so chain types override
> the AF defaults instead of the other way around. The second patch adds a
> pointer to the nf_hook_ops struct to nft_pktinfo for a later patch which
> uses ops->pf to match the actual AF of the packet instead of the dummy
> NFPROTO_INET value. The third patch changes the chain and hook registration
> logic to support multiple hook registrations. The nf_tables AF modules can
> provide a callback function to override defaults. The fourth patch finally
> adds a new "inet" family, which basically only initializes the hook
> functions to the IPv4 and IPv6 specific ones and registers a dummy filter
> chain type for NFPROTO_INET. Patches 5 and 6 add support for matching on
> the netfilter hook family and the L4 protocol number to the meta match.
> 
> With all this in place, we can create AF-specific rules and AF-independant
> rules that only match on the L4 protocol header and above in the inet table:
> 
> table inet filter {
>         chain input {
>                  type filter hook input priority 0;
>         }
> 
> 	chain forward {
>                  type filter hook forward priority 0;
>         }
> 
> 	chain output {
>                  type filter hook output priority 0;
>                  ip protocol tcp tcp dport 1234 counter packets 2 bytes 120
>                  ip6 nexthdr tcp tcp dport 1234 counter packets 2 bytes 160
>                  tcp dport 1234 counter packets 4 bytes 280
> 	}
> }
> 
> Userspace needs a bit of polishing but will most likely follow in a few
> hours.
> 
> Comments welcome.

This patchset looks pretty good, I think there is some clashing with
recent Arturo's work to set meta information, please see this patch.

http://git.kernel.org/cgit/linux/kernel/git/pablo/nftables.git/commit/?id=e035b77ac7be430a5fef8c9c23f60b6b50ec81c5

But that I can manually resolve that.

We'll also need route and mangle chains for the new inet family type,
but that's also easy to add.

Let me know if I can give you a hand with the userspace patch, you can
post a tentative RFC before polishing if you like.

Thanks!

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

* Re: [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support
  2014-01-05 20:39 ` [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Pablo Neira Ayuso
@ 2014-01-05 21:02   ` Patrick McHardy
  0 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2014-01-05 21:02 UTC (permalink / raw)
  To: Pablo Neira Ayuso; +Cc: netfilter-devel

On Sun, Jan 05, 2014 at 09:39:25PM +0100, Pablo Neira Ayuso wrote:
> Hi Patrick!
> 
> On Fri, Jan 03, 2014 at 12:16:12PM +0000, Patrick McHardy wrote:
> > The following patches add support for mixed IPv4/IPv6 tables to nftables.
> > 
> > The first patch fixes the chain type override logic so chain types override
> > the AF defaults instead of the other way around. The second patch adds a
> > pointer to the nf_hook_ops struct to nft_pktinfo for a later patch which
> > uses ops->pf to match the actual AF of the packet instead of the dummy
> > NFPROTO_INET value. The third patch changes the chain and hook registration
> > logic to support multiple hook registrations. The nf_tables AF modules can
> > provide a callback function to override defaults. The fourth patch finally
> > adds a new "inet" family, which basically only initializes the hook
> > functions to the IPv4 and IPv6 specific ones and registers a dummy filter
> > chain type for NFPROTO_INET. Patches 5 and 6 add support for matching on
> > the netfilter hook family and the L4 protocol number to the meta match.
> > 
> > With all this in place, we can create AF-specific rules and AF-independant
> > rules that only match on the L4 protocol header and above in the inet table:
> > 
> > table inet filter {
> >         chain input {
> >                  type filter hook input priority 0;
> >         }
> > 
> > 	chain forward {
> >                  type filter hook forward priority 0;
> >         }
> > 
> > 	chain output {
> >                  type filter hook output priority 0;
> >                  ip protocol tcp tcp dport 1234 counter packets 2 bytes 120
> >                  ip6 nexthdr tcp tcp dport 1234 counter packets 2 bytes 160
> >                  tcp dport 1234 counter packets 4 bytes 280
> > 	}
> > }
> > 
> > Userspace needs a bit of polishing but will most likely follow in a few
> > hours.
> > 
> > Comments welcome.
> 
> This patchset looks pretty good, I think there is some clashing with
> recent Arturo's work to set meta information, please see this patch.
> 
> http://git.kernel.org/cgit/linux/kernel/git/pablo/nftables.git/commit/?id=e035b77ac7be430a5fef8c9c23f60b6b50ec81c5
> 
> But that I can manually resolve that.
> 
> We'll also need route and mangle chains for the new inet family type,
> but that's also easy to add.

Well, route is certainly fine. If you mean nat (we don't have mangle),
I'll leave that to the future since the AF-specific stuff still needs a
bit of thought.

> Let me know if I can give you a hand with the userspace patch, you can
> post a tentative RFC before polishing if you like.

Actually its already finished, I just generalized it a bit to solve a
couple of related problems wrt. protocol contexts. Final patchsets will
come tommorrow.

Cheers,
Patrick

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

* [PATCH 7/6] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
  2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
                   ` (6 preceding siblings ...)
  2014-01-05 20:39 ` [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Pablo Neira Ayuso
@ 2014-01-06 18:09 ` Patrick McHardy
  2014-01-07 23:03   ` Pablo Neira Ayuso
  2014-01-07 23:03 ` [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Pablo Neira Ayuso
  8 siblings, 1 reply; 12+ messages in thread
From: Patrick McHardy @ 2014-01-06 18:09 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel

commit 71bcc5bde767f1a6da04391b0d9595f30e3f720b
Author: Patrick McHardy <kaber@trash.net>
Date:   Mon Jan 6 17:58:02 2014 +0000

    netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
    
    The ct expression can currently not be used in the inet family since
    we don't have a conntrack module for NFPROTO_INET, so
    nf_ct_l3proto_try_module_get() fails. Add some manual handling to
    load the modules for both NFPROTO_IPV4 and NFPROTO_IPV6 if the
    ct expression is used in the inet family.
    
    Signed-off-by: Patrick McHardy <kaber@trash.net>

diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c
index 955f4e6..78bf57c 100644
--- a/net/netfilter/nft_ct.c
+++ b/net/netfilter/nft_ct.c
@@ -129,6 +129,39 @@ static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = {
 	[NFTA_CT_DIRECTION]	= { .type = NLA_U8 },
 };
 
+static int nft_ct_l3proto_try_module_get(uint8_t family)
+{
+	int err;
+
+	if (family == NFPROTO_INET) {
+		err = nf_ct_l3proto_try_module_get(NFPROTO_IPV4);
+		if (err < 0)
+			goto err1;
+		err = nf_ct_l3proto_try_module_get(NFPROTO_IPV6);
+		if (err < 0)
+			goto err2;
+	} else {
+		err = nf_ct_l3proto_try_module_get(family);
+		if (err < 0)
+			goto err1;
+	}
+	return 0;
+
+err2:
+	nf_ct_l3proto_module_put(NFPROTO_IPV4);
+err1:
+	return err;
+}
+
+static void nft_ct_l3proto_module_put(uint8_t family)
+{
+	if (family == NFPROTO_INET) {
+		nf_ct_l3proto_module_put(NFPROTO_IPV4);
+		nf_ct_l3proto_module_put(NFPROTO_IPV6);
+	} else
+		nf_ct_l3proto_module_put(family);
+}
+
 static int nft_ct_init(const struct nft_ctx *ctx,
 		       const struct nft_expr *expr,
 		       const struct nlattr * const tb[])
@@ -179,7 +212,7 @@ static int nft_ct_init(const struct nft_ctx *ctx,
 		return -EOPNOTSUPP;
 	}
 
-	err = nf_ct_l3proto_try_module_get(ctx->afi->family);
+	err = nft_ct_l3proto_try_module_get(ctx->afi->family);
 	if (err < 0)
 		return err;
 	priv->family = ctx->afi->family;
@@ -195,7 +228,7 @@ static int nft_ct_init(const struct nft_ctx *ctx,
 	return 0;
 
 err1:
-	nf_ct_l3proto_module_put(ctx->afi->family);
+	nft_ct_l3proto_module_put(ctx->afi->family);
 	return err;
 }
 
@@ -203,7 +236,7 @@ static void nft_ct_destroy(const struct nft_expr *expr)
 {
 	struct nft_ct *priv = nft_expr_priv(expr);
 
-	nf_ct_l3proto_module_put(priv->family);
+	nft_ct_l3proto_module_put(priv->family);
 }
 
 static int nft_ct_dump(struct sk_buff *skb, const struct nft_expr *expr)

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

* Re: [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support
  2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
                   ` (7 preceding siblings ...)
  2014-01-06 18:09 ` [PATCH 7/6] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET Patrick McHardy
@ 2014-01-07 23:03 ` Pablo Neira Ayuso
  8 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-07 23:03 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel

On Fri, Jan 03, 2014 at 12:16:12PM +0000, Patrick McHardy wrote:
> The following patches add support for mixed IPv4/IPv6 tables to nftables.
> 
> The first patch fixes the chain type override logic so chain types override
> the AF defaults instead of the other way around. The second patch adds a
> pointer to the nf_hook_ops struct to nft_pktinfo for a later patch which
> uses ops->pf to match the actual AF of the packet instead of the dummy
> NFPROTO_INET value. The third patch changes the chain and hook registration
> logic to support multiple hook registrations. The nf_tables AF modules can
> provide a callback function to override defaults. The fourth patch finally
> adds a new "inet" family, which basically only initializes the hook
> functions to the IPv4 and IPv6 specific ones and registers a dummy filter
> chain type for NFPROTO_INET. Patches 5 and 6 add support for matching on
> the netfilter hook family and the L4 protocol number to the meta match.
> 
> With all this in place, we can create AF-specific rules and AF-independant
> rules that only match on the L4 protocol header and above in the inet table:
> 
> table inet filter {
>         chain input {
>                  type filter hook input priority 0;
>         }
> 
> 	chain forward {
>                  type filter hook forward priority 0;
>         }
> 
> 	chain output {
>                  type filter hook output priority 0;
>                  ip protocol tcp tcp dport 1234 counter packets 2 bytes 120
>                  ip6 nexthdr tcp tcp dport 1234 counter packets 2 bytes 160
>                  tcp dport 1234 counter packets 4 bytes 280
> 	}
> }
> 
> Userspace needs a bit of polishing but will most likely follow in a few
> hours.

Series applied, thanks Patrick!

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

* Re: [PATCH 7/6] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
  2014-01-06 18:09 ` [PATCH 7/6] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET Patrick McHardy
@ 2014-01-07 23:03   ` Pablo Neira Ayuso
  0 siblings, 0 replies; 12+ messages in thread
From: Pablo Neira Ayuso @ 2014-01-07 23:03 UTC (permalink / raw)
  To: Patrick McHardy; +Cc: netfilter-devel

On Mon, Jan 06, 2014 at 06:09:49PM +0000, Patrick McHardy wrote:
> commit 71bcc5bde767f1a6da04391b0d9595f30e3f720b
> Author: Patrick McHardy <kaber@trash.net>
> Date:   Mon Jan 6 17:58:02 2014 +0000
> 
>     netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET
>     
>     The ct expression can currently not be used in the inet family since
>     we don't have a conntrack module for NFPROTO_INET, so
>     nf_ct_l3proto_try_module_get() fails. Add some manual handling to
>     load the modules for both NFPROTO_IPV4 and NFPROTO_IPV6 if the
>     ct expression is used in the inet family.

Applied, thanks!

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

end of thread, other threads:[~2014-01-07 23:03 UTC | newest]

Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-03 12:16 [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Patrick McHardy
2014-01-03 12:16 ` [PATCH 1/6] netfilter: nf_tables: make chain types override the default AF functions Patrick McHardy
2014-01-03 12:16 ` [PATCH 2/6] netfilter: nf_tables: add hook ops to struct nft_pktinfo Patrick McHardy
2014-01-03 12:16 ` [PATCH 3/6] netfilter: nf_tables: add support for multi family tables Patrick McHardy
2014-01-03 12:16 ` [PATCH 4/6] netfilter: nf_tables: add "inet" table for IPv4/IPv6 Patrick McHardy
2014-01-03 12:16 ` [PATCH 5/6] netfilter: nf_tables: add nfproto support to meta expression Patrick McHardy
2014-01-03 12:16 ` [PATCH 6/6] netfilter: nft_meta: add l4proto support Patrick McHardy
2014-01-05 20:39 ` [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support Pablo Neira Ayuso
2014-01-05 21:02   ` Patrick McHardy
2014-01-06 18:09 ` [PATCH 7/6] netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET Patrick McHardy
2014-01-07 23:03   ` Pablo Neira Ayuso
2014-01-07 23:03 ` [RFC PATCH 0/6] netfilter: nf_tables: add mixed IPv4/IPv6 table support 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).