netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/18] Netfilter updates for net-next
@ 2015-08-04 10:02 Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 01/18] netfilter: kill nf_hooks_active Pablo Neira Ayuso
                   ` (18 more replies)
  0 siblings, 19 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Hi David,

The following patchset contains Netfilter updates for net-next, they are:

1) A couple of cleanups for the netfilter core hook from Eric Biederman.

2) Net namespace hook registration, also from Eric. This adds a dependency with
   the rtnl_lock. This should be fine by now but we have to keep an eye on this
   because if we ever get the per-subsys nfnl_lock before rtnl we have may
   problems in the future. But we have room to remove this in the future by
   propagating the complexity to the clients, by registering hooks for the init
   netns functions.

3) Update nf_tables to use the new net namespace hook infrastructure, also from
   Eric.

4) Three patches to refine and to address problems from the new net namespace
   hook infrastructure.

5) Switch to alternate jumpstack in xtables iff the packet is reentering. This
   only applies to a very special case, the TEE target, but Eric Dumazet
   reports that this is slowing down things for everyone else. So let's only
   switch to the alternate jumpstack if the tee target is in used through a
   static key. This batch also comes with offline precalculation of the
   jumpstack based on the callchain depth. From Florian Westphal.

6) Minimal SCTP multihoming support for our conntrack helper, from Michal
   Kubecek.

7) Reduce nf_bridge_info per skbuff scratchpad area to 32 bytes, from Florian
   Westphal.

8) Fix several checkpatch errors in bridge netfilter, from Bernhard Thaler.

9) Get rid of useless debug message in ip6t_REJECT, from Subash Abhinov.

You can pull these changes from:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git

Thanks!

----------------------------------------------------------------

The following changes since commit 0d6ef0688d8744454646298b85336407be05e309:

  ipvs: Delete an unnecessary check before the function call "module_put" (2015-07-15 17:51:22 +0200)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master

for you to fetch changes up to a6cd379b4d68867295ea35a719008e86d7a2ee9f:

  netfilter: ip6t_REJECT: Remove debug messages from reject_tg6() (2015-08-04 11:12:51 +0200)

----------------------------------------------------------------
Bernhard Thaler (1):
      netfilter: bridge: do not initialize statics to 0 or NULL

Eric W. Biederman (6):
      netfilter: kill nf_hooks_active
      netfilter: Simply the tests for enabling and disabling the ingress queue hook
      netfilter: Factor out the hook list selection from nf_register_hook
      netfilter: Per network namespace netfilter hooks.
      netfilter: nftables: Only run the nftables chains in the proper netns
      netfilter: Fix memory leak in nf_register_net_hook

Florian Westphal (6):
      netfilter: xtables: compute exact size needed for jumpstack
      netfilter: move tee_active to core
      netfilter: xtables: don't save/restore jumpstack offset
      netfilter: add and use jump label for xt_tee
      netfilter: xtables: remove __pure annotation
      netfilter: bridge: reduce nf_bridge_info to 32 bytes again

Michal Kubeček (1):
      netfilter: nf_ct_sctp: minimal multihoming support

Pablo Neira Ayuso (3):
      netfilter: nf_queue: fix nf_queue_nf_hook_drop()
      netfilter: fix possible removal of wrong hook
      netfilter: rename local nf_hook_list to hook_list

Subash Abhinov Kasiviswanathan (1):
      netfilter: ip6t_REJECT: Remove debug messages from reject_tg6()

 include/linux/netfilter.h                          |   42 ++--
 include/linux/netfilter/x_tables.h                 |    8 +-
 include/linux/netfilter_bridge.h                   |   12 +-
 include/linux/skbuff.h                             |   19 +-
 include/net/netns/netfilter.h                      |    1 +
 include/uapi/linux/netfilter/nf_conntrack_sctp.h   |    2 +
 include/uapi/linux/netfilter/nfnetlink_cttimeout.h |    2 +
 net/bridge/br_netfilter_hooks.c                    |   20 +-
 net/bridge/br_netfilter_ipv6.c                     |    2 +-
 net/ipv4/netfilter/arp_tables.c                    |   32 +--
 net/ipv4/netfilter/ip_tables.c                     |   68 +++---
 net/ipv4/netfilter/nf_defrag_ipv4.c                |    7 +-
 net/ipv6/netfilter/ip6_tables.c                    |   52 +++--
 net/ipv6/netfilter/ip6t_REJECT.c                   |    5 -
 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c          |    7 +-
 net/netfilter/core.c                               |  225 ++++++++++++++++----
 net/netfilter/nf_conntrack_proto_sctp.c            |  101 ++++++---
 net/netfilter/nf_internals.h                       |    2 +-
 net/netfilter/nf_queue.c                           |   12 +-
 net/netfilter/nf_tables_api.c                      |    8 +-
 net/netfilter/nf_tables_core.c                     |    5 -
 net/netfilter/x_tables.c                           |   29 ++-
 net/netfilter/xt_TEE.c                             |   15 +-
 23 files changed, 460 insertions(+), 216 deletions(-)
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" 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] 32+ messages in thread

* [PATCH 01/18] netfilter: kill nf_hooks_active
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 02/18] netfilter: Simply the tests for enabling and disabling the ingress queue hook Pablo Neira Ayuso
                   ` (17 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: "Eric W. Biederman" <ebiederm@xmission.com>

The function obscures what is going on in nf_hook_thresh and it's existence
requires computing the hook list twice.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netfilter.h |   11 ++++-------
 1 file changed, 4 insertions(+), 7 deletions(-)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 00050df..60e89348 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -150,11 +150,6 @@ static inline bool nf_hook_list_active(struct list_head *nf_hook_list,
 }
 #endif
 
-static inline bool nf_hooks_active(u_int8_t pf, unsigned int hook)
-{
-	return nf_hook_list_active(&nf_hooks[pf][hook], pf, hook);
-}
-
 int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state);
 
 /**
@@ -172,10 +167,12 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
 				 int (*okfn)(struct sock *, struct sk_buff *),
 				 int thresh)
 {
-	if (nf_hooks_active(pf, hook)) {
+	struct list_head *nf_hook_list = &nf_hooks[pf][hook];
+
+	if (nf_hook_list_active(nf_hook_list, pf, hook)) {
 		struct nf_hook_state state;
 
-		nf_hook_state_init(&state, &nf_hooks[pf][hook], hook, thresh,
+		nf_hook_state_init(&state, nf_hook_list, hook, thresh,
 				   pf, indev, outdev, sk, okfn);
 		return nf_hook_slow(skb, &state);
 	}
-- 
1.7.10.4

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

* [PATCH 02/18] netfilter: Simply the tests for enabling and disabling the ingress queue hook
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 01/18] netfilter: kill nf_hooks_active Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 03/18] netfilter: Factor out the hook list selection from nf_register_hook Pablo Neira Ayuso
                   ` (16 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: "Eric W. Biederman" <ebiederm@xmission.com>

Replace an overcomplicated switch statement with a simple if statement.

This also removes the ingress queue enable outside of nf_hook_mutex as
the protection provided by the mutex is not necessary and the code is
clearer having both of the static key increments together.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/core.c |   17 ++++++-----------
 1 file changed, 6 insertions(+), 11 deletions(-)

diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index a0e5497..c4c3b85 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -74,7 +74,6 @@ int nf_register_hook(struct nf_hook_ops *reg)
 		if (reg->hooknum == NF_NETDEV_INGRESS) {
 			BUG_ON(reg->dev == NULL);
 			nf_hook_list = &reg->dev->nf_hooks_ingress;
-			net_inc_ingress_queue();
 			break;
 		}
 #endif
@@ -90,6 +89,10 @@ int nf_register_hook(struct nf_hook_ops *reg)
 	}
 	list_add_rcu(&reg->list, elem->list.prev);
 	mutex_unlock(&nf_hook_mutex);
+#ifdef CONFIG_NETFILTER_INGRESS
+	if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS)
+		net_inc_ingress_queue();
+#endif
 #ifdef HAVE_JUMP_LABEL
 	static_key_slow_inc(&nf_hooks_needed[reg->pf][reg->hooknum]);
 #endif
@@ -102,18 +105,10 @@ void nf_unregister_hook(struct nf_hook_ops *reg)
 	mutex_lock(&nf_hook_mutex);
 	list_del_rcu(&reg->list);
 	mutex_unlock(&nf_hook_mutex);
-	switch (reg->pf) {
-	case NFPROTO_NETDEV:
 #ifdef CONFIG_NETFILTER_INGRESS
-		if (reg->hooknum == NF_NETDEV_INGRESS) {
-			net_dec_ingress_queue();
-			break;
-		}
-		break;
+	if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS)
+		net_dec_ingress_queue();
 #endif
-	default:
-		break;
-	}
 #ifdef HAVE_JUMP_LABEL
 	static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]);
 #endif
-- 
1.7.10.4


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

* [PATCH 03/18] netfilter: Factor out the hook list selection from nf_register_hook
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 01/18] netfilter: kill nf_hooks_active Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 02/18] netfilter: Simply the tests for enabling and disabling the ingress queue hook Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 04/18] netfilter: Per network namespace netfilter hooks Pablo Neira Ayuso
                   ` (15 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: "Eric W. Biederman" <ebiederm@xmission.com>

- Add a new function find_nf_hook_list to select the nf_hook_list

- Fail nf_register_hook when asked for a per netdevice hook list when
  support for per netdevice hook lists is not built into the kernel.

- Move the hook list head selection outside of nf_hook_mutex as
  nothing in the selection requires the hook list, and error handling
  is simpler if a mutex is not held.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/core.c |   32 ++++++++++++++++++--------------
 1 file changed, 18 insertions(+), 14 deletions(-)

diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index c4c3b85..fa4d3c1 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -62,27 +62,31 @@ EXPORT_SYMBOL(nf_hooks_needed);
 
 static DEFINE_MUTEX(nf_hook_mutex);
 
-int nf_register_hook(struct nf_hook_ops *reg)
+static struct list_head *find_nf_hook_list(const struct nf_hook_ops *reg)
 {
-	struct list_head *nf_hook_list;
-	struct nf_hook_ops *elem;
+	struct list_head *nf_hook_list = NULL;
 
-	mutex_lock(&nf_hook_mutex);
-	switch (reg->pf) {
-	case NFPROTO_NETDEV:
+	if (reg->pf != NFPROTO_NETDEV)
+		nf_hook_list = &nf_hooks[reg->pf][reg->hooknum];
+	else if (reg->hooknum == NF_NETDEV_INGRESS) {
 #ifdef CONFIG_NETFILTER_INGRESS
-		if (reg->hooknum == NF_NETDEV_INGRESS) {
-			BUG_ON(reg->dev == NULL);
+		if (reg->dev)
 			nf_hook_list = &reg->dev->nf_hooks_ingress;
-			break;
-		}
 #endif
-		/* Fall through. */
-	default:
-		nf_hook_list = &nf_hooks[reg->pf][reg->hooknum];
-		break;
 	}
