Skip to content

Commit 3f80196

Browse files
author
Florian Westphal
committed
netfilter: move nf_reinject into nfnetlink_queue modules
No need to keep this in the core, move it to the nfnetlink_queue module. nf_reroute is moved too, there were no other callers. Signed-off-by: Florian Westphal <[email protected]>
1 parent 5b65178 commit 3f80196

File tree

5 files changed

+142
-145
lines changed

5 files changed

+142
-145
lines changed

include/linux/netfilter.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -370,7 +370,6 @@ __sum16 nf_checksum_partial(struct sk_buff *skb, unsigned int hook,
370370
u_int8_t protocol, unsigned short family);
371371
int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl,
372372
bool strict, unsigned short family);
373-
int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry);
374373

375374
#include <net/flow.h>
376375

include/net/netfilter/nf_queue.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ struct nf_queue_handler {
3535

3636
void nf_register_queue_handler(const struct nf_queue_handler *qh);
3737
void nf_unregister_queue_handler(void);
38-
void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
3938

4039
bool nf_queue_entry_get_refs(struct nf_queue_entry *entry);
4140
void nf_queue_entry_free(struct nf_queue_entry *entry);

net/netfilter/nf_queue.c

Lines changed: 0 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -248,109 +248,3 @@ int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
248248
return 0;
249249
}
250250
EXPORT_SYMBOL_GPL(nf_queue);
251-
252-
static unsigned int nf_iterate(struct sk_buff *skb,
253-
struct nf_hook_state *state,
254-
const struct nf_hook_entries *hooks,
255-
unsigned int *index)
256-
{
257-
const struct nf_hook_entry *hook;
258-
unsigned int verdict, i = *index;
259-
260-
while (i < hooks->num_hook_entries) {
261-
hook = &hooks->hooks[i];
262-
repeat:
263-
verdict = nf_hook_entry_hookfn(hook, skb, state);
264-
if (verdict != NF_ACCEPT) {
265-
*index = i;
266-
if (verdict != NF_REPEAT)
267-
return verdict;
268-
goto repeat;
269-
}
270-
i++;
271-
}
272-
273-
*index = i;
274-
return NF_ACCEPT;
275-
}
276-
277-
static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum)
278-
{
279-
switch (pf) {
280-
#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
281-
case NFPROTO_BRIDGE:
282-
return rcu_dereference(net->nf.hooks_bridge[hooknum]);
283-
#endif
284-
case NFPROTO_IPV4:
285-
return rcu_dereference(net->nf.hooks_ipv4[hooknum]);
286-
case NFPROTO_IPV6:
287-
return rcu_dereference(net->nf.hooks_ipv6[hooknum]);
288-
default:
289-
WARN_ON_ONCE(1);
290-
return NULL;
291-
}
292-
293-
return NULL;
294-
}
295-
296-
/* Caller must hold rcu read-side lock */
297-
void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
298-
{
299-
const struct nf_hook_entry *hook_entry;
300-
const struct nf_hook_entries *hooks;
301-
struct sk_buff *skb = entry->skb;
302-
const struct net *net;
303-
unsigned int i;
304-
int err;
305-
u8 pf;
306-
307-
net = entry->state.net;
308-
pf = entry->state.pf;
309-
310-
hooks = nf_hook_entries_head(net, pf, entry->state.hook);
311-
312-
i = entry->hook_index;
313-
if (WARN_ON_ONCE(!hooks || i >= hooks->num_hook_entries)) {
314-
kfree_skb(skb);
315-
nf_queue_entry_free(entry);
316-
return;
317-
}
318-
319-
hook_entry = &hooks->hooks[i];
320-
321-
/* Continue traversal iff userspace said ok... */
322-
if (verdict == NF_REPEAT)
323-
verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state);
324-
325-
if (verdict == NF_ACCEPT) {
326-
if (nf_reroute(skb, entry) < 0)
327-
verdict = NF_DROP;
328-
}
329-
330-
if (verdict == NF_ACCEPT) {
331-
next_hook:
332-
++i;
333-
verdict = nf_iterate(skb, &entry->state, hooks, &i);
334-
}
335-
336-
switch (verdict & NF_VERDICT_MASK) {
337-
case NF_ACCEPT:
338-
case NF_STOP:
339-
local_bh_disable();
340-
entry->state.okfn(entry->state.net, entry->state.sk, skb);
341-
local_bh_enable();
342-
break;
343-
case NF_QUEUE:
344-
err = nf_queue(skb, &entry->state, i, verdict);
345-
if (err == 1)
346-
goto next_hook;
347-
break;
348-
case NF_STOLEN:
349-
break;
350-
default:
351-
kfree_skb(skb);
352-
}
353-
354-
nf_queue_entry_free(entry);
355-
}
356-
EXPORT_SYMBOL(nf_reinject);

