aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/net/netfilter/nf_queue.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2015-04-03 16:31:01 -0400
committerDavid S. Miller <davem@davemloft.net>2015-04-04 12:25:22 -0400
commit1d1de89b9a4746f1dd055a3b8d073dd2f962a3b6 (patch)
tree84465aaf839096b56d542b37da24cadbd861eb16 /net/netfilter/nf_queue.c
parentnetfilter: Create and use nf_hook_state. (diff)
downloadwireguard-linux-1d1de89b9a4746f1dd055a3b8d073dd2f962a3b6.tar.xz
wireguard-linux-1d1de89b9a4746f1dd055a3b8d073dd2f962a3b6.zip
netfilter: Use nf_hook_state in nf_queue_entry.
That way we don't have to reinstantiate another nf_hook_state on the stack of the nf_reinject() path. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/netfilter/nf_queue.c')
-rw-r--r--net/netfilter/nf_queue.c44
1 files changed, 19 insertions, 25 deletions
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 6f8e9485cc83..d3cd37edca18 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c
@@ -47,11 +47,13 @@ EXPORT_SYMBOL(nf_unregister_queue_handler);
void nf_queue_entry_release_refs(struct nf_queue_entry *entry)
{
+ struct nf_hook_state *state = &entry->state;
+
/* Release those devices we held, or Alexey will kill me. */
- if (entry->indev)
- dev_put(entry->indev);
- if (entry->outdev)
- dev_put(entry->outdev);
+ if (state->in)
+ dev_put(state->in);
+ if (state->out)
+ dev_put(state->out);
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
if (entry->skb->nf_bridge) {
struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
@@ -70,13 +72,15 @@ EXPORT_SYMBOL_GPL(nf_queue_entry_release_refs);
/* Bump dev refs so they don't vanish while packet is out */
bool nf_queue_entry_get_refs(struct nf_queue_entry *entry)
{
+ struct nf_hook_state *state = &entry->state;
+
if (!try_module_get(entry->elem->owner))
return false;
- if (entry->indev)
- dev_hold(entry->indev);
- if (entry->outdev)
- dev_hold(entry->outdev);
+ if (state->in)
+ dev_hold(state->in);
+ if (state->out)
+ dev_hold(state->out);
#if IS_ENABLED(CONFIG_BRIDGE_NETFILTER)
if (entry->skb->nf_bridge) {
struct nf_bridge_info *nf_bridge = entry->skb->nf_bridge;
@@ -131,11 +135,7 @@ int nf_queue(struct sk_buff *skb,
*entry = (struct nf_queue_entry) {
.skb = skb,
.elem = elem,
- .pf = state->pf,
- .hook = state->hook,
- .indev = state->in,
- .outdev = state->out,
- .okfn = state->okfn,
+ .state = *state,
.size = sizeof(*entry) + afinfo->route_key_size,
};
@@ -168,7 +168,6 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
struct sk_buff *skb = entry->skb;
struct nf_hook_ops *elem = entry->elem;
const struct nf_afinfo *afinfo;
- struct nf_hook_state state;
int err;
rcu_read_lock();
@@ -182,33 +181,28 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
}
if (verdict == NF_ACCEPT) {
- afinfo = nf_get_afinfo(entry->pf);
+ afinfo = nf_get_afinfo(entry->state.pf);
if (!afinfo || afinfo->reroute(skb, entry) < 0)
verdict = NF_DROP;
}
- state.hook = entry->hook;
- state.thresh = INT_MIN;
- state.pf = entry->pf;
- state.in = entry->indev;
- state.out = entry->outdev;
- state.okfn = entry->okfn;
+ entry->state.thresh = INT_MIN;
if (verdict == NF_ACCEPT) {
next_hook:
- verdict = nf_iterate(&nf_hooks[entry->pf][entry->hook],
- skb, &state, &elem);
+ verdict = nf_iterate(&nf_hooks[entry->state.pf][entry->state.hook],
+ skb, &entry->state, &elem);
}
switch (verdict & NF_VERDICT_MASK) {
case NF_ACCEPT:
case NF_STOP:
local_bh_disable();
- entry->okfn(skb);
+ entry->state.okfn(skb);
local_bh_enable();
break;
case NF_QUEUE:
- err = nf_queue(skb, elem, &state,
+ err = nf_queue(skb, elem, &entry->state,
verdict >> NF_VERDICT_QBITS);
if (err < 0) {
if (err == -ECANCELED)