+	return nf_hook_list;
+}
+
+int nf_register_hook(struct nf_hook_ops *reg)
+{
+	struct list_head *nf_hook_list;
+	struct nf_hook_ops *elem;
 
+	nf_hook_list = find_nf_hook_list(reg);
+	if (!nf_hook_list)
+		return -ENOENT;
+
+	mutex_lock(&nf_hook_mutex);
 	list_for_each_entry(elem, nf_hook_list, list) {
 		if (reg->priority < elem->priority)
 			break;
-- 
1.7.10.4

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

* [PATCH 04/18] netfilter: Per network namespace netfilter hooks.
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (2 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 03/18] netfilter: Factor out the hook list selection from nf_register_hook Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 05/18] netfilter: nftables: Only run the nftables chains in the proper netns Pablo Neira Ayuso
                   ` (14 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: "Eric W. Biederman" <ebiederm@xmission.com>

- Add a new set of functions for registering and unregistering per
  network namespace hooks.

- Modify the old global namespace hook functions to use the per
  network namespace hooks in their implementation, so their remains a
  single list that needs to be walked for any hook (this is important
  for keeping the hook priority working and for keeping the code
  walking the hooks simple).

- Only allow registering the per netdevice hooks in the network
  namespace where the network device lives.

- Dynamically allocate the structures in the per network namespace
  hook list in nf_register_net_hook, and unregister them in
  nf_unregister_net_hook.

  Dynamic allocate is required somewhere as the number of network
  namespaces are not fixed so we might as well allocate them in the
  registration function.

  The chain of registered hooks on any list is expected to be small so
  the cost of walking that list to find the entry we are unregistering
  should also be small.

  Performing the management of the dynamically allocated list entries
  in the registration and unregistration functions keeps the complexity
  from spreading.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 include/linux/netfilter.h     |   14 +++-
 include/net/netns/netfilter.h |    1 +
 net/netfilter/core.c          |  182 ++++++++++++++++++++++++++++++++++++-----
 3 files changed, 173 insertions(+), 24 deletions(-)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 60e89348..9bbd110 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -11,6 +11,8 @@
 #include <linux/list.h>
 #include <linux/static_key.h>
 #include <linux/netfilter_defs.h>
+#include <linux/netdevice.h>
+#include <net/net_namespace.h>
 
 #ifdef CONFIG_NETFILTER
 static inline int NF_DROP_GETERR(int verdict)
@@ -118,6 +120,13 @@ struct nf_sockopt_ops {
 };
 
 /* Function to register/unregister hook points. */
+int nf_register_net_hook(struct net *net, const struct nf_hook_ops *ops);
+void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *ops);
+int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg,
+			  unsigned int n);
+void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg,
+			     unsigned int n);
+
 int nf_register_hook(struct nf_hook_ops *reg);
 void nf_unregister_hook(struct nf_hook_ops *reg);
 int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n);
@@ -128,8 +137,6 @@ void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n);
 int nf_register_sockopt(struct nf_sockopt_ops *reg);
 void nf_unregister_sockopt(struct nf_sockopt_ops *reg);
 
-extern struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
-
 #ifdef HAVE_JUMP_LABEL
 extern struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
 
@@ -167,7 +174,8 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
 				 int (*okfn)(struct sock *, struct sk_buff *),
 				 int thresh)
 {
-	struct list_head *nf_hook_list = &nf_hooks[pf][hook];
+	struct net *net = dev_net(indev ? indev : outdev);
+	struct list_head *nf_hook_list = &net->nf.hooks[pf][hook];
 
 	if (nf_hook_list_active(nf_hook_list, pf, hook)) {
 		struct nf_hook_state state;
diff --git a/include/net/netns/netfilter.h b/include/net/netns/netfilter.h
index 532e4ba..38aa498 100644
--- a/include/net/netns/netfilter.h
+++ b/include/net/netns/netfilter.h
@@ -14,5 +14,6 @@ struct netns_nf {
 #ifdef CONFIG_SYSCTL
 	struct ctl_table_header *nf_log_dir_header;
 #endif
+	struct list_head hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
 };
 #endif
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index fa4d3c1..56ead1a 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -52,9 +52,6 @@ void nf_unregister_afinfo(const struct nf_afinfo *afinfo)
 }
 EXPORT_SYMBOL_GPL(nf_unregister_afinfo);
 
-struct list_head nf_hooks[NFPROTO_NUMPROTO][NF_MAX_HOOKS] __read_mostly;
-EXPORT_SYMBOL(nf_hooks);
-
 #ifdef HAVE_JUMP_LABEL
 struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
 EXPORT_SYMBOL(nf_hooks_needed);
@@ -62,27 +59,40 @@ EXPORT_SYMBOL(nf_hooks_needed);
 
 static DEFINE_MUTEX(nf_hook_mutex);
 
-static struct list_head *find_nf_hook_list(const struct nf_hook_ops *reg)
+static struct list_head *find_nf_hook_list(struct net *net,
+					   const struct nf_hook_ops *reg)
 {
 	struct list_head *nf_hook_list = NULL;
 
 	if (reg->pf != NFPROTO_NETDEV)
-		nf_hook_list = &nf_hooks[reg->pf][reg->hooknum];
+		nf_hook_list = &net->nf.hooks[reg->pf][reg->hooknum];
 	else if (reg->hooknum == NF_NETDEV_INGRESS) {
 #ifdef CONFIG_NETFILTER_INGRESS
-		if (reg->dev)
+		if (reg->dev && dev_net(reg->dev) == net)
 			nf_hook_list = &reg->dev->nf_hooks_ingress;
 #endif
 	}
 	return nf_hook_list;
 }
 
-int nf_register_hook(struct nf_hook_ops *reg)
+int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
 {
 	struct list_head *nf_hook_list;
-	struct nf_hook_ops *elem;
+	struct nf_hook_ops *elem, *new;
+
+	new = kzalloc(sizeof(*new), GFP_KERNEL);
+	if (!new)
+		return -ENOMEM;
 
-	nf_hook_list = find_nf_hook_list(reg);
+	new->hook     = reg->hook;
+	new->dev      = reg->dev;
+	new->owner    = reg->owner;
+	new->priv     = reg->priv;
+	new->pf       = reg->pf;
+	new->hooknum  = reg->hooknum;
+	new->priority = reg->priority;
+
+	nf_hook_list = find_nf_hook_list(net, reg);
 	if (!nf_hook_list)
 		return -ENOENT;
 
@@ -91,7 +101,7 @@ int nf_register_hook(struct nf_hook_ops *reg)
 		if (reg->priority < elem->priority)
 			break;
 	}
-	list_add_rcu(&reg->list, elem->list.prev);
+	list_add_rcu(&new->list, elem->list.prev);
 	mutex_unlock(&nf_hook_mutex);
 #ifdef CONFIG_NETFILTER_INGRESS
 	if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS)
@@ -102,13 +112,35 @@ int nf_register_hook(struct nf_hook_ops *reg)
 #endif
 	return 0;
 }
-EXPORT_SYMBOL(nf_register_hook);
+EXPORT_SYMBOL(nf_register_net_hook);
 
-void nf_unregister_hook(struct nf_hook_ops *reg)
+void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 {
+	struct list_head *nf_hook_list;
+	struct nf_hook_ops *elem;
+
+	nf_hook_list = find_nf_hook_list(net, reg);
+	if (!nf_hook_list)
+		return;
+
 	mutex_lock(&nf_hook_mutex);
-	list_del_rcu(&reg->list);
+	list_for_each_entry(elem, nf_hook_list, list) {
+		if ((reg->hook     == elem->hook) &&
+		    (reg->dev      == elem->dev) &&
+		    (reg->owner    == elem->owner) &&
+		    (reg->priv     == elem->priv) &&
+		    (reg->pf       == elem->pf) &&
+		    (reg->hooknum  == elem->hooknum) &&
+		    (reg->priority == elem->priority)) {
+			list_del_rcu(&elem->list);
+			break;
+		}
+	}
 	mutex_unlock(&nf_hook_mutex);
+	if (&elem->list == nf_hook_list) {
+		WARN(1, "nf_unregister_net_hook: hook not found!\n");
+		return;
+	}
 #ifdef CONFIG_NETFILTER_INGRESS
 	if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS)
 		net_dec_ingress_queue();
@@ -117,7 +149,77 @@ void nf_unregister_hook(struct nf_hook_ops *reg)
 	static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]);
 #endif
 	synchronize_net();
-	nf_queue_nf_hook_drop(reg);
+	nf_queue_nf_hook_drop(elem);
+	kfree(elem);
+}
+EXPORT_SYMBOL(nf_unregister_net_hook);
+
+int nf_register_net_hooks(struct net *net, const struct nf_hook_ops *reg,
+			  unsigned int n)
+{
+	unsigned int i;
+	int err = 0;
+
+	for (i = 0; i < n; i++) {
+		err = nf_register_net_hook(net, &reg[i]);
+		if (err)
+			goto err;
+	}
+	return err;
+
+err:
+	if (i > 0)
+		nf_unregister_net_hooks(net, reg, i);
+	return err;
+}
+EXPORT_SYMBOL(nf_register_net_hooks);
+
+void nf_unregister_net_hooks(struct net *net, const struct nf_hook_ops *reg,
+			     unsigned int n)
+{
+	while (n-- > 0)
+		nf_unregister_net_hook(net, &reg[n]);
+}
+EXPORT_SYMBOL(nf_unregister_net_hooks);
+
+static LIST_HEAD(nf_hook_list);
+
+int nf_register_hook(struct nf_hook_ops *reg)
+{
+	struct net *net, *last;
+	int ret;
+
+	rtnl_lock();
+	for_each_net(net) {
+		ret = nf_register_net_hook(net, reg);
+		if (ret && ret != -ENOENT)
+			goto rollback;
+	}
+	list_add_tail(&reg->list, &nf_hook_list);
+	rtnl_unlock();
+
+	return 0;
+rollback:
+	last = net;
+	for_each_net(net) {
+		if (net == last)
+			break;
+		nf_unregister_net_hook(net, reg);
+	}
+	rtnl_unlock();
+	return ret;
+}
+EXPORT_SYMBOL(nf_register_hook);
+
+void nf_unregister_hook(struct nf_hook_ops *reg)
+{
+	struct net *net;
+
+	rtnl_lock();
+	list_del(&reg->list);
+	for_each_net(net)
+		nf_unregister_net_hook(net, reg);
+	rtnl_unlock();
 }
 EXPORT_SYMBOL(nf_unregister_hook);
 
@@ -294,8 +396,46 @@ void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *);
 EXPORT_SYMBOL(nf_nat_decode_session_hook);
 #endif
 
+static int nf_register_hook_list(struct net *net)
+{
+	struct nf_hook_ops *elem;
+	int ret;
+
+	rtnl_lock();
+	list_for_each_entry(elem, &nf_hook_list, list) {
+		ret = nf_register_net_hook(net, elem);
+		if (ret && ret != -ENOENT)
+			goto out_undo;
+	}
+	rtnl_unlock();
+	return 0;
+
+out_undo:
+	list_for_each_entry_continue_reverse(elem, &nf_hook_list, list)
+		nf_unregister_net_hook(net, elem);
+	rtnl_unlock();
+	return ret;
+}
+
+static void nf_unregister_hook_list(struct net *net)
+{
+	struct nf_hook_ops *elem;
+
+	rtnl_lock();
+	list_for_each_entry(elem, &nf_hook_list, list)
+		nf_unregister_net_hook(net, elem);
+	rtnl_unlock();
+}
+
 static int __net_init netfilter_net_init(struct net *net)
 {
+	int i, h, ret;
+
+	for (i = 0; i < ARRAY_SIZE(net->nf.hooks); i++) {
+		for (h = 0; h < NF_MAX_HOOKS; h++)
+			INIT_LIST_HEAD(&net->nf.hooks[i][h]);
+	}
+
 #ifdef CONFIG_PROC_FS
 	net->nf.proc_netfilter = proc_net_mkdir(net, "netfilter",
 						net->proc_net);
@@ -306,11 +446,16 @@ static int __net_init netfilter_net_init(struct net *net)
 		return -ENOMEM;
 	}
 #endif
-	return 0;
+	ret = nf_register_hook_list(net);
+	if (ret)
+		remove_proc_entry("netfilter", net->proc_net);
+
+	return ret;
 }
 
 static void __net_exit netfilter_net_exit(struct net *net)
 {
+	nf_unregister_hook_list(net);
 	remove_proc_entry("netfilter", net->proc_net);
 }
 
@@ -321,12 +466,7 @@ static struct pernet_operations netfilter_net_ops = {
 
 int __init netfilter_init(void)
 {
-	int i, h, ret;
-
-	for (i = 0; i < ARRAY_SIZE(nf_hooks); i++) {
-		for (h = 0; h < NF_MAX_HOOKS; h++)
-			INIT_LIST_HEAD(&nf_hooks[i][h]);
-	}
+	int ret;
 
 	ret = register_pernet_subsys(&netfilter_net_ops);
 	if (ret < 0)
-- 
1.7.10.4

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

* [PATCH 05/18] netfilter: nftables: Only run the nftables chains in the proper netns
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (3 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 04/18] netfilter: Per network namespace netfilter hooks Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 06/18] netfilter: xtables: compute exact size needed for jumpstack Pablo Neira Ayuso
                   ` (13 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: "Eric W. Biederman" <ebiederm@xmission.com>

- Register the nftables chains in the network namespace that they need
  to run in.

- Remove the hacks that stopped chains running in the wrong network
  namespace.

Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/nf_tables_api.c  |    8 ++++++--
 net/netfilter/nf_tables_core.c |    5 -----
 2 files changed, 6 insertions(+), 7 deletions(-)

diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c
index cfe6368..4a41eb9 100644
--- a/net/netfilter/nf_tables_api.c
+++ b/net/netfilter/nf_tables_api.c
@@ -130,20 +130,24 @@ static void nft_trans_destroy(struct nft_trans *trans)
 int nft_register_basechain(struct nft_base_chain *basechain,
 			   unsigned int hook_nops)
 {
+	struct net *net = read_pnet(&basechain->pnet);
+
 	if (basechain->flags & NFT_BASECHAIN_DISABLED)
 		return 0;
 
-	return nf_register_hooks(basechain->ops, hook_nops);
+	return nf_register_net_hooks(net, basechain->ops, hook_nops);
 }
 EXPORT_SYMBOL_GPL(nft_register_basechain);
 
 void nft_unregister_basechain(struct nft_base_chain *basechain,
 			      unsigned int hook_nops)
 {
+	struct net *net = read_pnet(&basechain->pnet);
+
 	if (basechain->flags & NFT_BASECHAIN_DISABLED)
 		return;
 
-	nf_unregister_hooks(basechain->ops, hook_nops);
+	nf_unregister_net_hooks(net, basechain->ops, hook_nops);
 }
 EXPORT_SYMBOL_GPL(nft_unregister_basechain);
 
diff --git a/net/netfilter/nf_tables_core.c b/net/netfilter/nf_tables_core.c
index f77bad4..05d0b03 100644
--- a/net/netfilter/nf_tables_core.c
+++ b/net/netfilter/nf_tables_core.c
@@ -114,7 +114,6 @@ unsigned int
 nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
 {
 	const struct nft_chain *chain = ops->priv, *basechain = chain;
-	const struct net *chain_net = read_pnet(&nft_base_chain(basechain)->pnet);
 	const struct net *net = dev_net(pkt->in ? pkt->in : pkt->out);
 	const struct nft_rule *rule;
 	const struct nft_expr *expr, *last;
@@ -125,10 +124,6 @@ nft_do_chain(struct nft_pktinfo *pkt, const struct nf_hook_ops *ops)
 	int rulenum;
 	unsigned int gencursor = nft_genmask_cur(net);
 
-	/* Ignore chains that are not for the current network namespace */
-	if (!net_eq(net, chain_net))
-		return NF_ACCEPT;
-
 do_chain:
 	rulenum = 0;
 	rule = list_entry(&chain->rules, struct nft_rule, list);
-- 
1.7.10.4

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

* [PATCH 06/18] netfilter: xtables: compute exact size needed for jumpstack
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (4 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 05/18] netfilter: nftables: Only run the nftables chains in the proper netns Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 07/18] netfilter: move tee_active to core Pablo Neira Ayuso
                   ` (12 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Florian Westphal <fw@strlen.de>

The {arp,ip,ip6tables} jump stack is currently sized based
on the number of user chains.

However, its rather unlikely that every user defined chain jumps to the
next, so lets use the existing loop detection logic to also track the
chain depths.

The stacksize is then set to the largest chain depth seen.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/ipv4/netfilter/arp_tables.c |   19 ++++++++++++-------
 net/ipv4/netfilter/ip_tables.c  |   28 ++++++++++++++++++----------
 net/ipv6/netfilter/ip6_tables.c |   23 +++++++++++++++--------
 net/netfilter/x_tables.c        |    4 ++++
 4 files changed, 49 insertions(+), 25 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 92305a1..ae6d0a1 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -372,10 +372,13 @@ static inline bool unconditional(const struct arpt_arp *arp)
 
 /* Figures out from what hook each rule can be called: returns 0 if
  * there are loops.  Puts hook bitmask in comefrom.
+ *
+ * Keeps track of largest call depth seen and stores it in newinfo->stacksize.
  */
-static int mark_source_chains(const struct xt_table_info *newinfo,
+static int mark_source_chains(struct xt_table_info *newinfo,
 			      unsigned int valid_hooks, void *entry0)
 {
+	unsigned int calldepth, max_calldepth = 0;
 	unsigned int hook;
 
 	/* No recursion; use packet counter to save back ptrs (reset
@@ -391,6 +394,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
 
 		/* Set initial back pointer. */
 		e->counters.pcnt = pos;
+		calldepth = 0;
 
 		for (;;) {
 			const struct xt_standard_target *t
@@ -445,6 +449,8 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
 					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
+				if (calldepth > 0)
+					--calldepth;
 			} else {
 				int newpos = t->verdict;
 
@@ -459,6 +465,10 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
 						return 0;
 					}
 
+					if (entry0 + newpos != arpt_next_entry(e) &&
+					    ++calldepth > max_calldepth)
+						max_calldepth = calldepth;
+
 					/* This a jump; chase it. */
 					duprintf("Jump rule %u -> %u\n",
 						 pos, newpos);
@@ -475,6 +485,7 @@ static int mark_source_chains(const struct xt_table_info *newinfo,
 		next:
 		duprintf("Finished chain %u\n", hook);
 	}
+	newinfo->stacksize = max_calldepth;
 	return 1;
 }
 
@@ -664,9 +675,6 @@ static int translate_table(struct xt_table_info *newinfo, void *entry0,
 		if (ret != 0)
 			break;
 		++i;
-		if (strcmp(arpt_get_target(iter)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
 	}
 	duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret);
 	if (ret != 0)
@@ -1439,9 +1447,6 @@ static int translate_compat_table(const char *name,
 			break;
 		}
 		++i;
-		if (strcmp(arpt_get_target(iter1)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
 	}
 	if (ret) {
 		/*
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 6c72fbb..5e44b35 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -439,11 +439,15 @@ ipt_do_table(struct sk_buff *skb,
 }
 
 /* Figures out from what hook each rule can be called: returns 0 if
-   there are loops.  Puts hook bitmask in comefrom. */
+ * there are loops.  Puts hook bitmask in comefrom.
+ *
+ * Keeps track of largest call depth seen and stores it in newinfo->stacksize.
+ */
 static int
-mark_source_chains(const struct xt_table_info *newinfo,
+mark_source_chains(struct xt_table_info *newinfo,
 		   unsigned int valid_hooks, void *entry0)
 {
+	unsigned int calldepth, max_calldepth = 0;
 	unsigned int hook;
 
 	/* No recursion; use packet counter to save back ptrs (reset
@@ -457,6 +461,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
 
 		/* Set initial back pointer. */
 		e->counters.pcnt = pos;
+		calldepth = 0;
 
 		for (;;) {
 			const struct xt_standard_target *t
@@ -518,6 +523,9 @@ mark_source_chains(const struct xt_table_info *newinfo,
 					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
+				WARN_ON_ONCE(calldepth == 0);
+				if (calldepth > 0)
+					--calldepth;
 			} else {
 				int newpos = t->verdict;
 
@@ -531,9 +539,14 @@ mark_source_chains(const struct xt_table_info *newinfo,
 								newpos);
 						return 0;
 					}
+					if (entry0 + newpos != ipt_next_entry(e) &&
+					    !(e->ip.flags & IPT_F_GOTO) &&
+					    ++calldepth > max_calldepth)
+						max_calldepth = calldepth;
+
 					/* This a jump; chase it. */
-					duprintf("Jump rule %u -> %u\n",
-						 pos, newpos);
+					duprintf("Jump rule %u -> %u, calldepth %d\n",
+						 pos, newpos, calldepth);
 				} else {
 					/* ... this is a fallthru */
 					newpos = pos + e->next_offset;
@@ -547,6 +560,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
 		next:
 		duprintf("Finished chain %u\n", hook);
 	}
+	newinfo->stacksize = max_calldepth;
 	return 1;
 }
 
@@ -826,9 +840,6 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
 		if (ret != 0)
 			return ret;
 		++i;
-		if (strcmp(ipt_get_target(iter)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
 	}
 
 	if (i != repl->num_entries) {
@@ -1744,9 +1755,6 @@ translate_compat_table(struct net *net,
 		if (ret != 0)
 			break;
 		++i;
-		if (strcmp(ipt_get_target(iter1)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
 	}
 	if (ret) {
 		/*
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 3c35ced..baf0321 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -452,11 +452,15 @@ ip6t_do_table(struct sk_buff *skb,
 }
 
 /* Figures out from what hook each rule can be called: returns 0 if
-   there are loops.  Puts hook bitmask in comefrom. */
+ * there are loops.  Puts hook bitmask in comefrom.
+ *
+ * Keeps track of largest call depth seen and stores it in newinfo->stacksize.
+ */
 static int
-mark_source_chains(const struct xt_table_info *newinfo,
+mark_source_chains(struct xt_table_info *newinfo,
 		   unsigned int valid_hooks, void *entry0)
 {
+	unsigned int calldepth, max_calldepth = 0;
 	unsigned int hook;
 
 	/* No recursion; use packet counter to save back ptrs (reset
@@ -470,6 +474,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
 
 		/* Set initial back pointer. */
 		e->counters.pcnt = pos;
+		calldepth = 0;
 
 		for (;;) {
 			const struct xt_standard_target *t
@@ -531,6 +536,8 @@ mark_source_chains(const struct xt_table_info *newinfo,
 					(entry0 + pos + size);
 				e->counters.pcnt = pos;
 				pos += size;
+				if (calldepth > 0)
+					--calldepth;
 			} else {
 				int newpos = t->verdict;
 
@@ -544,6 +551,11 @@ mark_source_chains(const struct xt_table_info *newinfo,
 								newpos);
 						return 0;
 					}
+					if (entry0 + newpos != ip6t_next_entry(e) &&
+					    !(e->ipv6.flags & IP6T_F_GOTO) &&
+					    ++calldepth > max_calldepth)
+						max_calldepth = calldepth;
+
 					/* This a jump; chase it. */
 					duprintf("Jump rule %u -> %u\n",
 						 pos, newpos);
@@ -560,6 +572,7 @@ mark_source_chains(const struct xt_table_info *newinfo,
 		next:
 		duprintf("Finished chain %u\n", hook);
 	}
+	newinfo->stacksize = max_calldepth;
 	return 1;
 }
 
@@ -839,9 +852,6 @@ translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0,
 		if (ret != 0)
 			return ret;
 		++i;
-		if (strcmp(ip6t_get_target(iter)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
 	}
 
 	if (i != repl->num_entries) {
@@ -1754,9 +1764,6 @@ translate_compat_table(struct net *net,
 		if (ret != 0)
 			break;
 		++i;
-		if (strcmp(ip6t_get_target(iter1)->u.user.name,
-		    XT_ERROR_TARGET) == 0)
-			++newinfo->stacksize;
 	}
 	if (ret) {
 		/*
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index d324fe7..4db7d60 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -749,6 +749,10 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)
 	if (i->jumpstack == NULL)
 		return -ENOMEM;
 
+	/* ruleset without jumps -- no stack needed */
+	if (i->stacksize == 0)
+		return 0;
+
 	i->stacksize *= xt_jumpstack_multiplier;
 	size = sizeof(void *) * i->stacksize;
 	for_each_possible_cpu(cpu) {
-- 
1.7.10.4

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

* [PATCH 07/18] netfilter: move tee_active to core
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (5 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 06/18] netfilter: xtables: compute exact size needed for jumpstack Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 08/18] netfilter: xtables: don't save/restore jumpstack offset Pablo Neira Ayuso
                   ` (11 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Florian Westphal <fw@strlen.de>

This prepares for a TEE like expression in nftables.
We want to ensure only one duplicate is sent, so both will
use the same percpu variable to detect duplication.

The other use case is detection of recursive call to xtables, but since
we don't want dependency from nft to xtables core its put into core.c
instead of the x_tables core.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netfilter.h |   11 +++++++++++
 net/netfilter/core.c      |    3 +++
 net/netfilter/xt_TEE.c    |   13 ++++++-------
 3 files changed, 20 insertions(+), 7 deletions(-)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 9bbd110..e01da73 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -390,4 +390,15 @@ extern struct nfq_ct_hook __rcu *nfq_ct_hook;
 static inline void nf_ct_attach(struct sk_buff *new, struct sk_buff *skb) {}
 #endif
 
+/**
+ * nf_skb_duplicated - TEE target has sent a packet
+ *
+ * When a xtables target sends a packet, the OUTPUT and POSTROUTING
+ * hooks are traversed again, i.e. nft and xtables are invoked recursively.
+ *
+ * This is used by xtables TEE target to prevent the duplicated skb from
+ * being duplicated again.
+ */
+DECLARE_PER_CPU(bool, nf_skb_duplicated);
+
 #endif /*__LINUX_NETFILTER_H*/
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 56ead1a..6896cee 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -34,6 +34,9 @@ EXPORT_SYMBOL(nf_afinfo);
 const struct nf_ipv6_ops __rcu *nf_ipv6_ops __read_mostly;
 EXPORT_SYMBOL_GPL(nf_ipv6_ops);
 
+DEFINE_PER_CPU(bool, nf_skb_duplicated);
+EXPORT_SYMBOL_GPL(nf_skb_duplicated);
+
 int nf_register_afinfo(const struct nf_afinfo *afinfo)
 {
 	mutex_lock(&afinfo_mutex);
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index a747eb4..8950e79 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -37,7 +37,6 @@ struct xt_tee_priv {
 };
 
 static const union nf_inet_addr tee_zero_address;
-static DEFINE_PER_CPU(bool, tee_active);
 
 static struct net *pick_net(struct sk_buff *skb)
 {
@@ -88,7 +87,7 @@ tee_tg4(struct sk_buff *skb, const struct xt_action_param *par)
 	const struct xt_tee_tginfo *info = par->targinfo;
 	struct iphdr *iph;
 
-	if (__this_cpu_read(tee_active))
+	if (__this_cpu_read(nf_skb_duplicated))
 		return XT_CONTINUE;
 	/*
 	 * Copy the skb, and route the copy. Will later return %XT_CONTINUE for
@@ -125,9 +124,9 @@ tee_tg4(struct sk_buff *skb, const struct xt_action_param *par)
 	ip_send_check(iph);
 
 	if (tee_tg_route4(skb, info)) {
-		__this_cpu_write(tee_active, true);
+		__this_cpu_write(nf_skb_duplicated, true);
 		ip_local_out(skb);
-		__this_cpu_write(tee_active, false);
+		__this_cpu_write(nf_skb_duplicated, false);
 	} else {
 		kfree_skb(skb);
 	}
@@ -170,7 +169,7 @@ tee_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 {
 	const struct xt_tee_tginfo *info = par->targinfo;
 
-	if (__this_cpu_read(tee_active))
+	if (__this_cpu_read(nf_skb_duplicated))
 		return XT_CONTINUE;
 	skb = pskb_copy(skb, GFP_ATOMIC);
 	if (skb == NULL)
@@ -188,9 +187,9 @@ tee_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 		--iph->hop_limit;
 	}
 	if (tee_tg_route6(skb, info)) {
-		__this_cpu_write(tee_active, true);
+		__this_cpu_write(nf_skb_duplicated, true);
 		ip6_local_out(skb);
-		__this_cpu_write(tee_active, false);
+		__this_cpu_write(nf_skb_duplicated, false);
 	} else {
 		kfree_skb(skb);
 	}
-- 
1.7.10.4

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

* [PATCH 08/18] netfilter: xtables: don't save/restore jumpstack offset
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (6 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 07/18] netfilter: move tee_active to core Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 09/18] netfilter: add and use jump label for xt_tee Pablo Neira Ayuso
                   ` (10 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Florian Westphal <fw@strlen.de>

In most cases there is no reentrancy into ip/ip6tables.

For skbs sent by REJECT or SYNPROXY targets, there is one level
of reentrancy, but its not relevant as those targets issue an absolute
verdict, i.e. the jumpstack can be clobbered since its not used
after the target issues absolute verdict (ACCEPT, DROP, STOLEN, etc).

So the only special case where it is relevant is the TEE target, which
returns XT_CONTINUE.

This patch changes ip(6)_do_table to always use the jump stack starting
from 0.

When we detect we're operating on an skb sent via TEE (percpu
nf_skb_duplicated is 1) we switch to an alternate stack to leave
the original one alone.

Since there is no TEE support for arptables, it doesn't need to
test if tee is active.

The jump stack overflow tests are no longer needed as well --
since ->stacksize is the largest call depth we cannot exceed it.

A much better alternative to the external jumpstack would be to just
declare a jumps[32] stack on the local stack frame, but that would mean
we'd have to reject iptables rulesets that used to work before.

Another alternative would be to start rejecting rulesets with a larger
call depth, e.g. 1000 -- in this case it would be feasible to allocate the
entire stack in the percpu area which would avoid one dereference.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netfilter/x_tables.h |    1 -
 net/ipv4/netfilter/arp_tables.c    |   11 +++--------
 net/ipv4/netfilter/ip_tables.c     |   37 +++++++++++++++++++-----------------
 net/ipv6/netfilter/ip6_tables.c    |   26 +++++++++++++------------
 net/netfilter/x_tables.c           |   22 ++++++++++-----------
 5 files changed, 48 insertions(+), 49 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 286098a..1492845 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -222,7 +222,6 @@ struct xt_table_info {
 	 * @stacksize jumps (number of user chains) can possibly be made.
 	 */
 	unsigned int stacksize;
-	unsigned int __percpu *stackptr;
 	void ***jumpstack;
 
 	unsigned char entries[0] __aligned(8);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index ae6d0a1..969fdbe 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -280,6 +280,9 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 	table_base = private->entries;
 	jumpstack  = (struct arpt_entry **)private->jumpstack[cpu];
 
+	/* No TEE support for arptables, so no need to switch to alternate
+	 * stack.  All targets that reenter must return absolute verdicts.
+	 */
 	e = get_entry(table_base, private->hook_entry[hook]);
 
 	acpar.in      = state->in;
@@ -325,11 +328,6 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 			}
 			if (table_base + v
 			    != arpt_next_entry(e)) {
-
-				if (stackidx >= private->stacksize) {
-					verdict = NF_DROP;
-					break;
-				}
 				jumpstack[stackidx++] = e;
 			}
 
@@ -337,9 +335,6 @@ unsigned int arpt_do_table(struct sk_buff *skb,
 			continue;
 		}
 
-		/* Targets which reenter must return
-		 * abs. verdicts
-		 */
 		acpar.target   = t->u.kernel.target;
 		acpar.targinfo = t->data;
 		verdict = t->u.kernel.target->target(skb, &acpar);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 5e44b35..a2e4b01 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -296,12 +296,13 @@ ipt_do_table(struct sk_buff *skb,
 	const char *indev, *outdev;
 	const void *table_base;
 	struct ipt_entry *e, **jumpstack;
-	unsigned int *stackptr, origptr, cpu;
+	unsigned int stackidx, cpu;
 	const struct xt_table_info *private;
 	struct xt_action_param acpar;
 	unsigned int addend;
 
 	/* Initialization */
+	stackidx = 0;
 	ip = ip_hdr(skb);
 	indev = state->in ? state->in->name : nulldevname;
 	outdev = state->out ? state->out->name : nulldevname;
@@ -331,13 +332,20 @@ ipt_do_table(struct sk_buff *skb,
 	smp_read_barrier_depends();
 	table_base = private->entries;
 	jumpstack  = (struct ipt_entry **)private->jumpstack[cpu];
-	stackptr   = per_cpu_ptr(private->stackptr, cpu);
-	origptr    = *stackptr;
+
+	/* Switch to alternate jumpstack if we're being invoked via TEE.
+	 * TEE issues XT_CONTINUE verdict on original skb so we must not
+	 * clobber the jumpstack.
+	 *
+	 * For recursion via REJECT or SYNPROXY the stack will be clobbered
+	 * but it is no problem since absolute verdict is issued by these.
+	 */
+	jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
 
 	e = get_entry(table_base, private->hook_entry[hook]);
 
-	pr_debug("Entering %s(hook %u); sp at %u (UF %p)\n",
-		 table->name, hook, origptr,
+	pr_debug("Entering %s(hook %u), UF %p\n",
+		 table->name, hook,
 		 get_entry(table_base, private->underflow[hook]));
 
 	do {
@@ -383,28 +391,24 @@ ipt_do_table(struct sk_buff *skb,
 					verdict = (unsigned int)(-v) - 1;
 					break;
 				}
-				if (*stackptr <= origptr) {
+				if (stackidx == 0) {
 					e = get_entry(table_base,
 					    private->underflow[hook]);
 					pr_debug("Underflow (this is normal) "
 						 "to %p\n", e);
 				} else {
-					e = jumpstack[--*stackptr];
+					e = jumpstack[--stackidx];
 					pr_debug("Pulled %p out from pos %u\n",
-						 e, *stackptr);
+						 e, stackidx);
 					e = ipt_next_entry(e);
 				}
 				continue;
 			}
 			if (table_base + v != ipt_next_entry(e) &&
 			    !(e->ip.flags & IPT_F_GOTO)) {
-				if (*stackptr >= private->stacksize) {
-					verdict = NF_DROP;
-					break;
-				}
-				jumpstack[(*stackptr)++] = e;
+				jumpstack[stackidx++] = e;
 				pr_debug("Pushed %p into pos %u\n",
-					 e, *stackptr - 1);
+					 e, stackidx - 1);
 			}
 
 			e = get_entry(table_base, v);
@@ -423,9 +427,8 @@ ipt_do_table(struct sk_buff *skb,
 			/* Verdict */
 			break;
 	} while (!acpar.hotdrop);
-	pr_debug("Exiting %s; resetting sp from %u to %u\n",
-		 __func__, *stackptr, origptr);
-	*stackptr = origptr;
+	pr_debug("Exiting %s; sp at %u\n", __func__, stackidx);
+
  	xt_write_recseq_end(addend);
  	local_bh_enable();
 
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index baf0321..531281f 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -324,12 +324,13 @@ ip6t_do_table(struct sk_buff *skb,
 	const char *indev, *outdev;
 	const void *table_base;
 	struct ip6t_entry *e, **jumpstack;
-	unsigned int *stackptr, origptr, cpu;
+	unsigned int stackidx, cpu;
 	const struct xt_table_info *private;
 	struct xt_action_param acpar;
 	unsigned int addend;
 
 	/* Initialization */
+	stackidx = 0;
 	indev = state->in ? state->in->name : nulldevname;
 	outdev = state->out ? state->out->name : nulldevname;
 	/* We handle fragments by dealing with the first fragment as
@@ -357,8 +358,15 @@ ip6t_do_table(struct sk_buff *skb,
 	cpu        = smp_processor_id();
 	table_base = private->entries;
 	jumpstack  = (struct ip6t_entry **)private->jumpstack[cpu];
-	stackptr   = per_cpu_ptr(private->stackptr, cpu);
-	origptr    = *stackptr;
+
+	/* Switch to alternate jumpstack if we're being invoked via TEE.
+	 * TEE issues XT_CONTINUE verdict on original skb so we must not
+	 * clobber the jumpstack.
+	 *
+	 * For recursion via REJECT or SYNPROXY the stack will be clobbered
+	 * but it is no problem since absolute verdict is issued by these.
+	 */
+	jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
 
 	e = get_entry(table_base, private->hook_entry[hook]);
 
@@ -406,20 +414,16 @@ ip6t_do_table(struct sk_buff *skb,
 					verdict = (unsigned int)(-v) - 1;
 					break;
 				}
-				if (*stackptr <= origptr)
+				if (stackidx == 0)
 					e = get_entry(table_base,
 					    private->underflow[hook]);
 				else
-					e = ip6t_next_entry(jumpstack[--*stackptr]);
+					e = ip6t_next_entry(jumpstack[--stackidx]);
 				continue;
 			}
 			if (table_base + v != ip6t_next_entry(e) &&
 			    !(e->ipv6.flags & IP6T_F_GOTO)) {
-				if (*stackptr >= private->stacksize) {
-					verdict = NF_DROP;
-					break;
-				}
-				jumpstack[(*stackptr)++] = e;
+				jumpstack[stackidx++] = e;
 			}
 
 			e = get_entry(table_base, v);
@@ -437,8 +441,6 @@ ip6t_do_table(struct sk_buff *skb,
 			break;
 	} while (!acpar.hotdrop);
 
-	*stackptr = origptr;
-
  	xt_write_recseq_end(addend);
  	local_bh_enable();
 
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 4db7d60..154447e 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -67,9 +67,6 @@ static const char *const xt_prefix[NFPROTO_NUMPROTO] = {
 	[NFPROTO_IPV6]   = "ip6",
 };
 
-/* Allow this many total (re)entries. */
-static const unsigned int xt_jumpstack_multiplier = 2;
-
 /* Registration hooks for targets. */
 int xt_register_target(struct xt_target *target)
 {
@@ -688,8 +685,6 @@ void xt_free_table_info(struct xt_table_info *info)
 		kvfree(info->jumpstack);
 	}
 
-	free_percpu(info->stackptr);
-
 	kvfree(info);
 }
 EXPORT_SYMBOL(xt_free_table_info);
@@ -737,10 +732,6 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)
 	unsigned int size;
 	int cpu;
 
-	i->stackptr = alloc_percpu(unsigned int);
-	if (i->stackptr == NULL)
-		return -ENOMEM;
-
 	size = sizeof(void **) * nr_cpu_ids;
 	if (size > PAGE_SIZE)
 		i->jumpstack = vzalloc(size);
@@ -753,8 +744,17 @@ static int xt_jumpstack_alloc(struct xt_table_info *i)
 	if (i->stacksize == 0)
 		return 0;
 
-	i->stacksize *= xt_jumpstack_multiplier;
-	size = sizeof(void *) * i->stacksize;
+	/* Jumpstack needs to be able to record two full callchains, one
+	 * from the first rule set traversal, plus one table reentrancy
+	 * via -j TEE without clobbering the callchain that brought us to
+	 * TEE target.
+	 *
+	 * This is done by allocating two jumpstacks per cpu, on reentry
+	 * the upper half of the stack is used.
+	 *
+	 * see the jumpstack setup in ipt_do_table() for more details.
+	 */
+	size = sizeof(void *) * i->stacksize * 2u;
 	for_each_possible_cpu(cpu) {
 		if (size > PAGE_SIZE)
 			i->jumpstack[cpu] = vmalloc_node(size,
-- 
1.7.10.4


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

* [PATCH 09/18] netfilter: add and use jump label for xt_tee
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (7 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 08/18] netfilter: xtables: don't save/restore jumpstack offset Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 10/18] netfilter: xtables: remove __pure annotation Pablo Neira Ayuso
                   ` (9 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Florian Westphal <fw@strlen.de>

Don't bother testing if we need to switch to alternate stack
unless TEE target is used.

Suggested-by: Eric Dumazet <eric.dumazet@gmail.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netfilter/x_tables.h |    7 +++++++
 net/ipv4/netfilter/ip_tables.c     |    3 ++-
 net/ipv6/netfilter/ip6_tables.c    |    3 ++-
 net/netfilter/x_tables.c           |    3 +++
 net/netfilter/xt_TEE.c             |    2 ++
 5 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index 1492845..b006b71 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -3,6 +3,7 @@
 
 
 #include <linux/netdevice.h>
+#include <linux/static_key.h>
 #include <uapi/linux/netfilter/x_tables.h>
 
 /**
@@ -280,6 +281,12 @@ void xt_free_table_info(struct xt_table_info *info);
  */
 DECLARE_PER_CPU(seqcount_t, xt_recseq);
 
+/* xt_tee_enabled - true if x_tables needs to handle reentrancy
+ *
+ * Enabled if current ip(6)tables ruleset has at least one -j TEE rule.
+ */
+extern struct static_key xt_tee_enabled;
+
 /**
  * xt_write_recseq_begin - start of a write section
  *
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index a2e4b01..ff585bd 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -340,7 +340,8 @@ ipt_do_table(struct sk_buff *skb,
 	 * For recursion via REJECT or SYNPROXY the stack will be clobbered
 	 * but it is no problem since absolute verdict is issued by these.
 	 */
-	jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
+	if (static_key_false(&xt_tee_enabled))
+		jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
 
 	e = get_entry(table_base, private->hook_entry[hook]);
 
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 531281f..ea6d105 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -366,7 +366,8 @@ ip6t_do_table(struct sk_buff *skb,
 	 * For recursion via REJECT or SYNPROXY the stack will be clobbered
 	 * but it is no problem since absolute verdict is issued by these.
 	 */
-	jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
+	if (static_key_false(&xt_tee_enabled))
+		jumpstack += private->stacksize * __this_cpu_read(nf_skb_duplicated);
 
 	e = get_entry(table_base, private->hook_entry[hook]);
 
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 154447e..9b42b5e 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -727,6 +727,9 @@ EXPORT_SYMBOL_GPL(xt_compat_unlock);
 DEFINE_PER_CPU(seqcount_t, xt_recseq);
 EXPORT_PER_CPU_SYMBOL_GPL(xt_recseq);
 
+struct static_key xt_tee_enabled __read_mostly;
+EXPORT_SYMBOL_GPL(xt_tee_enabled);
+
 static int xt_jumpstack_alloc(struct xt_table_info *i)
 {
 	unsigned int size;
diff --git a/net/netfilter/xt_TEE.c b/net/netfilter/xt_TEE.c
index 8950e79..c5d6556 100644
--- a/net/netfilter/xt_TEE.c
+++ b/net/netfilter/xt_TEE.c
@@ -251,6 +251,7 @@ static int tee_tg_check(const struct xt_tgchk_param *par)
 	} else
 		info->priv = NULL;
 
+	static_key_slow_inc(&xt_tee_enabled);
 	return 0;
 }
 
@@ -262,6 +263,7 @@ static void tee_tg_destroy(const struct xt_tgdtor_param *par)
 		unregister_netdevice_notifier(&info->priv->notifier);
 		kfree(info->priv);
 	}
+	static_key_slow_dec(&xt_tee_enabled);
 }
 
 static struct xt_target tee_tg_reg[] __read_mostly = {
-- 
1.7.10.4


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

* [PATCH 10/18] netfilter: xtables: remove __pure annotation
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (8 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 09/18] netfilter: add and use jump label for xt_tee Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 11/18] netfilter: Fix memory leak in nf_register_net_hook Pablo Neira Ayuso
                   ` (8 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Florian Westphal <fw@strlen.de>

sparse complains:
ip_tables.c:361:27: warning: incorrect type in assignment (different modifiers)
ip_tables.c:361:27:    expected struct ipt_entry *[assigned] e
ip_tables.c:361:27:    got struct ipt_entry [pure] *

doesn't change generated code.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/ipv4/netfilter/arp_tables.c |    2 +-
 net/ipv4/netfilter/ip_tables.c  |    2 +-
 net/ipv6/netfilter/ip6_tables.c |    2 +-
 3 files changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 969fdbe..c416cb3 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -240,7 +240,7 @@ get_entry(const void *base, unsigned int offset)
 	return (struct arpt_entry *)(base + offset);
 }
 
-static inline __pure
+static inline
 struct arpt_entry *arpt_next_entry(const struct arpt_entry *entry)
 {
 	return (void *)entry + entry->next_offset;
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index ff585bd..787f99e 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -276,7 +276,7 @@ static void trace_packet(const struct sk_buff *skb,
 }
 #endif
 
-static inline __pure
+static inline
 struct ipt_entry *ipt_next_entry(const struct ipt_entry *entry)
 {
 	return (void *)entry + entry->next_offset;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index ea6d105..4e21f80 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -305,7 +305,7 @@ static void trace_packet(const struct sk_buff *skb,
 }
 #endif
 
-static inline __pure struct ip6t_entry *
+static inline struct ip6t_entry *
 ip6t_next_entry(const struct ip6t_entry *entry)
 {
 	return (void *)entry + entry->next_offset;
-- 
1.7.10.4

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

* [PATCH 11/18] netfilter: Fix memory leak in nf_register_net_hook
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (9 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 10/18] netfilter: xtables: remove __pure annotation Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 12/18] netfilter: nf_queue: fix nf_queue_nf_hook_drop() Pablo Neira Ayuso
                   ` (7 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: "Eric W. Biederman" <ebiederm@xmission.com>

In the rare case that when it is a attempted to use a per network device
netfilter hook and the network device does not exist the newly allocated
structure can leak.

Be a good citizen and free the newly allocated structure in the error
handling code.

Fixes: 085db2c04557 ("netfilter: Per network namespace netfilter hooks.")
Reported-by: kbuild@01.org
Reported-by: Dan Carpenter <dan.carpenter@oracle.com>
Signed-off-by: "Eric W. Biederman" <ebiederm@xmission.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/netfilter/core.c |    4 +++-
 1 file changed, 3 insertions(+), 1 deletion(-)

diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 6896cee..87d237d 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -96,8 +96,10 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
 	new->priority = reg->priority;
 
 	nf_hook_list = find_nf_hook_list(net, reg);
-	if (!nf_hook_list)
+	if (!nf_hook_list) {
+		kfree(new);
 		return -ENOENT;
+	}
 
 	mutex_lock(&nf_hook_mutex);
 	list_for_each_entry(elem, nf_hook_list, list) {
-- 
1.7.10.4


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

* [PATCH 12/18] netfilter: nf_queue: fix nf_queue_nf_hook_drop()
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (10 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 11/18] netfilter: Fix memory leak in nf_register_net_hook Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 13/18] netfilter: fix possible removal of wrong hook Pablo Neira Ayuso
                   ` (6 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

This function reacquires the rtnl_lock() which is already held by
nf_unregister_hook().

This can be triggered via: modprobe nf_conntrack_ipv4 && rmmod nf_conntrack_ipv4

[  720.628746] INFO: task rmmod:3578 blocked for more than 120 seconds.
[  720.628749]       Not tainted 4.2.0-rc2+ #113
[  720.628752] "echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
[  720.628754] rmmod           D ffff8800ca46fd58     0  3578   3571 0x00000080
[...]
[  720.628783] Call Trace:
[  720.628790]  [<ffffffff8152ea0b>] schedule+0x6b/0x90
[  720.628795]  [<ffffffff8152ecb3>] schedule_preempt_disabled+0x13/0x20
[  720.628799]  [<ffffffff8152ff55>] mutex_lock_nested+0x1f5/0x380
[  720.628803]  [<ffffffff81462622>] ? rtnl_lock+0x12/0x20
[  720.628807]  [<ffffffff81462622>] ? rtnl_lock+0x12/0x20
[  720.628812]  [<ffffffff81462622>] rtnl_lock+0x12/0x20
[  720.628817]  [<ffffffff8148ab25>] nf_queue_nf_hook_drop+0x15/0x160
[  720.628825]  [<ffffffff81488d48>] nf_unregister_net_hook+0x168/0x190
[  720.628831]  [<ffffffff81488e24>] nf_unregister_hook+0x64/0x80
[  720.628837]  [<ffffffff81488e60>] nf_unregister_hooks+0x20/0x30
[...]

Moreover, nf_unregister_net_hook() should only destroy the queue for this
netns, not for every netns.

Reported-by: Fengguang Wu <fengguang.wu@intel.com>
Fixes: 085db2c04557 ("netfilter: Per network namespace netfilter hooks.")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/netfilter/core.c         |    2 +-
 net/netfilter/nf_internals.h |    2 +-
 net/netfilter/nf_queue.c     |   12 +++---------
 3 files changed, 5 insertions(+), 11 deletions(-)

diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 87d237d..12504fbb 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -154,7 +154,7 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 	static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]);
 #endif
 	synchronize_net();
-	nf_queue_nf_hook_drop(elem);
+	nf_queue_nf_hook_drop(net, elem);
 	kfree(elem);
 }
 EXPORT_SYMBOL(nf_unregister_net_hook);
diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h
index 3992106..0655225 100644
--- a/net/netfilter/nf_internals.h
+++ b/net/netfilter/nf_internals.h
@@ -19,7 +19,7 @@ unsigned int nf_iterate(struct list_head *head, struct sk_buff *skb,
 /* nf_queue.c */
 int nf_queue(struct sk_buff *skb, struct nf_hook_ops *elem,
 	     struct nf_hook_state *state, unsigned int queuenum);
-void nf_queue_nf_hook_drop(struct nf_hook_ops *ops);
+void nf_queue_nf_hook_drop(struct net *net, struct nf_hook_ops *ops);
 int __init netfilter_queue_init(void);
 
 /* nf_log.c */
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 8a8b2ab..96777f9 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -105,21 +105,15 @@ bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
 }
 EXPORT_SYMBOL_GPL(nf_queue_entry_get_refs);
 
-void nf_queue_nf_hook_drop(struct nf_hook_ops *ops)
+void nf_queue_nf_hook_drop(struct net *net, struct nf_hook_ops *ops)
 {
 	const struct nf_queue_handler *qh;
-	struct net *net;
 
-	rtnl_lock();
 	rcu_read_lock();
 	qh = rcu_dereference(queue_handler);
-	if (qh) {
-		for_each_net(net) {
-			qh->nf_hook_drop(net, ops);
-		}
-	}
+	if (qh)
+		qh->nf_hook_drop(net, ops);
 	rcu_read_unlock();
-	rtnl_unlock();
 }
 
 /*
-- 
1.7.10.4

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

* [PATCH 13/18] netfilter: fix possible removal of wrong hook
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (11 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 12/18] netfilter: nf_queue: fix nf_queue_nf_hook_drop() Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 14/18] netfilter: rename local nf_hook_list to hook_list Pablo Neira Ayuso
                   ` (5 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

nf_unregister_net_hook() uses the nf_hook_ops fields as tuple to look up for
the corresponding hook in the list. However, we may have two hooks with exactly
the same configuration.

This shouldn't be a problem for nftables since every new chain has an unique
priv field set, but this may still cause us problems in the future, so better
address this problem now by keeping a reference to the original nf_hook_ops
structure to make sure we delete the right hook from nf_unregister_net_hook().

Fixes: 085db2c04557 ("netfilter: Per network namespace netfilter hooks.")
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 net/netfilter/core.c |   41 +++++++++++++++++++----------------------
 1 file changed, 19 insertions(+), 22 deletions(-)

diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 12504fbb..0ecb2b5 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -78,26 +78,27 @@ static struct list_head *find_nf_hook_list(struct net *net,
 	return nf_hook_list;
 }
 
+struct nf_hook_entry {
+	const struct nf_hook_ops	*orig_ops;
+	struct nf_hook_ops		ops;
+};
+
 int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
 {
 	struct list_head *nf_hook_list;
-	struct nf_hook_ops *elem, *new;
+	struct nf_hook_entry *entry;
+	struct nf_hook_ops *elem;
 
-	new = kzalloc(sizeof(*new), GFP_KERNEL);
-	if (!new)
+	entry = kmalloc(sizeof(*entry), GFP_KERNEL);
+	if (!entry)
 		return -ENOMEM;
 
-	new->hook     = reg->hook;
-	new->dev      = reg->dev;
-	new->owner    = reg->owner;
-	new->priv     = reg->priv;
-	new->pf       = reg->pf;
-	new->hooknum  = reg->hooknum;
-	new->priority = reg->priority;
+	entry->orig_ops	= reg;
+	entry->ops	= *reg;
 
 	nf_hook_list = find_nf_hook_list(net, reg);
 	if (!nf_hook_list) {
-		kfree(new);
+		kfree(entry);
 		return -ENOENT;
 	}
 
@@ -106,7 +107,7 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
 		if (reg->priority < elem->priority)
 			break;
 	}
-	list_add_rcu(&new->list, elem->list.prev);
+	list_add_rcu(&entry->ops.list, elem->list.prev);
 	mutex_unlock(&nf_hook_mutex);
 #ifdef CONFIG_NETFILTER_INGRESS
 	if (reg->pf == NFPROTO_NETDEV && reg->hooknum == NF_NETDEV_INGRESS)
@@ -122,6 +123,7 @@ EXPORT_SYMBOL(nf_register_net_hook);
 void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 {
 	struct list_head *nf_hook_list;
+	struct nf_hook_entry *entry;
 	struct nf_hook_ops *elem;
 
 	nf_hook_list = find_nf_hook_list(net, reg);
@@ -130,14 +132,9 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 
 	mutex_lock(&nf_hook_mutex);
 	list_for_each_entry(elem, nf_hook_list, list) {
-		if ((reg->hook     == elem->hook) &&
-		    (reg->dev      == elem->dev) &&
-		    (reg->owner    == elem->owner) &&
-		    (reg->priv     == elem->priv) &&
-		    (reg->pf       == elem->pf) &&
-		    (reg->hooknum  == elem->hooknum) &&
-		    (reg->priority == elem->priority)) {
-			list_del_rcu(&elem->list);
+		entry = container_of(elem, struct nf_hook_entry, ops);
+		if (entry->orig_ops == reg) {
+			list_del_rcu(&entry->ops.list);
 			break;
 		}
 	}
@@ -154,8 +151,8 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 	static_key_slow_dec(&nf_hooks_needed[reg->pf][reg->hooknum]);
 #endif
 	synchronize_net();
-	nf_queue_nf_hook_drop(net, elem);
-	kfree(elem);
+	nf_queue_nf_hook_drop(net, &entry->ops);
+	kfree(entry);
 }
 EXPORT_SYMBOL(nf_unregister_net_hook);
 
-- 
1.7.10.4

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

* [PATCH 14/18] netfilter: rename local nf_hook_list to hook_list
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (12 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 13/18] netfilter: fix possible removal of wrong hook Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 15/18] netfilter: nf_ct_sctp: minimal multihoming support Pablo Neira Ayuso
                   ` (4 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

085db2c04557 ("netfilter: Per network namespace netfilter hooks.") introduced a
new nf_hook_list that is global, so let's avoid this overlap.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Acked-by: "Eric W. Biederman" <ebiederm@xmission.com>
---
 include/linux/netfilter.h |   14 +++++++-------
 net/netfilter/core.c      |   28 ++++++++++++++--------------
 2 files changed, 21 insertions(+), 21 deletions(-)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index e01da73..d788ce6 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -140,20 +140,20 @@ void nf_unregister_sockopt(struct nf_sockopt_ops *reg);
 #ifdef HAVE_JUMP_LABEL
 extern struct static_key nf_hooks_needed[NFPROTO_NUMPROTO][NF_MAX_HOOKS];
 
-static inline bool nf_hook_list_active(struct list_head *nf_hook_list,
+static inline bool nf_hook_list_active(struct list_head *hook_list,
 				       u_int8_t pf, unsigned int hook)
 {
 	if (__builtin_constant_p(pf) &&
 	    __builtin_constant_p(hook))
 		return static_key_false(&nf_hooks_needed[pf][hook]);
 
-	return !list_empty(nf_hook_list);
+	return !list_empty(hook_list);
 }
 #else
-static inline bool nf_hook_list_active(struct list_head *nf_hook_list,
+static inline bool nf_hook_list_active(struct list_head *hook_list,
 				       u_int8_t pf, unsigned int hook)
 {
-	return !list_empty(nf_hook_list);
+	return !list_empty(hook_list);
 }
 #endif
 
@@ -175,12 +175,12 @@ static inline int nf_hook_thresh(u_int8_t pf, unsigned int hook,
 				 int thresh)
 {
 	struct net *net = dev_net(indev ? indev : outdev);
-	struct list_head *nf_hook_list = &net->nf.hooks[pf][hook];
+	struct list_head *hook_list = &net->nf.hooks[pf][hook];
 
-	if (nf_hook_list_active(nf_hook_list, pf, hook)) {
+	if (nf_hook_list_active(hook_list, pf, hook)) {
 		struct nf_hook_state state;
 
-		nf_hook_state_init(&state, nf_hook_list, hook, thresh,
+		nf_hook_state_init(&state, hook_list, hook, thresh,
 				   pf, indev, outdev, sk, okfn);
 		return nf_hook_slow(skb, &state);
 	}
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 0ecb2b5..2a5a070 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -62,20 +62,20 @@ EXPORT_SYMBOL(nf_hooks_needed);
 
 static DEFINE_MUTEX(nf_hook_mutex);
 
-static struct list_head *find_nf_hook_list(struct net *net,
+static struct list_head *nf_find_hook_list(struct net *net,
 					   const struct nf_hook_ops *reg)
 {
-	struct list_head *nf_hook_list = NULL;
+	struct list_head *hook_list = NULL;
 
 	if (reg->pf != NFPROTO_NETDEV)
-		nf_hook_list = &net->nf.hooks[reg->pf][reg->hooknum];
+		hook_list = &net->nf.hooks[reg->pf][reg->hooknum];
 	else if (reg->hooknum == NF_NETDEV_INGRESS) {
 #ifdef CONFIG_NETFILTER_INGRESS
 		if (reg->dev && dev_net(reg->dev) == net)
-			nf_hook_list = &reg->dev->nf_hooks_ingress;
+			hook_list = &reg->dev->nf_hooks_ingress;
 #endif
 	}
-	return nf_hook_list;
+	return hook_list;
 }
 
 struct nf_hook_entry {
@@ -85,7 +85,7 @@ struct nf_hook_entry {
 
 int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
 {
-	struct list_head *nf_hook_list;
+	struct list_head *hook_list;
 	struct nf_hook_entry *entry;
 	struct nf_hook_ops *elem;
 
@@ -96,14 +96,14 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
 	entry->orig_ops	= reg;
 	entry->ops	= *reg;
 
-	nf_hook_list = find_nf_hook_list(net, reg);
-	if (!nf_hook_list) {
+	hook_list = nf_find_hook_list(net, reg);
+	if (!hook_list) {
 		kfree(entry);
 		return -ENOENT;
 	}
 
 	mutex_lock(&nf_hook_mutex);
-	list_for_each_entry(elem, nf_hook_list, list) {
+	list_for_each_entry(elem, hook_list, list) {
 		if (reg->priority < elem->priority)
 			break;
 	}
@@ -122,16 +122,16 @@ EXPORT_SYMBOL(nf_register_net_hook);
 
 void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 {
-	struct list_head *nf_hook_list;
+	struct list_head *hook_list;
 	struct nf_hook_entry *entry;
 	struct nf_hook_ops *elem;
 
-	nf_hook_list = find_nf_hook_list(net, reg);
-	if (!nf_hook_list)
+	hook_list = nf_find_hook_list(net, reg);
+	if (!hook_list)
 		return;
 
 	mutex_lock(&nf_hook_mutex);
-	list_for_each_entry(elem, nf_hook_list, list) {
+	list_for_each_entry(elem, hook_list, list) {
 		entry = container_of(elem, struct nf_hook_entry, ops);
 		if (entry->orig_ops == reg) {
 			list_del_rcu(&entry->ops.list);
@@ -139,7 +139,7 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 		}
 	}
 	mutex_unlock(&nf_hook_mutex);
-	if (&elem->list == nf_hook_list) {
+	if (&elem->list == hook_list) {
 		WARN(1, "nf_unregister_net_hook: hook not found!\n");
 		return;
 	}
-- 
1.7.10.4

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

* [PATCH 15/18] netfilter: nf_ct_sctp: minimal multihoming support
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (13 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 14/18] netfilter: rename local nf_hook_list to hook_list Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 16/18] netfilter: bridge: reduce nf_bridge_info to 32 bytes again Pablo Neira Ayuso
                   ` (3 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Michal Kubeček <mkubecek@suse.cz>

Currently nf_conntrack_proto_sctp module handles only packets between
primary addresses used to establish the connection. Any packets between
secondary addresses are classified as invalid so that usual firewall
configurations drop them. Allowing HEARTBEAT and HEARTBEAT-ACK chunks to
establish a new conntrack would allow traffic between secondary
addresses to pass through. A more sophisticated solution based on the
addresses advertised in the initial handshake (and possibly also later
dynamic address addition and removal) would be much harder to implement.
Moreover, in general we cannot assume to always see the initial
handshake as it can be routed through a different path.

The patch adds two new conntrack states:

  SCTP_CONNTRACK_HEARTBEAT_SENT  - a HEARTBEAT chunk seen but not acked
  SCTP_CONNTRACK_HEARTBEAT_ACKED - a HEARTBEAT acked by HEARTBEAT-ACK

State transition rules:

- HEARTBEAT_SENT responds to usual chunks the same way as NONE (so that
  the behaviour changes as little as possible)
- HEARTBEAT_ACKED responds to usual chunks the same way as ESTABLISHED
  does, except the resulting state is HEARTBEAT_ACKED rather than
  ESTABLISHED
- previously existing states except NONE are preserved when HEARTBEAT or
  HEARTBEAT-ACK is seen
- NONE (in the initial direction) changes to HEARTBEAT_SENT on HEARTBEAT
  and to CLOSED on HEARTBEAT-ACK
- HEARTBEAT_SENT changes to HEARTBEAT_ACKED on HEARTBEAT-ACK in the
  reply direction
- HEARTBEAT_SENT and HEARTBEAT_ACKED are preserved on HEARTBEAT and
  HEARTBEAT-ACK otherwise

Normally, vtag is set from the INIT chunk for the reply direction and
from the INIT-ACK chunk for the originating direction (i.e. each of
these defines vtag value for the opposite direction). For secondary
conntracks, we can't rely on seeing INIT/INIT-ACK and even if we have
seen them, we would need to connect two different conntracks. Therefore
simplified logic is applied: vtag of first packet in each direction
(HEARTBEAT in the originating and HEARTBEAT-ACK in reply direction) is
saved and all following packets in that direction are compared with this
saved value. While INIT and INIT-ACK define vtag for the opposite
direction, vtags extracted from HEARTBEAT and HEARTBEAT-ACK are always
for their direction.

Default timeout values for new states are

  HEARTBEAT_SENT: 30 seconds (default hb_interval)
  HEARTBEAT_ACKED: 210 seconds (hb_interval * path_max_retry + max_rto)

(We cannot expect to see the shutdown sequence so that, unlike
ESTABLISHED, the HEARTBEAT_ACKED timeout shouldn't be too long.)

Signed-off-by: Michal Kubecek <mkubecek@suse.cz>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/uapi/linux/netfilter/nf_conntrack_sctp.h   |    2 +
 include/uapi/linux/netfilter/nfnetlink_cttimeout.h |    2 +
 net/netfilter/nf_conntrack_proto_sctp.c            |  101 +++++++++++++++-----
 3 files changed, 81 insertions(+), 24 deletions(-)

diff --git a/include/uapi/linux/netfilter/nf_conntrack_sctp.h b/include/uapi/linux/netfilter/nf_conntrack_sctp.h
index ceeefe6..ed4e776 100644
--- a/include/uapi/linux/netfilter/nf_conntrack_sctp.h
+++ b/include/uapi/linux/netfilter/nf_conntrack_sctp.h
@@ -13,6 +13,8 @@ enum sctp_conntrack {
 	SCTP_CONNTRACK_SHUTDOWN_SENT,
 	SCTP_CONNTRACK_SHUTDOWN_RECD,
 	SCTP_CONNTRACK_SHUTDOWN_ACK_SENT,
+	SCTP_CONNTRACK_HEARTBEAT_SENT,
+	SCTP_CONNTRACK_HEARTBEAT_ACKED,
 	SCTP_CONNTRACK_MAX
 };
 
diff --git a/include/uapi/linux/netfilter/nfnetlink_cttimeout.h b/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
index 1ab0b97..f2c10dc 100644
--- a/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
+++ b/include/uapi/linux/netfilter/nfnetlink_cttimeout.h
@@ -92,6 +92,8 @@ enum ctattr_timeout_sctp {
 	CTA_TIMEOUT_SCTP_SHUTDOWN_SENT,
 	CTA_TIMEOUT_SCTP_SHUTDOWN_RECD,
 	CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT,
+	CTA_TIMEOUT_SCTP_HEARTBEAT_SENT,
+	CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED,
 	__CTA_TIMEOUT_SCTP_MAX
 };
 #define CTA_TIMEOUT_SCTP_MAX (__CTA_TIMEOUT_SCTP_MAX - 1)
diff --git a/net/netfilter/nf_conntrack_proto_sctp.c b/net/netfilter/nf_conntrack_proto_sctp.c
index b45da90..6719773 100644
--- a/net/netfilter/nf_conntrack_proto_sctp.c
+++ b/net/netfilter/nf_conntrack_proto_sctp.c
@@ -42,6 +42,8 @@ static const char *const sctp_conntrack_names[] = {
 	"SHUTDOWN_SENT",
 	"SHUTDOWN_RECD",
 	"SHUTDOWN_ACK_SENT",
+	"HEARTBEAT_SENT",
+	"HEARTBEAT_ACKED",
 };
 
 #define SECS  * HZ
@@ -57,6 +59,8 @@ static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
 	[SCTP_CONNTRACK_SHUTDOWN_SENT]		= 300 SECS / 1000,
 	[SCTP_CONNTRACK_SHUTDOWN_RECD]		= 300 SECS / 1000,
 	[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT]	= 3 SECS,
+	[SCTP_CONNTRACK_HEARTBEAT_SENT]		= 30 SECS,
+	[SCTP_CONNTRACK_HEARTBEAT_ACKED]	= 210 SECS,
 };
 
 #define sNO SCTP_CONNTRACK_NONE
@@ -67,6 +71,8 @@ static unsigned int sctp_timeouts[SCTP_CONNTRACK_MAX] __read_mostly = {
 #define	sSS SCTP_CONNTRACK_SHUTDOWN_SENT
 #define	sSR SCTP_CONNTRACK_SHUTDOWN_RECD
 #define	sSA SCTP_CONNTRACK_SHUTDOWN_ACK_SENT
+#define	sHS SCTP_CONNTRACK_HEARTBEAT_SENT
+#define	sHA SCTP_CONNTRACK_HEARTBEAT_ACKED
 #define	sIV SCTP_CONNTRACK_MAX
 
 /*
@@ -88,6 +94,10 @@ SHUTDOWN_ACK_SENT - We have seen a SHUTDOWN_ACK chunk in the direction opposite
 		    to that of the SHUTDOWN chunk.
 CLOSED            - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
 		    the SHUTDOWN chunk. Connection is closed.
+HEARTBEAT_SENT    - We have seen a HEARTBEAT in a new flow.
+HEARTBEAT_ACKED   - We have seen a HEARTBEAT-ACK in the direction opposite to
+		    that of the HEARTBEAT chunk. Secondary connection is
+		    established.
 */
 
 /* TODO
@@ -97,36 +107,40 @@ CLOSED            - We have seen a SHUTDOWN_COMPLETE chunk in the direction of
  - Check the error type in the reply dir before transitioning from
 cookie echoed to closed.
  - Sec 5.2.4 of RFC 2960
- - Multi Homing support.
+ - Full Multi Homing support.
 */
 
 /* SCTP conntrack state transitions */
-static const u8 sctp_conntracks[2][9][SCTP_CONNTRACK_MAX] = {
+static const u8 sctp_conntracks[2][11][SCTP_CONNTRACK_MAX] = {
 	{
 /*	ORIGINAL	*/
-/*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
-/* init         */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA},
-/* init_ack     */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},
-/* abort        */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
-/* shutdown     */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA},
-/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA},
-/* error        */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't have Stale cookie*/
-/* cookie_echo  */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA},/* 5.2.4 - Big TODO */
-/* cookie_ack   */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in orig dir */
-/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL}
+/*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
+/* init         */ {sCW, sCW, sCW, sCE, sES, sSS, sSR, sSA, sCW, sHA},
+/* init_ack     */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},
+/* abort        */ {sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
+/* shutdown     */ {sCL, sCL, sCW, sCE, sSS, sSS, sSR, sSA, sCL, sSS},
+/* shutdown_ack */ {sSA, sCL, sCW, sCE, sES, sSA, sSA, sSA, sSA, sHA},
+/* error        */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* Can't have Stale cookie*/
+/* cookie_echo  */ {sCL, sCL, sCE, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* 5.2.4 - Big TODO */
+/* cookie_ack   */ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sCL, sHA},/* Can't come in orig dir */
+/* shutdown_comp*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sCL, sCL, sHA},
+/* heartbeat    */ {sHS, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
+/* heartbeat_ack*/ {sCL, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA}
 	},
 	{
 /*	REPLY	*/
-/*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA */
-/* init         */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* INIT in sCL Big TODO */
-/* init_ack     */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},
-/* abort        */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL},
-/* shutdown     */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA},
-/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA},
-/* error        */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA},
-/* cookie_echo  */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA},/* Can't come in reply dir */
-/* cookie_ack   */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA},
-/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL}
+/*                  sNO, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA */
+/* init         */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},/* INIT in sCL Big TODO */
+/* init_ack     */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},
+/* abort        */ {sIV, sCL, sCL, sCL, sCL, sCL, sCL, sCL, sIV, sCL},
+/* shutdown     */ {sIV, sCL, sCW, sCE, sSR, sSS, sSR, sSA, sIV, sSR},
+/* shutdown_ack */ {sIV, sCL, sCW, sCE, sES, sSA, sSA, sSA, sIV, sHA},
+/* error        */ {sIV, sCL, sCW, sCL, sES, sSS, sSR, sSA, sIV, sHA},
+/* cookie_echo  */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sIV, sHA},/* Can't come in reply dir */
+/* cookie_ack   */ {sIV, sCL, sCW, sES, sES, sSS, sSR, sSA, sIV, sHA},
+/* shutdown_comp*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sCL, sIV, sHA},
+/* heartbeat    */ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHS, sHA},
+/* heartbeat_ack*/ {sIV, sCL, sCW, sCE, sES, sSS, sSR, sSA, sHA, sHA}
 	}
 };
 