net/netfilter/nfnetlink_queue.c

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -225,6 +225,148 @@ find_dequeue_entry(struct nfqnl_instance *queue, unsigned int id)
225225
return entry;
226226
}
227227

228+
static unsigned int nf_iterate(struct sk_buff *skb,
229+
struct nf_hook_state *state,
230+
const struct nf_hook_entries *hooks,
231+
unsigned int *index)
232+
{
233+
const struct nf_hook_entry *hook;
234+
unsigned int verdict, i = *index;
235+
236+
while (i < hooks->num_hook_entries) {
237+
hook = &hooks->hooks[i];
238+
repeat:
239+
verdict = nf_hook_entry_hookfn(hook, skb, state);
240+
if (verdict != NF_ACCEPT) {
241+
*index = i;
242+
if (verdict != NF_REPEAT)
243+
return verdict;
244+
goto repeat;
245+
}
246+
i++;
247+
}
248+
249+
*index = i;
250+
return NF_ACCEPT;
251+
}
252+
253+
static struct nf_hook_entries *nf_hook_entries_head(const struct net *net, u8 pf, u8 hooknum)
254+
{
255+
switch (pf) {
256+
#ifdef CONFIG_NETFILTER_FAMILY_BRIDGE
257+
case NFPROTO_BRIDGE:
258+
return rcu_dereference(net->nf.hooks_bridge[hooknum]);
259+
#endif
260+
case NFPROTO_IPV4:
261+
return rcu_dereference(net->nf.hooks_ipv4[hooknum]);
262+
case NFPROTO_IPV6:
263+
return rcu_dereference(net->nf.hooks_ipv6[hooknum]);
264+
default:
265+
WARN_ON_ONCE(1);
266+
return NULL;
267+
}
268+
269+
return NULL;
270+
}
271+
272+
static int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry)
273+
{
274+
#ifdef CONFIG_INET
275+
const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
276+
277+
if (entry->state.hook == NF_INET_LOCAL_OUT) {
278+
const struct iphdr *iph = ip_hdr(skb);
279+
280+
if (!(iph->tos == rt_info->tos &&
281+
skb->mark == rt_info->mark &&
282+
iph->daddr == rt_info->daddr &&
283+
iph->saddr == rt_info->saddr))
284+
return ip_route_me_harder(entry->state.net, entry->state.sk,
285+
skb, RTN_UNSPEC);
286+
}
287+
#endif
288+
return 0;
289+
}
290+
291+
static int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry)
292+
{
293+
const struct nf_ipv6_ops *v6ops;
294+
int ret = 0;
295+
296+
switch (entry->state.pf) {
297+
case AF_INET:
298+
ret = nf_ip_reroute(skb, entry);
299+
break;
300+
case AF_INET6:
301+
v6ops = rcu_dereference(nf_ipv6_ops);
302+
if (v6ops)
303+
ret = v6ops->reroute(skb, entry);
304+
break;
305+
}
306+
return ret;
307+
}
308+
309+
/* caller must hold rcu read-side lock */
310+
static void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
311+
{
312+
const struct nf_hook_entry *hook_entry;
313+
const struct nf_hook_entries *hooks;
314+
struct sk_buff *skb = entry->skb;
315+
const struct net *net;
316+
unsigned int i;
317+
int err;
318+
u8 pf;
319+
320+
net = entry->state.net;
321+
pf = entry->state.pf;
322+
323+
hooks = nf_hook_entries_head(net, pf, entry->state.hook);
324+
325+
i = entry->hook_index;
326+
if (WARN_ON_ONCE(!hooks || i >= hooks->num_hook_entries)) {
327+
kfree_skb_reason(skb, SKB_DROP_REASON_NETFILTER_DROP);
328+
nf_queue_entry_free(entry);
329+
return;
330+
}
331+
332+
hook_entry = &hooks->hooks[i];
333+
334+
/* Continue traversal iff userspace said ok... */
335+
if (verdict == NF_REPEAT)
336+
verdict = nf_hook_entry_hookfn(hook_entry, skb, &entry->state);
337+
338+
if (verdict == NF_ACCEPT) {
339+
if (nf_reroute(skb, entry) < 0)
340+
verdict = NF_DROP;
341+
}
342+
343+
if (verdict == NF_ACCEPT) {
344+
next_hook:
345+
++i;
346+
verdict = nf_iterate(skb, &entry->state, hooks, &i);
347+
}
348+
349+
switch (verdict & NF_VERDICT_MASK) {
350+
case NF_ACCEPT:
351+
case NF_STOP:
352+
local_bh_disable();
353+
entry->state.okfn(entry->state.net, entry->state.sk, skb);
354+
local_bh_enable();
355+
break;
356+
case NF_QUEUE:
357+
err = nf_queue(skb, &entry->state, i, verdict);
358+
if (err == 1)
359+
goto next_hook;
360+
break;
361+
case NF_STOLEN:
362+
break;
363+
default:
364+
kfree_skb(skb);
365+
}
366+
367+
nf_queue_entry_free(entry);
368+
}
369+
228370
static void nfqnl_reinject(struct nf_queue_entry *entry, unsigned int verdict)
229371
{
230372
const struct nf_ct_hook *ct_hook;

net/netfilter/utils.c

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -179,43 +179,6 @@ int nf_route(struct net *net, struct dst_entry **dst, struct flowi *fl,
179179
}
180180
EXPORT_SYMBOL_GPL(nf_route);
181181

182-
static int nf_ip_reroute(struct sk_buff *skb, const struct nf_queue_entry *entry)
183-
{
184-
#ifdef CONFIG_INET
185-
const struct ip_rt_info *rt_info = nf_queue_entry_reroute(entry);
186-
187-
if (entry->state.hook == NF_INET_LOCAL_OUT) {
188-
const struct iphdr *iph = ip_hdr(skb);
189-
190-
if (!(iph->tos == rt_info->tos &&
191-
skb->mark == rt_info->mark &&
192-
iph->daddr == rt_info->daddr &&
193-
iph->saddr == rt_info->saddr))
194-
return ip_route_me_harder(entry->state.net, entry->state.sk,
195-
skb, RTN_UNSPEC);
196-
}
197-
#endif
198-
return 0;
199-
}
200-
201-
int nf_reroute(struct sk_buff *skb, struct nf_queue_entry *entry)
202-
{
203-
const struct nf_ipv6_ops *v6ops;
204-
int ret = 0;
205-
206-
switch (entry->state.pf) {
207-
case AF_INET:
208-
ret = nf_ip_reroute(skb, entry);
209-
break;
210-
case AF_INET6:
211-
v6ops = rcu_dereference(nf_ipv6_ops);
212-
if (v6ops)
213-
ret = v6ops->reroute(skb, entry);
214-
break;
215-
}
216-
return ret;
217-
}
218-
219182
/* Only get and check the lengths, not do any hop-by-hop stuff. */
220183
int nf_ip6_check_hbh_len(struct sk_buff *skb, u32 *plen)
221184
{

0 commit comments

Comments
 (0)