netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH nf-next 0/3] Additional nf_hook_entry compaction
@ 2016-11-15 22:48 Aaron Conole
  2016-11-15 22:48 ` [PATCH nf-next 1/3] netfilter: introduce accessor functions for hook entries Aaron Conole
                   ` (3 more replies)
  0 siblings, 4 replies; 5+ messages in thread
From: Aaron Conole @ 2016-11-15 22:48 UTC (permalink / raw)
  To: netfilter-devel
  Cc: Pablo Neira Ayuso, Florian Westphal, Jozsef Kadlecsik, coreteam,
	David S . Miller

This series introduces a set of accessors, compacts the nf_hook_entry, and
rearranges some of the loops in preparation for the final set of work going
to an array based hook system.

After this series, the nf_hook_entry should fit in a cacheline on a modern
Intel i7.

Tested on bare-metal system.

Aaron Conole (3):
  netfilter: introduce accessor functions for hook entries
  netfilter: decouple nf_hook_entry and nf_hook_ops
  netfilter: convert while loops to for loops

 include/linux/netfilter.h       | 31 ++++++++++++++++++++++++++++++-
 net/bridge/br_netfilter_hooks.c |  8 ++++----
 net/netfilter/core.c            | 16 ++++++----------
 net/netfilter/nf_queue.c        |  5 ++---
 4 files changed, 42 insertions(+), 18 deletions(-)

-- 
2.7.4


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

* [PATCH nf-next 1/3] netfilter: introduce accessor functions for hook entries
  2016-11-15 22:48 [PATCH nf-next 0/3] Additional nf_hook_entry compaction Aaron Conole
@ 2016-11-15 22:48 ` Aaron Conole
  2016-11-15 22:48 ` [PATCH nf-next 2/3] netfilter: decouple nf_hook_entry and nf_hook_ops Aaron Conole
                   ` (2 subsequent siblings)
  3 siblings, 0 replies; 5+ messages in thread
From: Aaron Conole @ 2016-11-15 22:48 UTC (permalink / raw)
  To: netfilter-devel
  Cc: Pablo Neira Ayuso, Florian Westphal, Jozsef Kadlecsik, coreteam,
	David S . Miller

This allows easier future refactoring.

Signed-off-by: Aaron Conole <aconole@bytheb.org>
---
 include/linux/netfilter.h       | 27 +++++++++++++++++++++++++++
 net/bridge/br_netfilter_hooks.c |  2 +-
 net/netfilter/core.c            | 10 ++++------
 net/netfilter/nf_queue.c        |  5 ++---
 4 files changed, 34 insertions(+), 10 deletions(-)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 6923014..575aa19 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -79,6 +79,33 @@ struct nf_hook_entry {
 	const struct nf_hook_ops	*orig_ops;
 };
 
+static inline void
+nf_hook_entry_init(struct nf_hook_entry *entry,	const struct nf_hook_ops *ops)
+{
+	entry->next = NULL;
+	entry->ops = *ops;
+	entry->orig_ops = ops;
+}
+
+static inline int
+nf_hook_entry_priority(const struct nf_hook_entry *entry)
+{
+	return entry->ops.priority;
+}
+
+static inline int
+nf_hook_entry_hookfn(const struct nf_hook_entry *entry, struct sk_buff *skb,
+		     struct nf_hook_state *state)
+{
+	return entry->ops.hook(entry->ops.priv, skb, state);
+}
+
+static inline const struct nf_hook_ops *
+nf_hook_entry_ops(const struct nf_hook_entry *entry)
+{
+	return entry->orig_ops;
+}
+
 static inline void nf_hook_state_init(struct nf_hook_state *p,
 				      unsigned int hook,
 				      u_int8_t pf,
diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index 8155bd2..ef8cfa7 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -1010,7 +1010,7 @@ int br_nf_hook_thresh(unsigned int hook, struct net *net,
 
 	elem = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]);
 
-	while (elem && (elem->ops.priority <= NF_BR_PRI_BRNF))
+	while (elem && (nf_hook_entry_priority(elem) <= NF_BR_PRI_BRNF))
 		elem = rcu_dereference(elem->next);
 
 	if (!elem)
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index de30e08..2bb46e2 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -102,15 +102,13 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
 	if (!entry)
 		return -ENOMEM;
 
-	entry->orig_ops	= reg;
-	entry->ops	= *reg;
-	entry->next	= NULL;
+	nf_hook_entry_init(entry, reg);
 
 	mutex_lock(&nf_hook_mutex);
 
 	/* Find the spot in the list */
 	while ((p = nf_entry_dereference(*pp)) != NULL) {
-		if (reg->priority < p->orig_ops->priority)
+		if (reg->priority < nf_hook_entry_priority(p))
 			break;
 		pp = &p->next;
 	}
@@ -140,7 +138,7 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 
 	mutex_lock(&nf_hook_mutex);
 	while ((p = nf_entry_dereference(*pp)) != NULL) {
-		if (p->orig_ops == reg) {
+		if (nf_hook_entry_ops(p) == reg) {
 			rcu_assign_pointer(*pp, p->next);
 			break;
 		}
@@ -311,7 +309,7 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
 	int ret;
 
 	do {
-		verdict = entry->ops.hook(entry->ops.priv, skb, state);
+		verdict = nf_hook_entry_hookfn(entry, skb, state);
 		switch (verdict & NF_VERDICT_MASK) {
 		case NF_ACCEPT:
 			entry = rcu_dereference(entry->next);
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 77cba9f..4a76624 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -185,7 +185,7 @@ static unsigned int nf_iterate(struct sk_buff *skb,
 
 	do {
 repeat:
-		verdict = (*entryp)->ops.hook((*entryp)->ops.priv, skb, state);
+		verdict = nf_hook_entry_hookfn((*entryp), skb, state);
 		if (verdict != NF_ACCEPT) {
 			if (verdict != NF_REPEAT)
 				return verdict;
@@ -200,7 +200,6 @@ static unsigned int nf_iterate(struct sk_buff *skb,
 void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
 {
 	struct nf_hook_entry *hook_entry = entry->hook;
-	struct nf_hook_ops *elem = &hook_entry->ops;
 	struct sk_buff *skb = entry->skb;
 	const struct nf_afinfo *afinfo;
 	int err;
@@ -209,7 +208,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
 
 	/* Continue traversal iff userspace said ok... */
 	if (verdict == NF_REPEAT)
-		verdict = elem->hook(elem->priv, skb, &entry->state);
+		verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state);
 
 	if (verdict == NF_ACCEPT) {
 		afinfo = nf_get_afinfo(entry->state.pf);
-- 
2.7.4


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

* [PATCH nf-next 2/3] netfilter: decouple nf_hook_entry and nf_hook_ops
  2016-11-15 22:48 [PATCH nf-next 0/3] Additional nf_hook_entry compaction Aaron Conole
  2016-11-15 22:48 ` [PATCH nf-next 1/3] netfilter: introduce accessor functions for hook entries Aaron Conole
