diff options
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 100 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 134 | ||||
-rw-r--r-- | net/ipv6/netfilter/ip6_tables.c | 132 |
3 files changed, 177 insertions, 189 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 940e54ba21b3..ecba246dc2a7 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -273,66 +273,62 @@ unsigned int arpt_do_table(struct sk_buff *skb, | |||
273 | 273 | ||
274 | arp = arp_hdr(skb); | 274 | arp = arp_hdr(skb); |
275 | do { | 275 | do { |
276 | if (arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { | 276 | struct arpt_entry_target *t; |
277 | struct arpt_entry_target *t; | 277 | int hdr_len; |
278 | int hdr_len; | ||
279 | 278 | ||
280 | hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) + | 279 | if (!arp_packet_match(arp, skb->dev, indev, outdev, &e->arp)) { |
281 | (2 * skb->dev->addr_len); | 280 | e = arpt_next_entry(e); |
281 | continue; | ||
282 | } | ||
282 | 283 | ||
283 | ADD_COUNTER(e->counters, hdr_len, 1); | 284 | hdr_len = sizeof(*arp) + (2 * sizeof(struct in_addr)) + |
285 | (2 * skb->dev->addr_len); | ||
286 | ADD_COUNTER(e->counters, hdr_len, 1); | ||
284 | 287 | ||
285 | t = arpt_get_target(e); | 288 | t = arpt_get_target(e); |
286 | 289 | ||
287 | /* Standard target? */ | 290 | /* Standard target? */ |
288 | if (!t->u.kernel.target->target) { | 291 | if (!t->u.kernel.target->target) { |
289 | int v; | 292 | int v; |
290 | 293 | ||
291 | v = ((struct arpt_standard_target *)t)->verdict; | 294 | v = ((struct arpt_standard_target *)t)->verdict; |
292 | if (v < 0) { | 295 | if (v < 0) { |
293 | /* Pop from stack? */ | 296 | /* Pop from stack? */ |
294 | if (v != ARPT_RETURN) { | 297 | if (v != ARPT_RETURN) { |
295 | verdict = (unsigned)(-v) - 1; | 298 | verdict = (unsigned)(-v) - 1; |
296 | break; | ||
297 | } | ||
298 | e = back; | ||
299 | back = get_entry(table_base, | ||
300 | back->comefrom); | ||
301 | continue; | ||
302 | } | ||
303 | if (table_base + v | ||
304 | != arpt_next_entry(e)) { | ||
305 | /* Save old back ptr in next entry */ | ||
306 | struct arpt_entry *next | ||
307 | = arpt_next_entry(e); | ||
308 | next->comefrom = | ||
309 | (void *)back - table_base; | ||
310 | |||
311 | /* set back pointer to next entry */ | ||
312 | back = next; | ||
313 | } | ||
314 | |||
315 | e = get_entry(table_base, v); | ||
316 | } else { | ||
317 | /* Targets which reenter must return | ||
318 | * abs. verdicts | ||
319 | */ | ||
320 | tgpar.target = t->u.kernel.target; | ||
321 | tgpar.targinfo = t->data; | ||
322 | verdict = t->u.kernel.target->target(skb, | ||
323 | &tgpar); | ||
324 | |||
325 | /* Target might have changed stuff. */ | ||
326 | arp = arp_hdr(skb); | ||
327 | |||
328 | if (verdict == ARPT_CONTINUE) | ||
329 | e = arpt_next_entry(e); | ||
330 | else | ||
331 | /* Verdict */ | ||
332 | break; | 299 | break; |
300 | } | ||
301 | e = back; | ||
302 | back = get_entry(table_base, back->comefrom); | ||
303 | continue; | ||
333 | } | 304 | } |
305 | if (table_base + v | ||
306 | != arpt_next_entry(e)) { | ||
307 | /* Save old back ptr in next entry */ | ||
308 | struct arpt_entry *next = arpt_next_entry(e); | ||
309 | next->comefrom = (void *)back - table_base; | ||
310 | |||
311 | /* set back pointer to next entry */ | ||
312 | back = next; | ||
313 | } | ||
314 | |||
315 | e = get_entry(table_base, v); | ||
334 | } else { | 316 | } else { |
335 | e = arpt_next_entry(e); | 317 | /* Targets which reenter must return |
318 | * abs. verdicts | ||
319 | */ | ||
320 | tgpar.target = t->u.kernel.target; | ||
321 | tgpar.targinfo = t->data; | ||
322 | verdict = t->u.kernel.target->target(skb, &tgpar); | ||
323 | |||
324 | /* Target might have changed stuff. */ | ||
325 | arp = arp_hdr(skb); | ||
326 | |||
327 | if (verdict == ARPT_CONTINUE) | ||
328 | e = arpt_next_entry(e); | ||
329 | else | ||
330 | /* Verdict */ | ||
331 | break; | ||
336 | } | 332 | } |
337 | } while (!hotdrop); | 333 | } while (!hotdrop); |
338 | xt_info_rdunlock_bh(); | 334 | xt_info_rdunlock_bh(); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index 7ec4e4092755..82888bc6bc1a 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -354,91 +354,87 @@ ipt_do_table(struct sk_buff *skb, | |||
354 | back = get_entry(table_base, private->underflow[hook]); | 354 | back = get_entry(table_base, private->underflow[hook]); |
355 | 355 | ||
356 | do { | 356 | do { |
357 | struct ipt_entry_target *t; | ||
358 | |||
357 | IP_NF_ASSERT(e); | 359 | IP_NF_ASSERT(e); |
358 | IP_NF_ASSERT(back); | 360 | IP_NF_ASSERT(back); |
359 | if (ip_packet_match(ip, indev, outdev, | 361 | if (!ip_packet_match(ip, indev, outdev, |
360 | &e->ip, mtpar.fragoff)) { | 362 | &e->ip, mtpar.fragoff)) { |
361 | struct ipt_entry_target *t; | 363 | no_match: |
364 | e = ipt_next_entry(e); | ||
365 | continue; | ||
366 | } | ||
362 | 367 | ||
363 | if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) | 368 | if (IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) |
364 | goto no_match; | 369 | goto no_match; |
365 | 370 | ||
366 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); | 371 | ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); |
367 | 372 | ||
368 | t = ipt_get_target(e); | 373 | t = ipt_get_target(e); |
369 | IP_NF_ASSERT(t->u.kernel.target); | 374 | IP_NF_ASSERT(t->u.kernel.target); |
370 | 375 | ||
371 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 376 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ |
372 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | 377 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) |
373 | /* The packet is traced: log it */ | 378 | /* The packet is traced: log it */ |
374 | if (unlikely(skb->nf_trace)) | 379 | if (unlikely(skb->nf_trace)) |
375 | trace_packet(skb, hook, in, out, | 380 | trace_packet(skb, hook, in, out, |
376 | table->name, private, e); | 381 | table->name, private, e); |
377 | #endif | 382 | #endif |
378 | /* Standard target? */ | 383 | /* Standard target? */ |
379 | if (!t->u.kernel.target->target) { | 384 | if (!t->u.kernel.target->target) { |
380 | int v; | 385 | int v; |
381 | 386 | ||
382 | v = ((struct ipt_standard_target *)t)->verdict; | 387 | v = ((struct ipt_standard_target *)t)->verdict; |
383 | if (v < 0) { | 388 | if (v < 0) { |
384 | /* Pop from stack? */ | 389 | /* Pop from stack? */ |
385 | if (v != IPT_RETURN) { | 390 | if (v != IPT_RETURN) { |
386 | verdict = (unsigned)(-v) - 1; | 391 | verdict = (unsigned)(-v) - 1; |
387 | break; | 392 | break; |
388 | } | ||
389 | e = back; | ||
390 | back = get_entry(table_base, | ||
391 | back->comefrom); | ||
392 | continue; | ||
393 | } | ||
394 | if (table_base + v != ipt_next_entry(e) | ||
395 | && !(e->ip.flags & IPT_F_GOTO)) { | ||
396 | /* Save old back ptr in next entry */ | ||
397 | struct ipt_entry *next | ||
398 | = ipt_next_entry(e); | ||
399 | next->comefrom | ||
400 | = (void *)back - table_base; | ||
401 | /* set back pointer to next entry */ | ||
402 | back = next; | ||
403 | } | 393 | } |
394 | e = back; | ||
395 | back = get_entry(table_base, back->comefrom); | ||
396 | continue; | ||
397 | } | ||
398 | if (table_base + v != ipt_next_entry(e) | ||
399 | && !(e->ip.flags & IPT_F_GOTO)) { | ||
400 | /* Save old back ptr in next entry */ | ||
401 | struct ipt_entry *next = ipt_next_entry(e); | ||
402 | next->comefrom = (void *)back - table_base; | ||
403 | /* set back pointer to next entry */ | ||
404 | back = next; | ||
405 | } | ||
404 | 406 | ||
405 | e = get_entry(table_base, v); | 407 | e = get_entry(table_base, v); |
406 | } else { | 408 | } else { |
407 | /* Targets which reenter must return | 409 | /* Targets which reenter must return |
408 | abs. verdicts */ | 410 | abs. verdicts */ |
409 | tgpar.target = t->u.kernel.target; | 411 | tgpar.target = t->u.kernel.target; |
410 | tgpar.targinfo = t->data; | 412 | tgpar.targinfo = t->data; |
411 | #ifdef CONFIG_NETFILTER_DEBUG | 413 | #ifdef CONFIG_NETFILTER_DEBUG |
412 | ((struct ipt_entry *)table_base)->comefrom | 414 | ((struct ipt_entry *)table_base)->comefrom |
413 | = 0xeeeeeeec; | 415 | = 0xeeeeeeec; |
414 | #endif | 416 | #endif |
415 | verdict = t->u.kernel.target->target(skb, | 417 | verdict = t->u.kernel.target->target(skb, &tgpar); |
416 | &tgpar); | ||
417 | #ifdef CONFIG_NETFILTER_DEBUG | 418 | #ifdef CONFIG_NETFILTER_DEBUG |
418 | if (((struct ipt_entry *)table_base)->comefrom | 419 | if (((struct ipt_entry *)table_base)->comefrom |
419 | != 0xeeeeeeec | 420 | != 0xeeeeeeec |
420 | && verdict == IPT_CONTINUE) { | 421 | && verdict == IPT_CONTINUE) { |
421 | printk("Target %s reentered!\n", | 422 | printk("Target %s reentered!\n", |
422 | t->u.kernel.target->name); | 423 | t->u.kernel.target->name); |
423 | verdict = NF_DROP; | 424 | verdict = NF_DROP; |
424 | } | ||
425 | ((struct ipt_entry *)table_base)->comefrom | ||
426 | = 0x57acc001; | ||
427 | #endif | ||
428 | /* Target might have changed stuff. */ | ||
429 | ip = ip_hdr(skb); | ||
430 | datalen = skb->len - ip->ihl * 4; | ||
431 | |||
432 | if (verdict == IPT_CONTINUE) | ||
433 | e = ipt_next_entry(e); | ||
434 | else | ||
435 | /* Verdict */ | ||
436 | break; | ||
437 | } | 425 | } |
438 | } else { | 426 | ((struct ipt_entry *)table_base)->comefrom |
439 | 427 | = 0x57acc001; | |
440 | no_match: | 428 | #endif |
441 | e = ipt_next_entry(e); | 429 | /* Target might have changed stuff. */ |
430 | ip = ip_hdr(skb); | ||
431 | datalen = skb->len - ip->ihl * 4; | ||
432 | |||
433 | if (verdict == IPT_CONTINUE) | ||
434 | e = ipt_next_entry(e); | ||
435 | else | ||
436 | /* Verdict */ | ||
437 | break; | ||
442 | } | 438 | } |
443 | } while (!hotdrop); | 439 | } while (!hotdrop); |
444 | xt_info_rdunlock_bh(); | 440 | xt_info_rdunlock_bh(); |
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c index 9176e98ace7a..a6c2213f821e 100644 --- a/net/ipv6/netfilter/ip6_tables.c +++ b/net/ipv6/netfilter/ip6_tables.c | |||
@@ -381,91 +381,87 @@ ip6t_do_table(struct sk_buff *skb, | |||
381 | back = get_entry(table_base, private->underflow[hook]); | 381 | back = get_entry(table_base, private->underflow[hook]); |
382 | 382 | ||
383 | do { | 383 | do { |
384 | struct ip6t_entry_target *t; | ||
385 | |||
384 | IP_NF_ASSERT(e); | 386 | IP_NF_ASSERT(e); |
385 | IP_NF_ASSERT(back); | 387 | IP_NF_ASSERT(back); |
386 | if (ip6_packet_match(skb, indev, outdev, &e->ipv6, | 388 | if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, |
387 | &mtpar.thoff, &mtpar.fragoff, &hotdrop)) { | 389 | &mtpar.thoff, &mtpar.fragoff, &hotdrop)) { |
388 | struct ip6t_entry_target *t; | 390 | no_match: |
391 | e = ip6t_next_entry(e); | ||
392 | continue; | ||
393 | } | ||
389 | 394 | ||
390 | if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) | 395 | if (IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) |
391 | goto no_match; | 396 | goto no_match; |
392 | 397 | ||
393 | ADD_COUNTER(e->counters, | 398 | ADD_COUNTER(e->counters, |
394 | ntohs(ipv6_hdr(skb)->payload_len) + | 399 | ntohs(ipv6_hdr(skb)->payload_len) + |
395 | sizeof(struct ipv6hdr), 1); | 400 | sizeof(struct ipv6hdr), 1); |
396 | 401 | ||
397 | t = ip6t_get_target(e); | 402 | t = ip6t_get_target(e); |
398 | IP_NF_ASSERT(t->u.kernel.target); | 403 | IP_NF_ASSERT(t->u.kernel.target); |
399 | 404 | ||
400 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ | 405 | #if defined(CONFIG_NETFILTER_XT_TARGET_TRACE) || \ |
401 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) | 406 | defined(CONFIG_NETFILTER_XT_TARGET_TRACE_MODULE) |
402 | /* The packet is traced: log it */ | 407 | /* The packet is traced: log it */ |
403 | if (unlikely(skb->nf_trace)) | 408 | if (unlikely(skb->nf_trace)) |
404 | trace_packet(skb, hook, in, out, | 409 | trace_packet(skb, hook, in, out, |
405 | table->name, private, e); | 410 | table->name, private, e); |
406 | #endif | 411 | #endif |
407 | /* Standard target? */ | 412 | /* Standard target? */ |
408 | if (!t->u.kernel.target->target) { | 413 | if (!t->u.kernel.target->target) { |
409 | int v; | 414 | int v; |
410 | 415 | ||
411 | v = ((struct ip6t_standard_target *)t)->verdict; | 416 | v = ((struct ip6t_standard_target *)t)->verdict; |
412 | if (v < 0) { | 417 | if (v < 0) { |
413 | /* Pop from stack? */ | 418 | /* Pop from stack? */ |
414 | if (v != IP6T_RETURN) { | 419 | if (v != IP6T_RETURN) { |
415 | verdict = (unsigned)(-v) - 1; | 420 | verdict = (unsigned)(-v) - 1; |
416 | break; | 421 | break; |
417 | } | ||
418 | e = back; | ||
419 | back = get_entry(table_base, | ||
420 | back->comefrom); | ||
421 | continue; | ||
422 | } | ||
423 | if (table_base + v != ip6t_next_entry(e) | ||
424 | && !(e->ipv6.flags & IP6T_F_GOTO)) { | ||
425 | /* Save old back ptr in next entry */ | ||
426 | struct ip6t_entry *next | ||
427 | = ip6t_next_entry(e); | ||
428 | next->comefrom | ||
429 | = (void *)back - table_base; | ||
430 | /* set back pointer to next entry */ | ||
431 | back = next; | ||
432 | } | 422 | } |
423 | e = back; | ||
424 | back = get_entry(table_base, back->comefrom); | ||
425 | continue; | ||
426 | } | ||
427 | if (table_base + v != ip6t_next_entry(e) | ||
428 | && !(e->ipv6.flags & IP6T_F_GOTO)) { | ||
429 | /* Save old back ptr in next entry */ | ||
430 | struct ip6t_entry *next = ip6t_next_entry(e); | ||
431 | next->comefrom = (void *)back - table_base; | ||
432 | /* set back pointer to next entry */ | ||
433 | back = next; | ||
434 | } | ||
433 | 435 | ||
434 | e = get_entry(table_base, v); | 436 | e = get_entry(table_base, v); |
435 | } else { | 437 | } else { |
436 | /* Targets which reenter must return | 438 | /* Targets which reenter must return |
437 | abs. verdicts */ | 439 | abs. verdicts */ |
438 | tgpar.target = t->u.kernel.target; | 440 | tgpar.target = t->u.kernel.target; |
439 | tgpar.targinfo = t->data; | 441 | tgpar.targinfo = t->data; |
440 | 442 | ||
441 | #ifdef CONFIG_NETFILTER_DEBUG | 443 | #ifdef CONFIG_NETFILTER_DEBUG |
442 | ((struct ip6t_entry *)table_base)->comefrom | 444 | ((struct ip6t_entry *)table_base)->comefrom |
443 | = 0xeeeeeeec; | 445 | = 0xeeeeeeec; |
444 | #endif | 446 | #endif |
445 | verdict = t->u.kernel.target->target(skb, | 447 | verdict = t->u.kernel.target->target(skb, &tgpar); |
446 | &tgpar); | ||
447 | 448 | ||
448 | #ifdef CONFIG_NETFILTER_DEBUG | 449 | #ifdef CONFIG_NETFILTER_DEBUG |
449 | if (((struct ip6t_entry *)table_base)->comefrom | 450 | if (((struct ip6t_entry *)table_base)->comefrom |
450 | != 0xeeeeeeec | 451 | != 0xeeeeeeec |
451 | && verdict == IP6T_CONTINUE) { | 452 | && verdict == IP6T_CONTINUE) { |
452 | printk("Target %s reentered!\n", | 453 | printk("Target %s reentered!\n", |
453 | t->u.kernel.target->name); | 454 | t->u.kernel.target->name); |
454 | verdict = NF_DROP; | 455 | verdict = NF_DROP; |
455 | } | ||
456 | ((struct ip6t_entry *)table_base)->comefrom | ||
457 | = 0x57acc001; | ||
458 | #endif | ||
459 | if (verdict == IP6T_CONTINUE) | ||
460 | e = ip6t_next_entry(e); | ||
461 | else | ||
462 | /* Verdict */ | ||
463 | break; | ||
464 | } | 456 | } |
465 | } else { | 457 | ((struct ip6t_entry *)table_base)->comefrom |
466 | 458 | = 0x57acc001; | |
467 | no_match: | 459 | #endif |
468 | e = ip6t_next_entry(e); | 460 | if (verdict == IP6T_CONTINUE) |
461 | e = ip6t_next_entry(e); | ||
462 | else | ||
463 | /* Verdict */ | ||
464 | break; | ||
469 | } | 465 | } |
470 | } while (!hotdrop); | 466 | } while (!hotdrop); |
471 | 467 | ||