@@ -278,9 +292,16 @@ static int sctp_new_state(enum ip_conntrack_dir dir,
 		pr_debug("SCTP_CID_SHUTDOWN_COMPLETE\n");
 		i = 8;
 		break;
+	case SCTP_CID_HEARTBEAT:
+		pr_debug("SCTP_CID_HEARTBEAT");
+		i = 9;
+		break;
+	case SCTP_CID_HEARTBEAT_ACK:
+		pr_debug("SCTP_CID_HEARTBEAT_ACK");
+		i = 10;
+		break;
 	default:
-		/* Other chunks like DATA, SACK, HEARTBEAT and
-		its ACK do not cause a change in state */
+		/* Other chunks like DATA or SACK do not change the state */
 		pr_debug("Unknown chunk type, Will stay in %s\n",
 			 sctp_conntrack_names[cur_state]);
 		return cur_state;
@@ -329,6 +350,8 @@ static int sctp_packet(struct nf_conn *ct,
 	    !test_bit(SCTP_CID_COOKIE_ECHO, map) &&
 	    !test_bit(SCTP_CID_ABORT, map) &&
 	    !test_bit(SCTP_CID_SHUTDOWN_ACK, map) &&
+	    !test_bit(SCTP_CID_HEARTBEAT, map) &&
+	    !test_bit(SCTP_CID_HEARTBEAT_ACK, map) &&
 	    sh->vtag != ct->proto.sctp.vtag[dir]) {
 		pr_debug("Verification tag check failed\n");
 		goto out;
@@ -357,6 +380,16 @@ static int sctp_packet(struct nf_conn *ct,
 			/* Sec 8.5.1 (D) */
 			if (sh->vtag != ct->proto.sctp.vtag[dir])
 				goto out_unlock;
+		} else if (sch->type == SCTP_CID_HEARTBEAT ||
+			   sch->type == SCTP_CID_HEARTBEAT_ACK) {
+			if (ct->proto.sctp.vtag[dir] == 0) {
+				pr_debug("Setting vtag %x for dir %d\n",
+					 sh->vtag, dir);
+				ct->proto.sctp.vtag[dir] = sh->vtag;
+			} else if (sh->vtag != ct->proto.sctp.vtag[dir]) {
+				pr_debug("Verification tag check failed\n");
+				goto out_unlock;
+			}
 		}
 
 		old_state = ct->proto.sctp.state;
@@ -466,6 +499,10 @@ static bool sctp_new(struct nf_conn *ct, const struct sk_buff *skb,
 				/* Sec 8.5.1 (A) */
 				return false;
 			}
+		} else if (sch->type == SCTP_CID_HEARTBEAT) {
+			pr_debug("Setting vtag %x for secondary conntrack\n",
+				 sh->vtag);
+			ct->proto.sctp.vtag[IP_CT_DIR_ORIGINAL] = sh->vtag;
 		}
 		/* If it is a shutdown ack OOTB packet, we expect a return
 		   shutdown complete, otherwise an ABORT Sec 8.4 (5) and (8) */
@@ -610,6 +647,8 @@ sctp_timeout_nla_policy[CTA_TIMEOUT_SCTP_MAX+1] = {
 	[CTA_TIMEOUT_SCTP_SHUTDOWN_SENT]	= { .type = NLA_U32 },
 	[CTA_TIMEOUT_SCTP_SHUTDOWN_RECD]	= { .type = NLA_U32 },
 	[CTA_TIMEOUT_SCTP_SHUTDOWN_ACK_SENT]	= { .type = NLA_U32 },
+	[CTA_TIMEOUT_SCTP_HEARTBEAT_SENT]	= { .type = NLA_U32 },
+	[CTA_TIMEOUT_SCTP_HEARTBEAT_ACKED]	= { .type = NLA_U32 },
 };
 #endif /* CONFIG_NF_CT_NETLINK_TIMEOUT */
 
@@ -658,6 +697,18 @@ static struct ctl_table sctp_sysctl_table[] = {
 		.mode		= 0644,
 		.proc_handler	= proc_dointvec_jiffies,
 	},
+	{
+		.procname	= "nf_conntrack_sctp_timeout_heartbeat_sent",
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_jiffies,
+	},
+	{
+		.procname	= "nf_conntrack_sctp_timeout_heartbeat_acked",
+		.maxlen		= sizeof(unsigned int),
+		.mode		= 0644,
+		.proc_handler	= proc_dointvec_jiffies,
+	},
 	{ }
 };
 
