Loading include/linux/netfilter/x_tables.h +9 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ struct xt_counters_info { __ret; \ }) #ifndef __KERNEL__ /* fn returns 0 to continue iteration */ #define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \ ({ \ Loading @@ -163,6 +164,14 @@ struct xt_counters_info { #define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \ XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args) #endif /* !__KERNEL__ */ /* pos is normally a struct ipt_entry/ip6t_entry/etc. */ #define xt_entry_foreach(pos, ehead, esize) \ for ((pos) = (typeof(pos))(ehead); \ (pos) < (typeof(pos))((char *)(ehead) + (esize)); \ (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset)) #ifdef __KERNEL__ #include <linux/netdevice.h> Loading include/linux/netfilter_arp/arp_tables.h +2 −8 Original line number Diff line number Diff line Loading @@ -211,9 +211,11 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e return (void *)e + e->target_offset; } #ifndef __KERNEL__ /* fn returns 0 to continue iteration */ #define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args) #endif /* * Main firewall chains definitions and global var's definitions. Loading Loading @@ -291,14 +293,6 @@ compat_arpt_get_target(struct compat_arpt_entry *e) #define COMPAT_ARPT_ALIGN(s) COMPAT_XT_ALIGN(s) /* fn returns 0 to continue iteration */ #define COMPAT_ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct compat_arpt_entry, entries, size, fn, ## args) #define COMPAT_ARPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ XT_ENTRY_ITERATE_CONTINUE(struct compat_arpt_entry, entries, size, n, \ fn, ## args) #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _ARPTABLES_H */ include/linux/netfilter_ipv4/ip_tables.h +2 −9 Original line number Diff line number Diff line Loading @@ -227,9 +227,11 @@ ipt_get_target(struct ipt_entry *e) #define IPT_MATCH_ITERATE(e, fn, args...) \ XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) #ifndef __KERNEL__ /* fn returns 0 to continue iteration */ #define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) #endif /* * Main firewall chains definitions and global var's definitions. Loading Loading @@ -317,15 +319,6 @@ compat_ipt_get_target(struct compat_ipt_entry *e) #define COMPAT_IPT_MATCH_ITERATE(e, fn, args...) \ XT_MATCH_ITERATE(struct compat_ipt_entry, e, fn, ## args) /* fn returns 0 to continue iteration */ #define COMPAT_IPT_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct compat_ipt_entry, entries, size, fn, ## args) /* fn returns 0 to continue iteration */ #define COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ XT_ENTRY_ITERATE_CONTINUE(struct compat_ipt_entry, entries, size, n, \ fn, ## args) #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _IPTABLES_H */ include/linux/netfilter_ipv6/ip6_tables.h +2 −8 Original line number Diff line number Diff line Loading @@ -284,9 +284,11 @@ ip6t_get_target(struct ip6t_entry *e) #define IP6T_MATCH_ITERATE(e, fn, args...) \ XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) #ifndef __KERNEL__ /* fn returns 0 to continue iteration */ #define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) #endif /* * Main firewall chains definitions and global var's definitions. Loading Loading @@ -345,14 +347,6 @@ compat_ip6t_get_target(struct compat_ip6t_entry *e) #define COMPAT_IP6T_MATCH_ITERATE(e, fn, args...) \ XT_MATCH_ITERATE(struct compat_ip6t_entry, e, fn, ## args) /* fn returns 0 to continue iteration */ #define COMPAT_IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct compat_ip6t_entry, entries, size, fn, ## args) #define COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ XT_ENTRY_ITERATE_CONTINUE(struct compat_ip6t_entry, entries, size, n, \ fn, ## args) #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _IP6_TABLES_H */ net/ipv4/netfilter/arp_tables.c +98 −53 Original line number Diff line number Diff line Loading @@ -641,8 +641,9 @@ static int translate_table(const char *name, const unsigned int *hook_entries, const unsigned int *underflows) { struct arpt_entry *iter; unsigned int i; int ret; int ret = 0; newinfo->size = size; newinfo->number = number; Loading @@ -657,12 +658,13 @@ static int translate_table(const char *name, i = 0; /* Walk through entries, checking offsets. */ ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, check_entry_size_and_hooks, newinfo, entry0, entry0 + size, hook_entries, underflows, valid_hooks, &i); xt_entry_foreach(iter, entry0, newinfo->size) { ret = check_entry_size_and_hooks(iter, newinfo, entry0, entry0 + size, hook_entries, underflows, valid_hooks, &i); if (ret != 0) break; } duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); if (ret != 0) return ret; Loading Loading @@ -697,12 +699,16 @@ static int translate_table(const char *name, /* Finally, each sanity check must pass */ i = 0; ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, find_check_entry, name, size, &i); xt_entry_foreach(iter, entry0, newinfo->size) { ret = find_check_entry(iter, name, size, &i); if (ret != 0) break; } if (ret != 0) { ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); xt_entry_foreach(iter, entry0, newinfo->size) if (cleanup_entry(iter, &i) != 0) break; return ret; } Loading Loading @@ -739,6 +745,7 @@ static inline int set_entry_to_counter(const struct arpt_entry *e, static void get_counters(const struct xt_table_info *t, struct xt_counters counters[]) { struct arpt_entry *iter; unsigned int cpu; unsigned int i; unsigned int curcpu; Loading @@ -754,22 +761,18 @@ static void get_counters(const struct xt_table_info *t, curcpu = smp_processor_id(); i = 0; ARPT_ENTRY_ITERATE(t->entries[curcpu], t->size, set_entry_to_counter, counters, &i); xt_entry_foreach(iter, t->entries[curcpu], t->size) if (set_entry_to_counter(iter, counters, &i) != 0) break; for_each_possible_cpu(cpu) { if (cpu == curcpu) continue; i = 0; xt_info_wrlock(cpu); ARPT_ENTRY_ITERATE(t->entries[cpu], t->size, add_entry_to_counter, counters, &i); xt_entry_foreach(iter, t->entries[cpu], t->size) if (add_entry_to_counter(iter, counters, &i) != 0) break; xt_info_wrunlock(cpu); } local_bh_enable(); Loading Loading @@ -899,7 +902,9 @@ static int compat_calc_entry(const struct arpt_entry *e, static int compat_table_info(const struct xt_table_info *info, struct xt_table_info *newinfo) { struct arpt_entry *iter; void *loc_cpu_entry; int ret = 0; if (!newinfo || !info) return -EINVAL; Loading @@ -908,9 +913,12 @@ static int compat_table_info(const struct xt_table_info *info, memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); newinfo->initial_entries = 0; loc_cpu_entry = info->entries[raw_smp_processor_id()]; return ARPT_ENTRY_ITERATE(loc_cpu_entry, info->size, compat_calc_entry, info, loc_cpu_entry, newinfo); xt_entry_foreach(iter, loc_cpu_entry, info->size) { ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); if (ret != 0) break; } return ret; } #endif Loading Loading @@ -1025,6 +1033,7 @@ static int __do_replace(struct net *net, const char *name, struct xt_table_info *oldinfo; struct xt_counters *counters; void *loc_cpu_old_entry; struct arpt_entry *iter; ret = 0; counters = vmalloc_node(num_counters * sizeof(struct xt_counters), Loading Loading @@ -1068,8 +1077,9 @@ static int __do_replace(struct net *net, const char *name, /* Decrease module usage counts and free resource */ loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, NULL); xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size) if (cleanup_entry(iter, NULL) != 0) break; xt_free_table_info(oldinfo); if (copy_to_user(counters_ptr, counters, Loading @@ -1095,6 +1105,7 @@ static int do_replace(struct net *net, const void __user *user, struct arpt_replace tmp; struct xt_table_info *newinfo; void *loc_cpu_entry; struct arpt_entry *iter; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) return -EFAULT; Loading Loading @@ -1130,7 +1141,9 @@ static int do_replace(struct net *net, const void __user *user, return 0; free_newinfo_untrans: ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) if (cleanup_entry(iter, NULL) != 0) break; free_newinfo: xt_free_table_info(newinfo); return ret; Loading Loading @@ -1163,6 +1176,7 @@ static int do_add_counters(struct net *net, const void __user *user, const struct xt_table_info *private; int ret = 0; void *loc_cpu_entry; struct arpt_entry *iter; #ifdef CONFIG_COMPAT struct compat_xt_counters_info compat_tmp; Loading Loading @@ -1220,11 +1234,9 @@ static int do_add_counters(struct net *net, const void __user *user, curcpu = smp_processor_id(); loc_cpu_entry = private->entries[curcpu]; xt_info_wrlock(curcpu); ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, add_counter_to_entry, paddc, &i); xt_entry_foreach(iter, loc_cpu_entry, private->size) if (add_counter_to_entry(iter, paddc, &i) != 0) break; xt_info_wrunlock(curcpu); unlock_up_free: local_bh_enable(); Loading Loading @@ -1388,8 +1400,10 @@ static int translate_compat_table(const char *name, unsigned int i, j; struct xt_table_info *newinfo, *info; void *pos, *entry0, *entry1; struct compat_arpt_entry *iter0; struct arpt_entry *iter1; unsigned int size; int ret; int ret = 0; info = *pinfo; entry0 = *pentry0; Loading @@ -1406,11 +1420,13 @@ static int translate_compat_table(const char *name, j = 0; xt_compat_lock(NFPROTO_ARP); /* Walk through entries, checking offsets. */ ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, check_compat_entry_size_and_hooks, info, &size, entry0, entry0 + total_size, hook_entries, underflows, &j, name); xt_entry_foreach(iter0, entry0, total_size) { ret = check_compat_entry_size_and_hooks(iter0, info, &size, entry0, entry0 + total_size, hook_entries, underflows, &j, name); if (ret != 0) break; } if (ret != 0) goto out_unlock; Loading Loading @@ -1451,9 +1467,12 @@ static int translate_compat_table(const char *name, entry1 = newinfo->entries[raw_smp_processor_id()]; pos = entry1; size = total_size; ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_copy_entry_from_user, &pos, &size, name, newinfo, entry1); xt_entry_foreach(iter0, entry0, total_size) { ret = compat_copy_entry_from_user(iter0, &pos, &size, name, newinfo, entry1); if (ret != 0) break; } xt_compat_flush_offsets(NFPROTO_ARP); xt_compat_unlock(NFPROTO_ARP); if (ret) Loading @@ -1464,13 +1483,28 @@ static int translate_compat_table(const char *name, goto free_newinfo; i = 0; ret = ARPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, name, &i); xt_entry_foreach(iter1, entry1, newinfo->size) { ret = compat_check_entry(iter1, name, &i); if (ret != 0) break; } if (ret) { /* * The first i matches need cleanup_entry (calls ->destroy) * because they had called ->check already. The other j-i * entries need only release. */ int skip = i; j -= i; COMPAT_ARPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, compat_release_entry, &j); ARPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); xt_entry_foreach(iter0, entry0, newinfo->size) { if (skip-- > 0) continue; if (compat_release_entry(iter0, &j) != 0) break; } xt_entry_foreach(iter1, entry1, newinfo->size) if (cleanup_entry(iter1, &i) != 0) break; xt_free_table_info(newinfo); return ret; } Loading @@ -1488,7 +1522,9 @@ static int translate_compat_table(const char *name, free_newinfo: xt_free_table_info(newinfo); out: COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); xt_entry_foreach(iter0, entry0, total_size) if (compat_release_entry(iter0, &j) != 0) break; return ret; out_unlock: xt_compat_flush_offsets(NFPROTO_ARP); Loading @@ -1515,6 +1551,7 @@ static int compat_do_replace(struct net *net, void __user *user, struct compat_arpt_replace tmp; struct xt_table_info *newinfo; void *loc_cpu_entry; struct arpt_entry *iter; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) return -EFAULT; Loading Loading @@ -1552,7 +1589,9 @@ static int compat_do_replace(struct net *net, void __user *user, return 0; free_newinfo_untrans: ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) if (cleanup_entry(iter, NULL) != 0) break; free_newinfo: xt_free_table_info(newinfo); return ret; Loading Loading @@ -1636,6 +1675,7 @@ static int compat_copy_entries_to_user(unsigned int total_size, int ret = 0; void *loc_cpu_entry; unsigned int i = 0; struct arpt_entry *iter; counters = alloc_counters(table); if (IS_ERR(counters)) Loading @@ -1645,9 +1685,12 @@ static int compat_copy_entries_to_user(unsigned int total_size, loc_cpu_entry = private->entries[raw_smp_processor_id()]; pos = userptr; size = total_size; ret = ARPT_ENTRY_ITERATE(loc_cpu_entry, total_size, compat_copy_entry_to_user, &pos, &size, counters, &i); xt_entry_foreach(iter, loc_cpu_entry, total_size) { ret = compat_copy_entry_to_user(iter, &pos, &size, counters, &i); if (ret != 0) break; } vfree(counters); return ret; } Loading Loading @@ -1843,13 +1886,15 @@ void arpt_unregister_table(struct xt_table *table) struct xt_table_info *private; void *loc_cpu_entry; struct module *table_owner = table->me; struct arpt_entry *iter; private = xt_unregister_table(table); /* Decrease module usage counts and free resources */ loc_cpu_entry = private->entries[raw_smp_processor_id()]; ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); xt_entry_foreach(iter, loc_cpu_entry, private->size) if (cleanup_entry(iter, NULL) != 0) break; if (private->number > private->initial_entries) module_put(table_owner); xt_free_table_info(private); Loading Loading
include/linux/netfilter/x_tables.h +9 −0 Original line number Diff line number Diff line Loading @@ -139,6 +139,7 @@ struct xt_counters_info { __ret; \ }) #ifndef __KERNEL__ /* fn returns 0 to continue iteration */ #define XT_ENTRY_ITERATE_CONTINUE(type, entries, size, n, fn, args...) \ ({ \ Loading @@ -163,6 +164,14 @@ struct xt_counters_info { #define XT_ENTRY_ITERATE(type, entries, size, fn, args...) \ XT_ENTRY_ITERATE_CONTINUE(type, entries, size, 0, fn, args) #endif /* !__KERNEL__ */ /* pos is normally a struct ipt_entry/ip6t_entry/etc. */ #define xt_entry_foreach(pos, ehead, esize) \ for ((pos) = (typeof(pos))(ehead); \ (pos) < (typeof(pos))((char *)(ehead) + (esize)); \ (pos) = (typeof(pos))((char *)(pos) + (pos)->next_offset)) #ifdef __KERNEL__ #include <linux/netdevice.h> Loading
include/linux/netfilter_arp/arp_tables.h +2 −8 Original line number Diff line number Diff line Loading @@ -211,9 +211,11 @@ static __inline__ struct arpt_entry_target *arpt_get_target(struct arpt_entry *e return (void *)e + e->target_offset; } #ifndef __KERNEL__ /* fn returns 0 to continue iteration */ #define ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct arpt_entry, entries, size, fn, ## args) #endif /* * Main firewall chains definitions and global var's definitions. Loading Loading @@ -291,14 +293,6 @@ compat_arpt_get_target(struct compat_arpt_entry *e) #define COMPAT_ARPT_ALIGN(s) COMPAT_XT_ALIGN(s) /* fn returns 0 to continue iteration */ #define COMPAT_ARPT_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct compat_arpt_entry, entries, size, fn, ## args) #define COMPAT_ARPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ XT_ENTRY_ITERATE_CONTINUE(struct compat_arpt_entry, entries, size, n, \ fn, ## args) #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _ARPTABLES_H */
include/linux/netfilter_ipv4/ip_tables.h +2 −9 Original line number Diff line number Diff line Loading @@ -227,9 +227,11 @@ ipt_get_target(struct ipt_entry *e) #define IPT_MATCH_ITERATE(e, fn, args...) \ XT_MATCH_ITERATE(struct ipt_entry, e, fn, ## args) #ifndef __KERNEL__ /* fn returns 0 to continue iteration */ #define IPT_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct ipt_entry, entries, size, fn, ## args) #endif /* * Main firewall chains definitions and global var's definitions. Loading Loading @@ -317,15 +319,6 @@ compat_ipt_get_target(struct compat_ipt_entry *e) #define COMPAT_IPT_MATCH_ITERATE(e, fn, args...) \ XT_MATCH_ITERATE(struct compat_ipt_entry, e, fn, ## args) /* fn returns 0 to continue iteration */ #define COMPAT_IPT_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct compat_ipt_entry, entries, size, fn, ## args) /* fn returns 0 to continue iteration */ #define COMPAT_IPT_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ XT_ENTRY_ITERATE_CONTINUE(struct compat_ipt_entry, entries, size, n, \ fn, ## args) #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _IPTABLES_H */
include/linux/netfilter_ipv6/ip6_tables.h +2 −8 Original line number Diff line number Diff line Loading @@ -284,9 +284,11 @@ ip6t_get_target(struct ip6t_entry *e) #define IP6T_MATCH_ITERATE(e, fn, args...) \ XT_MATCH_ITERATE(struct ip6t_entry, e, fn, ## args) #ifndef __KERNEL__ /* fn returns 0 to continue iteration */ #define IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct ip6t_entry, entries, size, fn, ## args) #endif /* * Main firewall chains definitions and global var's definitions. Loading Loading @@ -345,14 +347,6 @@ compat_ip6t_get_target(struct compat_ip6t_entry *e) #define COMPAT_IP6T_MATCH_ITERATE(e, fn, args...) \ XT_MATCH_ITERATE(struct compat_ip6t_entry, e, fn, ## args) /* fn returns 0 to continue iteration */ #define COMPAT_IP6T_ENTRY_ITERATE(entries, size, fn, args...) \ XT_ENTRY_ITERATE(struct compat_ip6t_entry, entries, size, fn, ## args) #define COMPAT_IP6T_ENTRY_ITERATE_CONTINUE(entries, size, n, fn, args...) \ XT_ENTRY_ITERATE_CONTINUE(struct compat_ip6t_entry, entries, size, n, \ fn, ## args) #endif /* CONFIG_COMPAT */ #endif /*__KERNEL__*/ #endif /* _IP6_TABLES_H */
net/ipv4/netfilter/arp_tables.c +98 −53 Original line number Diff line number Diff line Loading @@ -641,8 +641,9 @@ static int translate_table(const char *name, const unsigned int *hook_entries, const unsigned int *underflows) { struct arpt_entry *iter; unsigned int i; int ret; int ret = 0; newinfo->size = size; newinfo->number = number; Loading @@ -657,12 +658,13 @@ static int translate_table(const char *name, i = 0; /* Walk through entries, checking offsets. */ ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, check_entry_size_and_hooks, newinfo, entry0, entry0 + size, hook_entries, underflows, valid_hooks, &i); xt_entry_foreach(iter, entry0, newinfo->size) { ret = check_entry_size_and_hooks(iter, newinfo, entry0, entry0 + size, hook_entries, underflows, valid_hooks, &i); if (ret != 0) break; } duprintf("translate_table: ARPT_ENTRY_ITERATE gives %d\n", ret); if (ret != 0) return ret; Loading Loading @@ -697,12 +699,16 @@ static int translate_table(const char *name, /* Finally, each sanity check must pass */ i = 0; ret = ARPT_ENTRY_ITERATE(entry0, newinfo->size, find_check_entry, name, size, &i); xt_entry_foreach(iter, entry0, newinfo->size) { ret = find_check_entry(iter, name, size, &i); if (ret != 0) break; } if (ret != 0) { ARPT_ENTRY_ITERATE(entry0, newinfo->size, cleanup_entry, &i); xt_entry_foreach(iter, entry0, newinfo->size) if (cleanup_entry(iter, &i) != 0) break; return ret; } Loading Loading @@ -739,6 +745,7 @@ static inline int set_entry_to_counter(const struct arpt_entry *e, static void get_counters(const struct xt_table_info *t, struct xt_counters counters[]) { struct arpt_entry *iter; unsigned int cpu; unsigned int i; unsigned int curcpu; Loading @@ -754,22 +761,18 @@ static void get_counters(const struct xt_table_info *t, curcpu = smp_processor_id(); i = 0; ARPT_ENTRY_ITERATE(t->entries[curcpu], t->size, set_entry_to_counter, counters, &i); xt_entry_foreach(iter, t->entries[curcpu], t->size) if (set_entry_to_counter(iter, counters, &i) != 0) break; for_each_possible_cpu(cpu) { if (cpu == curcpu) continue; i = 0; xt_info_wrlock(cpu); ARPT_ENTRY_ITERATE(t->entries[cpu], t->size, add_entry_to_counter, counters, &i); xt_entry_foreach(iter, t->entries[cpu], t->size) if (add_entry_to_counter(iter, counters, &i) != 0) break; xt_info_wrunlock(cpu); } local_bh_enable(); Loading Loading @@ -899,7 +902,9 @@ static int compat_calc_entry(const struct arpt_entry *e, static int compat_table_info(const struct xt_table_info *info, struct xt_table_info *newinfo) { struct arpt_entry *iter; void *loc_cpu_entry; int ret = 0; if (!newinfo || !info) return -EINVAL; Loading @@ -908,9 +913,12 @@ static int compat_table_info(const struct xt_table_info *info, memcpy(newinfo, info, offsetof(struct xt_table_info, entries)); newinfo->initial_entries = 0; loc_cpu_entry = info->entries[raw_smp_processor_id()]; return ARPT_ENTRY_ITERATE(loc_cpu_entry, info->size, compat_calc_entry, info, loc_cpu_entry, newinfo); xt_entry_foreach(iter, loc_cpu_entry, info->size) { ret = compat_calc_entry(iter, info, loc_cpu_entry, newinfo); if (ret != 0) break; } return ret; } #endif Loading Loading @@ -1025,6 +1033,7 @@ static int __do_replace(struct net *net, const char *name, struct xt_table_info *oldinfo; struct xt_counters *counters; void *loc_cpu_old_entry; struct arpt_entry *iter; ret = 0; counters = vmalloc_node(num_counters * sizeof(struct xt_counters), Loading Loading @@ -1068,8 +1077,9 @@ static int __do_replace(struct net *net, const char *name, /* Decrease module usage counts and free resource */ loc_cpu_old_entry = oldinfo->entries[raw_smp_processor_id()]; ARPT_ENTRY_ITERATE(loc_cpu_old_entry, oldinfo->size, cleanup_entry, NULL); xt_entry_foreach(iter, loc_cpu_old_entry, oldinfo->size) if (cleanup_entry(iter, NULL) != 0) break; xt_free_table_info(oldinfo); if (copy_to_user(counters_ptr, counters, Loading @@ -1095,6 +1105,7 @@ static int do_replace(struct net *net, const void __user *user, struct arpt_replace tmp; struct xt_table_info *newinfo; void *loc_cpu_entry; struct arpt_entry *iter; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) return -EFAULT; Loading Loading @@ -1130,7 +1141,9 @@ static int do_replace(struct net *net, const void __user *user, return 0; free_newinfo_untrans: ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) if (cleanup_entry(iter, NULL) != 0) break; free_newinfo: xt_free_table_info(newinfo); return ret; Loading Loading @@ -1163,6 +1176,7 @@ static int do_add_counters(struct net *net, const void __user *user, const struct xt_table_info *private; int ret = 0; void *loc_cpu_entry; struct arpt_entry *iter; #ifdef CONFIG_COMPAT struct compat_xt_counters_info compat_tmp; Loading Loading @@ -1220,11 +1234,9 @@ static int do_add_counters(struct net *net, const void __user *user, curcpu = smp_processor_id(); loc_cpu_entry = private->entries[curcpu]; xt_info_wrlock(curcpu); ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, add_counter_to_entry, paddc, &i); xt_entry_foreach(iter, loc_cpu_entry, private->size) if (add_counter_to_entry(iter, paddc, &i) != 0) break; xt_info_wrunlock(curcpu); unlock_up_free: local_bh_enable(); Loading Loading @@ -1388,8 +1400,10 @@ static int translate_compat_table(const char *name, unsigned int i, j; struct xt_table_info *newinfo, *info; void *pos, *entry0, *entry1; struct compat_arpt_entry *iter0; struct arpt_entry *iter1; unsigned int size; int ret; int ret = 0; info = *pinfo; entry0 = *pentry0; Loading @@ -1406,11 +1420,13 @@ static int translate_compat_table(const char *name, j = 0; xt_compat_lock(NFPROTO_ARP); /* Walk through entries, checking offsets. */ ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, check_compat_entry_size_and_hooks, info, &size, entry0, entry0 + total_size, hook_entries, underflows, &j, name); xt_entry_foreach(iter0, entry0, total_size) { ret = check_compat_entry_size_and_hooks(iter0, info, &size, entry0, entry0 + total_size, hook_entries, underflows, &j, name); if (ret != 0) break; } if (ret != 0) goto out_unlock; Loading Loading @@ -1451,9 +1467,12 @@ static int translate_compat_table(const char *name, entry1 = newinfo->entries[raw_smp_processor_id()]; pos = entry1; size = total_size; ret = COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_copy_entry_from_user, &pos, &size, name, newinfo, entry1); xt_entry_foreach(iter0, entry0, total_size) { ret = compat_copy_entry_from_user(iter0, &pos, &size, name, newinfo, entry1); if (ret != 0) break; } xt_compat_flush_offsets(NFPROTO_ARP); xt_compat_unlock(NFPROTO_ARP); if (ret) Loading @@ -1464,13 +1483,28 @@ static int translate_compat_table(const char *name, goto free_newinfo; i = 0; ret = ARPT_ENTRY_ITERATE(entry1, newinfo->size, compat_check_entry, name, &i); xt_entry_foreach(iter1, entry1, newinfo->size) { ret = compat_check_entry(iter1, name, &i); if (ret != 0) break; } if (ret) { /* * The first i matches need cleanup_entry (calls ->destroy) * because they had called ->check already. The other j-i * entries need only release. */ int skip = i; j -= i; COMPAT_ARPT_ENTRY_ITERATE_CONTINUE(entry0, newinfo->size, i, compat_release_entry, &j); ARPT_ENTRY_ITERATE(entry1, newinfo->size, cleanup_entry, &i); xt_entry_foreach(iter0, entry0, newinfo->size) { if (skip-- > 0) continue; if (compat_release_entry(iter0, &j) != 0) break; } xt_entry_foreach(iter1, entry1, newinfo->size) if (cleanup_entry(iter1, &i) != 0) break; xt_free_table_info(newinfo); return ret; } Loading @@ -1488,7 +1522,9 @@ static int translate_compat_table(const char *name, free_newinfo: xt_free_table_info(newinfo); out: COMPAT_ARPT_ENTRY_ITERATE(entry0, total_size, compat_release_entry, &j); xt_entry_foreach(iter0, entry0, total_size) if (compat_release_entry(iter0, &j) != 0) break; return ret; out_unlock: xt_compat_flush_offsets(NFPROTO_ARP); Loading @@ -1515,6 +1551,7 @@ static int compat_do_replace(struct net *net, void __user *user, struct compat_arpt_replace tmp; struct xt_table_info *newinfo; void *loc_cpu_entry; struct arpt_entry *iter; if (copy_from_user(&tmp, user, sizeof(tmp)) != 0) return -EFAULT; Loading Loading @@ -1552,7 +1589,9 @@ static int compat_do_replace(struct net *net, void __user *user, return 0; free_newinfo_untrans: ARPT_ENTRY_ITERATE(loc_cpu_entry, newinfo->size, cleanup_entry, NULL); xt_entry_foreach(iter, loc_cpu_entry, newinfo->size) if (cleanup_entry(iter, NULL) != 0) break; free_newinfo: xt_free_table_info(newinfo); return ret; Loading Loading @@ -1636,6 +1675,7 @@ static int compat_copy_entries_to_user(unsigned int total_size, int ret = 0; void *loc_cpu_entry; unsigned int i = 0; struct arpt_entry *iter; counters = alloc_counters(table); if (IS_ERR(counters)) Loading @@ -1645,9 +1685,12 @@ static int compat_copy_entries_to_user(unsigned int total_size, loc_cpu_entry = private->entries[raw_smp_processor_id()]; pos = userptr; size = total_size; ret = ARPT_ENTRY_ITERATE(loc_cpu_entry, total_size, compat_copy_entry_to_user, &pos, &size, counters, &i); xt_entry_foreach(iter, loc_cpu_entry, total_size) { ret = compat_copy_entry_to_user(iter, &pos, &size, counters, &i); if (ret != 0) break; } vfree(counters); return ret; } Loading Loading @@ -1843,13 +1886,15 @@ void arpt_unregister_table(struct xt_table *table) struct xt_table_info *private; void *loc_cpu_entry; struct module *table_owner = table->me; struct arpt_entry *iter; private = xt_unregister_table(table); /* Decrease module usage counts and free resources */ loc_cpu_entry = private->entries[raw_smp_processor_id()]; ARPT_ENTRY_ITERATE(loc_cpu_entry, private->size, cleanup_entry, NULL); xt_entry_foreach(iter, loc_cpu_entry, private->size) if (cleanup_entry(iter, NULL) != 0) break; if (private->number > private->initial_entries) module_put(table_owner); xt_free_table_info(private); Loading