aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEthan Jackson <ethan@nicira.com>2013-04-06 15:22:14 -0700
committerEthan Jackson <ethan@nicira.com>2013-04-06 18:26:19 -0700
commit8fb7eddbcd1a487a883d6c3d96525a944b5a43f0 (patch)
treeee2f10507ae3eff80278085523a79b85a08fe8e6
parente7169719c9a6923654e098f72510fd54d249dcf2 (diff)
ofproto-dpif: Disable miss handling in rule_get_stats().
rule_get_stats() is often called when iterating over every rule in the flow table. To ensure up-to-date statistics, rule_get_stats() calls push_all_stats() which can cause flow misses to be handled. When using the learn action, this can cause rules to be added (and potentially removed) from the OpenFlow table. This could corrupt the caller's data structures, leading to a segmentation fault. This patch fixes the issue by disabling flow miss handling from within rule_get_stats(). Bug #15999. Signed-off-by: Ethan Jackson <ethan@nicira.com>
-rw-r--r--ofproto/ofproto-dpif.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index d535aadb..239f8d36 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -5109,7 +5109,7 @@ facet_push_stats(struct facet *facet)
}
static void
-push_all_stats(void)
+push_all_stats__(bool run_fast)
{
static long long int rl = LLONG_MIN;
struct ofproto_dpif *ofproto;
@@ -5123,7 +5123,9 @@ push_all_stats(void)
HMAP_FOR_EACH (facet, hmap_node, &ofproto->facets) {
facet_push_stats(facet);
- run_fast_rl();
+ if (run_fast) {
+ run_fast_rl();
+ }
}
}
@@ -5131,6 +5133,12 @@ push_all_stats(void)
}
static void
+push_all_stats(void)
+{
+ push_all_stats__(true);
+}
+
+static void
rule_credit_stats(struct rule_dpif *rule, const struct dpif_flow_stats *stats)
{
rule->packet_count += stats->n_packets;
@@ -5613,7 +5621,11 @@ rule_get_stats(struct rule *rule_, uint64_t *packets, uint64_t *bytes)
struct rule_dpif *rule = rule_dpif_cast(rule_);
struct facet *facet;
- push_all_stats();
+ /* push_all_stats() can handle flow misses which, when using the learn
+ * action, can cause rules to be added and deleted. This can corrupt our
+ * caller's datastructures which assume that rule_get_stats() doesn't have
+ * an impact on the flow table. To be safe, we disable miss handling. */
+ push_all_stats__(false);
/* Start from historical data for 'rule' itself that are no longer tracked
* in facets. This counts, for example, facets that have expired. */