@@ -730,6 +781,8 @@ static int sctp_kmemdup_sysctl_table(struct nf_proto_net *pn,
 	pn->ctl_table[4].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_SENT];
 	pn->ctl_table[5].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_RECD];
 	pn->ctl_table[6].data = &sn->timeouts[SCTP_CONNTRACK_SHUTDOWN_ACK_SENT];
+	pn->ctl_table[7].data = &sn->timeouts[SCTP_CONNTRACK_HEARTBEAT_SENT];
+	pn->ctl_table[8].data = &sn->timeouts[SCTP_CONNTRACK_HEARTBEAT_ACKED];
 #endif
 	return 0;
 }
-- 
1.7.10.4

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

* [PATCH 16/18] netfilter: bridge: reduce nf_bridge_info to 32 bytes again
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (14 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 15/18] netfilter: nf_ct_sctp: minimal multihoming support Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 17/18] netfilter: bridge: do not initialize statics to 0 or NULL Pablo Neira Ayuso
                   ` (2 subsequent siblings)
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Florian Westphal <fw@strlen.de>

We can use union for most of the temporary cruft (original ipv4/ipv6
address, source mac, physoutdev) since they're used during different
stages of br netfilter traversal.

Also get rid of the last two ->mask users.

Shrinks struct from 48 to 32 on 64bit arch.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 include/linux/netfilter_bridge.h          |   12 +++++++++---
 include/linux/skbuff.h                    |   19 +++++++++++++------
 net/bridge/br_netfilter_hooks.c           |   14 ++++++--------
 net/bridge/br_netfilter_ipv6.c            |    2 +-
 net/ipv4/netfilter/nf_defrag_ipv4.c       |    7 ++-----
 net/ipv6/netfilter/nf_defrag_ipv6_hooks.c |    7 ++-----
 6 files changed, 33 insertions(+), 28 deletions(-)

diff --git a/include/linux/netfilter_bridge.h b/include/linux/netfilter_bridge.h
index 6d80fc6..2437b8a 100644
--- a/include/linux/netfilter_bridge.h
+++ b/include/linux/netfilter_bridge.h
@@ -17,9 +17,6 @@ enum nf_br_hook_priorities {
 
 #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
 
-#define BRNF_BRIDGED_DNAT		0x02
-#define BRNF_NF_BRIDGE_PREROUTING	0x08
-
 int br_handle_frame_finish(struct sock *sk, struct sk_buff *skb);
 
 static inline void br_drop_fake_rtable(struct sk_buff *skb)
@@ -63,8 +60,17 @@ nf_bridge_get_physoutdev(const struct sk_buff *skb)
 {
 	return skb->nf_bridge ? skb->nf_bridge->physoutdev : NULL;
 }
+
+static inline bool nf_bridge_in_prerouting(const struct sk_buff *skb)
+{
+	return skb->nf_bridge && skb->nf_bridge->in_prerouting;
+}
 #else
 #define br_drop_fake_rtable(skb)	        do { } while (0)
+static inline bool nf_bridge_in_prerouting(const struct sk_buff *skb)
+{
+	return false;
+}
 #endif /* CONFIG_BRIDGE_NETFILTER */
 
 #endif
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index d6cdd6e..ac732e6 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -173,17 +173,24 @@ struct nf_bridge_info {
 		BRNF_PROTO_8021Q,
 		BRNF_PROTO_PPPOE
 	} orig_proto:8;
-	bool			pkt_otherhost;
+	u8			pkt_otherhost:1;
+	u8			in_prerouting:1;
+	u8			bridged_dnat:1;
 	__u16			frag_max_size;
-	unsigned int		mask;
 	struct net_device	*physindev;
 	union {
-		struct net_device *physoutdev;
-		char neigh_header[8];
-	};
-	union {
+		/* prerouting: detect dnat in orig/reply direction */
 		__be32          ipv4_daddr;
 		struct in6_addr ipv6_daddr;
+
+		/* after prerouting + nat detected: store original source
+		 * mac since neigh resolution overwrites it, only used while
+		 * skb is out in neigh layer.
+		 */
+		char neigh_header[8];
+
+		/* always valid & non-NULL from FORWARD on, for physdev match */
+		struct net_device *physoutdev;
 	};
 };
 #endif
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index c8b9bcf..ec51c2b 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -284,7 +284,7 @@ int br_nf_pre_routing_finish_bridge(struct sock *sk, struct sk_buff *skb)
 							 nf_bridge->neigh_header,
 							 ETH_HLEN-ETH_ALEN);
 			/* tell br_dev_xmit to continue with forwarding */
-			nf_bridge->mask |= BRNF_BRIDGED_DNAT;
+			nf_bridge->bridged_dnat = 1;
 			/* FIXME Need to refragment */
 			ret = neigh->output(neigh, skb);
 		}
@@ -356,7 +356,7 @@ static int br_nf_pre_routing_finish(struct sock *sk, struct sk_buff *skb)
 		skb->pkt_type = PACKET_OTHERHOST;
 		nf_bridge->pkt_otherhost = false;
 	}
-	nf_bridge->mask &= ~BRNF_NF_BRIDGE_PREROUTING;
+	nf_bridge->in_prerouting = 0;
 	if (br_nf_ipv4_daddr_was_changed(skb, nf_bridge)) {
 		if ((err = ip_route_input(skb, iph->daddr, iph->saddr, iph->tos, dev))) {
 			struct in_device *in_dev = __in_dev_get_rcu(dev);
@@ -444,7 +444,7 @@ struct net_device *setup_pre_routing(struct sk_buff *skb)
 		nf_bridge->pkt_otherhost = true;
 	}
 
-	nf_bridge->mask |= BRNF_NF_BRIDGE_PREROUTING;
+	nf_bridge->in_prerouting = 1;
 	nf_bridge->physindev = skb->dev;
 	skb->dev = brnf_get_logical_dev(skb, skb->dev);
 
@@ -850,10 +850,8 @@ static unsigned int ip_sabotage_in(const struct nf_hook_ops *ops,
 				   struct sk_buff *skb,
 				   const struct nf_hook_state *state)
 {
-	if (skb->nf_bridge &&
-	    !(skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)) {
+	if (skb->nf_bridge && !skb->nf_bridge->in_prerouting)
 		return NF_STOP;
-	}
 
 	return NF_ACCEPT;
 }
@@ -872,7 +870,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
 	struct nf_bridge_info *nf_bridge = nf_bridge_info_get(skb);
 
 	skb_pull(skb, ETH_HLEN);
-	nf_bridge->mask &= ~BRNF_BRIDGED_DNAT;
+	nf_bridge->bridged_dnat = 0;
 
 	BUILD_BUG_ON(sizeof(nf_bridge->neigh_header) != (ETH_HLEN - ETH_ALEN));
 
@@ -887,7 +885,7 @@ static void br_nf_pre_routing_finish_bridge_slow(struct sk_buff *skb)
 
 static int br_nf_dev_xmit(struct sk_buff *skb)
 {
-	if (skb->nf_bridge && (skb->nf_bridge->mask & BRNF_BRIDGED_DNAT)) {
+	if (skb->nf_bridge && skb->nf_bridge->bridged_dnat) {
 		br_nf_pre_routing_finish_bridge_slow(skb);
 		return 1;
 	}
diff --git a/net/bridge/br_netfilter_ipv6.c b/net/bridge/br_netfilter_ipv6.c
index 13b7d1e..77383bf 100644
--- a/net/bridge/br_netfilter_ipv6.c
+++ b/net/bridge/br_netfilter_ipv6.c
@@ -174,7 +174,7 @@ static int br_nf_pre_routing_finish_ipv6(struct sock *sk, struct sk_buff *skb)
 		skb->pkt_type = PACKET_OTHERHOST;
 		nf_bridge->pkt_otherhost = false;
 	}
-	nf_bridge->mask &= ~BRNF_NF_BRIDGE_PREROUTING;
+	nf_bridge->in_prerouting = 0;
 	if (br_nf_ipv6_daddr_was_changed(skb, nf_bridge)) {
 		skb_dst_drop(skb);
 		v6ops->route_input(skb);
diff --git a/net/ipv4/netfilter/nf_defrag_ipv4.c b/net/ipv4/netfilter/nf_defrag_ipv4.c
index c88b7d4..b69e82b 100644
--- a/net/ipv4/netfilter/nf_defrag_ipv4.c
+++ b/net/ipv4/netfilter/nf_defrag_ipv4.c
@@ -49,12 +49,9 @@ static enum ip_defrag_users nf_ct_defrag_user(unsigned int hooknum,
 	if (skb->nfct)
 		zone = nf_ct_zone((struct nf_conn *)skb->nfct);
 #endif
-
-#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
-	if (skb->nf_bridge &&
-	    skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
+	if (nf_bridge_in_prerouting(skb))
 		return IP_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
-#endif
+
 	if (hooknum == NF_INET_PRE_ROUTING)
 		return IP_DEFRAG_CONNTRACK_IN + zone;
 	else
diff --git a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
index a45db0b..267fb8d 100644
--- a/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
+++ b/net/ipv6/netfilter/nf_defrag_ipv6_hooks.c
@@ -39,12 +39,9 @@ static enum ip6_defrag_users nf_ct6_defrag_user(unsigned int hooknum,
 	if (skb->nfct)
 		zone = nf_ct_zone((struct nf_conn *)skb->nfct);
 #endif
-
-#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
-	if (skb->nf_bridge &&
-	    skb->nf_bridge->mask & BRNF_NF_BRIDGE_PREROUTING)
+	if (nf_bridge_in_prerouting(skb))
 		return IP6_DEFRAG_CONNTRACK_BRIDGE_IN + zone;
-#endif
+
 	if (hooknum == NF_INET_PRE_ROUTING)
 		return IP6_DEFRAG_CONNTRACK_IN + zone;
 	else
-- 
1.7.10.4

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

* [PATCH 17/18] netfilter: bridge: do not initialize statics to 0 or NULL
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (15 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 16/18] netfilter: bridge: reduce nf_bridge_info to 32 bytes again Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-04 10:02 ` [PATCH 18/18] netfilter: ip6t_REJECT: Remove debug messages from reject_tg6() Pablo Neira Ayuso
  2015-08-05  7:00 ` [PATCH 00/18] Netfilter updates for net-next David Miller
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Bernhard Thaler <bernhard.thaler@wvnet.at>

Fix checkpatch.pl "ERROR: do not initialise statics to 0 or NULL" for
all statics explicitly initialized to 0.

Signed-off-by: Bernhard Thaler <bernhard.thaler@wvnet.at>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/bridge/br_netfilter_hooks.c |    6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index ec51c2b..0a6f095 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -49,9 +49,9 @@ static struct ctl_table_header *brnf_sysctl_header;
 static int brnf_call_iptables __read_mostly = 1;
 static int brnf_call_ip6tables __read_mostly = 1;
 static int brnf_call_arptables __read_mostly = 1;
-static int brnf_filter_vlan_tagged __read_mostly = 0;
-static int brnf_filter_pppoe_tagged __read_mostly = 0;
-static int brnf_pass_vlan_indev __read_mostly = 0;
+static int brnf_filter_vlan_tagged __read_mostly;
+static int brnf_filter_pppoe_tagged __read_mostly;
+static int brnf_pass_vlan_indev __read_mostly;
 #else
 #define brnf_call_iptables 1
 #define brnf_call_ip6tables 1
-- 
1.7.10.4

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

* [PATCH 18/18] netfilter: ip6t_REJECT: Remove debug messages from reject_tg6()
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (16 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 17/18] netfilter: bridge: do not initialize statics to 0 or NULL Pablo Neira Ayuso
@ 2015-08-04 10:02 ` Pablo Neira Ayuso
  2015-08-05  7:00 ` [PATCH 00/18] Netfilter updates for net-next David Miller
  18 siblings, 0 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2015-08-04 10:02 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

From: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>

Make it similar to reject_tg() in ipt_REJECT.

Suggested-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Subash Abhinov Kasiviswanathan <subashab@codeaurora.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/ipv6/netfilter/ip6t_REJECT.c |    5 -----
 1 file changed, 5 deletions(-)

diff --git a/net/ipv6/netfilter/ip6t_REJECT.c b/net/ipv6/netfilter/ip6t_REJECT.c
index 12331ef..567367a 100644
--- a/net/ipv6/netfilter/ip6t_REJECT.c
+++ b/net/ipv6/netfilter/ip6t_REJECT.c
@@ -35,14 +35,12 @@ MODULE_AUTHOR("Yasuyuki KOZAKAI <yasuyuki.kozakai@toshiba.co.jp>");
 MODULE_DESCRIPTION("Xtables: packet \"rejection\" target for IPv6");
 MODULE_LICENSE("GPL");
 
-
 static unsigned int
 reject_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 {
 	const struct ip6t_reject_info *reject = par->targinfo;
 	struct net *net = dev_net((par->in != NULL) ? par->in : par->out);
 
-	pr_debug("%s: medium point\n", __func__);
 	switch (reject->with) {
 	case IP6T_ICMP6_NO_ROUTE:
 		nf_send_unreach6(net, skb, ICMPV6_NOROUTE, par->hooknum);
@@ -65,9 +63,6 @@ reject_tg6(struct sk_buff *skb, const struct xt_action_param *par)
 	case IP6T_TCP_RESET:
 		nf_send_reset6(net, skb, par->hooknum);
 		break;
-	default:
-		net_info_ratelimited("case %u not handled yet\n", reject->with);
-		break;
 	}
 
 	return NF_DROP;
-- 
1.7.10.4


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

* Re: [PATCH 00/18] Netfilter updates for net-next
  2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
                   ` (17 preceding siblings ...)
  2015-08-04 10:02 ` [PATCH 18/18] netfilter: ip6t_REJECT: Remove debug messages from reject_tg6() Pablo Neira Ayuso
@ 2015-08-05  7:00 ` David Miller
  18 siblings, 0 replies; 32+ messages in thread
