[ovs-dev] [PATCH 1/2] ofctrl: Refine treatment of duplicate flows in ofctrl_add_flow().
Ben Pfaff
blp at ovn.org
Wed Jul 20 00:07:34 UTC 2016
It's better to use the newer actions, in cases where the actions for
duplicate flows differ, because on balance they are more likely to be
correct.
Signed-off-by: Ben Pfaff <blp at ovn.org>
---
ovn/controller/ofctrl.c | 48 +++++++++++++++++++++++++++++++++++++++++++-----
1 file changed, 43 insertions(+), 5 deletions(-)
diff --git a/ovn/controller/ofctrl.c b/ovn/controller/ofctrl.c
index d10dcc6..5b55597 100644
--- a/ovn/controller/ofctrl.c
+++ b/ovn/controller/ofctrl.c
@@ -509,6 +509,18 @@ ofctrl_recv(const struct ofp_header *oh, enum ofptype type)
/* Flow table interfaces to the rest of ovn-controller. */
+static void
+log_ovn_flow_rl(struct vlog_rate_limit *rl, enum vlog_level level,
+ const struct ovn_flow *flow, const char *title)
+{
+ if (!vlog_should_drop(&this_module, level, rl)) {
+ char *s = ovn_flow_to_string(flow);
+ vlog(&this_module, level, "%s for parent "UUID_FMT": %s",
+ title, UUID_ARGS(&flow->uuid), s);
+ free(s);
+ }
+}
+
/* Adds a flow to the collection associated with 'uuid'. The flow has the
* specified 'match' and 'actions' to the OpenFlow table numbered 'table_id'
* with the given 'priority'. The caller retains ownership of 'match' and
@@ -554,12 +566,38 @@ ofctrl_add_flow(uint8_t table_id, uint16_t priority,
struct ovn_flow *d;
LIST_FOR_EACH (d, list_node, &existing) {
if (uuid_equals(&f->uuid, &d->uuid)) {
- static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
- char *s = ovn_flow_to_string(f);
- VLOG_WARN_RL(&rl, "found duplicate flow %s for parent "UUID_FMT,
- s, UUID_ARGS(&f->uuid));
+ /* Duplicate flows with the same UUID indicate some kind of bug
+ * (see the function-level comment), but we distinguish two
+ * cases:
+ *
+ * - If the actions for the duplicate flow are the same, then
+ * it's benign; it's hard to imagine how there could be a
+ * real problem. Log at INFO level.
+ *
+ * - If the actions are different, then one or the other set of
+ * actions must be wrong or (perhaps more likely) we've got a
+ * new set of actions replacing an old set but the caller
+ * neglected to use ofctrl_remove_flows() or
+ * ofctrl_set_flow() to do it properly. Log at WARN level to
+ * get some attention.
+ */
+ if (ofpacts_equal(f->ofpacts, f->ofpacts_len,
+ d->ofpacts, d->ofpacts_len)) {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
+ log_ovn_flow_rl(&rl, VLL_INFO, f, "duplicate flow");
+ } else {
+ static struct vlog_rate_limit rl = VLOG_RATE_LIMIT_INIT(5, 1);
+ log_ovn_flow_rl(&rl, VLL_WARN, f,
+ "duplicate flow with modified action");
+
+ /* It seems likely that the newer actions are the correct
+ * ones. */
+ free(d->ofpacts);
+ d->ofpacts = f->ofpacts;
+ d->ofpacts_len = f->ofpacts_len;
+ f->ofpacts = NULL;
+ }
ovn_flow_destroy(f);
- free(s);
return;
}
}
--
2.1.3
More information about the dev
mailing list