Commit 26dfab7216291cee94d6012d06c255fcc15cd72a

Authored by Pablo Neira Ayuso
1 parent 01886bd91f

netfilter: merge nf_iterate() into nf_hook_slow()

nf_iterate() has become rather simple, we can integrate this code into
nf_hook_slow() to reduce the amount of LOC in the core path.

However, we still need nf_iterate() around for nf_queue packet handling,
so move this function there where we only need it. I think it should be
possible to refactor nf_queue code to get rid of it definitely, but
given this is slow path anyway, let's have a look this later.

Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

Showing 3 changed files with 48 additions and 50 deletions Side-by-side Diff

net/netfilter/core.c
... ... @@ -302,26 +302,6 @@
302 302 }
303 303 EXPORT_SYMBOL(_nf_unregister_hooks);
304 304  
305   -unsigned int nf_iterate(struct sk_buff *skb,
306   - struct nf_hook_state *state,
307   - struct nf_hook_entry **entryp)
308   -{
309   - unsigned int verdict;
310   -
311   - do {
312   -repeat:
313   - verdict = (*entryp)->ops.hook((*entryp)->ops.priv, skb, state);
314   - if (verdict != NF_ACCEPT) {
315   - if (verdict != NF_REPEAT)
316   - return verdict;
317   - goto repeat;
318   - }
319   - *entryp = rcu_dereference((*entryp)->next);
320   - } while (*entryp);
321   - return NF_ACCEPT;
322   -}
323   -
324   -
325 305 /* Returns 1 if okfn() needs to be executed by the caller,
326 306 * -EPERM for NF_DROP, 0 otherwise. Caller must hold rcu_read_lock. */
327 307 int nf_hook_slow(struct sk_buff *skb, struct nf_hook_state *state,
... ... @@ -330,31 +310,34 @@
330 310 unsigned int verdict;
331 311 int ret;
332 312  
333   -next_hook:
334   - verdict = nf_iterate(skb, state, &entry);
335   - switch (verdict & NF_VERDICT_MASK) {
336   - case NF_ACCEPT:
337   - ret = 1;
338   - break;
339   - case NF_DROP:
340   - kfree_skb(skb);
341   - ret = NF_DROP_GETERR(verdict);
342   - if (ret == 0)
343   - ret = -EPERM;
344   - break;
345   - case NF_QUEUE:
346   - ret = nf_queue(skb, state, &entry, verdict);
347   - if (ret == 1 && entry)
348   - goto next_hook;
349   - /* Fall through. */
350   - default:
351   - /* Implicit handling for NF_STOLEN, as well as any other non
352   - * conventional verdicts.
353   - */
354   - ret = 0;
355   - break;
356   - }
357   - return ret;
  313 + do {
  314 + verdict = entry->ops.hook(entry->ops.priv, skb, state);
  315 + switch (verdict & NF_VERDICT_MASK) {
  316 + case NF_ACCEPT:
  317 + entry = rcu_dereference(entry->next);
  318 + break;
  319 + case NF_DROP:
  320 + kfree_skb(skb);
  321 + ret = NF_DROP_GETERR(verdict);
  322 + if (ret == 0)
  323 + ret = -EPERM;
  324 + return ret;
  325 + case NF_REPEAT:
  326 + continue;
  327 + case NF_QUEUE:
  328 + ret = nf_queue(skb, state, &entry, verdict);
  329 + if (ret == 1 && entry)
  330 + continue;
  331 + return ret;
  332 + default:
  333 + /* Implicit handling for NF_STOLEN, as well as any other
  334 + * non conventional verdicts.
  335 + */
  336 + return 0;
  337 + }
  338 + } while (entry);
  339 +
  340 + return 1;
358 341 }
359 342 EXPORT_SYMBOL(nf_hook_slow);
360 343  
net/netfilter/nf_internals.h
... ... @@ -11,11 +11,6 @@
11 11 #define NFDEBUG(format, args...)
12 12 #endif
13 13  
14   -
15   -/* core.c */
16   -unsigned int nf_iterate(struct sk_buff *skb, struct nf_hook_state *state,
17   - struct nf_hook_entry **entryp);
18   -
19 14 /* nf_queue.c */
20 15 int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
21 16 struct nf_hook_entry **entryp, unsigned int verdict);
net/netfilter/nf_queue.c
... ... @@ -177,6 +177,26 @@
177 177 return 0;
178 178 }
179 179  
  180 +static unsigned int nf_iterate(struct sk_buff *skb,
  181 + struct nf_hook_state *state,
  182 + struct nf_hook_entry **entryp)
  183 +{
  184 + unsigned int verdict;
  185 +
  186 + do {
  187 +repeat:
  188 + verdict = (*entryp)->ops.hook((*entryp)->ops.priv, skb, state);
  189 + if (verdict != NF_ACCEPT) {
  190 + if (verdict != NF_REPEAT)
  191 + return verdict;
  192 + goto repeat;
  193 + }
  194 + *entryp = rcu_dereference((*entryp)->next);
  195 + } while (*entryp);
  196 +
  197 + return NF_ACCEPT;
  198 +}
  199 +
180 200 void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict)
181 201 {
182 202 struct nf_hook_entry *hook_entry = entry->hook;