From: David Miller @ 2015-08-05  7:00 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Tue,  4 Aug 2015 12:02:30 +0200

> The following patchset contains Netfilter updates for net-next, they are:

Applied, thanks Pablo.

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

* Re: [PATCH 00/18] Netfilter updates for net-next
  2019-11-18 21:48 Pablo Neira Ayuso
@ 2019-11-19  0:47 ` David Miller
  0 siblings, 0 replies; 32+ messages in thread
From: David Miller @ 2019-11-19  0:47 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 18 Nov 2019 22:48:56 +0100

> The following patchset contains Netfilter updates for net-next:
 ...
> You can pull these changes from:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git

Pulled, thank you.

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

* [PATCH 00/18] Netfilter updates for net-next
@ 2019-11-18 21:48 Pablo Neira Ayuso
  2019-11-19  0:47 ` David Miller
  0 siblings, 1 reply; 32+ messages in thread
From: Pablo Neira Ayuso @ 2019-11-18 21:48 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Hi,

The following patchset contains Netfilter updates for net-next:

1) Wildcard support for the net,iface set from Kristian Evensen.

2) Offload support for matching on the input interface.

3) Simplify matching on vlan header fields.

4) Add nft_payload_rebuild_vlan_hdr() function to rebuild the vlan
   header from the vlan sk_buff metadata.