@ 2016-11-15 22:48 ` Aaron Conole
  2016-11-15 22:48 ` [PATCH nf-next 3/3] netfilter: convert while loops to for loops Aaron Conole
  2016-12-04 20:11 ` [PATCH nf-next 0/3] Additional nf_hook_entry compaction Pablo Neira Ayuso
  3 siblings, 0 replies; 5+ messages in thread
From: Aaron Conole @ 2016-11-15 22:48 UTC (permalink / raw)
  To: netfilter-devel
  Cc: Pablo Neira Ayuso, Florian Westphal, Jozsef Kadlecsik, coreteam,
	David S . Miller

From: Aaron Conole <aconole@redhat.com>

During nfhook traversal we only need a very small subset of
nf_hook_ops members.

We need:
- next element
- hook function to call
- hook function priv argument

Bridge netfilter also needs 'thresh'; can be obtained via ->orig_ops.

nf_hook_entry struct is now 32 bytes on x86_64.

A followup patch will turn the run-time list into an array that only
stores hook functions plus their priv arguments, eliminating the ->next
element.

Suggested-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Aaron Conole <aconole@bytheb.org>
---
 include/linux/netfilter.h | 10 ++++++----
 1 file changed, 6 insertions(+), 4 deletions(-)

diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 575aa19..a4b97be 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -75,7 +75,8 @@ struct nf_hook_ops {
 
 struct nf_hook_entry {
 	struct nf_hook_entry __rcu	*next;
-	struct nf_hook_ops		ops;
+	nf_hookfn			*hook;
+	void				*priv;
 	const struct nf_hook_ops	*orig_ops;
 };
 
@@ -83,21 +84,22 @@ static inline void
 nf_hook_entry_init(struct nf_hook_entry *entry,	const struct nf_hook_ops *ops)
 {
 	entry->next = NULL;
-	entry->ops = *ops;
+	entry->hook = ops->hook;
+	entry->priv = ops->priv;
 	entry->orig_ops = ops;
 }
 
 static inline int
 nf_hook_entry_priority(const struct nf_hook_entry *entry)
 {
-	return entry->ops.priority;
+	return entry->orig_ops->priority;
 }
 
 static inline int
 nf_hook_entry_hookfn(const struct nf_hook_entry *entry, struct sk_buff *skb,
 		     struct nf_hook_state *state)
 {
-	return entry->ops.hook(entry->ops.priv, skb, state);
+	return entry->hook(entry->priv, skb, state);
 }
 
 static inline const struct nf_hook_ops *
-- 
2.7.4


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

* [PATCH nf-next 3/3] netfilter: convert while loops to for loops
  2016-11-15 22:48 [PATCH nf-next 0/3] Additional nf_hook_entry compaction Aaron Conole
  2016-11-15 22:48 ` [PATCH nf-next 1/3] netfilter: introduce accessor functions for hook entries Aaron Conole
  2016-11-15 22:48 ` [PATCH nf-next 2/3] netfilter: decouple nf_hook_entry and nf_hook_ops Aaron Conole
@ 2016-11-15 22:48 ` Aaron Conole
  2016-12-04 20:11 ` [PATCH nf-next 0/3] Additional nf_hook_entry compaction Pablo Neira Ayuso
  3 siblings, 0 replies; 5+ messages in thread
From: Aaron Conole @ 2016-11-15 22:48 UTC (permalink / raw)
  To: netfilter-devel
  Cc: Pablo Neira Ayuso, Florian Westphal, Jozsef Kadlecsik, coreteam,
	David S . Miller

This is to facilitate converting from a singly-linked list to an array
of elements.

Signed-off-by: Aaron Conole <aconole@bytheb.org>
---
 net/bridge/br_netfilter_hooks.c | 8 ++++----
 net/netfilter/core.c            | 6 ++----
 2 files changed, 6 insertions(+), 8 deletions(-)

diff --git a/net/bridge/br_netfilter_hooks.c b/net/bridge/br_netfilter_hooks.c
index ef8cfa7..1434de1 100644
--- a/net/bridge/br_netfilter_hooks.c
+++ b/net/bridge/br_netfilter_hooks.c
@@ -1008,10 +1008,10 @@ int br_nf_hook_thresh(unsigned int hook, struct net *net,
 	struct nf_hook_state state;
 	int ret;
 
-	elem = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]);
-
-	while (elem && (nf_hook_entry_priority(elem) <= NF_BR_PRI_BRNF))
-		elem = rcu_dereference(elem->next);
+	for (elem = rcu_dereference(net->nf.hooks[NFPROTO_BRIDGE][hook]);
+	     nf_hook_entry_priority(elem) <= NF_BR_PRI_BRNF;
+	     elem = rcu_dereference(elem->next))
+		;
 
 	if (!elem)
 		return okfn(net, sk, skb);
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 2bb46e2..ce6adfa 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c
@@ -107,10 +107,9 @@ int nf_register_net_hook(struct net *net, const struct nf_hook_ops *reg)
 	mutex_lock(&nf_hook_mutex);
 
 	/* Find the spot in the list */
-	while ((p = nf_entry_dereference(*pp)) != NULL) {
+	for (; (p = nf_entry_dereference(*pp)) != NULL; pp = &p->next) {
 		if (reg->priority < nf_hook_entry_priority(p))
 			break;
-		pp = &p->next;
 	}
 	rcu_assign_pointer(entry->next, p);
 	rcu_assign_pointer(*pp, entry);
@@ -137,12 +136,11 @@ void nf_unregister_net_hook(struct net *net, const struct nf_hook_ops *reg)
 		return;
 
 	mutex_lock(&nf_hook_mutex);
-	while ((p = nf_entry_dereference(*pp)) != NULL) {
+	for (; (p = nf_entry_dereference(*pp)) != NULL; pp = &p->next) {
 		if (nf_hook_entry_ops(p) == reg) {
 			rcu_assign_pointer(*pp, p->next);
 			break;
 		}
-		pp = &p->next;
 	}
 	mutex_unlock(&nf_hook_mutex);
 	if (!p) {
-- 
2.7.4


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

* Re: [PATCH nf-next 0/3] Additional nf_hook_entry compaction
  2016-11-15 22:48 [PATCH nf-next 0/3] Additional nf_hook_entry compaction Aaron Conole
                   ` (2 preceding siblings ...)
  2016-11-15 22:48 ` [PATCH nf-next 3/3] netfilter: convert while loops to for loops Aaron Conole
@ 2016-12-04 20:11 ` Pablo Neira Ayuso
  3 siblings, 0 replies; 5+ messages in thread
