blob: 17dc1e9ca2ce8fbe1008ad0018a5d94b30705a0c [file] [log] [blame]
From f09a77d4fb46651e4ea38e7b1843aa92f8d41c27 Mon Sep 17 00:00:00 2001
From: Thomas Gleixner <tglx@linutronix.de>
Date: Tue, 27 Apr 2010 10:05:28 +0200
Subject: [PATCH] net: Fix iptables get_counters()
commit 863c3ad87b10617464fc52c21fc7e31987910559 in tip.
The preempt-rt changes to iptables get_counters() left the counters
array uninitialized which results in random packet statistic numbers.
Reported-by: prd.gtt@operamail.com
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
diff --git a/net/ipv4/netfilter/ip_tables.c b/net/ipv4/netfilter/ip_tables.c
index 1c33431..5f6042e 100644
--- a/net/ipv4/netfilter/ip_tables.c
+++ b/net/ipv4/netfilter/ip_tables.c
@@ -906,7 +906,7 @@ get_counters(const struct xt_table_info *t,
struct ipt_entry *iter;
unsigned int cpu;
unsigned int i;
- unsigned int curcpu = NR_CPUS;
+ unsigned int curcpu;
/* Instead of clearing (by a previous call to memset())
* the counters and using adds, we set the counters
@@ -916,16 +916,17 @@ get_counters(const struct xt_table_info *t,
* if new softirq were to run and call ipt_do_table
*/
local_bh_disable();
-#ifndef CONFIG_PREEMPT_RT
- curcpu = smp_processor_id();
+ curcpu = raw_smp_processor_id();
i = 0;
+ xt_info_wrlock(curcpu);
xt_entry_foreach(iter, t->entries[curcpu], t->size) {
SET_COUNTER(counters[i], iter->counters.bcnt,
iter->counters.pcnt);
++i;
}
-#endif
+ xt_info_wrunlock(curcpu);
+
for_each_possible_cpu(cpu) {
if (cpu == curcpu)
continue;
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index 6d5b78b..ff7ce7b 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -936,7 +936,7 @@ get_counters(const struct xt_table_info *t,
struct ip6t_entry *iter;
unsigned int cpu;
unsigned int i;
- unsigned int curcpu = NR_CPUS;
+ unsigned int curcpu;
/* Instead of clearing (by a previous call to memset())
* the counters and using adds, we set the counters
@@ -946,17 +946,17 @@ get_counters(const struct xt_table_info *t,
* if new softirq were to run and call ipt_do_table
*/
local_bh_disable();
-
-#ifndef CONFIG_PREEMPT_RT
- curcpu = smp_processor_id();
+ curcpu = raw_smp_processor_id();
i = 0;
+ xt_info_wrlock(curcpu);
xt_entry_foreach(iter, t->entries[curcpu], t->size) {
SET_COUNTER(counters[i], iter->counters.bcnt,
iter->counters.pcnt);
++i;
}
-#endif
+ xt_info_wrunlock(curcpu);
+
for_each_possible_cpu(cpu) {
if (cpu == curcpu)
continue;
--
1.7.1.1