5) Pass extack to nft_flow_cls_offload_setup().

6) Add C-VLAN matching support.

7) Use time64_t in xt_time to fix y2038 overflow, from Arnd Bergmann.

8) Use time_t in nft_meta to fix y2038 overflow, also from Arnd.

9) Add flow_action_entry_next() helper function to flowtable offload
   infrastructure.

10) Add IPv6 support to the flowtable offload infrastructure.

11) Support for input interface matching from postrouting,
    from Phil Sutter.

12) Missing check for ndo callback in flowtable offload, from wenxu.

13) Remove conntrack parameter from flow_offload_fill_dir(), from wenxu.

14) Do not pass flow_rule object for rule removal, cookie is sufficient
    to achieve this.

15) Release flow_rule object in case of error from the offload commit
    path.

16) Undo offload ruleset updates if transaction fails.

17) Check for error when binding flowtable callbacks, from wenxu.

18) Always unbind flowtable callbacks when unregistering hooks.

You can pull these changes from:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git

Thanks.

----------------------------------------------------------------

The following changes since commit 90bc72b13c08eedf73b7c0bd94ef23c467800c4a:

  Merge branch 'ARM-Enable-GENET-support-for-RPi-4' (2019-11-12 20:08:00 -0800)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git HEAD

for you to fetch changes up to ff4bf2f42a40e7dff28379f085b64df322c70b45:

  netfilter: nf_tables: add nft_unregister_flowtable_hook() (2019-11-15 23:44:54 +0100)

