A dpif reports EEXIST if a flow put operation that should create a new flow
instead attempts to modify an existing flow, or ENOENT if a flow put would
create a flow that overlaps some existing flow.  The latter does not always
indicate a bug in OVS userspace, because it can also mean that two
userspace OVS packet handler threads received packets that generated
the same megaflow for different microflows.  Until now, userspace has
logged this, which confuses users by making them suspect a bug.  We could
simply not log ENOENT in userspace, but that would suppress logging for
genuine bugs too.  Instead, this commit drops DPIF_FP_MODIFY from flow
put operations in ofproto-dpif, which transforms this particular
problem into EEXIST, which userspace already logs at "debug" level (see
flow_message_log_level()), effectively suppressing the logging in normal
circumstances.

It appears that in practice ofproto-dpif doesn't actually ever need to
modify flows in the datapath, only create and delete them, so this
shouldn't cause problems.

Suggested-by: Jesse Gross <je...@nicira.com>
Signed-off-by: Ben Pfaff <b...@nicira.com>
---
 ofproto/ofproto-dpif-upcall.c |    4 ++--
 ofproto/ofproto-dpif.c        |    4 ++--
 2 files changed, 4 insertions(+), 4 deletions(-)

diff --git a/ofproto/ofproto-dpif-upcall.c b/ofproto/ofproto-dpif-upcall.c
index 654fbd3..f456ec2 100644
--- a/ofproto/ofproto-dpif-upcall.c
+++ b/ofproto/ofproto-dpif-upcall.c
@@ -872,7 +872,7 @@ convert_upcall(struct udpif *udpif, struct upcall *upcall)
              * in the kernel. */
             VLOG_INFO_RL(&rl, "received packet on unassociated datapath "
                          "port %"PRIu32, odp_in_port);
-            dpif_flow_put(udpif->dpif, DPIF_FP_CREATE | DPIF_FP_MODIFY,
+            dpif_flow_put(udpif->dpif, DPIF_FP_CREATE,
                           dupcall->key, dupcall->key_len, NULL, 0, NULL, 0,
                           NULL);
         }
@@ -1012,7 +1012,7 @@ handle_upcalls(struct udpif *udpif, struct upcall 
*upcalls,
 
             op = &ops[n_ops++];
             op->type = DPIF_OP_FLOW_PUT;
-            op->u.flow_put.flags = DPIF_FP_CREATE | DPIF_FP_MODIFY;
+            op->u.flow_put.flags = DPIF_FP_CREATE;
             op->u.flow_put.key = upcall->key;
             op->u.flow_put.key_len = upcall->key_len;
             op->u.flow_put.mask = ofpbuf_data(&mask);
diff --git a/ofproto/ofproto-dpif.c b/ofproto/ofproto-dpif.c
index 980b04f..5ced9b5 100644
--- a/ofproto/ofproto-dpif.c
+++ b/ofproto/ofproto-dpif.c
@@ -962,7 +962,7 @@ check_recirc(struct dpif_backer *backer)
     ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
     odp_flow_key_from_flow(&key, &flow, NULL, 0, true);
 
-    error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE | DPIF_FP_MODIFY,
+    error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE,
                           ofpbuf_data(&key), ofpbuf_size(&key), NULL, 0, NULL,
                           0, NULL);
     if (error && error != EEXIST) {
@@ -1095,7 +1095,7 @@ check_max_mpls_depth(struct dpif_backer *backer)
         ofpbuf_use_stack(&key, &keybuf, sizeof keybuf);
         odp_flow_key_from_flow(&key, &flow, NULL, 0, false);
 
-        error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE | DPIF_FP_MODIFY,
+        error = dpif_flow_put(backer->dpif, DPIF_FP_CREATE,
                               ofpbuf_data(&key), ofpbuf_size(&key), NULL, 0, 
NULL, 0, NULL);
         if (error && error != EEXIST) {
             if (error != EINVAL) {
-- 
1.7.10.4

_______________________________________________
dev mailing list
dev@openvswitch.org
http://openvswitch.org/mailman/listinfo/dev

Reply via email to