aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/linux/netfilter/x_tables.h42
-rw-r--r--net/bridge/netfilter/ebtables.c30
-rw-r--r--net/ipv4/netfilter/arp_tables.c16
-rw-r--r--net/ipv4/netfilter/ip_tables.c32
-rw-r--r--net/ipv6/netfilter/ip6_tables.c27
5 files changed, 68 insertions, 79 deletions
diff --git a/include/linux/netfilter/x_tables.h b/include/linux/netfilter/x_tables.h
index eeb4884c30be..5efa3757d08c 100644
--- a/include/linux/netfilter/x_tables.h
+++ b/include/linux/netfilter/x_tables.h
@@ -182,13 +182,17 @@ struct xt_counters_info {
182 182
183#include <linux/netdevice.h> 183#include <linux/netdevice.h>
184 184
185#define xt_match_param xt_action_param
186#define xt_target_param xt_action_param
185/** 187/**
186 * struct xt_match_param - parameters for match extensions' match functions 188 * struct xt_action_param - parameters for matches/targets
187 * 189 *
190 * @match: the match extension
191 * @target: the target extension
192 * @matchinfo: per-match data
193 * @targetinfo: per-target data
188 * @in: input netdevice 194 * @in: input netdevice
189 * @out: output netdevice 195 * @out: output netdevice
190 * @match: struct xt_match through which this function was invoked
191 * @matchinfo: per-match data
192 * @fragoff: packet is a fragment, this is the data offset 196 * @fragoff: packet is a fragment, this is the data offset
193 * @thoff: position of transport header relative to skb->data 197 * @thoff: position of transport header relative to skb->data
194 * @hook: hook number given packet came from 198 * @hook: hook number given packet came from
@@ -197,10 +201,15 @@ struct xt_counters_info {
197 * @hotdrop: drop packet if we had inspection problems 201 * @hotdrop: drop packet if we had inspection problems
198 * Network namespace obtainable using dev_net(in/out) 202 * Network namespace obtainable using dev_net(in/out)
199 */ 203 */
200struct xt_match_param { 204struct xt_action_param {
205 union {
206 const struct xt_match *match;
207 const struct xt_target *target;
208 };
209 union {
210 const void *matchinfo, *targinfo;
211 };
201 const struct net_device *in, *out; 212 const struct net_device *in, *out;
202 const struct xt_match *match;
203 const void *matchinfo;
204 int fragoff; 213 int fragoff;
205 unsigned int thoff; 214 unsigned int thoff;
206 unsigned int hooknum; 215 unsigned int hooknum;
@@ -243,23 +252,6 @@ struct xt_mtdtor_param {
243}; 252};
244 253
245/** 254/**
246 * struct xt_target_param - parameters for target extensions' target functions
247 *
248 * @hooknum: hook through which this target was invoked
249 * @target: struct xt_target through which this function was invoked
250 * @targinfo: per-target data
251 *
252 * Other fields see above.
253 */
254struct xt_target_param {
255 const struct net_device *in, *out;
256 const struct xt_target *target;
257 const void *targinfo;
258 unsigned int hooknum;
259 u_int8_t family;
260};
261
262/**
263 * struct xt_tgchk_param - parameters for target extensions' 255 * struct xt_tgchk_param - parameters for target extensions'
264 * checkentry functions 256 * checkentry functions
265 * 257 *
@@ -298,7 +290,7 @@ struct xt_match {
298 non-linear skb, using skb_header_pointer and 290 non-linear skb, using skb_header_pointer and
299 skb_ip_make_writable. */ 291 skb_ip_make_writable. */
300 bool (*match)(const struct sk_buff *skb, 292 bool (*match)(const struct sk_buff *skb,
301 const struct xt_match_param *); 293 const struct xt_action_param *);
302 294
303 /* Called when user tries to insert an entry of this type. */ 295 /* Called when user tries to insert an entry of this type. */
304 int (*checkentry)(const struct xt_mtchk_param *); 296 int (*checkentry)(const struct xt_mtchk_param *);
@@ -335,7 +327,7 @@ struct xt_target {
335 must now handle non-linear skbs, using skb_copy_bits and 327 must now handle non-linear skbs, using skb_copy_bits and
336 skb_ip_make_writable. */ 328 skb_ip_make_writable. */
337 unsigned int (*target)(struct sk_buff *skb, 329 unsigned int (*target)(struct sk_buff *skb,
338 const struct xt_target_param *); 330 const struct xt_action_param *);
339 331
340 /* Called when user tries to insert an entry of this type: 332 /* Called when user tries to insert an entry of this type:
341 hook_mask is a bitmask of hooks from which it can be 333 hook_mask is a bitmask of hooks from which it can be
diff --git a/net/bridge/netfilter/ebtables.c b/net/bridge/netfilter/ebtables.c
index 1d8c2c0a7470..290d43541d46 100644
--- a/net/bridge/netfilter/ebtables.c
+++ b/net/bridge/netfilter/ebtables.c
@@ -86,7 +86,7 @@ static struct xt_target ebt_standard_target = {
86 86
87static inline int 87static inline int
88ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb, 88ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
89 struct xt_target_param *par) 89 struct xt_action_param *par)
90{ 90{
91 par->target = w->u.watcher; 91 par->target = w->u.watcher;
92 par->targinfo = w->data; 92 par->targinfo = w->data;
@@ -95,8 +95,9 @@ ebt_do_watcher(const struct ebt_entry_watcher *w, struct sk_buff *skb,
95 return 0; 95 return 0;
96} 96}
97 97
98static inline int ebt_do_match (struct ebt_entry_match *m, 98static inline int
99 const struct sk_buff *skb, struct xt_match_param *par) 99ebt_do_match(struct ebt_entry_match *m, const struct sk_buff *skb,
100 struct xt_action_param *par)
100{ 101{
101 par->match = m->u.match; 102 par->match = m->u.match;
102 par->matchinfo = m->data; 103 par->matchinfo = m->data;
@@ -186,14 +187,13 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
186 const char *base; 187 const char *base;
187 const struct ebt_table_info *private; 188 const struct ebt_table_info *private;
188 bool hotdrop = false; 189 bool hotdrop = false;
189 struct xt_match_param mtpar; 190 struct xt_action_param acpar;
190 struct xt_target_param tgpar;
191 191
192 mtpar.family = tgpar.family = NFPROTO_BRIDGE; 192 acpar.family = NFPROTO_BRIDGE;
193 mtpar.in = tgpar.in = in; 193 acpar.in = in;
194 mtpar.out = tgpar.out = out; 194 acpar.out = out;
195 mtpar.hotdrop = &hotdrop; 195 acpar.hotdrop = &hotdrop;
196 mtpar.hooknum = tgpar.hooknum = hook; 196 acpar.hooknum = hook;
197 197
198 read_lock_bh(&table->lock); 198 read_lock_bh(&table->lock);
199 private = table->private; 199 private = table->private;
@@ -214,7 +214,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
214 if (ebt_basic_match(point, eth_hdr(skb), in, out)) 214 if (ebt_basic_match(point, eth_hdr(skb), in, out))
215 goto letscontinue; 215 goto letscontinue;
216 216
217 if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &mtpar) != 0) 217 if (EBT_MATCH_ITERATE(point, ebt_do_match, skb, &acpar) != 0)
218 goto letscontinue; 218 goto letscontinue;
219 if (hotdrop) { 219 if (hotdrop) {
220 read_unlock_bh(&table->lock); 220 read_unlock_bh(&table->lock);
@@ -227,7 +227,7 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
227 227
228 /* these should only watch: not modify, nor tell us 228 /* these should only watch: not modify, nor tell us
229 what to do with the packet */ 229 what to do with the packet */
230 EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &tgpar); 230 EBT_WATCHER_ITERATE(point, ebt_do_watcher, skb, &acpar);
231 231
232 t = (struct ebt_entry_target *) 232 t = (struct ebt_entry_target *)
233 (((char *)point) + point->target_offset); 233 (((char *)point) + point->target_offset);
@@ -235,9 +235,9 @@ unsigned int ebt_do_table (unsigned int hook, struct sk_buff *skb,
235 if (!t->u.target->target) 235 if (!t->u.target->target)
236 verdict = ((struct ebt_standard_target *)t)->verdict; 236 verdict = ((struct ebt_standard_target *)t)->verdict;
237 else { 237 else {
238 tgpar.target = t->u.target; 238 acpar.target = t->u.target;
239 tgpar.targinfo = t->data; 239 acpar.targinfo = t->data;
240 verdict = t->u.target->target(skb, &tgpar); 240 verdict = t->u.target->target(skb, &acpar);
241 } 241 }
242 if (verdict == EBT_ACCEPT) { 242 if (verdict == EBT_ACCEPT) {
243 read_unlock_bh(&table->lock); 243 read_unlock_bh(&table->lock);
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c
index 07a699059390..73d924b88f89 100644
--- a/net/ipv4/netfilter/arp_tables.c
+++ b/net/ipv4/netfilter/arp_tables.c
@@ -265,7 +265,7 @@ unsigned int arpt_do_table(struct sk_buff *skb,
265 const char *indev, *outdev; 265 const char *indev, *outdev;
266 void *table_base; 266 void *table_base;
267 const struct xt_table_info *private; 267 const struct xt_table_info *private;
268 struct xt_target_param tgpar; 268 struct xt_action_param acpar;
269 269
270 if (!pskb_may_pull(skb, arp_hdr_len(skb->dev))) 270 if (!pskb_may_pull(skb, arp_hdr_len(skb->dev)))
271 return NF_DROP; 271 return NF_DROP;
@@ -280,10 +280,10 @@ unsigned int arpt_do_table(struct sk_buff *skb,
280 e = get_entry(table_base, private->hook_entry[hook]); 280 e = get_entry(table_base, private->hook_entry[hook]);
281 back = get_entry(table_base, private->underflow[hook]); 281 back = get_entry(table_base, private->underflow[hook]);
282 282
283 tgpar.in = in; 283 acpar.in = in;
284 tgpar.out = out; 284 acpar.out = out;
285 tgpar.hooknum = hook; 285 acpar.hooknum = hook;
286 tgpar.family = NFPROTO_ARP; 286 acpar.family = NFPROTO_ARP;
287 287
288 arp = arp_hdr(skb); 288 arp = arp_hdr(skb);
289 do { 289 do {
@@ -333,9 +333,9 @@ unsigned int arpt_do_table(struct sk_buff *skb,
333 /* Targets which reenter must return 333 /* Targets which reenter must return
334 * abs. verdicts 334 * abs. verdicts
335 */ 335 */
336 tgpar.target = t->u.kernel.target; 336 acpar.target = t->u.kernel.target;
337 tgpar.targinfo = t->data; 337 acpar.targinfo = t->data;
338 verdict = t->u.kernel.target->target(skb, &tgpar); 338 verdict = t->u.kernel.target->target(skb, &acpar);
339 339
340 /* Target might have changed stuff. */ 340 /* Target might have changed stuff. */
341 arp = arp_hdr(skb); 341 arp = arp_hdr(skb);
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 265cedf88660..e1a53c2da032 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -316,8 +316,7 @@ ipt_do_table(struct sk_buff *skb,
316 struct ipt_entry *e, **jumpstack; 316 struct ipt_entry *e, **jumpstack;
317 unsigned int *stackptr, origptr, cpu; 317 unsigned int *stackptr, origptr, cpu;
318 const struct xt_table_info *private; 318 const struct xt_table_info *private;
319 struct xt_match_param mtpar; 319 struct xt_action_param acpar;
320 struct xt_target_param tgpar;
321 320
322 /* Initialization */ 321 /* Initialization */
323 ip = ip_hdr(skb); 322 ip = ip_hdr(skb);
@@ -329,13 +328,13 @@ ipt_do_table(struct sk_buff *skb,
329 * things we don't know, ie. tcp syn flag or ports). If the 328 * things we don't know, ie. tcp syn flag or ports). If the
330 * rule is also a fragment-specific rule, non-fragments won't 329 * rule is also a fragment-specific rule, non-fragments won't
331 * match it. */ 330 * match it. */
332 mtpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET; 331 acpar.fragoff = ntohs(ip->frag_off) & IP_OFFSET;
333 mtpar.thoff = ip_hdrlen(skb); 332 acpar.thoff = ip_hdrlen(skb);
334 mtpar.hotdrop = &hotdrop; 333 acpar.hotdrop = &hotdrop;
335 mtpar.in = tgpar.in = in; 334 acpar.in = in;
336 mtpar.out = tgpar.out = out; 335 acpar.out = out;
337 mtpar.family = tgpar.family = NFPROTO_IPV4; 336 acpar.family = NFPROTO_IPV4;
338 mtpar.hooknum = tgpar.hooknum = hook; 337 acpar.hooknum = hook;
339 338
340 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 339 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
341 xt_info_rdlock_bh(); 340 xt_info_rdlock_bh();
@@ -358,16 +357,16 @@ ipt_do_table(struct sk_buff *skb,
358 357
359 IP_NF_ASSERT(e); 358 IP_NF_ASSERT(e);
360 if (!ip_packet_match(ip, indev, outdev, 359 if (!ip_packet_match(ip, indev, outdev,
361 &e->ip, mtpar.fragoff)) { 360 &e->ip, acpar.fragoff)) {
362 no_match: 361 no_match:
363 e = ipt_next_entry(e); 362 e = ipt_next_entry(e);
364 continue; 363 continue;
365 } 364 }
366 365
367 xt_ematch_foreach(ematch, e) { 366 xt_ematch_foreach(ematch, e) {
368 mtpar.match = ematch->u.kernel.match; 367 acpar.match = ematch->u.kernel.match;
369 mtpar.matchinfo = ematch->data; 368 acpar.matchinfo = ematch->data;
370 if (!mtpar.match->match(skb, &mtpar)) 369 if (!acpar.match->match(skb, &acpar))
371 goto no_match; 370 goto no_match;
372 } 371 }
373 372
@@ -422,11 +421,10 @@ ipt_do_table(struct sk_buff *skb,
422 continue; 421 continue;
423 } 422 }
424 423
425 tgpar.target = t->u.kernel.target; 424 acpar.target = t->u.kernel.target;
426 tgpar.targinfo = t->data; 425 acpar.targinfo = t->data;
427 426
428 427 verdict = t->u.kernel.target->target(skb, &acpar);
429 verdict = t->u.kernel.target->target(skb, &tgpar);
430 /* Target might have changed stuff. */ 428 /* Target might have changed stuff. */
431 ip = ip_hdr(skb); 429 ip = ip_hdr(skb);
432 if (verdict == IPT_CONTINUE) 430 if (verdict == IPT_CONTINUE)
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index f8ac4a0b5899..076308c1acd7 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -345,8 +345,7 @@ ip6t_do_table(struct sk_buff *skb,
345 struct ip6t_entry *e, **jumpstack; 345 struct ip6t_entry *e, **jumpstack;
346 unsigned int *stackptr, origptr, cpu; 346 unsigned int *stackptr, origptr, cpu;
347 const struct xt_table_info *private; 347 const struct xt_table_info *private;
348 struct xt_match_param mtpar; 348 struct xt_action_param acpar;
349 struct xt_target_param tgpar;
350 349
351 /* Initialization */ 350 /* Initialization */
352 indev = in ? in->name : nulldevname; 351 indev = in ? in->name : nulldevname;
@@ -357,11 +356,11 @@ ip6t_do_table(struct sk_buff *skb,
357 * things we don't know, ie. tcp syn flag or ports). If the 356 * things we don't know, ie. tcp syn flag or ports). If the
358 * rule is also a fragment-specific rule, non-fragments won't 357 * rule is also a fragment-specific rule, non-fragments won't
359 * match it. */ 358 * match it. */
360 mtpar.hotdrop = &hotdrop; 359 acpar.hotdrop = &hotdrop;
361 mtpar.in = tgpar.in = in; 360 acpar.in = in;
362 mtpar.out = tgpar.out = out; 361 acpar.out = out;
363 mtpar.family = tgpar.family = NFPROTO_IPV6; 362 acpar.family = NFPROTO_IPV6;
364 mtpar.hooknum = tgpar.hooknum = hook; 363 acpar.hooknum = hook;
365 364
366 IP_NF_ASSERT(table->valid_hooks & (1 << hook)); 365 IP_NF_ASSERT(table->valid_hooks & (1 << hook));
367 366
@@ -381,16 +380,16 @@ ip6t_do_table(struct sk_buff *skb,
381 380
382 IP_NF_ASSERT(e); 381 IP_NF_ASSERT(e);
383 if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, 382 if (!ip6_packet_match(skb, indev, outdev, &e->ipv6,
384 &mtpar.thoff, &mtpar.fragoff, &hotdrop)) { 383 &acpar.thoff, &acpar.fragoff, &hotdrop)) {
385 no_match: 384 no_match:
386 e = ip6t_next_entry(e); 385 e = ip6t_next_entry(e);
387 continue; 386 continue;
388 } 387 }
389 388
390 xt_ematch_foreach(ematch, e) { 389 xt_ematch_foreach(ematch, e) {
391 mtpar.match = ematch->u.kernel.match; 390 acpar.match = ematch->u.kernel.match;
392 mtpar.matchinfo = ematch->data; 391 acpar.matchinfo = ematch->data;
393 if (!mtpar.match->match(skb, &mtpar)) 392 if (!acpar.match->match(skb, &acpar))
394 goto no_match; 393 goto no_match;
395 } 394 }
396 395
@@ -439,10 +438,10 @@ ip6t_do_table(struct sk_buff *skb,
439 continue; 438 continue;
440 } 439 }
441 440
442 tgpar.target = t->u.kernel.target; 441 acpar.target = t->u.kernel.target;
443 tgpar.targinfo = t->data; 442 acpar.targinfo = t->data;
444 443
445 verdict = t->u.kernel.target->target(skb, &tgpar); 444 verdict = t->u.kernel.target->target(skb, &acpar);
446 if (verdict == IP6T_CONTINUE) 445 if (verdict == IP6T_CONTINUE)
447 e = ip6t_next_entry(e); 446 e = ip6t_next_entry(e);
448 else 447 else