----------------------------------------------------------------
Arnd Bergmann (2):
      netfilter: xt_time: use time64_t
      netfilter: nft_meta: use 64-bit time arithmetic

Kristian Evensen (1):
      netfilter: ipset: Add wildcard support to net,iface

Pablo Neira Ayuso (12):
      netfilter: nft_meta: offload support for interface index
      netfilter: nft_payload: simplify vlan header handling
      netfilter: nf_tables: add nft_payload_rebuild_vlan_hdr()
      netfilter: nf_tables_offload: pass extack to nft_flow_cls_offload_setup()
      netfilter: nft_payload: add C-VLAN support
      Merge branch 'master' of git://blackhole.kfki.hu/nf-next
      netfilter: nf_flow_table_offload: add flow_action_entry_next() and use it
      netfilter: nf_flow_table_offload: add IPv6 support
      netfilter: nf_tables_offload: remove reference to flow rule from deletion path
      netfilter: nf_tables_offload: release flow_rule on error from commit path
      netfilter: nf_tables_offload: undo updates if transaction fails
      netfilter: nf_tables: add nft_unregister_flowtable_hook()

Phil Sutter (1):
      netfilter: Support iif matches in POSTROUTING

wenxu (3):
      netfilter: nf_flow_table_offload: Fix check ndo_setup_tc when setup_block
      netfilter: nf_flow_table: remove unnecessary parameter in flow_offload_fill_dir
      netfilter: nf_tables: check if bind callback fails and unbind if hook registration fails

 include/net/netfilter/nf_flow_table.h       |   9 +-
 include/net/netfilter/nf_tables_offload.h   |   1 +
 include/uapi/linux/netfilter/ipset/ip_set.h |   2 +
 net/ipv4/ip_output.c                        |   4 +-
 net/ipv4/netfilter/nf_flow_table_ipv4.c     |   2 +-
 net/ipv4/xfrm4_output.c                     |   2 +-
 net/ipv6/ip6_output.c                       |   4 +-
 net/ipv6/netfilter/nf_flow_table_ipv6.c     |   2 +-
 net/ipv6/xfrm6_output.c                     |   2 +-
 net/netfilter/ipset/ip_set_hash_netiface.c  |  23 +++-
 net/netfilter/nf_flow_table_core.c          |   8 +-
 net/netfilter/nf_flow_table_inet.c          |  25 +++-
 net/netfilter/nf_flow_table_offload.c       | 179 +++++++++++++++++++++-------
 net/netfilter/nf_tables_api.c               |  49 ++++++--
 net/netfilter/nf_tables_offload.c           |  95 +++++++++++++--
 net/netfilter/nft_meta.c                    |  14 ++-
 net/netfilter/nft_payload.c                 |  56 +++++----
 net/netfilter/xt_time.c                     |  19 +--
 18 files changed, 370 insertions(+), 126 deletions(-)

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

* Re: [PATCH 00/18] Netfilter updates for net-next
  2018-05-23 18:42 Pablo Neira Ayuso
@ 2018-05-23 20:37 ` David Miller
  0 siblings, 0 replies; 32+ messages in thread
From: David Miller @ 2018-05-23 20:37 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Wed, 23 May 2018 20:42:36 +0200

> The following patchset contains Netfilter updates for your net-next
> tree, they are:
 ...
> This batch comes with is a conflict between 25fd386e0bc0 ("netfilter:
> core: add missing __rcu annotation") in your tree and 2c205dd3981f
> ("netfilter: add struct nf_nat_hook and use it") coming in this batch.
> This conflict can be solved by leaving the __rcu tag on
> __netfilter_net_init() - added by 25fd386e0bc0 - and remove all code
> related to nf_nat_decode_session_hook - which is gone after
> 2c205dd3981f, as described by:
> 
> diff --cc net/netfilter/core.c
> index e0ae4aae96f5,206fb2c4c319..168af54db975
> --- a/net/netfilter/core.c
> +++ b/net/netfilter/core.c
 ...
> I can also merge your net-next tree into nf-next, solve the conflict and
> resend the pull request if you prefer so.
> 
> You can pull these changes from:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git

Thanks for the merge conflict resolution guide.

Pulled, thanks.

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

* [PATCH 00/18] Netfilter updates for net-next
@ 2018-05-23 18:42 Pablo Neira Ayuso
  2018-05-23 20:37 ` David Miller
  0 siblings, 1 reply; 32+ messages in thread
From: Pablo Neira Ayuso @ 2018-05-23 18:42 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Hi David,

The following patchset contains Netfilter updates for your net-next
tree, they are:

1) Remove obsolete nf_log tracing from nf_tables, from Florian Westphal.

2) Add support for map lookups to numgen, random and hash expressions,
   from Laura Garcia.

3) Allow to register nat hooks for iptables and nftables at the same
   time. Patchset from Florian Westpha.

4) Timeout support for rbtree sets.

5) ip6_rpfilter works needs interface for link-local addresses, from
   Vincent Bernat.

6) Add nf_ct_hook and nf_nat_hook structures and use them.

7) Do not drop packets on packets raceing to insert conntrack entries
   into hashes, this is particularly a problem in nfqueue setups.

8) Address fallout from xt_osf separation to nf_osf, patches
   from Florian Westphal and Fernando Mancera.

9) Remove reference to struct nft_af_info, which doesn't exist anymore.
   From Taehee Yoo.

This batch comes with is a conflict between 25fd386e0bc0 ("netfilter:
core: add missing __rcu annotation") in your tree and 2c205dd3981f
("netfilter: add struct nf_nat_hook and use it") coming in this batch.
This conflict can be solved by leaving the __rcu tag on
__netfilter_net_init() - added by 25fd386e0bc0 - and remove all code
related to nf_nat_decode_session_hook - which is gone after
2c205dd3981f, as described by:

diff --cc net/netfilter/core.c
index e0ae4aae96f5,206fb2c4c319..168af54db975
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@@ -611,7 -580,13 +611,8 @@@ const struct nf_conntrack_zone nf_ct_zo
  EXPORT_SYMBOL_GPL(nf_ct_zone_dflt);
  #endif /* CONFIG_NF_CONNTRACK */
  
- static void __net_init __netfilter_net_init(struct nf_hook_entries **e, int max)
 -#ifdef CONFIG_NF_NAT_NEEDED
 -void (*nf_nat_decode_session_hook)(struct sk_buff *, struct flowi *);
 -EXPORT_SYMBOL(nf_nat_decode_session_hook);
 -#endif
 -
+ static void __net_init
+ __netfilter_net_init(struct nf_hook_entries __rcu **e, int max)
  {
  	int h;
  

I can also merge your net-next tree into nf-next, solve the conflict and
resend the pull request if you prefer so.

You can pull these changes from:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git

Thanks.

----------------------------------------------------------------

The following changes since commit 289e1f4e9e4a09c73a1c0152bb93855ea351ccda:

  net: ipv4: ipconfig: fix unused variable (2018-05-13 20:27:25 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git HEAD

for you to fetch changes up to 0c6bca747111dee19aa48c8f73d77fc85fcb8dd0:

  netfilter: nf_tables: remove nft_af_info. (2018-05-23 12:16:25 +0200)

----------------------------------------------------------------
Fernando Fernandez Mancera (1):
      netfilter: make NF_OSF non-visible symbol

Florian Westphal (9):
      netfilter: fix fallout from xt/nf osf separation
      netfilter: nf_tables: remove old nf_log based tracing
      netfilter: nf_nat: move common nat code to nat core
      netfilter: xtables: allow table definitions not backed by hook_ops
      netfilter: nf_tables: allow chain type to override hook register
      netfilter: core: export raw versions of add/delete hook functions
      netfilter: nf_nat: add nat hook register functions to nf_nat
      netfilter: nf_nat: add nat type hooks to nat core
      netfilter: lift one-nat-hook-only restriction

Laura Garcia Liebana (2):
      netfilter: nft_numgen: add map lookups for numgen random operations
      netfilter: nft_hash: add map lookups for hashing operations

Pablo Neira Ayuso (4):
      netfilter: nft_set_rbtree: add timeout support
      netfilter: add struct nf_ct_hook and use it
      netfilter: add struct nf_nat_hook and use it
      netfilter: nfnetlink_queue: resolve clash for unconfirmed conntracks

Taehee Yoo (1):
      netfilter: nf_tables: remove nft_af_info.

Vincent Bernat (1):
      netfilter: ip6t_rpfilter: provide input interface for route lookup

 include/linux/netfilter.h                |  34 +++-
 include/linux/netfilter/nf_osf.h         |   6 +
 include/net/netfilter/nf_nat.h           |   4 +
 include/net/netfilter/nf_nat_core.h      |  11 +-
 include/net/netfilter/nf_nat_l3proto.h   |  52 +-----
 include/net/netfilter/nf_tables.h        |   8 +-
 include/net/netns/nftables.h             |   2 -
 include/uapi/linux/netfilter/nf_osf.h    |   8 +-
 include/uapi/linux/netfilter/nf_tables.h |   4 +
 net/ipv4/netfilter/ip_tables.c           |   5 +-
 net/ipv4/netfilter/iptable_nat.c         |  85 ++++-----
 net/ipv4/netfilter/nf_nat_l3proto_ipv4.c | 135 ++++++--------
 net/ipv4/netfilter/nft_chain_nat_ipv4.c  |  52 ++----
 net/ipv6/netfilter/ip6_tables.c          |   5 +-
 net/ipv6/netfilter/ip6t_rpfilter.c       |   2 +
 net/ipv6/netfilter/ip6table_nat.c        |  84 ++++-----
 net/ipv6/netfilter/nf_nat_l3proto_ipv6.c | 129 ++++++--------
 net/ipv6/netfilter/nft_chain_nat_ipv6.c  |  48 ++---
 net/netfilter/Kconfig                    |   2 +-
 net/netfilter/core.c                     | 102 +++++++----
 net/netfilter/nf_conntrack_core.c        |  91 +++++++++-
 net/netfilter/nf_conntrack_netlink.c     |  10 +-
 net/netfilter/nf_internals.h             |   5 +
 net/netfilter/nf_nat_core.c              | 294 ++++++++++++++++++++++++++++---
 net/netfilter/nf_tables_api.c            |  87 ++-------
 net/netfilter/nf_tables_core.c           |  29 +--
 net/netfilter/nfnetlink_queue.c          |  28 ++-
 net/netfilter/nft_hash.c                 | 131 +++++++++++++-
 net/netfilter/nft_numgen.c               |  76 +++++++-
 net/netfilter/nft_set_rbtree.c           |  75 +++++++-
 30 files changed, 1033 insertions(+), 571 deletions(-)

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

* Re: [PATCH 00/18] Netfilter updates for net-next
  2014-07-18 11:00 Pablo Neira Ayuso
  2014-07-21  4:41 ` David Miller
@ 2014-07-22  8:02 ` David Miller
  1 sibling, 0 replies; 32+ messages in thread
From: David Miller @ 2014-07-22  8:02 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Fri, 18 Jul 2014 13:00:54 +0200

> BTW, I would need that you pull net into net-next after this batch, most
> likely we'll have another round of nf_tables updates for net-next
> that depend on changes that are available in your net tree.

I've now done this merge.

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

* Re: [PATCH 00/18] Netfilter updates for net-next
  2014-07-18 11:00 Pablo Neira Ayuso
@ 2014-07-21  4:41 ` David Miller
  2014-07-22  8:02 ` David Miller
  1 sibling, 0 replies; 32+ messages in thread
From: David Miller @ 2014-07-21  4:41 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Fri, 18 Jul 2014 13:00:54 +0200

> You can pull these changes from:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git

Pulled, thanks Pablo.

> BTW, I would need that you pull net into net-next after this batch, most
> likely we'll have another round of nf_tables updates for net-next
> that depend on changes that are available in your net tree.

I will work on doing this merge soon, thanks for asking.


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

* [PATCH 00/18] Netfilter updates for net-next
@ 2014-07-18 11:00 Pablo Neira Ayuso
  2014-07-21  4:41 ` David Miller
  2014-07-22  8:02 ` David Miller
  0 siblings, 2 replies; 32+ messages in thread
From: Pablo Neira Ayuso @ 2014-07-18 11:00 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Hi David,

The following patchset contains updates for your net-next tree,
they are:

1) Use kvfree() helper function from x_tables, from Eric Dumazet.

2) Remove extra timer from the conntrack ecache extension, use a
   workqueue instead to redeliver lost events to userspace instead,
   from Florian Westphal.

3) Removal of the ulog targets for ebtables and iptables. The nflog
   infrastructure superseded this almost 9 years ago, time to get rid
   of this code.

4) Replace the list of loggers by an array now that we can only have
   two possible non-overlapping logger flavours, ie. kernel ring buffer
   and netlink logging.

5) Move Eric Dumazet's log buffer code to nf_log to reuse it from
   all of the supported per-family loggers.

6) Consolidate nf_log_packet() as an unified interface for packet logging.
   After this patch, if the struct nf_loginfo is available, it explicitly
   selects the logger that is used.

7) Move ip and ip6 logging code from xt_LOG to the corresponding
   per-family loggers. Thus, x_tables and nf_tables share the same code
   for packet logging.

8) Add generic ARP packet logger, which is used by nf_tables. The
   format aims to be consistent with the output of xt_LOG.

9) Add generic bridge packet logger. Again, this is used by nf_tables
   and it routes the packets to the real family loggers. As a result,
   we get consistent logging format for the bridge family. The ebt_log
   logging code has been intentionally left in place not to break
   backward compatibility since the logging output differs from xt_LOG.

10) Update nft_log to explicitly request the required family logger when
    needed.

11) Finish nft_log so it supports arp, ip, ip6, bridge and inet families.
    Allowing selection between netlink and kernel buffer ring logging.

12) Several fixes coming after the netfilter core logging changes spotted
    by robots.

