Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/kaber/nf-next-2.6

+597 -656
+17
include/linux/netfilter/x_tables.h
··· 120 120 121 121 #define XT_INV_PROTO 0x40 /* Invert the sense of PROTO. */ 122 122 123 + #ifndef __KERNEL__ 123 124 /* fn returns 0 to continue iteration */ 124 125 #define XT_MATCH_ITERATE(type, e, fn, args...) \ 125 126 ({ \ ··· 163 162 /* fn returns 0 to continue iteration */ 164 163 #define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \ 165 164 XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args) 165 + 166 + #endif /* !__KERNEL__ */ 167 + 168 + /* pos is normally a struct ipt_entry/ip6t_entry/etc. */ 169 + #define xt_entry_foreach(pos, ehead, esize) \ 170 + for ((pos) = (typeof(pos))(ehead); \ 171 + (pos) < (typeof(pos))((char *)(ehead) + (esize)); \ 172 + (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset)) 173 + 174 + /* can only be xt_entry_match, so no use of typeof here */ 175 + #define xt_ematch_foreach(pos, entry) \ 176 + for ((pos) = (struct xt_entry_match *)entry->elems; \ 177 + (pos) < (struct xt_entry_match *)((char *)(entry) + \ 178 + (entry)->target_offset); \ 179 + (pos) = (struct xt_entry_match *)((char *)(pos) + \ 180 + (pos)->u.match_size)) 166 181 167 182 #ifdef __KERNEL__ 168 183
+2 -8
include/linux/netfilter_arp/arp_tables.h
··· 211 211 return (void *)e + e->target_offset; 212 212 } 213 213 214 + #ifndef __KERNEL__ 214 215 /* fn returns 0 to continue iteration */ 215 216 #define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ 216 217 XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args) 218 + #endif 217 219 218 220 /* 219 221 * Main firewall chains definitions and global var's definitions. ··· 292 290 } 293 291 294 292 #define COMPAT_ARPT_ALIGN(s) COMPAT_XT_ALIGN(s) 295 - 296 - /* fn returns 0 to continue iteration */ 297 - #define COMPAT_ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ 298 - XT_ENTRY_ITERATE(struct compat_arpt_entry, entries, size, fn, ## args) 299 - 300 - #define COMPAT_ARPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ 301 - XT_ENTRY_ITERATE_CONTINUE(struct compat_arpt_entry, entries, size, n, \ 302 - fn, ## args) 303 293 304 294 #endif /* CONFIG_COMPAT */ 305 295 #endif /*__KERNEL__*/
+2 -13
include/linux/netfilter_ipv4/ip_tables.h
··· 223 223 return (void *)e + e->target_offset; 224 224 } 225 225 226 + #ifndef __KERNEL__ 226 227 /* fn returns 0 to continue iteration */ 227 228 #define IPT_MATCH_ITERATE(e, fn, args...) \ 228 229 XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) ··· 231 230 /* fn returns 0 to continue iteration */ 232 231 #define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ 233 232 XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) 233 + #endif 234 234 235 235 /* 236 236 * Main firewall chains definitions and global var's definitions. ··· 314 312 } 315 313 316 314 #define COMPAT_IPT_ALIGN(s) COMPAT_XT_ALIGN(s) 317 - 318 - /* fn returns 0 to continue iteration */ 319 - #define COMPAT_IPT_MATCH_ITERATE(e, fn, args...) \ 320 - XT_MATCH_ITERATE(struct compat_ipt_entry, e, fn, ## args) 321 - 322 - /* fn returns 0 to continue iteration */ 323 - #define COMPAT_IPT_ENTRY_ITERATE(entries, size, fn, args...) \ 324 - XT_ENTRY_ITERATE(struct compat_ipt_entry, entries, size, fn, ## args) 325 - 326 - /* fn returns 0 to continue iteration */ 327 - #define COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ 328 - XT_ENTRY_ITERATE_CONTINUE(struct compat_ipt_entry, entries, size, n, \ 329 - fn, ## args) 330 315 331 316 #endif /* CONFIG_COMPAT */ 332 317 #endif /*__KERNEL__*/
+2 -12
include/linux/netfilter_ipv6/ip6_tables.h
··· 280 280 return (void *)e + e->target_offset; 281 281 } 282 282 283 + #ifndef __KERNEL__ 283 284 /* fn returns 0 to continue iteration */ 284 285 #define IP6T_MATCH_ITERATE(e, fn, args...) \ 285 286 XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) ··· 288 287 /* fn returns 0 to continue iteration */ 289 288 #define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ 290 289 XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) 290 + #endif 291 291 292 292 /* 293 293 * Main firewall chains definitions and global var's definitions. ··· 342 340 } 343 341 344 342 #define COMPAT_IP6T_ALIGN(s) COMPAT_XT_ALIGN(s) 345 - 346 - /* fn returns 0 to continue iteration */ 347 - #define COMPAT_IP6T_MATCH_ITERATE(e, fn, args...) \ 348 - XT_MATCH_ITERATE(struct compat_ip6t_entry, e, fn, ## args) 349 - 350 - /* fn returns 0 to continue iteration */ 351 - #define COMPAT_IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ 352 - XT_ENTRY_ITERATE(struct compat_ip6t_entry, entries, size, fn, ## args) 353 - 354 - #define COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ 355 - XT_ENTRY_ITERATE_CONTINUE(struct compat_ip6t_entry, entries, size, n, \ 356 - fn, ## args) 357 343 358 344 #endif /* CONFIG_COMPAT */ 359 345 #endif /*__KERNEL__*/
+135 -166
net/ipv4/netfilter/arp_tables.c
··· 512 512 } 513 513 514 514 static inline int 515 - find_check_entry(struct arpt_entry *e, const char *name, unsigned int size, 516 - unsigned int *i) 515 + find_check_entry(struct arpt_entry *e, const char *name, unsigned int size) 517 516 { 518 517 struct arpt_entry_target *t; 519 518 struct xt_target *target; ··· 537 538 ret = check_target(e, name); 538 539 if (ret) 539 540 goto err; 540 - 541 - (*i)++; 542 541 return 0; 543 542 err: 544 543 module_put(t->u.kernel.target->me); ··· 565 568 const unsigned char *limit, 566 569 const unsigned int *hook_entries, 567 570 const unsigned int *underflows, 568 - unsigned int valid_hooks, 569 - unsigned int *i) 571 + unsigned int valid_hooks) 570 572 { 571 573 unsigned int h; 572 574 ··· 602 606 /* Clear counters and comefrom */ 603 607 e->counters = ((struct xt_counters) { 0, 0 }); 604 608 e->comefrom = 0; 605 - 606 - (*i)++; 607 609 return 0; 608 610 } 609 611 610 - static inline int cleanup_entry(struct arpt_entry *e, unsigned int *i) 612 + static inline void cleanup_entry(struct arpt_entry *e) 611 613 { 612 614 struct xt_tgdtor_param par; 613 615 struct arpt_entry_target *t; 614 - 615 - if (i && (*i)-- == 0) 616 - return 1; 617 616 618 617 t = arpt_get_target(e); 619 618 par.target = t->u.kernel.target; ··· 617 626 if (par.target->destroy != NULL) 618 627 par.target->destroy(&par); 619 628 module_put(par.target->me); 620 - return 0; 621 629 } 622 630 623 631 /* Checks and translates the user-supplied table segment (held in 624 632 * newinfo). 625 633 */ 626 - static int translate_table(const char *name, 627 - unsigned int valid_hooks, 628 - struct xt_table_info *newinfo, 629 - void *entry0, 630 - unsigned int size, 631 - unsigned int number, 632 - const unsigned int *hook_entries, 633 - const unsigned int *underflows) 634 + static int translate_table(struct xt_table_info *newinfo, void *entry0, 635 + const struct arpt_replace *repl) 634 636 { 637 + struct arpt_entry *iter; 635 638 unsigned int i; 636 - int ret; 639 + int ret = 0; 637 640 638 - newinfo->size = size; 639 - newinfo->number = number; 641 + newinfo->size = repl->size; 642 + newinfo->number = repl->num_entries; 640 643 641 644 /* Init all hooks to impossible value. */ 642 645 for (i = 0; i < NF_ARP_NUMHOOKS; i++) { ··· 642 657 i = 0; 643 658 644 659 /* Walk through entries, checking offsets. */ 645 - ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, 646 - check_entry_size_and_hooks, 647 - newinfo, 648 - entry0, 649 - entry0 + size, 650 - hook_entries, underflows, valid_hooks, &i); 660 + xt_entry_foreach(iter, entry0, newinfo->size) { 661 + ret = check_entry_size_and_hooks(iter, newinfo, entry0, 662 + entry0 + repl->size, repl->hook_entry, repl->underflow, 663 + repl->valid_hooks); 664 + if (ret != 0) 665 + break; 666 + ++i; 667 + } 651 668 duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); 652 669 if (ret != 0) 653 670 return ret; 654 671 655 - if (i != number) { 672 + if (i != repl->num_entries) { 656 673 duprintf("translate_table: %u not %u entries\n", 657 - i, number); 674 + i, repl->num_entries); 658 675 return -EINVAL; 659 676 } 660 677 661 678 /* Check hooks all assigned */ 662 679 for (i = 0; i < NF_ARP_NUMHOOKS; i++) { 663 680 /* Only hooks which are valid */ 664 - if (!(valid_hooks & (1 << i))) 681 + if (!(repl->valid_hooks & (1 << i))) 665 682 continue; 666 683 if (newinfo->hook_entry[i] == 0xFFFFFFFF) { 667 684 duprintf("Invalid hook entry %u %u\n", 668 - i, hook_entries[i]); 685 + i, repl->hook_entry[i]); 669 686 return -EINVAL; 670 687 } 671 688 if (newinfo->underflow[i] == 0xFFFFFFFF) { 672 689 duprintf("Invalid underflow %u %u\n", 673 - i, underflows[i]); 690 + i, repl->underflow[i]); 674 691 return -EINVAL; 675 692 } 676 693 } 677 694 678 - if (!mark_source_chains(newinfo, valid_hooks, entry0)) { 695 + if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) { 679 696 duprintf("Looping hook\n"); 680 697 return -ELOOP; 681 698 } 682 699 683 700 /* Finally, each sanity check must pass */ 684 701 i = 0; 685 - ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, 686 - find_check_entry, name, size, &i); 702 + xt_entry_foreach(iter, entry0, newinfo->size) { 703 + ret = find_check_entry(iter, repl->name, repl->size); 704 + if (ret != 0) 705 + break; 706 + ++i; 707 + } 687 708 688 709 if (ret != 0) { 689 - ARPT_ENTRY_ITERATE(entry0, newinfo->size, 690 - cleanup_entry, &i); 710 + xt_entry_foreach(iter, entry0, newinfo->size) { 711 + if (i-- == 0) 712 + break; 713 + cleanup_entry(iter); 714 + } 691 715 return ret; 692 716 } 693 717 ··· 709 715 return ret; 710 716 } 711 717 712 - /* Gets counters. */ 713 - static inline int add_entry_to_counter(const struct arpt_entry *e, 714 - struct xt_counters total[], 715 - unsigned int *i) 716 - { 717 - ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); 718 - 719 - (*i)++; 720 - return 0; 721 - } 722 - 723 - static inline int set_entry_to_counter(const struct arpt_entry *e, 724 - struct xt_counters total[], 725 - unsigned int *i) 726 - { 727 - SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); 728 - 729 - (*i)++; 730 - return 0; 731 - } 732 - 733 718 static void get_counters(const struct xt_table_info *t, 734 719 struct xt_counters counters[]) 735 720 { 721 + struct arpt_entry *iter; 736 722 unsigned int cpu; 737 723 unsigned int i; 738 724 unsigned int curcpu; ··· 728 754 curcpu = smp_processor_id(); 729 755 730 756 i = 0; 731 - ARPT_ENTRY_ITERATE(t->entries[curcpu], 732 - t->size, 733 - set_entry_to_counter, 734 - counters, 735 - &i); 757 + xt_entry_foreach(iter, t->entries[curcpu], t->size) { 758 + SET_COUNTER(counters[i], iter->counters.bcnt, 759 + iter->counters.pcnt); 760 + ++i; 761 + } 736 762 737 763 for_each_possible_cpu(cpu) { 738 764 if (cpu == curcpu) 739 765 continue; 740 766 i = 0; 741 767 xt_info_wrlock(cpu); 742 - ARPT_ENTRY_ITERATE(t->entries[cpu], 743 - t->size, 744 - add_entry_to_counter, 745 - counters, 746 - &i); 768 + xt_entry_foreach(iter, t->entries[cpu], t->size) { 769 + ADD_COUNTER(counters[i], iter->counters.bcnt, 770 + iter->counters.pcnt); 771 + ++i; 772 + } 747 773 xt_info_wrunlock(cpu); 748 774 } 749 775 local_bh_enable(); ··· 873 899 static int compat_table_info(const struct xt_table_info *info, 874 900 struct xt_table_info *newinfo) 875 901 { 902 + struct arpt_entry *iter; 876 903 void *loc_cpu_entry; 904 + int ret; 877 905 878 906 if (!newinfo || !info) 879 907 return -EINVAL; ··· 884 908 memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); 885 909 newinfo->initial_entries = 0; 886 910 loc_cpu_entry = info->entries[raw_smp_processor_id()]; 887 - return ARPT_ENTRY_ITERATE(loc_cpu_entry, info->size, 888 - compat_calc_entry, info, loc_cpu_entry, 889 - newinfo); 911 + xt_entry_foreach(iter, loc_cpu_entry, info->size) { 912 + ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); 913 + if (ret != 0) 914 + return ret; 915 + } 916 + return 0; 890 917 } 891 918 #endif 892 919 ··· 1004 1025 struct xt_table_info *oldinfo; 1005 1026 struct xt_counters *counters; 1006 1027 void *loc_cpu_old_entry; 1028 + struct arpt_entry *iter; 1007 1029 1008 1030 ret = 0; 1009 1031 counters = vmalloc_node(num_counters * sizeof(struct xt_counters), ··· 1048 1068 1049 1069 /* Decrease module usage counts and free resource */ 1050 1070 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1051 - ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, 1052 - NULL); 1071 + xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size) 1072 + cleanup_entry(iter); 1053 1073 1054 1074 xt_free_table_info(oldinfo); 1055 1075 if (copy_to_user(counters_ptr, counters, ··· 1075 1095 struct arpt_replace tmp; 1076 1096 struct xt_table_info *newinfo; 1077 1097 void *loc_cpu_entry; 1098 + struct arpt_entry *iter; 1078 1099 1079 1100 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1080 1101 return -EFAULT; ··· 1096 1115 goto free_newinfo; 1097 1116 } 1098 1117 1099 - ret = translate_table(tmp.name, tmp.valid_hooks, 1100 - newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, 1101 - tmp.hook_entry, tmp.underflow); 1118 + ret = translate_table(newinfo, loc_cpu_entry, &tmp); 1102 1119 if (ret != 0) 1103 1120 goto free_newinfo; 1104 1121 ··· 1109 1130 return 0; 1110 1131 1111 1132 free_newinfo_untrans: 1112 - ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1133 + xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) 1134 + cleanup_entry(iter); 1113 1135 free_newinfo: 1114 1136 xt_free_table_info(newinfo); 1115 1137 return ret; 1116 - } 1117 - 1118 - /* We're lazy, and add to the first CPU; overflow works its fey magic 1119 - * and everything is OK. */ 1120 - static int 1121 - add_counter_to_entry(struct arpt_entry *e, 1122 - const struct xt_counters addme[], 1123 - unsigned int *i) 1124 - { 1125 - ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); 1126 - 1127 - (*i)++; 1128 - return 0; 1129 1138 } 1130 1139 1131 1140 static int do_add_counters(struct net *net, const void __user *user, ··· 1130 1163 const struct xt_table_info *private; 1131 1164 int ret = 0; 1132 1165 void *loc_cpu_entry; 1166 + struct arpt_entry *iter; 1133 1167 #ifdef CONFIG_COMPAT 1134 1168 struct compat_xt_counters_info compat_tmp; 1135 1169 ··· 1188 1220 curcpu = smp_processor_id(); 1189 1221 loc_cpu_entry = private->entries[curcpu]; 1190 1222 xt_info_wrlock(curcpu); 1191 - ARPT_ENTRY_ITERATE(loc_cpu_entry, 1192 - private->size, 1193 - add_counter_to_entry, 1194 - paddc, 1195 - &i); 1223 + xt_entry_foreach(iter, loc_cpu_entry, private->size) { 1224 + ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt); 1225 + ++i; 1226 + } 1196 1227 xt_info_wrunlock(curcpu); 1197 1228 unlock_up_free: 1198 1229 local_bh_enable(); ··· 1204 1237 } 1205 1238 1206 1239 #ifdef CONFIG_COMPAT 1207 - static inline int 1208 - compat_release_entry(struct compat_arpt_entry *e, unsigned int *i) 1240 + static inline void compat_release_entry(struct compat_arpt_entry *e) 1209 1241 { 1210 1242 struct arpt_entry_target *t; 1211 1243 1212 - if (i && (*i)-- == 0) 1213 - return 1; 1214 - 1215 1244 t = compat_arpt_get_target(e); 1216 1245 module_put(t->u.kernel.target->me); 1217 - return 0; 1218 1246 } 1219 1247 1220 1248 static inline int ··· 1220 1258 const unsigned char *limit, 1221 1259 const unsigned int *hook_entries, 1222 1260 const unsigned int *underflows, 1223 - unsigned int *i, 1224 1261 const char *name) 1225 1262 { 1226 1263 struct arpt_entry_target *t; ··· 1279 1318 /* Clear counters and comefrom */ 1280 1319 memset(&e->counters, 0, sizeof(e->counters)); 1281 1320 e->comefrom = 0; 1282 - 1283 - (*i)++; 1284 1321 return 0; 1285 1322 1286 1323 release_target: ··· 1322 1363 return ret; 1323 1364 } 1324 1365 1325 - static inline int compat_check_entry(struct arpt_entry *e, const char *name, 1326 - unsigned int *i) 1327 - { 1328 - int ret; 1329 - 1330 - ret = check_target(e, name); 1331 - if (ret) 1332 - return ret; 1333 - 1334 - (*i)++; 1335 - return 0; 1336 - } 1337 - 1338 1366 static int translate_compat_table(const char *name, 1339 1367 unsigned int valid_hooks, 1340 1368 struct xt_table_info **pinfo, ··· 1334 1388 unsigned int i, j; 1335 1389 struct xt_table_info *newinfo, *info; 1336 1390 void *pos, *entry0, *entry1; 1391 + struct compat_arpt_entry *iter0; 1392 + struct arpt_entry *iter1; 1337 1393 unsigned int size; 1338 - int ret; 1394 + int ret = 0; 1339 1395 1340 1396 info = *pinfo; 1341 1397 entry0 = *pentry0; ··· 1354 1406 j = 0; 1355 1407 xt_compat_lock(NFPROTO_ARP); 1356 1408 /* Walk through entries, checking offsets. */ 1357 - ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, 1358 - check_compat_entry_size_and_hooks, 1359 - info, &size, entry0, 1360 - entry0 + total_size, 1361 - hook_entries, underflows, &j, name); 1362 - if (ret != 0) 1363 - goto out_unlock; 1409 + xt_entry_foreach(iter0, entry0, total_size) { 1410 + ret = check_compat_entry_size_and_hooks(iter0, info, &size, 1411 + entry0, entry0 + total_size, hook_entries, underflows, 1412 + name); 1413 + if (ret != 0) 1414 + goto out_unlock; 1415 + ++j; 1416 + } 1364 1417 1365 1418 ret = -EINVAL; 1366 1419 if (j != number) { ··· 1400 1451 entry1 = newinfo->entries[raw_smp_processor_id()]; 1401 1452 pos = entry1; 1402 1453 size = total_size; 1403 - ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, 1404 - compat_copy_entry_from_user, 1405 - &pos, &size, name, newinfo, entry1); 1454 + xt_entry_foreach(iter0, entry0, total_size) { 1455 + ret = compat_copy_entry_from_user(iter0, &pos, 1456 + &size, name, newinfo, entry1); 1457 + if (ret != 0) 1458 + break; 1459 + } 1406 1460 xt_compat_flush_offsets(NFPROTO_ARP); 1407 1461 xt_compat_unlock(NFPROTO_ARP); 1408 1462 if (ret) ··· 1416 1464 goto free_newinfo; 1417 1465 1418 1466 i = 0; 1419 - ret = ARPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, 1420 - name, &i); 1467 + xt_entry_foreach(iter1, entry1, newinfo->size) { 1468 + ret = check_target(iter1, name); 1469 + if (ret != 0) 1470 + break; 1471 + ++i; 1472 + } 1421 1473 if (ret) { 1474 + /* 1475 + * The first i matches need cleanup_entry (calls ->destroy) 1476 + * because they had called ->check already. The other j-i 1477 + * entries need only release. 1478 + */ 1479 + int skip = i; 1422 1480 j -= i; 1423 - COMPAT_ARPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, 1424 - compat_release_entry, &j); 1425 - ARPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); 1481 + xt_entry_foreach(iter0, entry0, newinfo->size) { 1482 + if (skip-- > 0) 1483 + continue; 1484 + if (j-- == 0) 1485 + break; 1486 + compat_release_entry(iter0); 1487 + } 1488 + xt_entry_foreach(iter1, entry1, newinfo->size) { 1489 + if (i-- == 0) 1490 + break; 1491 + cleanup_entry(iter1); 1492 + } 1426 1493 xt_free_table_info(newinfo); 1427 1494 return ret; 1428 1495 } ··· 1459 1488 free_newinfo: 1460 1489 xt_free_table_info(newinfo); 1461 1490 out: 1462 - COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); 1491 + xt_entry_foreach(iter0, entry0, total_size) { 1492 + if (j-- == 0) 1493 + break; 1494 + compat_release_entry(iter0); 1495 + } 1463 1496 return ret; 1464 1497 out_unlock: 1465 1498 xt_compat_flush_offsets(NFPROTO_ARP); ··· 1490 1515 struct compat_arpt_replace tmp; 1491 1516 struct xt_table_info *newinfo; 1492 1517 void *loc_cpu_entry; 1518 + struct arpt_entry *iter; 1493 1519 1494 1520 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1495 1521 return -EFAULT; ··· 1528 1552 return 0; 1529 1553 1530 1554 free_newinfo_untrans: 1531 - ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); 1555 + xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) 1556 + cleanup_entry(iter); 1532 1557 free_newinfo: 1533 1558 xt_free_table_info(newinfo); 1534 1559 return ret; ··· 1563 1586 static int compat_copy_entry_to_user(struct arpt_entry *e, void __user **dstptr, 1564 1587 compat_uint_t *size, 1565 1588 struct xt_counters *counters, 1566 - unsigned int *i) 1589 + unsigned int i) 1567 1590 { 1568 1591 struct arpt_entry_target *t; 1569 1592 struct compat_arpt_entry __user *ce; ··· 1571 1594 compat_uint_t origsize; 1572 1595 int ret; 1573 1596 1574 - ret = -EFAULT; 1575 1597 origsize = *size; 1576 1598 ce = (struct compat_arpt_entry __user *)*dstptr; 1577 - if (copy_to_user(ce, e, sizeof(struct arpt_entry))) 1578 - goto out; 1579 - 1580 - if (copy_to_user(&ce->counters, &counters[*i], sizeof(counters[*i]))) 1581 - goto out; 1599 + if (copy_to_user(ce, e, sizeof(struct arpt_entry)) != 0 || 1600 + copy_to_user(&ce->counters, &counters[i], 1601 + sizeof(counters[i])) != 0) 1602 + return -EFAULT; 1582 1603 1583 1604 *dstptr += sizeof(struct compat_arpt_entry); 1584 1605 *size -= sizeof(struct arpt_entry) - sizeof(struct compat_arpt_entry); ··· 1586 1611 t = arpt_get_target(e); 1587 1612 ret = xt_compat_target_to_user(t, dstptr, size); 1588 1613 if (ret) 1589 - goto out; 1590 - ret = -EFAULT; 1614 + return ret; 1591 1615 next_offset = e->next_offset - (origsize - *size); 1592 - if (put_user(target_offset, &ce->target_offset)) 1593 - goto out; 1594 - if (put_user(next_offset, &ce->next_offset)) 1595 - goto out; 1596 - 1597 - (*i)++; 1616 + if (put_user(target_offset, &ce->target_offset) != 0 || 1617 + put_user(next_offset, &ce->next_offset) != 0) 1618 + return -EFAULT; 1598 1619 return 0; 1599 - out: 1600 - return ret; 1601 1620 } 1602 1621 1603 1622 static int compat_copy_entries_to_user(unsigned int total_size, ··· 1605 1636 int ret = 0; 1606 1637 void *loc_cpu_entry; 1607 1638 unsigned int i = 0; 1639 + struct arpt_entry *iter; 1608 1640 1609 1641 counters = alloc_counters(table); 1610 1642 if (IS_ERR(counters)) ··· 1615 1645 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1616 1646 pos = userptr; 1617 1647 size = total_size; 1618 - ret = ARPT_ENTRY_ITERATE(loc_cpu_entry, total_size, 1619 - compat_copy_entry_to_user, 1620 - &pos, &size, counters, &i); 1648 + xt_entry_foreach(iter, loc_cpu_entry, total_size) { 1649 + ret = compat_copy_entry_to_user(iter, &pos, 1650 + &size, counters, i++); 1651 + if (ret != 0) 1652 + break; 1653 + } 1621 1654 vfree(counters); 1622 1655 return ret; 1623 1656 } ··· 1788 1815 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; 1789 1816 memcpy(loc_cpu_entry, repl->entries, repl->size); 1790 1817 1791 - ret = translate_table(table->name, table->valid_hooks, 1792 - newinfo, loc_cpu_entry, repl->size, 1793 - repl->num_entries, 1794 - repl->hook_entry, 1795 - repl->underflow); 1796 - 1818 + ret = translate_table(newinfo, loc_cpu_entry, repl); 1797 1819 duprintf("arpt_register_table: translate table gives %d\n", ret); 1798 1820 if (ret != 0) 1799 1821 goto out_free; ··· 1811 1843 struct xt_table_info *private; 1812 1844 void *loc_cpu_entry; 1813 1845 struct module *table_owner = table->me; 1846 + struct arpt_entry *iter; 1814 1847 1815 1848 private = xt_unregister_table(table); 1816 1849 1817 1850 /* Decrease module usage counts and free resources */ 1818 1851 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1819 - ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, 1820 - cleanup_entry, NULL); 1852 + xt_entry_foreach(iter, loc_cpu_entry, private->size) 1853 + cleanup_entry(iter); 1821 1854 if (private->number > private->initial_entries) 1822 1855 module_put(table_owner); 1823 1856 xt_free_table_info(private);
+214 -222
net/ipv4/netfilter/ip_tables.c
··· 288 288 const void *table_base; 289 289 const struct ipt_entry *root; 290 290 const char *hookname, *chainname, *comment; 291 + const struct ipt_entry *iter; 291 292 unsigned int rulenum = 0; 292 293 293 294 table_base = private->entries[smp_processor_id()]; ··· 297 296 hookname = chainname = hooknames[hook]; 298 297 comment = comments[NF_IP_TRACE_COMMENT_RULE]; 299 298 300 - IPT_ENTRY_ITERATE(root, 301 - private->size - private->hook_entry[hook], 302 - get_chainname_rulenum, 303 - e, hookname, &chainname, &comment, &rulenum); 299 + xt_entry_foreach(iter, root, private->size - private->hook_entry[hook]) 300 + if (get_chainname_rulenum(iter, e, hookname, 301 + &chainname, &comment, &rulenum) != 0) 302 + break; 304 303 305 304 nf_log_packet(AF_INET, hook, skb, in, out, &trace_loginfo, 306 305 "TRACE: %s:%s:%s:%u ", ··· 366 365 367 366 do { 368 367 const struct ipt_entry_target *t; 368 + const struct xt_entry_match *ematch; 369 369 370 370 IP_NF_ASSERT(e); 371 371 IP_NF_ASSERT(back); 372 372 if (!ip_packet_match(ip, indev, outdev, 373 - &e->ip, mtpar.fragoff) || 374 - IPT_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) { 373 + &e->ip, mtpar.fragoff)) { 374 + no_match: 375 375 e = ipt_next_entry(e); 376 376 continue; 377 377 } 378 + 379 + xt_ematch_foreach(ematch, e) 380 + if (do_match(ematch, skb, &mtpar) != 0) 381 + goto no_match; 378 382 379 383 ADD_COUNTER(e->counters, ntohs(ip->tot_len), 1); 380 384 ··· 572 566 return 1; 573 567 } 574 568 575 - static int 576 - cleanup_match(struct ipt_entry_match *m, struct net *net, unsigned int *i) 569 + static void cleanup_match(struct ipt_entry_match *m, struct net *net) 577 570 { 578 571 struct xt_mtdtor_param par; 579 - 580 - if (i && (*i)-- == 0) 581 - return 1; 582 572 583 573 par.net = net; 584 574 par.match = m->u.kernel.match; ··· 583 581 if (par.match->destroy != NULL) 584 582 par.match->destroy(&par); 585 583 module_put(par.match->me); 586 - return 0; 587 584 } 588 585 589 586 static int ··· 607 606 } 608 607 609 608 static int 610 - check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par, 611 - unsigned int *i) 609 + check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) 612 610 { 613 611 const struct ipt_ip *ip = par->entryinfo; 614 612 int ret; ··· 622 622 par.match->name); 623 623 return ret; 624 624 } 625 - ++*i; 626 625 return 0; 627 626 } 628 627 629 628 static int 630 - find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par, 631 - unsigned int *i) 629 + find_check_match(struct ipt_entry_match *m, struct xt_mtchk_param *par) 632 630 { 633 631 struct xt_match *match; 634 632 int ret; ··· 640 642 } 641 643 m->u.kernel.match = match; 642 644 643 - ret = check_match(m, par, i); 645 + ret = check_match(m, par); 644 646 if (ret) 645 647 goto err; 646 648 ··· 676 678 677 679 static int 678 680 find_check_entry(struct ipt_entry *e, struct net *net, const char *name, 679 - unsigned int size, unsigned int *i) 681 + unsigned int size) 680 682 { 681 683 struct ipt_entry_target *t; 682 684 struct xt_target *target; 683 685 int ret; 684 686 unsigned int j; 685 687 struct xt_mtchk_param mtpar; 688 + struct xt_entry_match *ematch; 686 689 687 690 ret = check_entry(e, name); 688 691 if (ret) ··· 695 696 mtpar.entryinfo = &e->ip; 696 697 mtpar.hook_mask = e->comefrom; 697 698 mtpar.family = NFPROTO_IPV4; 698 - ret = IPT_MATCH_ITERATE(e, find_check_match, &mtpar, &j); 699 - if (ret != 0) 700 - goto cleanup_matches; 699 + xt_ematch_foreach(ematch, e) { 700 + ret = find_check_match(ematch, &mtpar); 701 + if (ret != 0) 702 + goto cleanup_matches; 703 + ++j; 704 + } 701 705 702 706 t = ipt_get_target(e); 703 707 target = try_then_request_module(xt_find_target(AF_INET, ··· 717 715 ret = check_target(e, net, name); 718 716 if (ret) 719 717 goto err; 720 - 721 - (*i)++; 722 718 return 0; 723 719 err: 724 720 module_put(t->u.kernel.target->me); 725 721 cleanup_matches: 726 - IPT_MATCH_ITERATE(e, cleanup_match, net, &j); 722 + xt_ematch_foreach(ematch, e) { 723 + if (j-- == 0) 724 + break; 725 + cleanup_match(ematch, net); 726 + } 727 727 return ret; 728 728 } 729 729 ··· 751 747 const unsigned char *limit, 752 748 const unsigned int *hook_entries, 753 749 const unsigned int *underflows, 754 - unsigned int valid_hooks, 755 - unsigned int *i) 750 + unsigned int valid_hooks) 756 751 { 757 752 unsigned int h; 758 753 ··· 788 785 /* Clear counters and comefrom */ 789 786 e->counters = ((struct xt_counters) { 0, 0 }); 790 787 e->comefrom = 0; 791 - 792 - (*i)++; 793 788 return 0; 794 789 } 795 790 796 - static int 797 - cleanup_entry(struct ipt_entry *e, struct net *net, unsigned int *i) 791 + static void 792 + cleanup_entry(struct ipt_entry *e, struct net *net) 798 793 { 799 794 struct xt_tgdtor_param par; 800 795 struct ipt_entry_target *t; 801 - 802 - if (i && (*i)-- == 0) 803 - return 1; 796 + struct xt_entry_match *ematch; 804 797 805 798 /* Cleanup all matches */ 806 - IPT_MATCH_ITERATE(e, cleanup_match, net, NULL); 799 + xt_ematch_foreach(ematch, e) 800 + cleanup_match(ematch, net); 807 801 t = ipt_get_target(e); 808 802 809 803 par.net = net; ··· 810 810 if (par.target->destroy != NULL) 811 811 par.target->destroy(&par); 812 812 module_put(par.target->me); 813 - return 0; 814 813 } 815 814 816 815 /* Checks and translates the user-supplied table segment (held in 817 816 newinfo) */ 818 817 static int 819 - translate_table(struct net *net, 820 - const char *name, 821 - unsigned int valid_hooks, 822 - struct xt_table_info *newinfo, 823 - void *entry0, 824 - unsigned int size, 825 - unsigned int number, 826 - const unsigned int *hook_entries, 827 - const unsigned int *underflows) 818 + translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, 819 + const struct ipt_replace *repl) 828 820 { 821 + struct ipt_entry *iter; 829 822 unsigned int i; 830 - int ret; 823 + int ret = 0; 831 824 832 - newinfo->size = size; 833 - newinfo->number = number; 825 + newinfo->size = repl->size; 826 + newinfo->number = repl->num_entries; 834 827 835 828 /* Init all hooks to impossible value. */ 836 829 for (i = 0; i < NF_INET_NUMHOOKS; i++) { ··· 834 841 duprintf("translate_table: size %u\n", newinfo->size); 835 842 i = 0; 836 843 /* Walk through entries, checking offsets. */ 837 - ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, 838 - check_entry_size_and_hooks, 839 - newinfo, 840 - entry0, 841 - entry0 + size, 842 - hook_entries, underflows, valid_hooks, &i); 843 - if (ret != 0) 844 - return ret; 844 + xt_entry_foreach(iter, entry0, newinfo->size) { 845 + ret = check_entry_size_and_hooks(iter, newinfo, entry0, 846 + entry0 + repl->size, repl->hook_entry, repl->underflow, 847 + repl->valid_hooks); 848 + if (ret != 0) 849 + return ret; 850 + ++i; 851 + } 845 852 846 - if (i != number) { 853 + if (i != repl->num_entries) { 847 854 duprintf("translate_table: %u not %u entries\n", 848 - i, number); 855 + i, repl->num_entries); 849 856 return -EINVAL; 850 857 } 851 858 852 859 /* Check hooks all assigned */ 853 860 for (i = 0; i < NF_INET_NUMHOOKS; i++) { 854 861 /* Only hooks which are valid */ 855 - if (!(valid_hooks & (1 << i))) 862 + if (!(repl->valid_hooks & (1 << i))) 856 863 continue; 857 864 if (newinfo->hook_entry[i] == 0xFFFFFFFF) { 858 865 duprintf("Invalid hook entry %u %u\n", 859 - i, hook_entries[i]); 866 + i, repl->hook_entry[i]); 860 867 return -EINVAL; 861 868 } 862 869 if (newinfo->underflow[i] == 0xFFFFFFFF) { 863 870 duprintf("Invalid underflow %u %u\n", 864 - i, underflows[i]); 871 + i, repl->underflow[i]); 865 872 return -EINVAL; 866 873 } 867 874 } 868 875 869 - if (!mark_source_chains(newinfo, valid_hooks, entry0)) 876 + if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) 870 877 return -ELOOP; 871 878 872 879 /* Finally, each sanity check must pass */ 873 880 i = 0; 874 - ret = IPT_ENTRY_ITERATE(entry0, newinfo->size, 875 - find_check_entry, net, name, size, &i); 881 + xt_entry_foreach(iter, entry0, newinfo->size) { 882 + ret = find_check_entry(iter, net, repl->name, repl->size); 883 + if (ret != 0) 884 + break; 885 + ++i; 886 + } 876 887 877 888 if (ret != 0) { 878 - IPT_ENTRY_ITERATE(entry0, newinfo->size, 879 - cleanup_entry, net, &i); 889 + xt_entry_foreach(iter, entry0, newinfo->size) { 890 + if (i-- == 0) 891 + break; 892 + cleanup_entry(iter, net); 893 + } 880 894 return ret; 881 895 } 882 896 ··· 896 896 return ret; 897 897 } 898 898 899 - /* Gets counters. */ 900 - static inline int 901 - add_entry_to_counter(const struct ipt_entry *e, 902 - struct xt_counters total[], 903 - unsigned int *i) 904 - { 905 - ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); 906 - 907 - (*i)++; 908 - return 0; 909 - } 910 - 911 - static inline int 912 - set_entry_to_counter(const struct ipt_entry *e, 913 - struct ipt_counters total[], 914 - unsigned int *i) 915 - { 916 - SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); 917 - 918 - (*i)++; 919 - return 0; 920 - } 921 - 922 899 static void 923 900 get_counters(const struct xt_table_info *t, 924 901 struct xt_counters counters[]) 925 902 { 903 + struct ipt_entry *iter; 926 904 unsigned int cpu; 927 905 unsigned int i; 928 906 unsigned int curcpu; ··· 916 938 curcpu = smp_processor_id(); 917 939 918 940 i = 0; 919 - IPT_ENTRY_ITERATE(t->entries[curcpu], 920 - t->size, 921 - set_entry_to_counter, 922 - counters, 923 - &i); 941 + xt_entry_foreach(iter, t->entries[curcpu], t->size) { 942 + SET_COUNTER(counters[i], iter->counters.bcnt, 943 + iter->counters.pcnt); 944 + ++i; 945 + } 924 946 925 947 for_each_possible_cpu(cpu) { 926 948 if (cpu == curcpu) 927 949 continue; 928 950 i = 0; 929 951 xt_info_wrlock(cpu); 930 - IPT_ENTRY_ITERATE(t->entries[cpu], 931 - t->size, 932 - add_entry_to_counter, 933 - counters, 934 - &i); 952 + xt_entry_foreach(iter, t->entries[cpu], t->size) { 953 + ADD_COUNTER(counters[i], iter->counters.bcnt, 954 + iter->counters.pcnt); 955 + ++i; /* macro does multi eval of i */ 956 + } 935 957 xt_info_wrunlock(cpu); 936 958 } 937 959 local_bh_enable(); ··· 1050 1072 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; 1051 1073 } 1052 1074 1053 - static inline int 1054 - compat_calc_match(const struct ipt_entry_match *m, int *size) 1055 - { 1056 - *size += xt_compat_match_offset(m->u.kernel.match); 1057 - return 0; 1058 - } 1059 - 1060 1075 static int compat_calc_entry(const struct ipt_entry *e, 1061 1076 const struct xt_table_info *info, 1062 1077 const void *base, struct xt_table_info *newinfo) 1063 1078 { 1079 + const struct xt_entry_match *ematch; 1064 1080 const struct ipt_entry_target *t; 1065 1081 unsigned int entry_offset; 1066 1082 int off, i, ret; 1067 1083 1068 1084 off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); 1069 1085 entry_offset = (void *)e - base; 1070 - IPT_MATCH_ITERATE(e, compat_calc_match, &off); 1086 + xt_ematch_foreach(ematch, e) 1087 + off += xt_compat_match_offset(ematch->u.kernel.match); 1071 1088 t = ipt_get_target_c(e); 1072 1089 off += xt_compat_target_offset(t->u.kernel.target); 1073 1090 newinfo->size -= off; ··· 1084 1111 static int compat_table_info(const struct xt_table_info *info, 1085 1112 struct xt_table_info *newinfo) 1086 1113 { 1114 + struct ipt_entry *iter; 1087 1115 void *loc_cpu_entry; 1116 + int ret; 1088 1117 1089 1118 if (!newinfo || !info) 1090 1119 return -EINVAL; ··· 1095 1120 memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); 1096 1121 newinfo->initial_entries = 0; 1097 1122 loc_cpu_entry = info->entries[raw_smp_processor_id()]; 1098 - return IPT_ENTRY_ITERATE(loc_cpu_entry, info->size, 1099 - compat_calc_entry, info, loc_cpu_entry, 1100 - newinfo); 1123 + xt_entry_foreach(iter, loc_cpu_entry, info->size) { 1124 + ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); 1125 + if (ret != 0) 1126 + return ret; 1127 + } 1128 + return 0; 1101 1129 } 1102 1130 #endif 1103 1131 ··· 1214 1236 struct xt_table_info *oldinfo; 1215 1237 struct xt_counters *counters; 1216 1238 void *loc_cpu_old_entry; 1239 + struct ipt_entry *iter; 1217 1240 1218 1241 ret = 0; 1219 1242 counters = vmalloc(num_counters * sizeof(struct xt_counters)); ··· 1257 1278 1258 1279 /* Decrease module usage counts and free resource */ 1259 1280 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1260 - IPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, 1261 - net, NULL); 1281 + xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size) 1282 + cleanup_entry(iter, net); 1283 + 1262 1284 xt_free_table_info(oldinfo); 1263 1285 if (copy_to_user(counters_ptr, counters, 1264 1286 sizeof(struct xt_counters) * num_counters) != 0) ··· 1284 1304 struct ipt_replace tmp; 1285 1305 struct xt_table_info *newinfo; 1286 1306 void *loc_cpu_entry; 1307 + struct ipt_entry *iter; 1287 1308 1288 1309 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1289 1310 return -EFAULT; ··· 1305 1324 goto free_newinfo; 1306 1325 } 1307 1326 1308 - ret = translate_table(net, tmp.name, tmp.valid_hooks, 1309 - newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, 1310 - tmp.hook_entry, tmp.underflow); 1327 + ret = translate_table(net, newinfo, loc_cpu_entry, &tmp); 1311 1328 if (ret != 0) 1312 1329 goto free_newinfo; 1313 1330 ··· 1318 1339 return 0; 1319 1340 1320 1341 free_newinfo_untrans: 1321 - IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); 1342 + xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) 1343 + cleanup_entry(iter, net); 1322 1344 free_newinfo: 1323 1345 xt_free_table_info(newinfo); 1324 1346 return ret; 1325 - } 1326 - 1327 - /* We're lazy, and add to the first CPU; overflow works its fey magic 1328 - * and everything is OK. */ 1329 - static int 1330 - add_counter_to_entry(struct ipt_entry *e, 1331 - const struct xt_counters addme[], 1332 - unsigned int *i) 1333 - { 1334 - ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); 1335 - 1336 - (*i)++; 1337 - return 0; 1338 1347 } 1339 1348 1340 1349 static int ··· 1340 1373 const struct xt_table_info *private; 1341 1374 int ret = 0; 1342 1375 void *loc_cpu_entry; 1376 + struct ipt_entry *iter; 1343 1377 #ifdef CONFIG_COMPAT 1344 1378 struct compat_xt_counters_info compat_tmp; 1345 1379 ··· 1398 1430 curcpu = smp_processor_id(); 1399 1431 loc_cpu_entry = private->entries[curcpu]; 1400 1432 xt_info_wrlock(curcpu); 1401 - IPT_ENTRY_ITERATE(loc_cpu_entry, 1402 - private->size, 1403 - add_counter_to_entry, 1404 - paddc, 1405 - &i); 1433 + xt_entry_foreach(iter, loc_cpu_entry, private->size) { 1434 + ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt); 1435 + ++i; 1436 + } 1406 1437 xt_info_wrunlock(curcpu); 1407 1438 unlock_up_free: 1408 1439 local_bh_enable(); ··· 1429 1462 static int 1430 1463 compat_copy_entry_to_user(struct ipt_entry *e, void __user **dstptr, 1431 1464 unsigned int *size, struct xt_counters *counters, 1432 - unsigned int *i) 1465 + unsigned int i) 1433 1466 { 1434 1467 struct ipt_entry_target *t; 1435 1468 struct compat_ipt_entry __user *ce; 1436 1469 u_int16_t target_offset, next_offset; 1437 1470 compat_uint_t origsize; 1438 - int ret; 1471 + const struct xt_entry_match *ematch; 1472 + int ret = 0; 1439 1473 1440 - ret = -EFAULT; 1441 1474 origsize = *size; 1442 1475 ce = (struct compat_ipt_entry __user *)*dstptr; 1443 - if (copy_to_user(ce, e, sizeof(struct ipt_entry))) 1444 - goto out; 1445 - 1446 - if (copy_to_user(&ce->counters, &counters[*i], sizeof(counters[*i]))) 1447 - goto out; 1476 + if (copy_to_user(ce, e, sizeof(struct ipt_entry)) != 0 || 1477 + copy_to_user(&ce->counters, &counters[i], 1478 + sizeof(counters[i])) != 0) 1479 + return -EFAULT; 1448 1480 1449 1481 *dstptr += sizeof(struct compat_ipt_entry); 1450 1482 *size -= sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); 1451 1483 1452 - ret = IPT_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size); 1484 + xt_ematch_foreach(ematch, e) { 1485 + ret = xt_compat_match_to_user(ematch, dstptr, size); 1486 + if (ret != 0) 1487 + return ret; 1488 + } 1453 1489 target_offset = e->target_offset - (origsize - *size); 1454 - if (ret) 1455 - goto out; 1456 1490 t = ipt_get_target(e); 1457 1491 ret = xt_compat_target_to_user(t, dstptr, size); 1458 1492 if (ret) 1459 - goto out; 1460 - ret = -EFAULT; 1493 + return ret; 1461 1494 next_offset = e->next_offset - (origsize - *size); 1462 - if (put_user(target_offset, &ce->target_offset)) 1463 - goto out; 1464 - if (put_user(next_offset, &ce->next_offset)) 1465 - goto out; 1466 - 1467 - (*i)++; 1495 + if (put_user(target_offset, &ce->target_offset) != 0 || 1496 + put_user(next_offset, &ce->next_offset) != 0) 1497 + return -EFAULT; 1468 1498 return 0; 1469 - out: 1470 - return ret; 1471 1499 } 1472 1500 1473 1501 static int ··· 1470 1508 const char *name, 1471 1509 const struct ipt_ip *ip, 1472 1510 unsigned int hookmask, 1473 - int *size, unsigned int *i) 1511 + int *size) 1474 1512 { 1475 1513 struct xt_match *match; 1476 1514 ··· 1484 1522 } 1485 1523 m->u.kernel.match = match; 1486 1524 *size += xt_compat_match_offset(match); 1487 - 1488 - (*i)++; 1489 1525 return 0; 1490 1526 } 1491 1527 1492 - static int 1493 - compat_release_match(struct ipt_entry_match *m, unsigned int *i) 1494 - { 1495 - if (i && (*i)-- == 0) 1496 - return 1; 1497 - 1498 - module_put(m->u.kernel.match->me); 1499 - return 0; 1500 - } 1501 - 1502 - static int 1503 - compat_release_entry(struct compat_ipt_entry *e, unsigned int *i) 1528 + static void compat_release_entry(struct compat_ipt_entry *e) 1504 1529 { 1505 1530 struct ipt_entry_target *t; 1506 - 1507 - if (i && (*i)-- == 0) 1508 - return 1; 1531 + struct xt_entry_match *ematch; 1509 1532 1510 1533 /* Cleanup all matches */ 1511 - COMPAT_IPT_MATCH_ITERATE(e, compat_release_match, NULL); 1534 + xt_ematch_foreach(ematch, e) 1535 + module_put(ematch->u.kernel.match->me); 1512 1536 t = compat_ipt_get_target(e); 1513 1537 module_put(t->u.kernel.target->me); 1514 - return 0; 1515 1538 } 1516 1539 1517 1540 static int ··· 1507 1560 const unsigned char *limit, 1508 1561 const unsigned int *hook_entries, 1509 1562 const unsigned int *underflows, 1510 - unsigned int *i, 1511 1563 const char *name) 1512 1564 { 1565 + struct xt_entry_match *ematch; 1513 1566 struct ipt_entry_target *t; 1514 1567 struct xt_target *target; 1515 1568 unsigned int entry_offset; ··· 1538 1591 off = sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); 1539 1592 entry_offset = (void *)e - (void *)base; 1540 1593 j = 0; 1541 - ret = COMPAT_IPT_MATCH_ITERATE(e, compat_find_calc_match, name, 1542 - &e->ip, e->comefrom, &off, &j); 1543 - if (ret != 0) 1544 - goto release_matches; 1594 + xt_ematch_foreach(ematch, e) { 1595 + ret = compat_find_calc_match(ematch, name, 1596 + &e->ip, e->comefrom, &off); 1597 + if (ret != 0) 1598 + goto release_matches; 1599 + ++j; 1600 + } 1545 1601 1546 1602 t = compat_ipt_get_target(e); 1547 1603 target = try_then_request_module(xt_find_target(AF_INET, ··· 1576 1626 /* Clear counters and comefrom */ 1577 1627 memset(&e->counters, 0, sizeof(e->counters)); 1578 1628 e->comefrom = 0; 1579 - 1580 - (*i)++; 1581 1629 return 0; 1582 1630 1583 1631 out: 1584 1632 module_put(t->u.kernel.target->me); 1585 1633 release_matches: 1586 - IPT_MATCH_ITERATE(e, compat_release_match, &j); 1634 + xt_ematch_foreach(ematch, e) { 1635 + if (j-- == 0) 1636 + break; 1637 + module_put(ematch->u.kernel.match->me); 1638 + } 1587 1639 return ret; 1588 1640 } 1589 1641 ··· 1599 1647 struct ipt_entry *de; 1600 1648 unsigned int origsize; 1601 1649 int ret, h; 1650 + struct xt_entry_match *ematch; 1602 1651 1603 1652 ret = 0; 1604 1653 origsize = *size; ··· 1610 1657 *dstptr += sizeof(struct ipt_entry); 1611 1658 *size += sizeof(struct ipt_entry) - sizeof(struct compat_ipt_entry); 1612 1659 1613 - ret = COMPAT_IPT_MATCH_ITERATE(e, xt_compat_match_from_user, 1614 - dstptr, size); 1615 - if (ret) 1616 - return ret; 1660 + xt_ematch_foreach(ematch, e) { 1661 + ret = xt_compat_match_from_user(ematch, dstptr, size); 1662 + if (ret != 0) 1663 + return ret; 1664 + } 1617 1665 de->target_offset = e->target_offset - (origsize - *size); 1618 1666 t = compat_ipt_get_target(e); 1619 1667 target = t->u.kernel.target; ··· 1631 1677 } 1632 1678 1633 1679 static int 1634 - compat_check_entry(struct ipt_entry *e, struct net *net, const char *name, 1635 - unsigned int *i) 1680 + compat_check_entry(struct ipt_entry *e, struct net *net, const char *name) 1636 1681 { 1682 + struct xt_entry_match *ematch; 1637 1683 struct xt_mtchk_param mtpar; 1638 1684 unsigned int j; 1639 - int ret; 1685 + int ret = 0; 1640 1686 1641 1687 j = 0; 1642 1688 mtpar.net = net; ··· 1644 1690 mtpar.entryinfo = &e->ip; 1645 1691 mtpar.hook_mask = e->comefrom; 1646 1692 mtpar.family = NFPROTO_IPV4; 1647 - ret = IPT_MATCH_ITERATE(e, check_match, &mtpar, &j); 1648 - if (ret) 1649 - goto cleanup_matches; 1693 + xt_ematch_foreach(ematch, e) { 1694 + ret = check_match(ematch, &mtpar); 1695 + if (ret != 0) 1696 + goto cleanup_matches; 1697 + ++j; 1698 + } 1650 1699 1651 1700 ret = check_target(e, net, name); 1652 1701 if (ret) 1653 1702 goto cleanup_matches; 1654 - 1655 - (*i)++; 1656 1703 return 0; 1657 1704 1658 1705 cleanup_matches: 1659 - IPT_MATCH_ITERATE(e, cleanup_match, net, &j); 1706 + xt_ematch_foreach(ematch, e) { 1707 + if (j-- == 0) 1708 + break; 1709 + cleanup_match(ematch, net); 1710 + } 1660 1711 return ret; 1661 1712 } 1662 1713 ··· 1679 1720 unsigned int i, j; 1680 1721 struct xt_table_info *newinfo, *info; 1681 1722 void *pos, *entry0, *entry1; 1723 + struct compat_ipt_entry *iter0; 1724 + struct ipt_entry *iter1; 1682 1725 unsigned int size; 1683 1726 int ret; 1684 1727 ··· 1699 1738 j = 0; 1700 1739 xt_compat_lock(AF_INET); 1701 1740 /* Walk through entries, checking offsets. */ 1702 - ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, 1703 - check_compat_entry_size_and_hooks, 1704 - info, &size, entry0, 1705 - entry0 + total_size, 1706 - hook_entries, underflows, &j, name); 1707 - if (ret != 0) 1708 - goto out_unlock; 1741 + xt_entry_foreach(iter0, entry0, total_size) { 1742 + ret = check_compat_entry_size_and_hooks(iter0, info, &size, 1743 + entry0, entry0 + total_size, hook_entries, underflows, 1744 + name); 1745 + if (ret != 0) 1746 + goto out_unlock; 1747 + ++j; 1748 + } 1709 1749 1710 1750 ret = -EINVAL; 1711 1751 if (j != number) { ··· 1745 1783 entry1 = newinfo->entries[raw_smp_processor_id()]; 1746 1784 pos = entry1; 1747 1785 size = total_size; 1748 - ret = COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, 1749 - compat_copy_entry_from_user, 1750 - &pos, &size, name, newinfo, entry1); 1786 + xt_entry_foreach(iter0, entry0, total_size) { 1787 + ret = compat_copy_entry_from_user(iter0, &pos, 1788 + &size, name, newinfo, entry1); 1789 + if (ret != 0) 1790 + break; 1791 + } 1751 1792 xt_compat_flush_offsets(AF_INET); 1752 1793 xt_compat_unlock(AF_INET); 1753 1794 if (ret) ··· 1761 1796 goto free_newinfo; 1762 1797 1763 1798 i = 0; 1764 - ret = IPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, 1765 - net, name, &i); 1799 + xt_entry_foreach(iter1, entry1, newinfo->size) { 1800 + ret = compat_check_entry(iter1, net, name); 1801 + if (ret != 0) 1802 + break; 1803 + ++i; 1804 + } 1766 1805 if (ret) { 1806 + /* 1807 + * The first i matches need cleanup_entry (calls ->destroy) 1808 + * because they had called ->check already. The other j-i 1809 + * entries need only release. 1810 + */ 1811 + int skip = i; 1767 1812 j -= i; 1768 - COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, 1769 - compat_release_entry, &j); 1770 - IPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, net, &i); 1813 + xt_entry_foreach(iter0, entry0, newinfo->size) { 1814 + if (skip-- > 0) 1815 + continue; 1816 + if (j-- == 0) 1817 + break; 1818 + compat_release_entry(iter0); 1819 + } 1820 + xt_entry_foreach(iter1, entry1, newinfo->size) { 1821 + if (i-- == 0) 1822 + break; 1823 + cleanup_entry(iter1, net); 1824 + } 1771 1825 xt_free_table_info(newinfo); 1772 1826 return ret; 1773 1827 } ··· 1804 1820 free_newinfo: 1805 1821 xt_free_table_info(newinfo); 1806 1822 out: 1807 - COMPAT_IPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); 1823 + xt_entry_foreach(iter0, entry0, total_size) { 1824 + if (j-- == 0) 1825 + break; 1826 + compat_release_entry(iter0); 1827 + } 1808 1828 return ret; 1809 1829 out_unlock: 1810 1830 xt_compat_flush_offsets(AF_INET); ··· 1823 1835 struct compat_ipt_replace tmp; 1824 1836 struct xt_table_info *newinfo; 1825 1837 void *loc_cpu_entry; 1838 + struct ipt_entry *iter; 1826 1839 1827 1840 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1828 1841 return -EFAULT; ··· 1862 1873 return 0; 1863 1874 1864 1875 free_newinfo_untrans: 1865 - IPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); 1876 + xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) 1877 + cleanup_entry(iter, net); 1866 1878 free_newinfo: 1867 1879 xt_free_table_info(newinfo); 1868 1880 return ret; ··· 1912 1922 int ret = 0; 1913 1923 const void *loc_cpu_entry; 1914 1924 unsigned int i = 0; 1925 + struct ipt_entry *iter; 1915 1926 1916 1927 counters = alloc_counters(table); 1917 1928 if (IS_ERR(counters)) ··· 1925 1934 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1926 1935 pos = userptr; 1927 1936 size = total_size; 1928 - ret = IPT_ENTRY_ITERATE(loc_cpu_entry, total_size, 1929 - compat_copy_entry_to_user, 1930 - &pos, &size, counters, &i); 1937 + xt_entry_foreach(iter, loc_cpu_entry, total_size) { 1938 + ret = compat_copy_entry_to_user(iter, &pos, 1939 + &size, counters, i++); 1940 + if (ret != 0) 1941 + break; 1942 + } 1931 1943 1932 1944 vfree(counters); 1933 1945 return ret; ··· 2104 2110 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; 2105 2111 memcpy(loc_cpu_entry, repl->entries, repl->size); 2106 2112 2107 - ret = translate_table(net, table->name, table->valid_hooks, 2108 - newinfo, loc_cpu_entry, repl->size, 2109 - repl->num_entries, 2110 - repl->hook_entry, 2111 - repl->underflow); 2113 + ret = translate_table(net, newinfo, loc_cpu_entry, repl); 2112 2114 if (ret != 0) 2113 2115 goto out_free; 2114 2116 ··· 2127 2137 struct xt_table_info *private; 2128 2138 void *loc_cpu_entry; 2129 2139 struct module *table_owner = table->me; 2140 + struct ipt_entry *iter; 2130 2141 2131 2142 private = xt_unregister_table(table); 2132 2143 2133 2144 /* Decrease module usage counts and free resources */ 2134 2145 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 2135 - IPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, net, NULL); 2146 + xt_entry_foreach(iter, loc_cpu_entry, private->size) 2147 + cleanup_entry(iter, net); 2136 2148 if (private->number > private->initial_entries) 2137 2149 module_put(table_owner); 2138 2150 xt_free_table_info(private);
+214 -222
net/ipv6/netfilter/ip6_tables.c
··· 318 318 const void *table_base; 319 319 const struct ip6t_entry *root; 320 320 const char *hookname, *chainname, *comment; 321 + const struct ip6t_entry *iter; 321 322 unsigned int rulenum = 0; 322 323 323 324 table_base = private->entries[smp_processor_id()]; ··· 327 326 hookname = chainname = hooknames[hook]; 328 327 comment = comments[NF_IP6_TRACE_COMMENT_RULE]; 329 328 330 - IP6T_ENTRY_ITERATE(root, 331 - private->size - private->hook_entry[hook], 332 - get_chainname_rulenum, 333 - e, hookname, &chainname, &comment, &rulenum); 329 + xt_entry_foreach(iter, root, private->size - private->hook_entry[hook]) 330 + if (get_chainname_rulenum(iter, e, hookname, 331 + &chainname, &comment, &rulenum) != 0) 332 + break; 334 333 335 334 nf_log_packet(AF_INET6, hook, skb, in, out, &trace_loginfo, 336 335 "TRACE: %s:%s:%s:%u ", ··· 393 392 394 393 do { 395 394 const struct ip6t_entry_target *t; 395 + const struct xt_entry_match *ematch; 396 396 397 397 IP_NF_ASSERT(e); 398 398 IP_NF_ASSERT(back); 399 399 if (!ip6_packet_match(skb, indev, outdev, &e->ipv6, 400 - &mtpar.thoff, &mtpar.fragoff, &hotdrop) || 401 - IP6T_MATCH_ITERATE(e, do_match, skb, &mtpar) != 0) { 400 + &mtpar.thoff, &mtpar.fragoff, &hotdrop)) { 401 + no_match: 402 402 e = ip6t_next_entry(e); 403 403 continue; 404 404 } 405 + 406 + xt_ematch_foreach(ematch, e) 407 + if (do_match(ematch, skb, &mtpar) != 0) 408 + goto no_match; 405 409 406 410 ADD_COUNTER(e->counters, 407 411 ntohs(ipv6_hdr(skb)->payload_len) + ··· 603 597 return 1; 604 598 } 605 599 606 - static int 607 - cleanup_match(struct ip6t_entry_match *m, struct net *net, unsigned int *i) 600 + static void cleanup_match(struct ip6t_entry_match *m, struct net *net) 608 601 { 609 602 struct xt_mtdtor_param par; 610 - 611 - if (i && (*i)-- == 0) 612 - return 1; 613 603 614 604 par.net = net; 615 605 par.match = m->u.kernel.match; ··· 614 612 if (par.match->destroy != NULL) 615 613 par.match->destroy(&par); 616 614 module_put(par.match->me); 617 - return 0; 618 615 } 619 616 620 617 static int ··· 637 636 return 0; 638 637 } 639 638 640 - static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par, 641 - unsigned int *i) 639 + static int check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) 642 640 { 643 641 const struct ip6t_ip6 *ipv6 = par->entryinfo; 644 642 int ret; ··· 652 652 par.match->name); 653 653 return ret; 654 654 } 655 - ++*i; 656 655 return 0; 657 656 } 658 657 659 658 static int 660 - find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par, 661 - unsigned int *i) 659 + find_check_match(struct ip6t_entry_match *m, struct xt_mtchk_param *par) 662 660 { 663 661 struct xt_match *match; 664 662 int ret; ··· 670 672 } 671 673 m->u.kernel.match = match; 672 674 673 - ret = check_match(m, par, i); 675 + ret = check_match(m, par); 674 676 if (ret) 675 677 goto err; 676 678 ··· 707 709 708 710 static int 709 711 find_check_entry(struct ip6t_entry *e, struct net *net, const char *name, 710 - unsigned int size, unsigned int *i) 712 + unsigned int size) 711 713 { 712 714 struct ip6t_entry_target *t; 713 715 struct xt_target *target; 714 716 int ret; 715 717 unsigned int j; 716 718 struct xt_mtchk_param mtpar; 719 + struct xt_entry_match *ematch; 717 720 718 721 ret = check_entry(e, name); 719 722 if (ret) ··· 726 727 mtpar.entryinfo = &e->ipv6; 727 728 mtpar.hook_mask = e->comefrom; 728 729 mtpar.family = NFPROTO_IPV6; 729 - ret = IP6T_MATCH_ITERATE(e, find_check_match, &mtpar, &j); 730 - if (ret != 0) 731 - goto cleanup_matches; 730 + xt_ematch_foreach(ematch, e) { 731 + ret = find_check_match(ematch, &mtpar); 732 + if (ret != 0) 733 + goto cleanup_matches; 734 + ++j; 735 + } 732 736 733 737 t = ip6t_get_target(e); 734 738 target = try_then_request_module(xt_find_target(AF_INET6, ··· 748 746 ret = check_target(e, net, name); 749 747 if (ret) 750 748 goto err; 751 - 752 - (*i)++; 753 749 return 0; 754 750 err: 755 751 module_put(t->u.kernel.target->me); 756 752 cleanup_matches: 757 - IP6T_MATCH_ITERATE(e, cleanup_match, net, &j); 753 + xt_ematch_foreach(ematch, e) { 754 + if (j-- == 0) 755 + break; 756 + cleanup_match(ematch, net); 757 + } 758 758 return ret; 759 759 } 760 760 ··· 782 778 const unsigned char *limit, 783 779 const unsigned int *hook_entries, 784 780 const unsigned int *underflows, 785 - unsigned int valid_hooks, 786 - unsigned int *i) 781 + unsigned int valid_hooks) 787 782 { 788 783 unsigned int h; 789 784 ··· 819 816 /* Clear counters and comefrom */ 820 817 e->counters = ((struct xt_counters) { 0, 0 }); 821 818 e->comefrom = 0; 822 - 823 - (*i)++; 824 819 return 0; 825 820 } 826 821 827 - static int 828 - cleanup_entry(struct ip6t_entry *e, struct net *net, unsigned int *i) 822 + static void cleanup_entry(struct ip6t_entry *e, struct net *net) 829 823 { 830 824 struct xt_tgdtor_param par; 831 825 struct ip6t_entry_target *t; 832 - 833 - if (i && (*i)-- == 0) 834 - return 1; 826 + struct xt_entry_match *ematch; 835 827 836 828 /* Cleanup all matches */ 837 - IP6T_MATCH_ITERATE(e, cleanup_match, net, NULL); 829 + xt_ematch_foreach(ematch, e) 830 + cleanup_match(ematch, net); 838 831 t = ip6t_get_target(e); 839 832 840 833 par.net = net; ··· 840 841 if (par.target->destroy != NULL) 841 842 par.target->destroy(&par); 842 843 module_put(par.target->me); 843 - return 0; 844 844 } 845 845 846 846 /* Checks and translates the user-supplied table segment (held in 847 847 newinfo) */ 848 848 static int 849 - translate_table(struct net *net, 850 - const char *name, 851 - unsigned int valid_hooks, 852 - struct xt_table_info *newinfo, 853 - void *entry0, 854 - unsigned int size, 855 - unsigned int number, 856 - const unsigned int *hook_entries, 857 - const unsigned int *underflows) 849 + translate_table(struct net *net, struct xt_table_info *newinfo, void *entry0, 850 + const struct ip6t_replace *repl) 858 851 { 852 + struct ip6t_entry *iter; 859 853 unsigned int i; 860 - int ret; 854 + int ret = 0; 861 855 862 - newinfo->size = size; 863 - newinfo->number = number; 856 + newinfo->size = repl->size; 857 + newinfo->number = repl->num_entries; 864 858 865 859 /* Init all hooks to impossible value. */ 866 860 for (i = 0; i < NF_INET_NUMHOOKS; i++) { ··· 864 872 duprintf("translate_table: size %u\n", newinfo->size); 865 873 i = 0; 866 874 /* Walk through entries, checking offsets. */ 867 - ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, 868 - check_entry_size_and_hooks, 869 - newinfo, 870 - entry0, 871 - entry0 + size, 872 - hook_entries, underflows, valid_hooks, &i); 873 - if (ret != 0) 874 - return ret; 875 + xt_entry_foreach(iter, entry0, newinfo->size) { 876 + ret = check_entry_size_and_hooks(iter, newinfo, entry0, 877 + entry0 + repl->size, repl->hook_entry, repl->underflow, 878 + repl->valid_hooks); 879 + if (ret != 0) 880 + return ret; 881 + ++i; 882 + } 875 883 876 - if (i != number) { 884 + if (i != repl->num_entries) { 877 885 duprintf("translate_table: %u not %u entries\n", 878 - i, number); 886 + i, repl->num_entries); 879 887 return -EINVAL; 880 888 } 881 889 882 890 /* Check hooks all assigned */ 883 891 for (i = 0; i < NF_INET_NUMHOOKS; i++) { 884 892 /* Only hooks which are valid */ 885 - if (!(valid_hooks & (1 << i))) 893 + if (!(repl->valid_hooks & (1 << i))) 886 894 continue; 887 895 if (newinfo->hook_entry[i] == 0xFFFFFFFF) { 888 896 duprintf("Invalid hook entry %u %u\n", 889 - i, hook_entries[i]); 897 + i, repl->hook_entry[i]); 890 898 return -EINVAL; 891 899 } 892 900 if (newinfo->underflow[i] == 0xFFFFFFFF) { 893 901 duprintf("Invalid underflow %u %u\n", 894 - i, underflows[i]); 902 + i, repl->underflow[i]); 895 903 return -EINVAL; 896 904 } 897 905 } 898 906 899 - if (!mark_source_chains(newinfo, valid_hooks, entry0)) 907 + if (!mark_source_chains(newinfo, repl->valid_hooks, entry0)) 900 908 return -ELOOP; 901 909 902 910 /* Finally, each sanity check must pass */ 903 911 i = 0; 904 - ret = IP6T_ENTRY_ITERATE(entry0, newinfo->size, 905 - find_check_entry, net, name, size, &i); 912 + xt_entry_foreach(iter, entry0, newinfo->size) { 913 + ret = find_check_entry(iter, net, repl->name, repl->size); 914 + if (ret != 0) 915 + break; 916 + ++i; 917 + } 906 918 907 919 if (ret != 0) { 908 - IP6T_ENTRY_ITERATE(entry0, newinfo->size, 909 - cleanup_entry, net, &i); 920 + xt_entry_foreach(iter, entry0, newinfo->size) { 921 + if (i-- == 0) 922 + break; 923 + cleanup_entry(iter, net); 924 + } 910 925 return ret; 911 926 } 912 927 ··· 926 927 return ret; 927 928 } 928 929 929 - /* Gets counters. */ 930 - static inline int 931 - add_entry_to_counter(const struct ip6t_entry *e, 932 - struct xt_counters total[], 933 - unsigned int *i) 934 - { 935 - ADD_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); 936 - 937 - (*i)++; 938 - return 0; 939 - } 940 - 941 - static inline int 942 - set_entry_to_counter(const struct ip6t_entry *e, 943 - struct ip6t_counters total[], 944 - unsigned int *i) 945 - { 946 - SET_COUNTER(total[*i], e->counters.bcnt, e->counters.pcnt); 947 - 948 - (*i)++; 949 - return 0; 950 - } 951 - 952 930 static void 953 931 get_counters(const struct xt_table_info *t, 954 932 struct xt_counters counters[]) 955 933 { 934 + struct ip6t_entry *iter; 956 935 unsigned int cpu; 957 936 unsigned int i; 958 937 unsigned int curcpu; ··· 946 969 curcpu = smp_processor_id(); 947 970 948 971 i = 0; 949 - IP6T_ENTRY_ITERATE(t->entries[curcpu], 950 - t->size, 951 - set_entry_to_counter, 952 - counters, 953 - &i); 972 + xt_entry_foreach(iter, t->entries[curcpu], t->size) { 973 + SET_COUNTER(counters[i], iter->counters.bcnt, 974 + iter->counters.pcnt); 975 + ++i; 976 + } 954 977 955 978 for_each_possible_cpu(cpu) { 956 979 if (cpu == curcpu) 957 980 continue; 958 981 i = 0; 959 982 xt_info_wrlock(cpu); 960 - IP6T_ENTRY_ITERATE(t->entries[cpu], 961 - t->size, 962 - add_entry_to_counter, 963 - counters, 964 - &i); 983 + xt_entry_foreach(iter, t->entries[cpu], t->size) { 984 + ADD_COUNTER(counters[i], iter->counters.bcnt, 985 + iter->counters.pcnt); 986 + ++i; 987 + } 965 988 xt_info_wrunlock(cpu); 966 989 } 967 990 local_bh_enable(); ··· 1080 1103 return copy_to_user(dst, &cv, sizeof(cv)) ? -EFAULT : 0; 1081 1104 } 1082 1105 1083 - static inline int 1084 - compat_calc_match(const struct ip6t_entry_match *m, int *size) 1085 - { 1086 - *size += xt_compat_match_offset(m->u.kernel.match); 1087 - return 0; 1088 - } 1089 - 1090 1106 static int compat_calc_entry(const struct ip6t_entry *e, 1091 1107 const struct xt_table_info *info, 1092 1108 const void *base, struct xt_table_info *newinfo) 1093 1109 { 1110 + const struct xt_entry_match *ematch; 1094 1111 const struct ip6t_entry_target *t; 1095 1112 unsigned int entry_offset; 1096 1113 int off, i, ret; 1097 1114 1098 1115 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1099 1116 entry_offset = (void *)e - base; 1100 - IP6T_MATCH_ITERATE(e, compat_calc_match, &off); 1117 + xt_ematch_foreach(ematch, e) 1118 + off += xt_compat_match_offset(ematch->u.kernel.match); 1101 1119 t = ip6t_get_target_c(e); 1102 1120 off += xt_compat_target_offset(t->u.kernel.target); 1103 1121 newinfo->size -= off; ··· 1114 1142 static int compat_table_info(const struct xt_table_info *info, 1115 1143 struct xt_table_info *newinfo) 1116 1144 { 1145 + struct ip6t_entry *iter; 1117 1146 void *loc_cpu_entry; 1147 + int ret; 1118 1148 1119 1149 if (!newinfo || !info) 1120 1150 return -EINVAL; ··· 1125 1151 memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); 1126 1152 newinfo->initial_entries = 0; 1127 1153 loc_cpu_entry = info->entries[raw_smp_processor_id()]; 1128 - return IP6T_ENTRY_ITERATE(loc_cpu_entry, info->size, 1129 - compat_calc_entry, info, loc_cpu_entry, 1130 - newinfo); 1154 + xt_entry_foreach(iter, loc_cpu_entry, info->size) { 1155 + ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); 1156 + if (ret != 0) 1157 + return ret; 1158 + } 1159 + return 0; 1131 1160 } 1132 1161 #endif 1133 1162 ··· 1244 1267 struct xt_table_info *oldinfo; 1245 1268 struct xt_counters *counters; 1246 1269 const void *loc_cpu_old_entry; 1270 + struct ip6t_entry *iter; 1247 1271 1248 1272 ret = 0; 1249 1273 counters = vmalloc_node(num_counters * sizeof(struct xt_counters), ··· 1288 1310 1289 1311 /* Decrease module usage counts and free resource */ 1290 1312 loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; 1291 - IP6T_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, 1292 - net, NULL); 1313 + xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size) 1314 + cleanup_entry(iter, net); 1315 + 1293 1316 xt_free_table_info(oldinfo); 1294 1317 if (copy_to_user(counters_ptr, counters, 1295 1318 sizeof(struct xt_counters) * num_counters) != 0) ··· 1315 1336 struct ip6t_replace tmp; 1316 1337 struct xt_table_info *newinfo; 1317 1338 void *loc_cpu_entry; 1339 + struct ip6t_entry *iter; 1318 1340 1319 1341 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1320 1342 return -EFAULT; ··· 1336 1356 goto free_newinfo; 1337 1357 } 1338 1358 1339 - ret = translate_table(net, tmp.name, tmp.valid_hooks, 1340 - newinfo, loc_cpu_entry, tmp.size, tmp.num_entries, 1341 - tmp.hook_entry, tmp.underflow); 1359 + ret = translate_table(net, newinfo, loc_cpu_entry, &tmp); 1342 1360 if (ret != 0) 1343 1361 goto free_newinfo; 1344 1362 ··· 1349 1371 return 0; 1350 1372 1351 1373 free_newinfo_untrans: 1352 - IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); 1374 + xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) 1375 + cleanup_entry(iter, net); 1353 1376 free_newinfo: 1354 1377 xt_free_table_info(newinfo); 1355 1378 return ret; 1356 - } 1357 - 1358 - /* We're lazy, and add to the first CPU; overflow works its fey magic 1359 - * and everything is OK. */ 1360 - static int 1361 - add_counter_to_entry(struct ip6t_entry *e, 1362 - const struct xt_counters addme[], 1363 - unsigned int *i) 1364 - { 1365 - ADD_COUNTER(e->counters, addme[*i].bcnt, addme[*i].pcnt); 1366 - 1367 - (*i)++; 1368 - return 0; 1369 1379 } 1370 1380 1371 1381 static int ··· 1371 1405 const struct xt_table_info *private; 1372 1406 int ret = 0; 1373 1407 const void *loc_cpu_entry; 1408 + struct ip6t_entry *iter; 1374 1409 #ifdef CONFIG_COMPAT 1375 1410 struct compat_xt_counters_info compat_tmp; 1376 1411 ··· 1430 1463 curcpu = smp_processor_id(); 1431 1464 xt_info_wrlock(curcpu); 1432 1465 loc_cpu_entry = private->entries[curcpu]; 1433 - IP6T_ENTRY_ITERATE(loc_cpu_entry, 1434 - private->size, 1435 - add_counter_to_entry, 1436 - paddc, 1437 - &i); 1466 + xt_entry_foreach(iter, loc_cpu_entry, private->size) { 1467 + ADD_COUNTER(iter->counters, paddc[i].bcnt, paddc[i].pcnt); 1468 + ++i; 1469 + } 1438 1470 xt_info_wrunlock(curcpu); 1439 1471 1440 1472 unlock_up_free: ··· 1462 1496 static int 1463 1497 compat_copy_entry_to_user(struct ip6t_entry *e, void __user **dstptr, 1464 1498 unsigned int *size, struct xt_counters *counters, 1465 - unsigned int *i) 1499 + unsigned int i) 1466 1500 { 1467 1501 struct ip6t_entry_target *t; 1468 1502 struct compat_ip6t_entry __user *ce; 1469 1503 u_int16_t target_offset, next_offset; 1470 1504 compat_uint_t origsize; 1471 - int ret; 1505 + const struct xt_entry_match *ematch; 1506 + int ret = 0; 1472 1507 1473 - ret = -EFAULT; 1474 1508 origsize = *size; 1475 1509 ce = (struct compat_ip6t_entry __user *)*dstptr; 1476 - if (copy_to_user(ce, e, sizeof(struct ip6t_entry))) 1477 - goto out; 1478 - 1479 - if (copy_to_user(&ce->counters, &counters[*i], sizeof(counters[*i]))) 1480 - goto out; 1510 + if (copy_to_user(ce, e, sizeof(struct ip6t_entry)) != 0 || 1511 + copy_to_user(&ce->counters, &counters[i], 1512 + sizeof(counters[i])) != 0) 1513 + return -EFAULT; 1481 1514 1482 1515 *dstptr += sizeof(struct compat_ip6t_entry); 1483 1516 *size -= sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1484 1517 1485 - ret = IP6T_MATCH_ITERATE(e, xt_compat_match_to_user, dstptr, size); 1518 + xt_ematch_foreach(ematch, e) { 1519 + ret = xt_compat_match_to_user(ematch, dstptr, size); 1520 + if (ret != 0) 1521 + return ret; 1522 + } 1486 1523 target_offset = e->target_offset - (origsize - *size); 1487 - if (ret) 1488 - goto out; 1489 1524 t = ip6t_get_target(e); 1490 1525 ret = xt_compat_target_to_user(t, dstptr, size); 1491 1526 if (ret) 1492 - goto out; 1493 - ret = -EFAULT; 1527 + return ret; 1494 1528 next_offset = e->next_offset - (origsize - *size); 1495 - if (put_user(target_offset, &ce->target_offset)) 1496 - goto out; 1497 - if (put_user(next_offset, &ce->next_offset)) 1498 - goto out; 1499 - 1500 - (*i)++; 1529 + if (put_user(target_offset, &ce->target_offset) != 0 || 1530 + put_user(next_offset, &ce->next_offset) != 0) 1531 + return -EFAULT; 1501 1532 return 0; 1502 - out: 1503 - return ret; 1504 1533 } 1505 1534 1506 1535 static int ··· 1503 1542 const char *name, 1504 1543 const struct ip6t_ip6 *ipv6, 1505 1544 unsigned int hookmask, 1506 - int *size, unsigned int *i) 1545 + int *size) 1507 1546 { 1508 1547 struct xt_match *match; 1509 1548 ··· 1517 1556 } 1518 1557 m->u.kernel.match = match; 1519 1558 *size += xt_compat_match_offset(match); 1520 - 1521 - (*i)++; 1522 1559 return 0; 1523 1560 } 1524 1561 1525 - static int 1526 - compat_release_match(struct ip6t_entry_match *m, unsigned int *i) 1527 - { 1528 - if (i && (*i)-- == 0) 1529 - return 1; 1530 - 1531 - module_put(m->u.kernel.match->me); 1532 - return 0; 1533 - } 1534 - 1535 - static int 1536 - compat_release_entry(struct compat_ip6t_entry *e, unsigned int *i) 1562 + static void compat_release_entry(struct compat_ip6t_entry *e) 1537 1563 { 1538 1564 struct ip6t_entry_target *t; 1539 - 1540 - if (i && (*i)-- == 0) 1541 - return 1; 1565 + struct xt_entry_match *ematch; 1542 1566 1543 1567 /* Cleanup all matches */ 1544 - COMPAT_IP6T_MATCH_ITERATE(e, compat_release_match, NULL); 1568 + xt_ematch_foreach(ematch, e) 1569 + module_put(ematch->u.kernel.match->me); 1545 1570 t = compat_ip6t_get_target(e); 1546 1571 module_put(t->u.kernel.target->me); 1547 - return 0; 1548 1572 } 1549 1573 1550 1574 static int ··· 1540 1594 const unsigned char *limit, 1541 1595 const unsigned int *hook_entries, 1542 1596 const unsigned int *underflows, 1543 - unsigned int *i, 1544 1597 const char *name) 1545 1598 { 1599 + struct xt_entry_match *ematch; 1546 1600 struct ip6t_entry_target *t; 1547 1601 struct xt_target *target; 1548 1602 unsigned int entry_offset; ··· 1571 1625 off = sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1572 1626 entry_offset = (void *)e - (void *)base; 1573 1627 j = 0; 1574 - ret = COMPAT_IP6T_MATCH_ITERATE(e, compat_find_calc_match, name, 1575 - &e->ipv6, e->comefrom, &off, &j); 1576 - if (ret != 0) 1577 - goto release_matches; 1628 + xt_ematch_foreach(ematch, e) { 1629 + ret = compat_find_calc_match(ematch, name, 1630 + &e->ipv6, e->comefrom, &off); 1631 + if (ret != 0) 1632 + goto release_matches; 1633 + ++j; 1634 + } 1578 1635 1579 1636 t = compat_ip6t_get_target(e); 1580 1637 target = try_then_request_module(xt_find_target(AF_INET6, ··· 1609 1660 /* Clear counters and comefrom */ 1610 1661 memset(&e->counters, 0, sizeof(e->counters)); 1611 1662 e->comefrom = 0; 1612 - 1613 - (*i)++; 1614 1663 return 0; 1615 1664 1616 1665 out: 1617 1666 module_put(t->u.kernel.target->me); 1618 1667 release_matches: 1619 - IP6T_MATCH_ITERATE(e, compat_release_match, &j); 1668 + xt_ematch_foreach(ematch, e) { 1669 + if (j-- == 0) 1670 + break; 1671 + module_put(ematch->u.kernel.match->me); 1672 + } 1620 1673 return ret; 1621 1674 } 1622 1675 ··· 1632 1681 struct ip6t_entry *de; 1633 1682 unsigned int origsize; 1634 1683 int ret, h; 1684 + struct xt_entry_match *ematch; 1635 1685 1636 1686 ret = 0; 1637 1687 origsize = *size; ··· 1643 1691 *dstptr += sizeof(struct ip6t_entry); 1644 1692 *size += sizeof(struct ip6t_entry) - sizeof(struct compat_ip6t_entry); 1645 1693 1646 - ret = COMPAT_IP6T_MATCH_ITERATE(e, xt_compat_match_from_user, 1647 - dstptr, size); 1648 - if (ret) 1649 - return ret; 1694 + xt_ematch_foreach(ematch, e) { 1695 + ret = xt_compat_match_from_user(ematch, dstptr, size); 1696 + if (ret != 0) 1697 + return ret; 1698 + } 1650 1699 de->target_offset = e->target_offset - (origsize - *size); 1651 1700 t = compat_ip6t_get_target(e); 1652 1701 target = t->u.kernel.target; ··· 1664 1711 } 1665 1712 1666 1713 static int compat_check_entry(struct ip6t_entry *e, struct net *net, 1667 - const char *name, unsigned int *i) 1714 + const char *name) 1668 1715 { 1669 1716 unsigned int j; 1670 - int ret; 1717 + int ret = 0; 1671 1718 struct xt_mtchk_param mtpar; 1719 + struct xt_entry_match *ematch; 1672 1720 1673 1721 j = 0; 1674 1722 mtpar.net = net; ··· 1677 1723 mtpar.entryinfo = &e->ipv6; 1678 1724 mtpar.hook_mask = e->comefrom; 1679 1725 mtpar.family = NFPROTO_IPV6; 1680 - ret = IP6T_MATCH_ITERATE(e, check_match, &mtpar, &j); 1681 - if (ret) 1682 - goto cleanup_matches; 1726 + xt_ematch_foreach(ematch, e) { 1727 + ret = check_match(ematch, &mtpar); 1728 + if (ret != 0) 1729 + goto cleanup_matches; 1730 + ++j; 1731 + } 1683 1732 1684 1733 ret = check_target(e, net, name); 1685 1734 if (ret) 1686 1735 goto cleanup_matches; 1687 - 1688 - (*i)++; 1689 1736 return 0; 1690 1737 1691 1738 cleanup_matches: 1692 - IP6T_MATCH_ITERATE(e, cleanup_match, net, &j); 1739 + xt_ematch_foreach(ematch, e) { 1740 + if (j-- == 0) 1741 + break; 1742 + cleanup_match(ematch, net); 1743 + } 1693 1744 return ret; 1694 1745 } 1695 1746 ··· 1712 1753 unsigned int i, j; 1713 1754 struct xt_table_info *newinfo, *info; 1714 1755 void *pos, *entry0, *entry1; 1756 + struct compat_ip6t_entry *iter0; 1757 + struct ip6t_entry *iter1; 1715 1758 unsigned int size; 1716 - int ret; 1759 + int ret = 0; 1717 1760 1718 1761 info = *pinfo; 1719 1762 entry0 = *pentry0; ··· 1732 1771 j = 0; 1733 1772 xt_compat_lock(AF_INET6); 1734 1773 /* Walk through entries, checking offsets. */ 1735 - ret = COMPAT_IP6T_ENTRY_ITERATE(entry0, total_size, 1736 - check_compat_entry_size_and_hooks, 1737 - info, &size, entry0, 1738 - entry0 + total_size, 1739 - hook_entries, underflows, &j, name); 1740 - if (ret != 0) 1741 - goto out_unlock; 1774 + xt_entry_foreach(iter0, entry0, total_size) { 1775 + ret = check_compat_entry_size_and_hooks(iter0, info, &size, 1776 + entry0, entry0 + total_size, hook_entries, underflows, 1777 + name); 1778 + if (ret != 0) 1779 + goto out_unlock; 1780 + ++j; 1781 + } 1742 1782 1743 1783 ret = -EINVAL; 1744 1784 if (j != number) { ··· 1778 1816 entry1 = newinfo->entries[raw_smp_processor_id()]; 1779 1817 pos = entry1; 1780 1818 size = total_size; 1781 - ret = COMPAT_IP6T_ENTRY_ITERATE(entry0, total_size, 1782 - compat_copy_entry_from_user, 1783 - &pos, &size, name, newinfo, entry1); 1819 + xt_entry_foreach(iter0, entry0, total_size) { 1820 + ret = compat_copy_entry_from_user(iter0, &pos, 1821 + &size, name, newinfo, entry1); 1822 + if (ret != 0) 1823 + break; 1824 + } 1784 1825 xt_compat_flush_offsets(AF_INET6); 1785 1826 xt_compat_unlock(AF_INET6); 1786 1827 if (ret) ··· 1794 1829 goto free_newinfo; 1795 1830 1796 1831 i = 0; 1797 - ret = IP6T_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, 1798 - net, name, &i); 1832 + xt_entry_foreach(iter1, entry1, newinfo->size) { 1833 + ret = compat_check_entry(iter1, net, name); 1834 + if (ret != 0) 1835 + break; 1836 + ++i; 1837 + } 1799 1838 if (ret) { 1839 + /* 1840 + * The first i matches need cleanup_entry (calls ->destroy) 1841 + * because they had called ->check already. The other j-i 1842 + * entries need only release. 1843 + */ 1844 + int skip = i; 1800 1845 j -= i; 1801 - COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, 1802 - compat_release_entry, &j); 1803 - IP6T_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, net, &i); 1846 + xt_entry_foreach(iter0, entry0, newinfo->size) { 1847 + if (skip-- > 0) 1848 + continue; 1849 + if (j-- == 0) 1850 + break; 1851 + compat_release_entry(iter0); 1852 + } 1853 + xt_entry_foreach(iter1, entry1, newinfo->size) { 1854 + if (i-- == 0) 1855 + break; 1856 + cleanup_entry(iter1, net); 1857 + } 1804 1858 xt_free_table_info(newinfo); 1805 1859 return ret; 1806 1860 } ··· 1837 1853 free_newinfo: 1838 1854 xt_free_table_info(newinfo); 1839 1855 out: 1840 - COMPAT_IP6T_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); 1856 + xt_entry_foreach(iter0, entry0, total_size) { 1857 + if (j-- == 0) 1858 + break; 1859 + compat_release_entry(iter0); 1860 + } 1841 1861 return ret; 1842 1862 out_unlock: 1843 1863 xt_compat_flush_offsets(AF_INET6); ··· 1856 1868 struct compat_ip6t_replace tmp; 1857 1869 struct xt_table_info *newinfo; 1858 1870 void *loc_cpu_entry; 1871 + struct ip6t_entry *iter; 1859 1872 1860 1873 if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) 1861 1874 return -EFAULT; ··· 1895 1906 return 0; 1896 1907 1897 1908 free_newinfo_untrans: 1898 - IP6T_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, net, NULL); 1909 + xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) 1910 + cleanup_entry(iter, net); 1899 1911 free_newinfo: 1900 1912 xt_free_table_info(newinfo); 1901 1913 return ret; ··· 1945 1955 int ret = 0; 1946 1956 const void *loc_cpu_entry; 1947 1957 unsigned int i = 0; 1958 + struct ip6t_entry *iter; 1948 1959 1949 1960 counters = alloc_counters(table); 1950 1961 if (IS_ERR(counters)) ··· 1958 1967 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 1959 1968 pos = userptr; 1960 1969 size = total_size; 1961 - ret = IP6T_ENTRY_ITERATE(loc_cpu_entry, total_size, 1962 - compat_copy_entry_to_user, 1963 - &pos, &size, counters, &i); 1970 + xt_entry_foreach(iter, loc_cpu_entry, total_size) { 1971 + ret = compat_copy_entry_to_user(iter, &pos, 1972 + &size, counters, i++); 1973 + if (ret != 0) 1974 + break; 1975 + } 1964 1976 1965 1977 vfree(counters); 1966 1978 return ret; ··· 2137 2143 loc_cpu_entry = newinfo->entries[raw_smp_processor_id()]; 2138 2144 memcpy(loc_cpu_entry, repl->entries, repl->size); 2139 2145 2140 - ret = translate_table(net, table->name, table->valid_hooks, 2141 - newinfo, loc_cpu_entry, repl->size, 2142 - repl->num_entries, 2143 - repl->hook_entry, 2144 - repl->underflow); 2146 + ret = translate_table(net, newinfo, loc_cpu_entry, repl); 2145 2147 if (ret != 0) 2146 2148 goto out_free; 2147 2149 ··· 2159 2169 struct xt_table_info *private; 2160 2170 void *loc_cpu_entry; 2161 2171 struct module *table_owner = table->me; 2172 + struct ip6t_entry *iter; 2162 2173 2163 2174 private = xt_unregister_table(table); 2164 2175 2165 2176 /* Decrease module usage counts and free resources */ 2166 2177 loc_cpu_entry = private->entries[raw_smp_processor_id()]; 2167 - IP6T_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, net, NULL); 2178 + xt_entry_foreach(iter, loc_cpu_entry, private->size) 2179 + cleanup_entry(iter, net); 2168 2180 if (private->number > private->initial_entries) 2169 2181 module_put(table_owner); 2170 2182 xt_free_table_info(private);
+1 -7
net/ipv6/netfilter/nf_conntrack_reasm.c
··· 469 469 470 470 /* all original skbs are linked into the NFCT_FRAG6_CB(head).orig */ 471 471 fp = skb_shinfo(head)->frag_list; 472 - if (NFCT_FRAG6_CB(fp)->orig == NULL) 472 + if (fp && NFCT_FRAG6_CB(fp)->orig == NULL) 473 473 /* at above code, head skb is divided into two skbs. */ 474 474 fp = fp->next; 475 475 ··· 594 594 skb_set_transport_header(clone, fhoff); 595 595 hdr = ipv6_hdr(clone); 596 596 fhdr = (struct frag_hdr *)skb_transport_header(clone); 597 - 598 - if (!(fhdr->frag_off & htons(0xFFF9))) { 599 - pr_debug("Invalid fragment offset\n"); 600 - /* It is not a fragmented frame */ 601 - goto ret_orig; 602 - } 603 597 604 598 if (atomic_read(&nf_init_frags.mem) > nf_init_frags.high_thresh) 605 599 nf_ct_frag6_evictor();
+8 -4
net/netfilter/xt_TCPMSS.c
··· 239 239 { 240 240 const struct xt_tcpmss_info *info = par->targinfo; 241 241 const struct ipt_entry *e = par->entryinfo; 242 + const struct xt_entry_match *ematch; 242 243 243 244 if (info->mss == XT_TCPMSS_CLAMP_PMTU && 244 245 (par->hook_mask & ~((1 << NF_INET_FORWARD) | ··· 249 248 "FORWARD, OUTPUT and POSTROUTING hooks\n"); 250 249 return false; 251 250 } 252 - if (IPT_MATCH_ITERATE(e, find_syn_match)) 253 - return true; 251 + xt_ematch_foreach(ematch, e) 252 + if (find_syn_match(ematch)) 253 + return true; 254 254 printk("xt_TCPMSS: Only works on TCP SYN packets\n"); 255 255 return false; 256 256 } ··· 261 259 { 262 260 const struct xt_tcpmss_info *info = par->targinfo; 263 261 const struct ip6t_entry *e = par->entryinfo; 262 + const struct xt_entry_match *ematch; 264 263 265 264 if (info->mss == XT_TCPMSS_CLAMP_PMTU && 266 265 (par->hook_mask & ~((1 << NF_INET_FORWARD) | ··· 271 268 "FORWARD, OUTPUT and POSTROUTING hooks\n"); 272 269 return false; 273 270 } 274 - if (IP6T_MATCH_ITERATE(e, find_syn_match)) 275 - return true; 271 + xt_ematch_foreach(ematch, e) 272 + if (find_syn_match(ematch)) 273 + return true; 276 274 printk("xt_TCPMSS: Only works on TCP SYN packets\n"); 277 275 return false; 278 276 }
+2 -2
net/netfilter/xt_recent.c
··· 177 177 178 178 static void recent_entry_update(struct recent_table *t, struct recent_entry *e) 179 179 { 180 + e->index %= ip_pkt_list_tot; 180 181 e->stamps[e->index++] = jiffies; 181 182 if (e->index > e->nstamps) 182 183 e->nstamps = e->index; 183 - e->index %= ip_pkt_list_tot; 184 184 list_move_tail(&e->lru_list, &t->lru_list); 185 185 } 186 186 ··· 267 267 for (i = 0; i < e->nstamps; i++) { 268 268 if (info->seconds && time_after(time, e->stamps[i])) 269 269 continue; 270 - if (++hits >= info->hit_count) { 270 + if (info->hit_count && ++hits >= info->hit_count) { 271 271 ret = !ret; 272 272 break; 273 273 }