From: Pablo Neira Ayuso @ 2016-12-04 20:11 UTC (permalink / raw)
  To: Aaron Conole
  Cc: netfilter-devel, Florian Westphal, Jozsef Kadlecsik, coreteam,
	David S . Miller

On Tue, Nov 15, 2016 at 05:48:43PM -0500, Aaron Conole wrote:
> This series introduces a set of accessors, compacts the nf_hook_entry, and
> rearranges some of the loops in preparation for the final set of work going
> to an array based hook system.
> 
> After this series, the nf_hook_entry should fit in a cacheline on a modern
> Intel i7.

Series applied, thanks Aaron.

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

end of thread, other threads:[~2016-12-04 20:11 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-11-15 22:48 [PATCH nf-next 0/3] Additional nf_hook_entry compaction Aaron Conole
2016-11-15 22:48 ` [PATCH nf-next 1/3] netfilter: introduce accessor functions for hook entries Aaron Conole
2016-11-15 22:48 ` [PATCH nf-next 2/3] netfilter: decouple nf_hook_entry and nf_hook_ops Aaron Conole
2016-11-15 22:48 ` [PATCH nf-next 3/3] netfilter: convert while loops to for loops Aaron Conole
2016-12-04 20:11 ` [PATCH nf-next 0/3] Additional nf_hook_entry compaction Pablo Neira Ayuso

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).