13) Use IS_ENABLED() macros whenever possible in the netfilter tree,
    from Duan Jiong.

14) Removal of a couple of unnecessary branch before kfree, from Fabian
    Frederick.

You can pull these changes from:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git

BTW, I would need that you pull net into net-next after this batch, most
likely we'll have another round of nf_tables updates for net-next
that depend on changes that are available in your net tree.

Thanks a lot!

----------------------------------------------------------------

The following changes since commit 5433ba365f6dd9f30899188755eb4b093314732c:

  cxgb4: Fix endian bug introduced in cxgb4 dcb patchset (2014-06-24 12:54:52 -0700)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master

for you to fetch changes up to 16ea4c6b9dde2ff44b2bd8bb459daa283cf3a46e:

  ipvs: Remove dead debug code (2014-07-16 10:07:11 +0900)

----------------------------------------------------------------
Duan Jiong (1):
      netfilter: use IS_ENABLED() macro

Eric Dumazet (1):
      netfilter: x_tables: xt_free_table_info() cleanup

Fabian Frederick (2):
      netfilter: ctnetlink: remove null test before kfree
      ipvs: remove null test before kfree

Fengguang Wu (1):
      netfilter: nft_log: fix coccinelle warnings

Florian Westphal (1):
      netfilter: conntrack: remove timer from ecache extension

Pablo Neira Ayuso (11):
      netfilter: kill ulog targets
      netfilter: nf_log: use an array of loggers instead of list
      netfilter: nf_log: move log buffering to core logging
      netfilter: log: split family specific code to nf_log_{ip,ip6,common}.c files
      netfilter: log: nf_log_packet() as real unified interface
      netfilter: add generic ARP packet logger
      netfilter: bridge: add generic packet logger
      netfilter: nft_log: request explicit logger when loading rules
      netfilter: nft_log: complete logging support
      netfilter: fix several Kconfig problems in NF_LOG_*
      netfilter: xt_LOG: add missing string format in nf_log_packet()

Yannick Brosseau (1):
      ipvs: Remove dead debug code

 include/net/netfilter/nf_conntrack_ecache.h    |   26 +-
 include/net/netfilter/nf_log.h                 |   42 +-
 include/net/netfilter/xt_log.h                 |   54 --
 include/net/netns/conntrack.h                  |    6 +-
 include/uapi/linux/netfilter/nf_tables.h       |    4 +
 include/uapi/linux/netfilter_bridge/Kbuild     |    1 -
 include/uapi/linux/netfilter_bridge/ebt_ulog.h |   38 -
 include/uapi/linux/netfilter_ipv4/Kbuild       |    1 -
 include/uapi/linux/netfilter_ipv4/ipt_ULOG.h   |   49 --
 net/bridge/netfilter/Kconfig                   |   19 +-
 net/bridge/netfilter/Makefile                  |    3 +
 net/bridge/netfilter/ebt_log.c                 |   47 +-
 net/bridge/netfilter/ebt_ulog.c                |  393 -----------
 net/bridge/netfilter/nf_log_bridge.c           |   96 +++
 net/ipv4/netfilter/Kconfig                     |   29 +-
 net/ipv4/netfilter/Makefile                    |    4 +
 net/ipv4/netfilter/ipt_ULOG.c                  |  498 -------------
 net/ipv4/netfilter/nf_conntrack_l3proto_ipv4.c |    4 +-
 net/ipv4/netfilter/nf_conntrack_proto_icmp.c   |    4 +-
 net/ipv4/netfilter/nf_defrag_ipv4.c            |    8 +-
 net/ipv4/netfilter/nf_log_arp.c                |  149 ++++
 net/ipv4/netfilter/nf_log_ipv4.c               |  385 +++++++++++
 net/ipv4/netfilter/nf_nat_l3proto_ipv4.c       |    4 +
 net/ipv4/netfilter/nf_nat_proto_gre.c          |    2 +-
 net/ipv4/netfilter/nf_nat_proto_icmp.c         |    2 +-
 net/ipv6/netfilter/Kconfig                     |    5 +
 net/ipv6/netfilter/Makefile                    |    3 +
 net/ipv6/netfilter/nf_log_ipv6.c               |  417 +++++++++++
 net/ipv6/netfilter/nf_nat_l3proto_ipv6.c       |    4 +
 net/netfilter/Kconfig                          |    4 +
 net/netfilter/Makefile                         |    3 +
 net/netfilter/ipvs/ip_vs_ctl.c                 |   86 ---
 net/netfilter/ipvs/ip_vs_sync.c                |    3 +-
 net/netfilter/nf_conntrack_core.c              |   68 +-
 net/netfilter/nf_conntrack_ecache.c            |   96 ++-
 net/netfilter/nf_conntrack_netlink.c           |    3 +-
 net/netfilter/nf_log.c                         |  155 ++++-
 net/netfilter/nf_log_common.c                  |  187 +++++
 net/netfilter/nf_nat_core.c                    |    2 +-
 net/netfilter/nf_nat_proto_common.c            |    2 +-
 net/netfilter/nf_nat_proto_dccp.c              |    2 +-
 net/netfilter/nf_nat_proto_sctp.c              |    2 +-
 net/netfilter/nf_nat_proto_tcp.c               |    2 +-
 net/netfilter/nf_nat_proto_udp.c               |    2 +-
 net/netfilter/nf_nat_proto_udplite.c           |    2 +-
 net/netfilter/nfnetlink_log.c                  |    4 +
 net/netfilter/nft_log.c                        |   98 ++-
 net/netfilter/x_tables.c                       |   23 +-
 net/netfilter/xt_LOG.c                         |  884 +-----------------------
 49 files changed, 1694 insertions(+), 2231 deletions(-)
 delete mode 100644 include/net/netfilter/xt_log.h
 delete mode 100644 include/uapi/linux/netfilter_bridge/ebt_ulog.h
 delete mode 100644 include/uapi/linux/netfilter_ipv4/ipt_ULOG.h
 delete mode 100644 net/bridge/netfilter/ebt_ulog.c
 create mode 100644 net/bridge/netfilter/nf_log_bridge.c
 delete mode 100644 net/ipv4/netfilter/ipt_ULOG.c
 create mode 100644 net/ipv4/netfilter/nf_log_arp.c
 create mode 100644 net/ipv4/netfilter/nf_log_ipv4.c
 create mode 100644 net/ipv6/netfilter/nf_log_ipv6.c
 create mode 100644 net/netfilter/nf_log_common.c

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

* Re: [PATCH 00/18] netfilter updates for net-next
  2013-04-29 15:37 ` David Miller
  2013-04-29 17:50   ` Pablo Neira Ayuso
@ 2013-04-29 20:27   ` Jozsef Kadlecsik
  1 sibling, 0 replies; 32+ messages in thread
From: Jozsef Kadlecsik @ 2013-04-29 20:27 UTC (permalink / raw)
  To: David Miller; +Cc: pablo, netfilter-devel, netdev

On Mon, 29 Apr 2013, David Miller wrote:

> This doesn't compile:
> 
> net/sched/em_ipset.c:86:5: error: ?struct ip_set_adt_opt? has no member named ?timeout?
> N?????r??y????b?X????v?^?)??{.n?+???z?????u???)????w*\x1fjg???\x1e
???????j/???z?????2???????&?)???a??\x7f??\x1e
???G???h???\x0f?j:+v???w??????

Sorry, that was my fault: I had net sched disabled for faster compilation 
and thus I missed that em_ipset.c had to be adapted to the changes in the 
ipset core.

And Pablo was faster than me - thanks for taking care this too.

Best regards,
Jozsef
-
E-mail  : kadlec@blackhole.kfki.hu, kadlecsik.jozsef@wigner.mta.hu
PGP key : http://www.kfki.hu/~kadlec/pgp_public_key.txt
Address : Wigner Research Centre for Physics, Hungarian Academy of Sciences
          H-1525 Budapest 114, POB. 49, Hungary

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

* Re: [PATCH 00/18] netfilter updates for net-next
  2013-04-29 17:50   ` Pablo Neira Ayuso
@ 2013-04-29 17:54     ` David Miller
  0 siblings, 0 replies; 32+ messages in thread
From: David Miller @ 2013-04-29 17:54 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev

From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 29 Apr 2013 19:50:35 +0200

> On Mon, Apr 29, 2013 at 11:37:20AM -0400, David Miller wrote:
>> 
>> This doesn't compile:
>> 
>> net/sched/em_ipset.c:86:5: error: ‘struct ip_set_adt_opt’ has no member named ‘timeout’
> 
> Sorry, I overlooked em_ipset, it was not appropriately adapted after
> the new ipset extension infrastructure was added.
> 
> The attached patch fixes the problem. Should I send a new pull
> request?

Please fix the commit in your tree that introduces the compile
failure and send me a new pull request.

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

* Re: [PATCH 00/18] netfilter updates for net-next
  2013-04-29 15:37 ` David Miller
@ 2013-04-29 17:50   ` Pablo Neira Ayuso
  2013-04-29 17:54     ` David Miller
  2013-04-29 20:27   ` Jozsef Kadlecsik
  1 sibling, 1 reply; 32+ messages in thread
From: Pablo Neira Ayuso @ 2013-04-29 17:50 UTC (permalink / raw)
  To: David Miller; +Cc: netfilter-devel, netdev

[-- Attachment #1: Type: text/plain, Size: 383 bytes --]

On Mon, Apr 29, 2013 at 11:37:20AM -0400, David Miller wrote:
> 
> This doesn't compile:
> 
> net/sched/em_ipset.c:86:5: error: ‘struct ip_set_adt_opt’ has no member named ‘timeout’

Sorry, I overlooked em_ipset, it was not appropriately adapted after
the new ipset extension infrastructure was added.

The attached patch fixes the problem. Should I send a new pull
request?

[-- Attachment #2: 0001-sched-em_ipset-fix-compilation-after-new-ipset-exten.patch --]
[-- Type: text/x-diff, Size: 1047 bytes --]

>From 8a61fa178549c91822ac4c148053d6b6a519a6d5 Mon Sep 17 00:00:00 2001
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Mon, 29 Apr 2013 19:44:00 +0200
Subject: [PATCH] sched: em_ipset: fix compilation after new ipset extension
 infrastructure

This fixes compilation for the ipset packet classifier which was not
appropriately adapted when the new ipset extension infrastructure was
added in (80eddba netfilter: ipset: Introduce extensions to elements
in the core).

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
---
 net/sched/em_ipset.c |    2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/sched/em_ipset.c b/net/sched/em_ipset.c
index 3130320..938b7cb 100644
--- a/net/sched/em_ipset.c
+++ b/net/sched/em_ipset.c
@@ -83,7 +83,7 @@ static int em_ipset_match(struct sk_buff *skb, struct tcf_ematch *em,
 	opt.dim = set->dim;
 	opt.flags = set->flags;
 	opt.cmdflags = 0;
-	opt.timeout = ~0u;
+	opt.ext.timeout = ~0u;
 
 	network_offset = skb_network_offset(skb);
 	skb_pull(skb, network_offset);
-- 
1.7.10.4


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

* Re: [PATCH 00/18] netfilter updates for net-next
  2013-04-27 18:58 [PATCH 00/18] netfilter " Pablo Neira Ayuso
@ 2013-04-29 15:37 ` David Miller
  2013-04-29 17:50   ` Pablo Neira Ayuso
  2013-04-29 20:27   ` Jozsef Kadlecsik
  0 siblings, 2 replies; 32+ messages in thread
From: David Miller @ 2013-04-29 15:37 UTC (permalink / raw)
  To: pablo; +Cc: netfilter-devel, netdev


This doesn't compile:

net/sched/em_ipset.c:86:5: error: ‘struct ip_set_adt_opt’ has no member named ‘timeout’

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

* [PATCH 00/18] netfilter updates for net-next
@ 2013-04-27 18:58 Pablo Neira Ayuso
  2013-04-29 15:37 ` David Miller
  0 siblings, 1 reply; 32+ messages in thread
From: Pablo Neira Ayuso @ 2013-04-27 18:58 UTC (permalink / raw)
  To: netfilter-devel; +Cc: davem, netdev

Hi David,

The following patchset contains relevant updates for the Netfilter
tree, they are:

* Enhancements for ipset: Add the counter extension for sets, this
  information can be used from the iptables set match, to change
  the matching behaviour. Jozsef required to add the extension
  infrastructure and moved the existing timeout support upon it.

* Enhancements for performance boosting in nfnetlink_queue: Add new
  configuration flags that allows user-space to receive big packets (GRO)
  and to disable checksumming calculation. This were proposed by Eric
  Dumazet during the Netfilter Workshop 2013 in Copenhagen. Florian
  Westphal was kind enough to find the time to materialize the proposal.

* A sparse fix from Simon, he noticed it in the SCTP NAT helper, the fix
  required a change in the interface of sctp_end_cksum.

Let me know if we're still in time to get this into net-next. Thanks!

The following changes since commit 37fe0660981d7a1577409226f77554c2c5123e27:

  net: fix address check in rtnl_fdb_del (2013-04-25 04:14:08 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/pablo/nf-next.git master

for you to fetch changes up to 3a44129aabea6813dc05b829c552fd98b3ab0b68:

  sctp: Correct type and usage of sctp_end_cksum() (2013-04-27 19:55:00 +0200)

----------------------------------------------------------------
Florian Westphal (4):
      netfilter: nf_queue: move device refcount bump to extra function
      netfilter: move skb_gso_segment into nfnetlink_queue module
      netfilter: nfnetlink_queue: add skb info attribute
      netfilter: nfnetlink_queue: avoid expensive gso segmentation and checksum fixup

Jozsef Kadlecsik (13):
      netfilter: ipset: Make possible to test elements marked with nomatch
      netfilter: ipset: Move often used IPv6 address masking function to header file
      netfilter: ipset: Introduce extensions to elements in the core
      netfilter: ipset: Unified bitmap type generation
      netfilter: ipset: Bitmap types using the unified code base
      netfilter: ipset: Unified hash type generation
      netfilter: ipset: Hash types using the unified code base
      netfilter: ipset: list:set type using the extension interface
      netfilter: ipset: Introduce the counter extension in the core
      netfilter: ipset: The bitmap types with counter support
      netfilter: ipset: The hash types with counter support
      netfilter: ipset: The list:set type with counter support
      netfilter: ipset: set match: add support to match the counters

Simon Horman (1):
      sctp: Correct type and usage of sctp_end_cksum()


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

end of thread, other threads:[~2019-11-19  0:47 UTC | newest]

Thread overview: 32+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-08-04 10:02 [PATCH 00/18] Netfilter updates for net-next Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 01/18] netfilter: kill nf_hooks_active Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 02/18] netfilter: Simply the tests for enabling and disabling the ingress queue hook Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 03/18] netfilter: Factor out the hook list selection from nf_register_hook Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 04/18] netfilter: Per network namespace netfilter hooks Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 05/18] netfilter: nftables: Only run the nftables chains in the proper netns Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 06/18] netfilter: xtables: compute exact size needed for jumpstack Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 07/18] netfilter: move tee_active to core Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 08/18] netfilter: xtables: don't save/restore jumpstack offset Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 09/18] netfilter: add and use jump label for xt_tee Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 10/18] netfilter: xtables: remove __pure annotation Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 11/18] netfilter: Fix memory leak in nf_register_net_hook Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 12/18] netfilter: nf_queue: fix nf_queue_nf_hook_drop() Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 13/18] netfilter: fix possible removal of wrong hook Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 14/18] netfilter: rename local nf_hook_list to hook_list Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 15/18] netfilter: nf_ct_sctp: minimal multihoming support Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 16/18] netfilter: bridge: reduce nf_bridge_info to 32 bytes again Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 17/18] netfilter: bridge: do not initialize statics to 0 or NULL Pablo Neira Ayuso
2015-08-04 10:02 ` [PATCH 18/18] netfilter: ip6t_REJECT: Remove debug messages from reject_tg6() Pablo Neira Ayuso
2015-08-05  7:00 ` [PATCH 00/18] Netfilter updates for net-next David Miller
  -- strict thread matches above, loose matches on Subject: below --
2019-11-18 21:48 Pablo Neira Ayuso
2019-11-19  0:47 ` David Miller
2018-05-23 18:42 Pablo Neira Ayuso
2018-05-23 20:37 ` David Miller
2014-07-18 11:00 Pablo Neira Ayuso
2014-07-21  4:41 ` David Miller
2014-07-22  8:02 ` David Miller
2013-04-27 18:58 [PATCH 00/18] netfilter " Pablo Neira Ayuso
2013-04-29 15:37 ` David Miller
2013-04-29 17:50   ` Pablo Neira Ayuso
2013-04-29 17:54     ` David Miller
2013-04-29 20:27   ` Jozsef Kadlecsik

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).