diff options
author | Jan Engelhardt <jengelh@medozas.de> | 2010-02-24 12:32:59 -0500 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2010-02-24 12:32:59 -0500 |
commit | 72b2b1dd77e8feb0b7c0b26dee58f2a1e2c9828c (patch) | |
tree | 4289fef5441a1664f60a17cb473d657f77cf1112 /net/ipv4 | |
parent | 8ccb92ad41cb311e52ad1b1fe77992c7f47a3b63 (diff) |
netfilter: xtables: replace XT_ENTRY_ITERATE macro
The macro is replaced by a list.h-like foreach loop. This makes
the code much more inspectable.
Signed-off-by: Jan Engelhardt <jengelh@medozas.de>
Signed-off-by: Patrick McHardy <kaber@trash.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r-- | net/ipv4/netfilter/arp_tables.c | 151 | ||||
-rw-r--r-- | net/ipv4/netfilter/ip_tables.c | 160 |
2 files changed, 202 insertions, 109 deletions
diff --git a/net/ipv4/netfilter/arp_tables.c b/net/ipv4/netfilter/arp_tables.c index 4db5c1ece0f9..f7338869fc4c 100644 --- a/net/ipv4/netfilter/arp_tables.c +++ b/net/ipv4/netfilter/arp_tables.c | |||
@@ -641,8 +641,9 @@ static int translate_table(const char *name, | |||
641 | const unsigned int *hook_entries, | 641 | const unsigned int *hook_entries, |
642 | const unsigned int *underflows) | 642 | const unsigned int *underflows) |
643 | { | 643 | { |
644 | struct arpt_entry *iter; | ||
644 | unsigned int i; | 645 | unsigned int i; |
645 | int ret; | 646 | int ret = 0; |
646 | 647 | ||
647 | newinfo->size = size; | 648 | newinfo->size = size; |
648 | newinfo->number = number; | 649 | newinfo->number = number; |
@@ -657,12 +658,13 @@ static int translate_table(const char *name, | |||
657 | i = 0; | 658 | i = 0; |
658 | 659 | ||
659 | /* Walk through entries, checking offsets. */ | 660 | /* Walk through entries, checking offsets. */ |
660 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 661 | xt_entry_foreach(iter, entry0, newinfo->size) { |
661 | check_entry_size_and_hooks, | 662 | ret = check_entry_size_and_hooks(iter, newinfo, entry0, |
662 | newinfo, | 663 | entry0 + size, hook_entries, underflows, |
663 | entry0, | 664 | valid_hooks, &i); |
664 | entry0 + size, | 665 | if (ret != 0) |
665 | hook_entries, underflows, valid_hooks, &i); | 666 | break; |
667 | } | ||
666 | duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); | 668 | duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); |
667 | if (ret != 0) | 669 | if (ret != 0) |
668 | return ret; | 670 | return ret; |
@@ -697,12 +699,16 @@ static int translate_table(const char *name, | |||
697 | 699 | ||
698 | /* Finally, each sanity check must pass */ | 700 | /* Finally, each sanity check must pass */ |
699 | i = 0; | 701 | i = 0; |
700 | ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 702 | xt_entry_foreach(iter, entry0, newinfo->size) { |
701 | find_check_entry, name, size, &i); | 703 | ret = find_check_entry(iter, name, size, &i); |
704 | if (ret != 0) | ||
705 | break; | ||
706 | } | ||
702 | 707 | ||
703 | if (ret != 0) { | 708 | if (ret != 0) { |
704 | ARPT_ENTRY_ITERATE(entry0, newinfo->size, | 709 | xt_entry_foreach(iter, entry0, newinfo->size) |
705 | cleanup_entry, &i); | 710 | if (cleanup_entry(iter, &i) != 0) |
711 | break; | ||
706 | return ret; | 712 | return ret; |
707 | } | 713 | } |
708 | 714 | ||
@@ -739,6 +745,7 @@ static inline int set_entry_to_counter(const struct arpt_entry *e, | |||
739 | static void get_counters(const struct xt_table_info *t, | 745 | static void get_counters(const struct xt_table_info *t, |
740 | struct xt_counters counters[]) | 746 | struct xt_counters counters[]) |
741 | { | 747 | { |
748 | struct arpt_entry *iter; | ||
742 | unsigned int cpu; | 749 | unsigned int cpu; |
743 | unsigned int i; | 750 | unsigned int i; |
744 | unsigned int curcpu; | 751 | unsigned int curcpu; |
@@ -754,22 +761,18 @@ static void get_counters(const struct xt_table_info *t, | |||
754 | curcpu = smp_processor_id(); | 761 | curcpu = smp_processor_id(); |
755 | 762 | ||
756 | i = 0; | 763 | i = 0; |
757 | ARPT_ENTRY_ITERATE(t->entries[curcpu], | 764 | xt_entry_foreach(iter, t->entries[curcpu], t->size) |
758 | t->size, | 765 | if (set_entry_to_counter(iter, counters, &i) != 0) |
759 | set_entry_to_counter, | 766 | break; |
760 | counters, | ||
761 | &i); | ||
762 | 767 | ||
763 | for_each_possible_cpu(cpu) { | 768 | for_each_possible_cpu(cpu) { |
764 | if (cpu == curcpu) | 769 | if (cpu == curcpu) |
765 | continue; | 770 | continue; |
766 | i = 0; | 771 | i = 0; |
767 | xt_info_wrlock(cpu); | 772 | xt_info_wrlock(cpu); |
768 | ARPT_ENTRY_ITERATE(t->entries[cpu], | 773 | xt_entry_foreach(iter, t->entries[cpu], t->size) |
769 | t->size, | 774 | if (add_entry_to_counter(iter, counters, &i) != 0) |
770 | add_entry_to_counter, | 775 | break; |
771 | counters, | ||
772 | &i); | ||
773 | xt_info_wrunlock(cpu); | 776 | xt_info_wrunlock(cpu); |
774 | } | 777 | } |
775 | local_bh_enable(); | 778 | local_bh_enable(); |
@@ -899,7 +902,9 @@ static int compat_calc_entry(const struct arpt_entry *e, | |||
899 | static int compat_table_info(const struct xt_table_info *info, | 902 | static int compat_table_info(const struct xt_table_info *info, |
900 | struct xt_table_info *newinfo) | 903 | struct xt_table_info *newinfo) |
901 | { | 904 | { |
905 | struct arpt_entry *iter; | ||
902 | void *loc_cpu_entry; | 906 | void *loc_cpu_entry; |
907 | int ret = 0; | ||
903 | 908 | ||
904 | if (!newinfo || !info) | 909 | if (!newinfo || !info) |
905 | return -EINVAL; | 910 | return -EINVAL; |
@@ -908,9 +913,12 @@ static int compat_table_info(const struct xt_table_info *info, | |||
908 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); | 913 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); |
909 | newinfo->initial_entries = 0; | 914 | newinfo->initial_entries = 0; |
910 | loc_cpu_entry = info->entries[raw_smp_processor_id()]; | 915 | loc_cpu_entry = info->entries[raw_smp_processor_id()]; |
911 | return ARPT_ENTRY_ITERATE(loc_cpu_entry, info->size, | 916 | xt_entry_foreach(iter, loc_cpu_entry, info->size) { |
912 | compat_calc_entry, info, loc_cpu_entry, | 917 | ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); |
913 | newinfo); | 918 | if (ret != 0) |
919 | break; | ||
920 | } | ||
921 | return ret; | ||
914 | } | 922 | } |
915 | #endif | 923 | #endif |
916 | 924 | ||
@@ -1025,6 +1033,7 @@ static int __do_replace(struct net *net, const char *name, | |||
1025 | struct xt_table_info *oldinfo; | 1033 | struct xt_table_info *oldinfo; |
1026 | struct xt_counters *counters; | 1034 | struct xt_counters *counters; |
1027 | void *loc_cpu_old_entry; | 1035 | void *loc_cpu_old_entry; |
1036 | struct arpt_entry *iter; | ||
1028 | 1037 | ||
1029 | ret = 0; | 1038 | ret = 0; |
1030 | counters = vmalloc_node(num_counters * sizeof(struct xt_counters), | 1039 | counters = vmalloc_node(num_counters * sizeof(struct xt_counters), |
@@ -1068,8 +1077,9 @@ static int __do_replace(struct net *net, const char *name, | |||
1068 | 1077 | ||
1069 | /* Decrease module usage counts and free resource */ | 1078 | /* Decrease module usage counts and free resource */ |
1070 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; | 1079 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
1071 | ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, | 1080 | xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size) |
1072 | NULL); | 1081 | if (cleanup_entry(iter, NULL) != 0) |
1082 | break; | ||
1073 | 1083 | ||
1074 | xt_free_table_info(oldinfo); | 1084 | xt_free_table_info(oldinfo); |
1075 | if (copy_to_user(counters_ptr, counters, | 1085 | if (copy_to_user(counters_ptr, counters, |
@@ -1095,6 +1105,7 @@ static int do_replace(struct net *net, const void __user *user, | |||
1095 | struct arpt_replace tmp; | 1105 | struct arpt_replace tmp; |
1096 | struct xt_table_info *newinfo; | 1106 | struct xt_table_info *newinfo; |
1097 | void *loc_cpu_entry; | 1107 | void *loc_cpu_entry; |
1108 | struct arpt_entry *iter; | ||
1098 | 1109 | ||
1099 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1110 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1100 | return -EFAULT; | 1111 | return -EFAULT; |
@@ -1130,7 +1141,9 @@ static int do_replace(struct net *net, const void __user *user, | |||
1130 | return 0; | 1141 | return 0; |
1131 | 1142 | ||
1132 | free_newinfo_untrans: | 1143 | free_newinfo_untrans: |
1133 | ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); | 1144 | xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) |
1145 | if (cleanup_entry(iter, NULL) != 0) | ||
1146 | break; | ||
1134 | free_newinfo: | 1147 | free_newinfo: |
1135 | xt_free_table_info(newinfo); | 1148 | xt_free_table_info(newinfo); |
1136 | return ret; | 1149 | return ret; |
@@ -1163,6 +1176,7 @@ static int do_add_counters(struct net *net, const void __user *user, | |||
1163 | const struct xt_table_info *private; | 1176 | const struct xt_table_info *private; |
1164 | int ret = 0; | 1177 | int ret = 0; |
1165 | void *loc_cpu_entry; | 1178 | void *loc_cpu_entry; |
1179 | struct arpt_entry *iter; | ||
1166 | #ifdef CONFIG_COMPAT | 1180 | #ifdef CONFIG_COMPAT |
1167 | struct compat_xt_counters_info compat_tmp; | 1181 | struct compat_xt_counters_info compat_tmp; |
1168 | 1182 | ||
@@ -1220,11 +1234,9 @@ static int do_add_counters(struct net *net, const void __user *user, | |||
1220 | curcpu = smp_processor_id(); | 1234 | curcpu = smp_processor_id(); |
1221 | loc_cpu_entry = private->entries[curcpu]; | 1235 | loc_cpu_entry = private->entries[curcpu]; |
1222 | xt_info_wrlock(curcpu); | 1236 | xt_info_wrlock(curcpu); |
1223 | ARPT_ENTRY_ITERATE(loc_cpu_entry, | 1237 | xt_entry_foreach(iter, loc_cpu_entry, private->size) |
1224 | private->size, | 1238 | if (add_counter_to_entry(iter, paddc, &i) != 0) |
1225 | add_counter_to_entry, | 1239 | break; |
1226 | paddc, | ||
1227 | &i); | ||
1228 | xt_info_wrunlock(curcpu); | 1240 | xt_info_wrunlock(curcpu); |
1229 | unlock_up_free: | 1241 | unlock_up_free: |
1230 | local_bh_enable(); | 1242 | local_bh_enable(); |
@@ -1388,8 +1400,10 @@ static int translate_compat_table(const char *name, | |||
1388 | unsigned int i, j; | 1400 | unsigned int i, j; |
1389 | struct xt_table_info *newinfo, *info; | 1401 | struct xt_table_info *newinfo, *info; |
1390 | void *pos, *entry0, *entry1; | 1402 | void *pos, *entry0, *entry1; |
1403 | struct compat_arpt_entry *iter0; | ||
1404 | struct arpt_entry *iter1; | ||
1391 | unsigned int size; | 1405 | unsigned int size; |
1392 | int ret; | 1406 | int ret = 0; |
1393 | 1407 | ||
1394 | info = *pinfo; | 1408 | info = *pinfo; |
1395 | entry0 = *pentry0; | 1409 | entry0 = *pentry0; |
@@ -1406,11 +1420,13 @@ static int translate_compat_table(const char *name, | |||
1406 | j = 0; | 1420 | j = 0; |
1407 | xt_compat_lock(NFPROTO_ARP); | 1421 | xt_compat_lock(NFPROTO_ARP); |
1408 | /* Walk through entries, checking offsets. */ | 1422 | /* Walk through entries, checking offsets. */ |
1409 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, | 1423 | xt_entry_foreach(iter0, entry0, total_size) { |
1410 | check_compat_entry_size_and_hooks, | 1424 | ret = check_compat_entry_size_and_hooks(iter0, info, &size, |
1411 | info, &size, entry0, | 1425 | entry0, entry0 + total_size, hook_entries, underflows, |
1412 | entry0 + total_size, | 1426 | &j, name); |
1413 | hook_entries, underflows, &j, name); | 1427 | if (ret != 0) |
1428 | break; | ||
1429 | } | ||
1414 | if (ret != 0) | 1430 | if (ret != 0) |
1415 | goto out_unlock; | 1431 | goto out_unlock; |
1416 | 1432 | ||
@@ -1451,9 +1467,12 @@ static int translate_compat_table(const char *name, | |||
1451 | entry1 = newinfo->entries[raw_smp_processor_id()]; | 1467 | entry1 = newinfo->entries[raw_smp_processor_id()]; |
1452 | pos = entry1; | 1468 | pos = entry1; |
1453 | size = total_size; | 1469 | size = total_size; |
1454 | ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, | 1470 | xt_entry_foreach(iter0, entry0, total_size) { |
1455 | compat_copy_entry_from_user, | 1471 | ret = compat_copy_entry_from_user(iter0, &pos, |
1456 | &pos, &size, name, newinfo, entry1); | 1472 | &size, name, newinfo, entry1); |
1473 | if (ret != 0) | ||
1474 | break; | ||
1475 | } | ||
1457 | xt_compat_flush_offsets(NFPROTO_ARP); | 1476 | xt_compat_flush_offsets(NFPROTO_ARP); |
1458 | xt_compat_unlock(NFPROTO_ARP); | 1477 | xt_compat_unlock(NFPROTO_ARP); |
1459 | if (ret) | 1478 | if (ret) |
@@ -1464,13 +1483,28 @@ static int translate_compat_table(const char *name, | |||
1464 | goto free_newinfo; | 1483 | goto free_newinfo; |
1465 | 1484 | ||
1466 | i = 0; | 1485 | i = 0; |
1467 | ret = ARPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, | 1486 | xt_entry_foreach(iter1, entry1, newinfo->size) { |
1468 | name, &i); | 1487 | ret = compat_check_entry(iter1, name, &i); |
1488 | if (ret != 0) | ||
1489 | break; | ||
1490 | } | ||
1469 | if (ret) { | 1491 | if (ret) { |
1492 | /* | ||
1493 | * The first i matches need cleanup_entry (calls ->destroy) | ||
1494 | * because they had called ->check already. The other j-i | ||
1495 | * entries need only release. | ||
1496 | */ | ||
1497 | int skip = i; | ||
1470 | j -= i; | 1498 | j -= i; |
1471 | COMPAT_ARPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, | 1499 | xt_entry_foreach(iter0, entry0, newinfo->size) { |
1472 | compat_release_entry, &j); | 1500 | if (skip-- > 0) |
1473 | ARPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); | 1501 | continue; |
1502 | if (compat_release_entry(iter0, &j) != 0) | ||
1503 | break; | ||
1504 | } | ||
1505 | xt_entry_foreach(iter1, entry1, newinfo->size) | ||
1506 | if (cleanup_entry(iter1, &i) != 0) | ||
1507 | break; | ||
1474 | xt_free_table_info(newinfo); | 1508 | xt_free_table_info(newinfo); |
1475 | return ret; | 1509 | return ret; |
1476 | } | 1510 | } |
@@ -1488,7 +1522,9 @@ static int translate_compat_table(const char *name, | |||
1488 | free_newinfo: | 1522 | free_newinfo: |
1489 | xt_free_table_info(newinfo); | 1523 | xt_free_table_info(newinfo); |
1490 | out: | 1524 | out: |
1491 | COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); | 1525 | xt_entry_foreach(iter0, entry0, total_size) |
1526 | if (compat_release_entry(iter0, &j) != 0) | ||
1527 | break; | ||
1492 | return ret; | 1528 | return ret; |
1493 | out_unlock: | 1529 | out_unlock: |
1494 | xt_compat_flush_offsets(NFPROTO_ARP); | 1530 | xt_compat_flush_offsets(NFPROTO_ARP); |
@@ -1515,6 +1551,7 @@ static int compat_do_replace(struct net *net, void __user *user, | |||
1515 | struct compat_arpt_replace tmp; | 1551 | struct compat_arpt_replace tmp; |
1516 | struct xt_table_info *newinfo; | 1552 | struct xt_table_info *newinfo; |
1517 | void *loc_cpu_entry; | 1553 | void *loc_cpu_entry; |
1554 | struct arpt_entry *iter; | ||
1518 | 1555 | ||
1519 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1556 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1520 | return -EFAULT; | 1557 | return -EFAULT; |
@@ -1552,7 +1589,9 @@ static int compat_do_replace(struct net *net, void __user *user, | |||
1552 | return 0; | 1589 | return 0; |
1553 | 1590 | ||
1554 | free_newinfo_untrans: | 1591 | free_newinfo_untrans: |
1555 | ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); | 1592 | xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) |
1593 | if (cleanup_entry(iter, NULL) != 0) | ||
1594 | break; | ||
1556 | free_newinfo: | 1595 | free_newinfo: |
1557 | xt_free_table_info(newinfo); | 1596 | xt_free_table_info(newinfo); |
1558 | return ret; | 1597 | return ret; |
@@ -1636,6 +1675,7 @@ static int compat_copy_entries_to_user(unsigned int total_size, | |||
1636 | int ret = 0; | 1675 | int ret = 0; |
1637 | void *loc_cpu_entry; | 1676 | void *loc_cpu_entry; |
1638 | unsigned int i = 0; | 1677 | unsigned int i = 0; |
1678 | struct arpt_entry *iter; | ||
1639 | 1679 | ||
1640 | counters = alloc_counters(table); | 1680 | counters = alloc_counters(table); |
1641 | if (IS_ERR(counters)) | 1681 | if (IS_ERR(counters)) |
@@ -1645,9 +1685,12 @@ static int compat_copy_entries_to_user(unsigned int total_size, | |||
1645 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; | 1685 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1646 | pos = userptr; | 1686 | pos = userptr; |
1647 | size = total_size; | 1687 | size = total_size; |
1648 | ret = ARPT_ENTRY_ITERATE(loc_cpu_entry, total_size, | 1688 | xt_entry_foreach(iter, loc_cpu_entry, total_size) { |
1649 | compat_copy_entry_to_user, | 1689 | ret = compat_copy_entry_to_user(iter, &pos, |
1650 | &pos, &size, counters, &i); | 1690 | &size, counters, &i); |
1691 | if (ret != 0) | ||
1692 | break; | ||
1693 | } | ||
1651 | vfree(counters); | 1694 | vfree(counters); |
1652 | return ret; | 1695 | return ret; |
1653 | } | 1696 | } |
@@ -1843,13 +1886,15 @@ void arpt_unregister_table(struct xt_table *table) | |||
1843 | struct xt_table_info *private; | 1886 | struct xt_table_info *private; |
1844 | void *loc_cpu_entry; | 1887 | void *loc_cpu_entry; |
1845 | struct module *table_owner = table->me; | 1888 | struct module *table_owner = table->me; |
1889 | struct arpt_entry *iter; | ||
1846 | 1890 | ||
1847 | private = xt_unregister_table(table); | 1891 | private = xt_unregister_table(table); |
1848 | 1892 | ||
1849 | /* Decrease module usage counts and free resources */ | 1893 | /* Decrease module usage counts and free resources */ |
1850 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; | 1894 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1851 | ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, | 1895 | xt_entry_foreach(iter, loc_cpu_entry, private->size) |
1852 | cleanup_entry, NULL); | 1896 | if (cleanup_entry(iter, NULL) != 0) |
1897 | break; | ||
1853 | if (private->number > private->initial_entries) | 1898 | if (private->number > private->initial_entries) |
1854 | module_put(table_owner); | 1899 | module_put(table_owner); |
1855 | xt_free_table_info(private); | 1900 | xt_free_table_info(private); |
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c index e94c18bdfc68..b43280aad8a2 100644 --- a/net/ipv4/netfilter/ip_tables.c +++ b/net/ipv4/netfilter/ip_tables.c | |||
@@ -288,6 +288,7 @@ static void trace_packet(const struct sk_buff *skb, | |||
288 | const void *table_base; | 288 | const void *table_base; |
289 | const struct ipt_entry *root; | 289 | const struct ipt_entry *root; |
290 | const char *hookname, *chainname, *comment; | 290 | const char *hookname, *chainname, *comment; |
291 | const struct ipt_entry *iter; | ||
291 | unsigned int rulenum = 0; | 292 | unsigned int rulenum = 0; |
292 | 293 | ||
293 | table_base = private->entries[smp_processor_id()]; | 294 | table_base = private->entries[smp_processor_id()]; |
@@ -296,10 +297,10 @@ static void trace_packet(const struct sk_buff *skb, | |||
296 | hookname = chainname = hooknames[hook]; | 297 | hookname = chainname = hooknames[hook]; |
297 | comment = comments[NF_IP_TRACE_COMMENT_RULE]; | 298 | comment = comments[NF_IP_TRACE_COMMENT_RULE]; |
298 | 299 | ||
299 | IPT_ENTRY_ITERATE(root, | 300 | xt_entry_foreach(iter, root, private->size - private->hook_entry[hook]) |
300 | private->size - private->hook_entry[hook], | 301 | if (get_chainname_rulenum(iter, e, hookname, |
301 | get_chainname_rulenum, | 302 | &chainname, &comment, &rulenum) != 0) |
302 | e, hookname, &chainname, &comment, &rulenum); | 303 | break; |
303 | 304 | ||
304 | nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo, | 305 | nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo, |
305 | "TRACE: %s:%s:%s:%u ", | 306 | "TRACE: %s:%s:%s:%u ", |
@@ -826,8 +827,9 @@ translate_table(struct net *net, | |||
826 | const unsigned int *hook_entries, | 827 | const unsigned int *hook_entries, |
827 | const unsigned int *underflows) | 828 | const unsigned int *underflows) |
828 | { | 829 | { |
830 | struct ipt_entry *iter; | ||
829 | unsigned int i; | 831 | unsigned int i; |
830 | int ret; | 832 | int ret = 0; |
831 | 833 | ||
832 | newinfo->size = size; | 834 | newinfo->size = size; |
833 | newinfo->number = number; | 835 | newinfo->number = number; |
@@ -841,12 +843,13 @@ translate_table(struct net *net, | |||
841 | duprintf("translate_table: size %u\n", newinfo->size); | 843 | duprintf("translate_table: size %u\n", newinfo->size); |
842 | i = 0; | 844 | i = 0; |
843 | /* Walk through entries, checking offsets. */ | 845 | /* Walk through entries, checking offsets. */ |
844 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, | 846 | xt_entry_foreach(iter, entry0, newinfo->size) { |
845 | check_entry_size_and_hooks, | 847 | ret = check_entry_size_and_hooks(iter, newinfo, entry0, |
846 | newinfo, | 848 | entry0 + size, hook_entries, underflows, |
847 | entry0, | 849 | valid_hooks, &i); |
848 | entry0 + size, | 850 | if (ret != 0) |
849 | hook_entries, underflows, valid_hooks, &i); | 851 | break; |
852 | } | ||
850 | if (ret != 0) | 853 | if (ret != 0) |
851 | return ret; | 854 | return ret; |
852 | 855 | ||
@@ -878,12 +881,16 @@ translate_table(struct net *net, | |||
878 | 881 | ||
879 | /* Finally, each sanity check must pass */ | 882 | /* Finally, each sanity check must pass */ |
880 | i = 0; | 883 | i = 0; |
881 | ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, | 884 | xt_entry_foreach(iter, entry0, newinfo->size) { |
882 | find_check_entry, net, name, size, &i); | 885 | ret = find_check_entry(iter, net, name, size, &i); |
886 | if (ret != 0) | ||
887 | break; | ||
888 | } | ||
883 | 889 | ||
884 | if (ret != 0) { | 890 | if (ret != 0) { |
885 | IPT_ENTRY_ITERATE(entry0, newinfo->size, | 891 | xt_entry_foreach(iter, entry0, newinfo->size) |
886 | cleanup_entry, net, &i); | 892 | if (cleanup_entry(iter, net, &i) != 0) |
893 | break; | ||
887 | return ret; | 894 | return ret; |
888 | } | 895 | } |
889 | 896 | ||
@@ -923,6 +930,7 @@ static void | |||
923 | get_counters(const struct xt_table_info *t, | 930 | get_counters(const struct xt_table_info *t, |
924 | struct xt_counters counters[]) | 931 | struct xt_counters counters[]) |
925 | { | 932 | { |
933 | struct ipt_entry *iter; | ||
926 | unsigned int cpu; | 934 | unsigned int cpu; |
927 | unsigned int i; | 935 | unsigned int i; |
928 | unsigned int curcpu; | 936 | unsigned int curcpu; |
@@ -938,22 +946,18 @@ get_counters(const struct xt_table_info *t, | |||
938 | curcpu = smp_processor_id(); | 946 | curcpu = smp_processor_id(); |
939 | 947 | ||
940 | i = 0; | 948 | i = 0; |
941 | IPT_ENTRY_ITERATE(t->entries[curcpu], | 949 | xt_entry_foreach(iter, t->entries[curcpu], t->size) |
942 | t->size, | 950 | if (set_entry_to_counter(iter, counters, &i) != 0) |
943 | set_entry_to_counter, | 951 | break; |
944 | counters, | ||
945 | &i); | ||
946 | 952 | ||
947 | for_each_possible_cpu(cpu) { | 953 | for_each_possible_cpu(cpu) { |
948 | if (cpu == curcpu) | 954 | if (cpu == curcpu) |
949 | continue; | 955 | continue; |
950 | i = 0; | 956 | i = 0; |
951 | xt_info_wrlock(cpu); | 957 | xt_info_wrlock(cpu); |
952 | IPT_ENTRY_ITERATE(t->entries[cpu], | 958 | xt_entry_foreach(iter, t->entries[cpu], t->size) |
953 | t->size, | 959 | if (add_entry_to_counter(iter, counters, &i) != 0) |
954 | add_entry_to_counter, | 960 | break; |
955 | counters, | ||
956 | &i); | ||
957 | xt_info_wrunlock(cpu); | 961 | xt_info_wrunlock(cpu); |
958 | } | 962 | } |
959 | local_bh_enable(); | 963 | local_bh_enable(); |
@@ -1111,7 +1115,9 @@ static int compat_calc_entry(const struct ipt_entry *e, | |||
1111 | static int compat_table_info(const struct xt_table_info *info, | 1115 | static int compat_table_info(const struct xt_table_info *info, |
1112 | struct xt_table_info *newinfo) | 1116 | struct xt_table_info *newinfo) |
1113 | { | 1117 | { |
1118 | struct ipt_entry *iter; | ||
1114 | void *loc_cpu_entry; | 1119 | void *loc_cpu_entry; |
1120 | int ret = 0; | ||
1115 | 1121 | ||
1116 | if (!newinfo || !info) | 1122 | if (!newinfo || !info) |
1117 | return -EINVAL; | 1123 | return -EINVAL; |
@@ -1120,9 +1126,12 @@ static int compat_table_info(const struct xt_table_info *info, | |||
1120 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); | 1126 | memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); |
1121 | newinfo->initial_entries = 0; | 1127 | newinfo->initial_entries = 0; |
1122 | loc_cpu_entry = info->entries[raw_smp_processor_id()]; | 1128 | loc_cpu_entry = info->entries[raw_smp_processor_id()]; |
1123 | return IPT_ENTRY_ITERATE(loc_cpu_entry, info->size, | 1129 | xt_entry_foreach(iter, loc_cpu_entry, info->size) { |
1124 | compat_calc_entry, info, loc_cpu_entry, | 1130 | ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); |
1125 | newinfo); | 1131 | if (ret != 0) |
1132 | break; | ||
1133 | } | ||
1134 | return ret; | ||
1126 | } | 1135 | } |
1127 | #endif | 1136 | #endif |
1128 | 1137 | ||
@@ -1236,6 +1245,7 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, | |||
1236 | struct xt_table_info *oldinfo; | 1245 | struct xt_table_info *oldinfo; |
1237 | struct xt_counters *counters; | 1246 | struct xt_counters *counters; |
1238 | void *loc_cpu_old_entry; | 1247 | void *loc_cpu_old_entry; |
1248 | struct ipt_entry *iter; | ||
1239 | 1249 | ||
1240 | ret = 0; | 1250 | ret = 0; |
1241 | counters = vmalloc(num_counters * sizeof(struct xt_counters)); | 1251 | counters = vmalloc(num_counters * sizeof(struct xt_counters)); |
@@ -1278,8 +1288,10 @@ __do_replace(struct net *net, const char *name, unsigned int valid_hooks, | |||
1278 | 1288 | ||
1279 | /* Decrease module usage counts and free resource */ | 1289 | /* Decrease module usage counts and free resource */ |
1280 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; | 1290 | loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; |
1281 | IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, | 1291 | xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size) |
1282 | net, NULL); | 1292 | if (cleanup_entry(iter, net, NULL) != 0) |
1293 | break; | ||
1294 | |||
1283 | xt_free_table_info(oldinfo); | 1295 | xt_free_table_info(oldinfo); |
1284 | if (copy_to_user(counters_ptr, counters, | 1296 | if (copy_to_user(counters_ptr, counters, |
1285 | sizeof(struct xt_counters) * num_counters) != 0) | 1297 | sizeof(struct xt_counters) * num_counters) != 0) |
@@ -1304,6 +1316,7 @@ do_replace(struct net *net, const void __user *user, unsigned int len) | |||
1304 | struct ipt_replace tmp; | 1316 | struct ipt_replace tmp; |
1305 | struct xt_table_info *newinfo; | 1317 | struct xt_table_info *newinfo; |
1306 | void *loc_cpu_entry; | 1318 | void *loc_cpu_entry; |
1319 | struct ipt_entry *iter; | ||
1307 | 1320 | ||
1308 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1321 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1309 | return -EFAULT; | 1322 | return -EFAULT; |
@@ -1339,7 +1352,9 @@ do_replace(struct net *net, const void __user *user, unsigned int len) | |||
1339 | return 0; | 1352 | return 0; |
1340 | 1353 | ||
1341 | free_newinfo_untrans: | 1354 | free_newinfo_untrans: |
1342 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); | 1355 | xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) |
1356 | if (cleanup_entry(iter, net, NULL) != 0) | ||
1357 | break; | ||
1343 | free_newinfo: | 1358 | free_newinfo: |
1344 | xt_free_table_info(newinfo); | 1359 | xt_free_table_info(newinfo); |
1345 | return ret; | 1360 | return ret; |
@@ -1373,6 +1388,7 @@ do_add_counters(struct net *net, const void __user *user, | |||
1373 | const struct xt_table_info *private; | 1388 | const struct xt_table_info *private; |
1374 | int ret = 0; | 1389 | int ret = 0; |
1375 | void *loc_cpu_entry; | 1390 | void *loc_cpu_entry; |
1391 | struct ipt_entry *iter; | ||
1376 | #ifdef CONFIG_COMPAT | 1392 | #ifdef CONFIG_COMPAT |
1377 | struct compat_xt_counters_info compat_tmp; | 1393 | struct compat_xt_counters_info compat_tmp; |
1378 | 1394 | ||
@@ -1430,11 +1446,9 @@ do_add_counters(struct net *net, const void __user *user, | |||
1430 | curcpu = smp_processor_id(); | 1446 | curcpu = smp_processor_id(); |
1431 | loc_cpu_entry = private->entries[curcpu]; | 1447 | loc_cpu_entry = private->entries[curcpu]; |
1432 | xt_info_wrlock(curcpu); | 1448 | xt_info_wrlock(curcpu); |
1433 | IPT_ENTRY_ITERATE(loc_cpu_entry, | 1449 | xt_entry_foreach(iter, loc_cpu_entry, private->size) |
1434 | private->size, | 1450 | if (add_counter_to_entry(iter, paddc, &i) != 0) |
1435 | add_counter_to_entry, | 1451 | break; |
1436 | paddc, | ||
1437 | &i); | ||
1438 | xt_info_wrunlock(curcpu); | 1452 | xt_info_wrunlock(curcpu); |
1439 | unlock_up_free: | 1453 | unlock_up_free: |
1440 | local_bh_enable(); | 1454 | local_bh_enable(); |
@@ -1720,8 +1734,10 @@ translate_compat_table(struct net *net, | |||
1720 | unsigned int i, j; | 1734 | unsigned int i, j; |
1721 | struct xt_table_info *newinfo, *info; | 1735 | struct xt_table_info *newinfo, *info; |
1722 | void *pos, *entry0, *entry1; | 1736 | void *pos, *entry0, *entry1; |
1737 | struct compat_ipt_entry *iter0; | ||
1738 | struct ipt_entry *iter1; | ||
1723 | unsigned int size; | 1739 | unsigned int size; |
1724 | int ret; | 1740 | int ret = 0; |
1725 | 1741 | ||
1726 | info = *pinfo; | 1742 | info = *pinfo; |
1727 | entry0 = *pentry0; | 1743 | entry0 = *pentry0; |
@@ -1738,11 +1754,13 @@ translate_compat_table(struct net *net, | |||
1738 | j = 0; | 1754 | j = 0; |
1739 | xt_compat_lock(AF_INET); | 1755 | xt_compat_lock(AF_INET); |
1740 | /* Walk through entries, checking offsets. */ | 1756 | /* Walk through entries, checking offsets. */ |
1741 | ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, | 1757 | xt_entry_foreach(iter0, entry0, total_size) { |
1742 | check_compat_entry_size_and_hooks, | 1758 | ret = check_compat_entry_size_and_hooks(iter0, info, &size, |
1743 | info, &size, entry0, | 1759 | entry0, entry0 + total_size, hook_entries, underflows, |
1744 | entry0 + total_size, | 1760 | &j, name); |
1745 | hook_entries, underflows, &j, name); | 1761 | if (ret != 0) |
1762 | break; | ||
1763 | } | ||
1746 | if (ret != 0) | 1764 | if (ret != 0) |
1747 | goto out_unlock; | 1765 | goto out_unlock; |
1748 | 1766 | ||
@@ -1783,9 +1801,12 @@ translate_compat_table(struct net *net, | |||
1783 | entry1 = newinfo->entries[raw_smp_processor_id()]; | 1801 | entry1 = newinfo->entries[raw_smp_processor_id()]; |
1784 | pos = entry1; | 1802 | pos = entry1; |
1785 | size = total_size; | 1803 | size = total_size; |
1786 | ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, | 1804 | xt_entry_foreach(iter0, entry0, total_size) { |
1787 | compat_copy_entry_from_user, | 1805 | ret = compat_copy_entry_from_user(iter0, &pos, |
1788 | &pos, &size, name, newinfo, entry1); | 1806 | &size, name, newinfo, entry1); |
1807 | if (ret != 0) | ||
1808 | break; | ||
1809 | } | ||
1789 | xt_compat_flush_offsets(AF_INET); | 1810 | xt_compat_flush_offsets(AF_INET); |
1790 | xt_compat_unlock(AF_INET); | 1811 | xt_compat_unlock(AF_INET); |
1791 | if (ret) | 1812 | if (ret) |
@@ -1796,13 +1817,28 @@ translate_compat_table(struct net *net, | |||
1796 | goto free_newinfo; | 1817 | goto free_newinfo; |
1797 | 1818 | ||
1798 | i = 0; | 1819 | i = 0; |
1799 | ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, | 1820 | xt_entry_foreach(iter1, entry1, newinfo->size) { |
1800 | net, name, &i); | 1821 | ret = compat_check_entry(iter1, net, name, &i); |
1822 | if (ret != 0) | ||
1823 | break; | ||
1824 | } | ||
1801 | if (ret) { | 1825 | if (ret) { |
1826 | /* | ||
1827 | * The first i matches need cleanup_entry (calls ->destroy) | ||
1828 | * because they had called ->check already. The other j-i | ||
1829 | * entries need only release. | ||
1830 | */ | ||
1831 | int skip = i; | ||
1802 | j -= i; | 1832 | j -= i; |
1803 | COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, | 1833 | xt_entry_foreach(iter0, entry0, newinfo->size) { |
1804 | compat_release_entry, &j); | 1834 | if (skip-- > 0) |
1805 | IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, net, &i); | 1835 | continue; |
1836 | if (compat_release_entry(iter0, &i) != 0) | ||
1837 | break; | ||
1838 | } | ||
1839 | xt_entry_foreach(iter1, entry1, newinfo->size) | ||
1840 | if (cleanup_entry(iter1, net, &i) != 0) | ||
1841 | break; | ||
1806 | xt_free_table_info(newinfo); | 1842 | xt_free_table_info(newinfo); |
1807 | return ret; | 1843 | return ret; |
1808 | } | 1844 | } |
@@ -1820,7 +1856,9 @@ translate_compat_table(struct net *net, | |||
1820 | free_newinfo: | 1856 | free_newinfo: |
1821 | xt_free_table_info(newinfo); | 1857 | xt_free_table_info(newinfo); |
1822 | out: | 1858 | out: |
1823 | COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); | 1859 | xt_entry_foreach(iter0, entry0, total_size) |
1860 | if (compat_release_entry(iter0, &j) != 0) | ||
1861 | break; | ||
1824 | return ret; | 1862 | return ret; |
1825 | out_unlock: | 1863 | out_unlock: |
1826 | xt_compat_flush_offsets(AF_INET); | 1864 | xt_compat_flush_offsets(AF_INET); |
@@ -1835,6 +1873,7 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len) | |||
1835 | struct compat_ipt_replace tmp; | 1873 | struct compat_ipt_replace tmp; |
1836 | struct xt_table_info *newinfo; | 1874 | struct xt_table_info *newinfo; |
1837 | void *loc_cpu_entry; | 1875 | void *loc_cpu_entry; |
1876 | struct ipt_entry *iter; | ||
1838 | 1877 | ||
1839 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) | 1878 | if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) |
1840 | return -EFAULT; | 1879 | return -EFAULT; |
@@ -1873,7 +1912,9 @@ compat_do_replace(struct net *net, void __user *user, unsigned int len) | |||
1873 | return 0; | 1912 | return 0; |
1874 | 1913 | ||
1875 | free_newinfo_untrans: | 1914 | free_newinfo_untrans: |
1876 | IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); | 1915 | xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) |
1916 | if (cleanup_entry(iter, net, NULL) != 0) | ||
1917 | break; | ||
1877 | free_newinfo: | 1918 | free_newinfo: |
1878 | xt_free_table_info(newinfo); | 1919 | xt_free_table_info(newinfo); |
1879 | return ret; | 1920 | return ret; |
@@ -1922,6 +1963,7 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, | |||
1922 | int ret = 0; | 1963 | int ret = 0; |
1923 | const void *loc_cpu_entry; | 1964 | const void *loc_cpu_entry; |
1924 | unsigned int i = 0; | 1965 | unsigned int i = 0; |
1966 | struct ipt_entry *iter; | ||
1925 | 1967 | ||
1926 | counters = alloc_counters(table); | 1968 | counters = alloc_counters(table); |
1927 | if (IS_ERR(counters)) | 1969 | if (IS_ERR(counters)) |
@@ -1934,9 +1976,12 @@ compat_copy_entries_to_user(unsigned int total_size, struct xt_table *table, | |||
1934 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; | 1976 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
1935 | pos = userptr; | 1977 | pos = userptr; |
1936 | size = total_size; | 1978 | size = total_size; |
1937 | ret = IPT_ENTRY_ITERATE(loc_cpu_entry, total_size, | 1979 | xt_entry_foreach(iter, loc_cpu_entry, total_size) { |
1938 | compat_copy_entry_to_user, | 1980 | ret = compat_copy_entry_to_user(iter, &pos, |
1939 | &pos, &size, counters, &i); | 1981 | &size, counters, &i); |
1982 | if (ret != 0) | ||
1983 | break; | ||
1984 | } | ||
1940 | 1985 | ||
1941 | vfree(counters); | 1986 | vfree(counters); |
1942 | return ret; | 1987 | return ret; |
@@ -2137,12 +2182,15 @@ void ipt_unregister_table(struct net *net, struct xt_table *table) | |||
2137 | struct xt_table_info *private; | 2182 | struct xt_table_info *private; |
2138 | void *loc_cpu_entry; | 2183 | void *loc_cpu_entry; |
2139 | struct module *table_owner = table->me; | 2184 | struct module *table_owner = table->me; |
2185 | struct ipt_entry *iter; | ||
2140 | 2186 | ||
2141 | private = xt_unregister_table(table); | 2187 | private = xt_unregister_table(table); |
2142 | 2188 | ||
2143 | /* Decrease module usage counts and free resources */ | 2189 | /* Decrease module usage counts and free resources */ |
2144 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; | 2190 | loc_cpu_entry = private->entries[raw_smp_processor_id()]; |
2145 | IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, net, NULL); | 2191 | xt_entry_foreach(iter, loc_cpu_entry, private->size) |
2192 | if (cleanup_entry(iter, net, NULL) != 0) | ||
2193 | break; | ||
2146 | if (private->number > private->initial_entries) | 2194 | if (private->number > private->initial_entries) |
2147 | module_put(table_owner); | 2195 | module_put(table_owner); |
2148 | xt_free_table_info(private); | 2196 | xt_free_table_info(private); |