aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorJan Engelhardt <jengelh@medozas.de>2010-02-24 12:32:59 -0500
committerPatrick McHardy <kaber@trash.net>2010-02-24 12:32:59 -0500
commit72b2b1dd77e8feb0b7c0b26dee58f2a1e2c9828c (patch)
tree4289fef5441a1664f60a17cb473d657f77cf1112 /net/ipv4
parent8ccb92ad41cb311e52ad1b1fe77992c7f47a3b63 (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.c151
-rw-r--r--net/ipv4/netfilter/ip_tables.c160
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,
739static void get_counters(const struct xt_table_info *t, 745static 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,
899static int compat_table_info(const struct xt_table_info *info, 902static 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,
1488free_newinfo: 1522free_newinfo:
1489 xt_free_table_info(newinfo); 1523 xt_free_table_info(newinfo);
1490out: 1524out:
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;
1493out_unlock: 1529out_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
923get_counters(const struct xt_table_info *t, 930get_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,
1111static int compat_table_info(const struct xt_table_info *info, 1115static 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,
1820free_newinfo: 1856free_newinfo:
1821 xt_free_table_info(newinfo); 1857 xt_free_table_info(newinfo);
1822out: 1858out:
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;
1825out_unlock: 1863out_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);