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