diff options
author | Patrick McHardy <kaber@trash.net> | 2007-12-18 00:56:33 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2008-01-28 17:58:46 -0500 |
commit | fb5b6095f320bd5a615049aa5fe8827ae9d1bf80 (patch) | |
tree | 71d99ffe6c738a4340f61794bb142526a78ff8a3 /net | |
parent | 70f0bfcf6a24e259d51f62354f866f42f8a3d317 (diff) |
[NETFILTER]: arp_tables: move entry and target checks to seperate functions
Resync with ip_tables.c as preparation for compat support.
Signed-off-by: Patrick McHardy <kaber@trash.net>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 58 |
1 files changed, 41 insertions, 17 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index cafb35ae285..b0f43315842 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -435,12 +435,9 @@ static int mark_source_chains(struct xt_table_info *newinfo, | |||
435 | return 1; | 435 | return 1; |
436 | } | 436 | } |
437 | 437 | ||
438 | static inline int check_entry(struct arpt_entry *e, const char *name, unsigned int size, | 438 | static inline int check_entry(struct arpt_entry *e, const char *name) |
439 | unsigned int *i) | ||
440 | { | 439 | { |
441 | struct arpt_entry_target *t; | 440 | struct arpt_entry_target *t; |
442 | struct arpt_target *target; | ||
443 | int ret; | ||
444 | 441 | ||
445 | if (!arp_checkentry(&e->arp)) { | 442 | if (!arp_checkentry(&e->arp)) { |
446 | duprintf("arp_tables: arp check failed %p %s.\n", e, name); | 443 | duprintf("arp_tables: arp check failed %p %s.\n", e, name); |
@@ -454,30 +451,57 @@ static inline int check_entry(struct arpt_entry *e, const char *name, unsigned i | |||
454 | if (e->target_offset + t->u.target_size > e->next_offset) | 451 | if (e->target_offset + t->u.target_size > e->next_offset) |
455 | return -EINVAL; | 452 | return -EINVAL; |
456 | 453 | ||
454 | return 0; | ||
455 | } | ||
456 | |||
457 | static inline int check_target(struct arpt_entry *e, const char *name) | ||
458 | { | ||
459 | struct arpt_entry_target *t; | ||
460 | struct arpt_target *target; | ||
461 | int ret; | ||
462 | |||
463 | t = arpt_get_target(e); | ||
464 | target = t->u.kernel.target; | ||
465 | |||
466 | ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t), | ||
467 | name, e->comefrom, 0, 0); | ||
468 | if (!ret && t->u.kernel.target->checkentry | ||
469 | && !t->u.kernel.target->checkentry(name, e, target, t->data, | ||
470 | e->comefrom)) { | ||
471 | duprintf("arp_tables: check failed for `%s'.\n", | ||
472 | t->u.kernel.target->name); | ||
473 | ret = -EINVAL; | ||
474 | } | ||
475 | return ret; | ||
476 | } | ||
477 | |||
478 | static inline int | ||
479 | find_check_entry(struct arpt_entry *e, const char *name, unsigned int size, | ||
480 | unsigned int *i) | ||
481 | { | ||
482 | struct arpt_entry_target *t; | ||
483 | struct arpt_target *target; | ||
484 | int ret; | ||
485 | |||
486 | ret = check_entry(e, name); | ||
487 | if (ret) | ||
488 | return ret; | ||
489 | |||
490 | t = arpt_get_target(e); | ||
457 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, | 491 | target = try_then_request_module(xt_find_target(NF_ARP, t->u.user.name, |
458 | t->u.user.revision), | 492 | t->u.user.revision), |
459 | "arpt_%s", t->u.user.name); | 493 | "arpt_%s", t->u.user.name); |
460 | if (IS_ERR(target) || !target) { | 494 | if (IS_ERR(target) || !target) { |
461 | duprintf("check_entry: `%s' not found\n", t->u.user.name); | 495 | duprintf("find_check_entry: `%s' not found\n", t->u.user.name); |
462 | ret = target ? PTR_ERR(target) : -ENOENT; | 496 | ret = target ? PTR_ERR(target) : -ENOENT; |
463 | goto out; | 497 | goto out; |
464 | } | 498 | } |
465 | t->u.kernel.target = target; | 499 | t->u.kernel.target = target; |
466 | 500 | ||
467 | ret = xt_check_target(target, NF_ARP, t->u.target_size - sizeof(*t), | 501 | ret = check_target(e, name); |
468 | name, e->comefrom, 0, 0); | ||
469 | if (ret) | 502 | if (ret) |
470 | goto err; | 503 | goto err; |
471 | 504 | ||
472 | if (t->u.kernel.target->checkentry | ||
473 | && !t->u.kernel.target->checkentry(name, e, target, t->data, | ||
474 | e->comefrom)) { | ||
475 | duprintf("arp_tables: check failed for `%s'.\n", | ||
476 | t->u.kernel.target->name); | ||
477 | ret = -EINVAL; | ||
478 | goto err; | ||
479 | } | ||
480 | |||
481 | (*i)++; | 505 | (*i)++; |
482 | return 0; | 506 | return 0; |
483 | err: | 507 | err: |
@@ -611,7 +635,7 @@ static int translate_table(const char *name, | |||
611 | /* Finally, each sanity check must pass */ | 635 | /* Finally, each sanity check must pass */ |
612 | i = 0; | 636 | i = 0; |
613 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 637 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, |
614 | check_entry, name, size, &i); | 638 | find_check_entry, name, size, &i); |
615 | 639 | ||
616 | if (ret != 0) { | 640 | if (ret != 0) { |
617 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 641 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, |