diff options
| author | Michael Wang <wangyun@linux.vnet.ibm.com> | 2012-08-22 15:59:57 -0400 |
|---|---|---|
| committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2012-09-03 07:52:44 -0400 |
| commit | 2a6decfd8a5fae0422c98a22aa6bc30224b8a3ec (patch) | |
| tree | 62c21cdac0ffeee0afe68b012350bb47e289b4d1 /net/netfilter | |
| parent | 965505015beccc4ec900798070165875b8e8dccf (diff) | |
netfilter: pass 'nf_hook_ops' instead of 'list_head' to nf_iterate()
Since 'list_for_each_continue_rcu' has already been replaced by
'list_for_each_entry_continue_rcu', pass 'list_head' to nf_iterate() as a
parameter can not benefit us any more.
This patch will replace 'list_head' with 'nf_hook_ops' as the parameter of
nf_iterate() to save code.
Signed-off-by: Michael Wang <wangyun@linux.vnet.ibm.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'net/netfilter')
| -rw-r--r-- | net/netfilter/core.c | 24 | ||||
| -rw-r--r-- | net/netfilter/nf_internals.h | 2 | ||||
| -rw-r--r-- | net/netfilter/nf_queue.c | 6 |
3 files changed, 14 insertions, 18 deletions
diff --git a/net/netfilter/core.c b/net/netfilter/core.c index e61b3ac9591b..0b119d94c31a 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c | |||
| @@ -126,42 +126,38 @@ unsigned int nf_iterate(struct list_head *head, | |||
| 126 | unsigned int hook, | 126 | unsigned int hook, |
| 127 | const struct net_device *indev, | 127 | const struct net_device *indev, |
| 128 | const struct net_device *outdev, | 128 | const struct net_device *outdev, |
| 129 | struct list_head **i, | 129 | struct nf_hook_ops **elemp, |
| 130 | int (*okfn)(struct sk_buff *), | 130 | int (*okfn)(struct sk_buff *), |
| 131 | int hook_thresh) | 131 | int hook_thresh) |
| 132 | { | 132 | { |
| 133 | unsigned int verdict; | 133 | unsigned int verdict; |
| 134 | struct nf_hook_ops *elem = list_entry_rcu(*i, struct nf_hook_ops, list); | ||
| 135 | 134 | ||
| 136 | /* | 135 | /* |
| 137 | * The caller must not block between calls to this | 136 | * The caller must not block between calls to this |
| 138 | * function because of risk of continuing from deleted element. | 137 | * function because of risk of continuing from deleted element. |
| 139 | */ | 138 | */ |
| 140 | list_for_each_entry_continue_rcu(elem, head, list) { | 139 | list_for_each_entry_continue_rcu((*elemp), head, list) { |
| 141 | if (hook_thresh > elem->priority) | 140 | if (hook_thresh > (*elemp)->priority) |
| 142 | continue; | 141 | continue; |
| 143 | 142 | ||
| 144 | /* Optimization: we don't need to hold module | 143 | /* Optimization: we don't need to hold module |
| 145 | reference here, since function can't sleep. --RR */ | 144 | reference here, since function can't sleep. --RR */ |
| 146 | repeat: | 145 | repeat: |
| 147 | verdict = elem->hook(hook, skb, indev, outdev, okfn); | 146 | verdict = (*elemp)->hook(hook, skb, indev, outdev, okfn); |
| 148 | if (verdict != NF_ACCEPT) { | 147 | if (verdict != NF_ACCEPT) { |
| 149 | #ifdef CONFIG_NETFILTER_DEBUG | 148 | #ifdef CONFIG_NETFILTER_DEBUG |
| 150 | if (unlikely((verdict & NF_VERDICT_MASK) | 149 | if (unlikely((verdict & NF_VERDICT_MASK) |
| 151 | > NF_MAX_VERDICT)) { | 150 | > NF_MAX_VERDICT)) { |
| 152 | NFDEBUG("Evil return from %p(%u).\n", | 151 | NFDEBUG("Evil return from %p(%u).\n", |
| 153 | elem->hook, hook); | 152 | (*elemp)->hook, hook); |
| 154 | continue; | 153 | continue; |
| 155 | } | 154 | } |
| 156 | #endif | 155 | #endif |
| 157 | if (verdict != NF_REPEAT) { | 156 | if (verdict != NF_REPEAT) |
| 158 | *i = &elem->list; | ||
| 159 | return verdict; | 157 | return verdict; |
| 160 | } | ||
| 161 | goto repeat; | 158 | goto repeat; |
| 162 | } | 159 | } |
| 163 | } | 160 | } |
| 164 | *i = &elem->list; | ||
| 165 | return NF_ACCEPT; | 161 | return NF_ACCEPT; |
| 166 | } | 162 | } |
| 167 | 163 | ||
| @@ -174,14 +170,14 @@ int nf_hook_slow(u_int8_t pf, unsigned int hook, struct sk_buff *skb, | |||
| 174 | int (*okfn)(struct sk_buff *), | 170 | int (*okfn)(struct sk_buff *), |
| 175 | int hook_thresh) | 171 | int hook_thresh) |
| 176 | { | 172 | { |
| 177 | struct list_head *elem; | 173 | struct nf_hook_ops *elem; |
| 178 | unsigned int verdict; | 174 | unsigned int verdict; |
| 179 | int ret = 0; | 175 | int ret = 0; |
| 180 | 176 | ||
| 181 | /* We may already have this, but read-locks nest anyway */ | 177 | /* We may already have this, but read-locks nest anyway */ |
| 182 | rcu_read_lock(); | 178 | rcu_read_lock(); |
| 183 | 179 | ||
| 184 | elem = &nf_hooks[pf][hook]; | 180 | elem = list_entry_rcu(&nf_hooks[pf][hook], struct nf_hook_ops, list); |
| 185 | next_hook: | 181 | next_hook: |
| 186 | verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev, | 182 | verdict = nf_iterate(&nf_hooks[pf][hook], skb, hook, indev, |
| 187 | outdev, &elem, okfn, hook_thresh); | 183 | outdev, &elem, okfn, hook_thresh); |
| @@ -193,8 +189,8 @@ next_hook: | |||
| 193 | if (ret == 0) | 189 | if (ret == 0) |
| 194 | ret = -EPERM; | 190 | ret = -EPERM; |
| 195 | } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { | 191 | } else if ((verdict & NF_VERDICT_MASK) == NF_QUEUE) { |
| 196 | int err = nf_queue(skb, elem, pf, hook, indev, outdev, okfn, | 192 | int err = nf_queue(skb, &elem->list, pf, hook, indev, outdev, |
| 197 | verdict >> NF_VERDICT_QBITS); | 193 | okfn, verdict >> NF_VERDICT_QBITS); |
| 198 | if (err < 0) { | 194 | if (err < 0) { |
| 199 | if (err == -ECANCELED) | 195 | if (err == -ECANCELED) |
| 200 | goto next_hook; | 196 | goto next_hook; |
diff --git a/net/netfilter/nf_internals.h b/net/netfilter/nf_internals.h index 770f76432ad0..2886231d20a8 100644 --- a/net/netfilter/nf_internals.h +++ b/net/netfilter/nf_internals.h | |||
| @@ -18,7 +18,7 @@ extern unsigned int nf_iterate(struct list_head *head, | |||
| 18 | unsigned int hook, | 18 | unsigned int hook, |
| 19 | const struct net_device *indev, | 19 | const struct net_device *indev, |
| 20 | const struct net_device *outdev, | 20 | const struct net_device *outdev, |
| 21 | struct list_head **i, | 21 | struct nf_hook_ops **elemp, |
| 22 | int (*okfn)(struct sk_buff *), | 22 | int (*okfn)(struct sk_buff *), |
| 23 | int hook_thresh); | 23 | int hook_thresh); |
| 24 | 24 | ||
diff --git a/net/netfilter/nf_queue.c b/net/netfilter/nf_queue.c index ce60cf0f6c11..29fe102d3436 100644 --- a/net/netfilter/nf_queue.c +++ b/net/netfilter/nf_queue.c | |||
| @@ -287,7 +287,7 @@ int nf_queue(struct sk_buff *skb, | |||
| 287 | void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) | 287 | void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) |
| 288 | { | 288 | { |
| 289 | struct sk_buff *skb = entry->skb; | 289 | struct sk_buff *skb = entry->skb; |
| 290 | struct list_head *elem = &entry->elem->list; | 290 | struct nf_hook_ops *elem = entry->elem; |
| 291 | const struct nf_afinfo *afinfo; | 291 | const struct nf_afinfo *afinfo; |
| 292 | int err; | 292 | int err; |
| 293 | 293 | ||
| @@ -297,7 +297,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) | |||
| 297 | 297 | ||
| 298 | /* Continue traversal iff userspace said ok... */ | 298 | /* Continue traversal iff userspace said ok... */ |
| 299 | if (verdict == NF_REPEAT) { | 299 | if (verdict == NF_REPEAT) { |
| 300 | elem = elem->prev; | 300 | elem = list_entry(elem->list.prev, struct nf_hook_ops, list); |
| 301 | verdict = NF_ACCEPT; | 301 | verdict = NF_ACCEPT; |
| 302 | } | 302 | } |
| 303 | 303 | ||
| @@ -323,7 +323,7 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) | |||
| 323 | local_bh_enable(); | 323 | local_bh_enable(); |
| 324 | break; | 324 | break; |
| 325 | case NF_QUEUE: | 325 | case NF_QUEUE: |
| 326 | err = __nf_queue(skb, elem, entry->pf, entry->hook, | 326 | err = __nf_queue(skb, &elem->list, entry->pf, entry->hook, |
| 327 | entry->indev, entry->outdev, entry->okfn, | 327 | entry->indev, entry->outdev, entry->okfn, |
| 328 | verdict >> NF_VERDICT_QBITS); | 328 | verdict >> NF_VERDICT_QBITS); |
| 329 | if (err < 0) { | 329 | if (err < 0) { |
