aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/ipv4/netfilter/arp_tables.c100
-rw-r--r--net/ipv4/netfilter/ip_tables.c134
-rw-r--r--net/ipv6/netfilter/ip6_tables.c132
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