[PATCH RFC nf-next 1/9] netfilter: nf_queue: carry index in hook state
flat view
STALE1821d
From: Florian Westphal <fw@strlen.de>
Date: 2021-10-14 12:11:13
Also in:
bpf, netfilter-devel
Subsystem:
ethernet bridge, netfilter, networking [general], the rest · Maintainers:
Nikolay Aleksandrov, Ido Schimmel, Pablo Neira Ayuso, Florian Westphal, "David S. Miller", Eric Dumazet, Jakub Kicinski, Paolo Abeni, Linus Torvalds
Revision rfc of 2 in this series.
Revisions (2)
- rfc
- rfc current
Rather than passing the index (hook function to call next) as function argument, store it in the hook state. This is a prerequesite to allow passing all nf hook arguments in a single structure. Signed-off-by: Florian Westphal <fw@strlen.de> --- include/linux/netfilter.h | 1 + include/net/netfilter/nf_queue.h | 3 +-- net/bridge/br_input.c | 3 ++- net/netfilter/core.c | 6 +++++- net/netfilter/nf_queue.c | 12 ++++++------ 5 files changed, 15 insertions(+), 10 deletions(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 3fda1a508733..1d8b87abd54c 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h@@ -67,6 +67,7 @@ struct sock; struct nf_hook_state { u8 hook; u8 pf; + u16 hook_index; /* index in hook_entries->hook[] */ struct net_device *in; struct net_device *out; struct sock *sk;
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h
index 9eed51e920e8..bc245b96143a 100644
--- a/include/net/netfilter/nf_queue.h
+++ b/include/net/netfilter/nf_queue.h@@ -13,7 +13,6 @@ struct nf_queue_entry { struct list_head list; struct sk_buff *skb; unsigned int id; - unsigned int hook_index; /* index in hook_entries->hook[] */ #if IS_ENABLED(CONFIG_BRIDGE_NETFILTER) struct net_device *physin; struct net_device *physout;
@@ -125,6 +124,6 @@ nfqueue_hash(const struct sk_buff *skb, u16 queue, u16 queues_total, u8 family, } int nf_queue(struct sk_buff *skb, struct nf_hook_state *state, - unsigned int index, unsigned int verdict); + unsigned int verdict); #endif /* _NF_QUEUE_H */
diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c
index b50382f957c1..f0a025db263f 100644
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c@@ -239,7 +239,8 @@ static int nf_hook_bridge_pre(struct sk_buff *skb, struct sk_buff **pskb) kfree_skb(skb); return RX_HANDLER_CONSUMED; case NF_QUEUE: - ret = nf_queue(skb, &state, i, verdict); + state.hook_index = i; + ret = nf_queue(skb, &state, verdict); if (ret == 1) continue; return RX_HANDLER_CONSUMED;
diff --git a/net/netfilter/core.c b/net/netfilter/core.c
index 63d032191e62..57685334d32b 100644
--- a/net/netfilter/core.c
+++ b/net/netfilter/core.c@@ -597,7 +597,8 @@ int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state, ret = -EPERM; return ret; case NF_QUEUE: - ret = nf_queue(skb, state, s, verdict); + state->hook_index = s; + ret = nf_queue(skb, state, verdict); if (ret == 1) continue; return ret;
@@ -753,6 +754,9 @@ int __init netfilter_init(void) { int ret; + /* state->index */ + BUILD_BUG_ON(MAX_HOOK_COUNT > USHRT_MAX); + ret = register_pernet_subsys(&netfilter_net_ops); if (ret < 0) goto err;
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c
index 6d12afabfe8a..a869ae3b9665 100644
--- a/net/netfilter/nf_queue.c
+++ b/net/netfilter/nf_queue.c@@ -145,7 +145,7 @@ static void nf_ip6_saveroute(const struct sk_buff *skb, } static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, - unsigned int index, unsigned int queuenum) + unsigned int queuenum) { struct nf_queue_entry *entry = NULL; const struct nf_queue_handler *qh;
@@ -181,7 +181,6 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, *entry = (struct nf_queue_entry) { .skb = skb, .state = *state, - .hook_index = index, .size = sizeof(*entry) + route_key_size, };
@@ -209,11 +208,11 @@ static int __nf_queue(struct sk_buff *skb, const struct nf_hook_state *state, /* Packets leaving via this function must come back through nf_reinject(). */ int nf_queue(struct sk_buff *skb, struct nf_hook_state *state, - unsigned int index, unsigned int verdict) + unsigned int verdict) { int ret; - ret = __nf_queue(skb, state, index, verdict >> NF_VERDICT_QBITS); + ret = __nf_queue(skb, state, verdict >> NF_VERDICT_QBITS); if (ret < 0) { if (ret == -ESRCH && (verdict & NF_VERDICT_FLAG_QUEUE_BYPASS))
@@ -285,7 +284,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) hooks = nf_hook_entries_head(net, pf, entry->state.hook); - i = entry->hook_index; + i = entry->state.hook_index; if (WARN_ON_ONCE(!hooks || i >= hooks->num_hook_entries)) { kfree_skb(skb); nf_queue_entry_free(entry);
@@ -317,7 +316,8 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) local_bh_enable(); break; case NF_QUEUE: - err = nf_queue(skb, &entry->state, i, verdict); + entry->state.hook_index = i; + err = nf_queue(skb, &entry->state, verdict); if (err == 1) goto next_hook; break;
--
2.32.0