aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorMichael Wang <wangyun@linux.vnet.ibm.com>2012-08-22 15:59:57 -0400
committerPablo Neira Ayuso <pablo@netfilter.org>2012-09-03 07:52:44 -0400
commit2a6decfd8a5fae0422c98a22aa6bc30224b8a3ec (patch)
tree62c21cdac0ffeee0afe68b012350bb47e289b4d1 /net
parent965505015beccc4ec900798070165875b8e8dccf (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')
-rw-r--r--net/netfilter/core.c24
-rw-r--r--net/netfilter/nf_internals.h2
-rw-r--r--net/netfilter/nf_queue.c6
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 */
146repeat: 145repeat:
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);
185next_hook: 181next_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,
287void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict) 287void 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) {