Signed-off-by: Jarno Rajahalme <jrajaha...@nicira.com>
---
 ofproto/bundles.c |   40 ++++-----
 ofproto/bundles.h |   21 +++--
 ofproto/ofproto.c |  235 +++++++++++++++++++++++++++++++++++++++++++++++++++--
 tests/ofproto.at  |   66 +++++++--------
 4 files changed, 293 insertions(+), 69 deletions(-)

diff --git a/ofproto/bundles.c b/ofproto/bundles.c
index ebf8f7f..9f125a5 100644
--- a/ofproto/bundles.c
+++ b/ofproto/bundles.c
@@ -121,31 +121,6 @@ ofp_bundle_close(struct ofconn *ofconn, uint32_t id, 
uint16_t flags)
 }
 
 enum ofperr
-ofp_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags)
-{
-    struct ofp_bundle *bundle;
-    enum ofperr error = 0;
-    struct ofp_bundle_entry *msg;
-
-    bundle = ofconn_get_bundle(ofconn, id);
-
-    if (!bundle) {
-        return OFPERR_OFPBFC_BAD_ID;
-    }
-    if (bundle->flags != flags) {
-        error = OFPERR_OFPBFC_BAD_FLAGS;
-    } else {
-        LIST_FOR_EACH (msg, node, &bundle->msg_list) {
-            /* XXX: actual commit */
-            error = OFPERR_OFPBFC_MSG_FAILED;
-        }
-    }
-
-    ofp_bundle_remove__(ofconn, bundle);
-    return error;
-}
-
-enum ofperr
 ofp_bundle_discard(struct ofconn *ofconn, uint32_t id)
 {
     struct ofp_bundle *bundle;
@@ -161,6 +136,14 @@ ofp_bundle_discard(struct ofconn *ofconn, uint32_t id)
     return 0;
 }
 
+/* Bundle conflicts.  A new message being added into the bundle is deemed to be
+ * in conflict, if it would delete or modify a flow or a port that was added or
+ * modified by an earlier message in the bundle.
+ *
+ * We check for this at the bundle add time, and rely on the messages not being
+ * in conflict at the bundle commit time.  This simplifies the state management
+ * requirements for rolling back failing commits.
+ */
 enum ofperr
 ofp_bundle_add_message(struct ofconn *ofconn, uint32_t id, uint16_t flags,
                        struct ofp_bundle_entry *bmsg)
@@ -186,6 +169,13 @@ ofp_bundle_add_message(struct ofconn *ofconn, uint32_t id, 
uint16_t flags,
         return OFPERR_OFPBFC_BAD_FLAGS;
     }
 
+    /* Check for conflicts. */
+
+    /* The spec says to return OFPBFC_MSG_CONFLICT when processing the
+     * BUNDLE_ADD, but with big bundles that may be very expensive.  It may be
+     * a lot cheaper to check that mods/deletes do not target any of the rules
+     * added/modded by the current bundle at the commit time. */
+
     list_push_back(&bundle->msg_list, &bmsg->node);
     return 0;
 }
diff --git a/ofproto/bundles.h b/ofproto/bundles.h
index 353a893..7dbfae0 100644
--- a/ofproto/bundles.h
+++ b/ofproto/bundles.h
@@ -24,6 +24,8 @@
 #include "connmgr.h"
 #include "ofp-msgs.h"
 #include "ofp-util.h"
+#include "ofproto-provider.h"
+#include "util.h"
 
 #ifdef  __cplusplus
 extern "C" {
@@ -31,13 +33,20 @@ extern "C" {
 
 struct ofp_bundle_entry {
     struct ovs_list   node;
-    ovs_be32          xid;   /* For error returns. */
     enum ofptype      type;
     union {
         struct ofputil_flow_mod fm;
         struct ofputil_port_mod pm;
     };
     struct ofpbuf ofpacts;
+
+    /* Used during commit. */
+    struct rule_collection rules;   /* Affected rules. */
+    struct rule *rule;
+    bool modify;
+
+    /* OpenFlow header and some of the message contents for error reporting. */
+    struct ofp_header ofp_msg[DIV_ROUND_UP(64, sizeof(struct ofp_header))];
     uint64_t ofpacts_stub[1024 / 8];
 };
 
@@ -57,12 +66,11 @@ struct ofp_bundle {
 };
 
 static inline struct ofp_bundle_entry *ofp_bundle_entry_alloc(
-    enum ofptype type, ovs_be32 xid);
+    enum ofptype type, const struct ofp_header *oh);
 static inline void ofp_bundle_entry_free(struct ofp_bundle_entry *);
 
 enum ofperr ofp_bundle_open(struct ofconn *, uint32_t id, uint16_t flags);
 enum ofperr ofp_bundle_close(struct ofconn *, uint32_t id, uint16_t flags);
-enum ofperr ofp_bundle_commit(struct ofconn *, uint32_t id, uint16_t flags);
 enum ofperr ofp_bundle_discard(struct ofconn *, uint32_t id);
 enum ofperr ofp_bundle_add_message(struct ofconn *, uint32_t id,
                                    uint16_t flags, struct ofp_bundle_entry *);
@@ -70,19 +78,20 @@ enum ofperr ofp_bundle_add_message(struct ofconn *, 
uint32_t id,
 void ofp_bundle_remove__(struct ofconn *ofconn, struct ofp_bundle *bundle);
 
 static inline struct ofp_bundle_entry *
-ofp_bundle_entry_alloc(enum ofptype type, ovs_be32 xid)
+ofp_bundle_entry_alloc(enum ofptype type, const struct ofp_header *oh)
 {
     struct ofp_bundle_entry *entry = xmalloc(sizeof *entry);
 
     ofpbuf_use_stub(&entry->ofpacts, entry->ofpacts_stub,
                     sizeof entry->ofpacts_stub);
-    entry->xid = xid;
     entry->type = type;
 
+    memcpy(entry->ofp_msg, oh, MAX(ntohs(oh->length), 64));
     return entry;
 }
 
-static inline void ofp_bundle_entry_free(struct ofp_bundle_entry *entry)
+static inline void
+ofp_bundle_entry_free(struct ofp_bundle_entry *entry)
 {
     if (entry) {
         ofpbuf_uninit(&entry->ofpacts);
diff --git a/ofproto/ofproto.c b/ofproto/ofproto.c
index 03b6551..5204875 100644
--- a/ofproto/ofproto.c
+++ b/ofproto/ofproto.c
@@ -4389,7 +4389,8 @@ add_flow_begin(struct ofproto *ofproto, struct 
ofputil_flow_mod *fm,
 
     cls_rule_init(&cr, &fm->match, fm->priority);
 
-    /* Check for the existence of an identical rule. */
+    /* Check for the existence of an identical rule.
+     * This will not return rules earlier marked as 'to_be_removed'. */
     rule = rule_from_cls_rule(classifier_find_rule_exactly(&table->cls, &cr));
     if (rule) {
         /* Transform "add" into "modify" of an existing identical flow. */
@@ -4451,6 +4452,27 @@ add_flow_begin(struct ofproto *ofproto, struct 
ofputil_flow_mod *fm,
     return 0;
 }
 
+/* Revert the effects of add_flow_begin().
+ * 'new_rule' must be passed in as NULL, if no new rule was allocated and
+ * inserted to the classifier.
+ * Note: evictions cannot be reverted. */
+static void
+add_flow_revert(struct ofproto *ofproto, struct rule *new_rule)
+    OVS_REQUIRES(ofproto_mutex)
+{
+    /* Old rule was not changed yet, only need to revert a new rule. */
+    if (new_rule) {
+        struct oftable *table = &ofproto->tables[new_rule->table_id];
+
+        ovs_assert(classifier_remove(&table->cls, &new_rule->cr));
+        classifier_publish(&table->cls);
+
+        ofproto_rule_remove__(ofproto, new_rule);
+        ofproto->ofproto_class->rule_delete(new_rule);
+        ofproto_rule_unref(new_rule);
+    }
+}
+
 static void
 add_flow_finish(struct ofproto *ofproto, struct ofputil_flow_mod *fm,
                 const struct flow_mod_requester *req,
@@ -4750,6 +4772,17 @@ modify_flows_begin_loose(struct ofproto *ofproto, struct 
ofputil_flow_mod *fm,
 }
 
 static void
+modify_flows_revert(struct ofproto *ofproto, struct rule_collection *rules)
+    OVS_REQUIRES(ofproto_mutex)
+{
+    /* Old rules were not changed yet, only need to revert a new rule. */
+    if (rules->n == 0 && rules->rules[0] != NULL) {
+        add_flow_revert(ofproto, rules->rules[0]);
+    }
+    rule_collection_destroy(rules);
+}
+
+static void
 modify_flows_finish(struct ofproto *ofproto, struct ofputil_flow_mod *fm,
                     const struct flow_mod_requester *req,
                     struct rule_collection *rules)
@@ -4901,6 +4934,18 @@ delete_flows_begin_loose(struct ofproto *ofproto,
 }
 
 static void
+delete_flows_revert(struct rule_collection *rules)
+    OVS_REQUIRES(ofproto_mutex)
+{
+    for (size_t i = 0; i < rules->n; i++) {
+        struct rule *rule = rules->rules[i];
+
+        CONST_CAST(struct cls_rule *, &rule->cr)->to_be_removed = false;
+    }
+    rule_collection_destroy(rules);
+}
+
+static void
 delete_flows_finish(const struct ofputil_flow_mod *fm,
                     const struct flow_mod_requester *req,
                     struct rule_collection *rules)
@@ -6497,12 +6542,188 @@ handle_table_mod(struct ofconn *ofconn, const struct 
ofp_header *oh)
 }
 
 static enum ofperr
-handle_bundle_control(struct ofconn *ofconn, const struct ofp_header *oh)
+do_bundle_flow_mod_begin(struct ofproto *ofproto, struct ofputil_flow_mod *fm,
+                         struct ofp_bundle_entry *be)
+    OVS_REQUIRES(ofproto_mutex)
+{
+    enum ofperr error;
+
+    switch (fm->command) {
+    case OFPFC_ADD:
+        error = add_flow_begin(ofproto, fm, &be->rule, &be->modify);
+        break;
+
+    case OFPFC_MODIFY:
+        error = modify_flows_begin_loose(ofproto, fm, &be->rules);
+        break;
+
+    case OFPFC_MODIFY_STRICT:
+        error = modify_flow_begin_strict(ofproto, fm, &be->rules);
+        break;
+
+    case OFPFC_DELETE:
+        error = delete_flows_begin_loose(ofproto, fm, &be->rules);
+        break;
+
+    case OFPFC_DELETE_STRICT:
+        error = delete_flow_begin_strict(ofproto, fm, &be->rules);
+        break;
+
+    default:
+        if (fm->command > 0xff) {
+            VLOG_WARN_RL(&rl, "%s: flow_mod has explicit table_id but "
+                         "flow_mod_table_id extension is not enabled",
+                         ofproto->name);
+        }
+        error = OFPERR_OFPFMFC_BAD_COMMAND;
+        break;
+    }
+
+    return error;
+}
+
+static void
+do_bundle_flow_mod_revert(struct ofproto *ofproto, struct ofputil_flow_mod *fm,
+                          struct ofp_bundle_entry *be)
+    OVS_REQUIRES(ofproto_mutex)
+{
+    switch (fm->command) {
+    case OFPFC_ADD:
+        add_flow_revert(ofproto, be->modify ? NULL : be->rule);
+        break;
+
+    case OFPFC_MODIFY:
+    case OFPFC_MODIFY_STRICT:
+        modify_flows_revert(ofproto, &be->rules);
+        break;
+
+    case OFPFC_DELETE:
+    case OFPFC_DELETE_STRICT:
+        delete_flows_revert(&be->rules);
+        break;
+
+    default:
+        break;
+    }
+}
+
+static void
+do_bundle_flow_mod_finish(struct ofproto *ofproto, struct ofputil_flow_mod *fm,
+                          const struct flow_mod_requester *req,
+                          struct ofp_bundle_entry *be)
+    OVS_REQUIRES(ofproto_mutex)
+{
+    switch (fm->command) {
+    case OFPFC_ADD:
+        add_flow_finish(ofproto, fm, req, be->rule, be->modify);
+        break;
+
+    case OFPFC_MODIFY:
+    case OFPFC_MODIFY_STRICT:
+        modify_flows_finish(ofproto, fm, req, &be->rules);
+        break;
+
+    case OFPFC_DELETE:
+    case OFPFC_DELETE_STRICT:
+        delete_flows_finish(fm, req, &be->rules);
+        break;
+
+    default:
+        break;
+    }
+}
+
+/* Commit phases (all while locking ofproto_mutex):
+ *
+ * 1. Gather resources - do not send any events or notifications.
+ *
+ * add: Check conflicts, check for a displaced flow. If no displaced flow
+ *      exists, add the new flow, but mark it as "invisible".
+ * mod: Collect affected flows, Do not modify yet.
+ * del: Collect affected flows, Do not delete yet.
+ *
+ * 2a. Fail if any errors are found.  After this point no errors are possible.
+ * No visible changes were made, so rollback is minimal (remove added invisible
+ * flows, revert 'to_be_removed' status of flows).
+ *
+ * 2b. Commit the changes
+ *
+ * add: if have displaced flow, modify it, otherwise mark the new flow as
+ *      "visible".
+ * mod: Modify the collected flows.
+ * del: Delete the collected flows.
+ */
+static enum ofperr
+do_bundle_commit(struct ofconn *ofconn, uint32_t id, uint16_t flags)
 {
+    struct ofproto *ofproto = ofconn_get_ofproto(ofconn);
+    struct ofp_bundle *bundle;
+    struct ofp_bundle_entry *be;
     enum ofperr error;
+
+    bundle = ofconn_get_bundle(ofconn, id);
+
+    if (!bundle) {
+        return OFPERR_OFPBFC_BAD_ID;
+    }
+    if (bundle->flags != flags) {
+        error = OFPERR_OFPBFC_BAD_FLAGS;
+    } else {
+        error = 0;
+        ovs_mutex_lock(&ofproto_mutex);
+        LIST_FOR_EACH (be, node, &bundle->msg_list) {
+            if (be->type == OFPTYPE_PORT_MOD) {
+                /* Not supported yet. */
+                error = OFPERR_OFPBFC_MSG_FAILED;
+            } else if (be->type == OFPTYPE_FLOW_MOD) {
+                error = do_bundle_flow_mod_begin(ofproto, &be->fm, be);
+            } else {
+                OVS_NOT_REACHED();
+            }
+            if (error) {
+                break;
+            }
+        }
+        if (error) {
+            /* Send error referring to the original message. */
+            if (error) {
+                ofconn_send_error(ofconn, be->ofp_msg, error);
+                error = OFPERR_OFPBFC_MSG_FAILED;
+            }
+
+            /* Revert all previous entires. */
+            LIST_FOR_EACH_REVERSE_CONTINUE(be, node, &bundle->msg_list) {
+                if (be->type == OFPTYPE_FLOW_MOD) {
+                    do_bundle_flow_mod_revert(ofproto, &be->fm, be);
+                }
+            }
+        } else {
+            /* Finish the changes. */
+            LIST_FOR_EACH (be, node, &bundle->msg_list) {
+                if (be->type == OFPTYPE_FLOW_MOD) {
+                    struct flow_mod_requester req = { ofconn, be->ofp_msg };
+
+                    do_bundle_flow_mod_finish(ofproto, &be->fm, &req, be);
+                }
+            }
+        }
+        ofmonitor_flush(ofproto->connmgr);
+        ovs_mutex_unlock(&ofproto_mutex);
+
+        run_rule_executes(ofproto);
+    }
+    /* The bundle is discarded regardless the outcome. */
+    ofp_bundle_remove__(ofconn, bundle);
+    return error;
+}
+
+static enum ofperr
+handle_bundle_control(struct ofconn *ofconn, const struct ofp_header *oh)
+{
     struct ofputil_bundle_ctrl_msg bctrl;
-    struct ofpbuf *buf;
     struct ofputil_bundle_ctrl_msg reply;
+    struct ofpbuf *buf;
+    enum ofperr error;
 
     error = reject_slave_controller(ofconn);
     if (error) {
@@ -6513,6 +6734,10 @@ handle_bundle_control(struct ofconn *ofconn, const 
struct ofp_header *oh)
     if (error) {
         return error;
     }
+    /* Atomic updates not supported yet. */
+    if (bctrl.flags & OFPBF_ATOMIC) {
+        return OFPERR_OFPBFC_BAD_FLAGS;
+    }
     reply.flags = 0;
     reply.bundle_id = bctrl.bundle_id;
 
@@ -6526,7 +6751,7 @@ handle_bundle_control(struct ofconn *ofconn, const struct 
ofp_header *oh)
         reply.type = OFPBCT_CLOSE_REPLY;;
         break;
     case OFPBCT_COMMIT_REQUEST:
-        error = ofp_bundle_commit(ofconn, bctrl.bundle_id, bctrl.flags);
+        error = do_bundle_commit(ofconn, bctrl.bundle_id, bctrl.flags);
         reply.type = OFPBCT_COMMIT_REPLY;
         break;
     case OFPBCT_DISCARD_REQUEST:
@@ -6568,7 +6793,7 @@ handle_bundle_add(struct ofconn *ofconn, const struct 
ofp_header *oh)
         return error;
     }
 
-    bmsg = ofp_bundle_entry_alloc(type, badd.msg->xid);
+    bmsg = ofp_bundle_entry_alloc(type, badd.msg);
 
     if (type == OFPTYPE_PORT_MOD) {
         error = ofputil_decode_port_mod(badd.msg, &bmsg->pm, false);
diff --git a/tests/ofproto.at b/tests/ofproto.at
index f4e5321..9729a7c 100644
--- a/tests/ofproto.at
+++ b/tests/ofproto.at
@@ -3227,13 +3227,13 @@ ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir 
--pidfile >monitor.log 2
 AT_CAPTURE_FILE([monitor.log])
 
 # Send an OpenFlow14 message (05), OFPT_BUNDLE_CONTROL (21), length (10), xid 
(0a)
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
 ovs-appctl -t ovs-ofctl exit
 
 AT_CHECK([ofctl_strip < monitor.log], [], [dnl
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=OPEN_REQUEST flags=atomic
+ bundle_id=0x1 type=OPEN_REQUEST flags=ordered
 OFPT_BUNDLE_CONTROL (OF1.4):
  bundle_id=0x1 type=OPEN_REPLY flags=0
 OFPT_BARRIER_REPLY (OF1.4):
@@ -3251,23 +3251,23 @@ ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir 
--pidfile >monitor.log 2
 AT_CAPTURE_FILE([monitor.log])
 
 # Send twice an OpenFlow14 message (05), OFPT_BUNDLE_CONTROL (21), length 
(10), xid (0a)
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
 ovs-appctl -t ovs-ofctl exit
 
 AT_CHECK([ofctl_strip < monitor.log], [0], [dnl
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=OPEN_REQUEST flags=atomic
+ bundle_id=0x1 type=OPEN_REQUEST flags=ordered
 OFPT_BUNDLE_CONTROL (OF1.4):
  bundle_id=0x1 type=OPEN_REPLY flags=0
 OFPT_BARRIER_REPLY (OF1.4):
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=OPEN_REQUEST flags=atomic
+ bundle_id=0x1 type=OPEN_REQUEST flags=ordered
 OFPT_ERROR (OF1.4): OFPBFC_BAD_ID
 OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=OPEN_REQUEST flags=atomic
+ bundle_id=0x1 type=OPEN_REQUEST flags=ordered
 OFPT_BARRIER_REPLY (OF1.4):
 ])
 
@@ -3282,16 +3282,16 @@ OVS_VSWITCHD_START
 ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir --pidfile >monitor.log 
2>&1
 AT_CAPTURE_FILE([monitor.log])
 
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 02 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 02 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
 ovs-appctl -t ovs-ofctl exit
 
 AT_CHECK([ofctl_strip < monitor.log], [0], [dnl
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=CLOSE_REQUEST flags=atomic
+ bundle_id=0x1 type=CLOSE_REQUEST flags=ordered
 OFPT_ERROR (OF1.4): OFPBFC_BAD_ID
 OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=CLOSE_REQUEST flags=atomic
+ bundle_id=0x1 type=CLOSE_REQUEST flags=ordered
 OFPT_BARRIER_REPLY (OF1.4):
 ])
 
@@ -3307,30 +3307,30 @@ ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir 
--pidfile >monitor.log 2
 AT_CAPTURE_FILE([monitor.log])
 
 # Open, Close, Close
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 02 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 02 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 02 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 02 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
 ovs-appctl -t ovs-ofctl exit
 
 AT_CHECK([ofctl_strip < monitor.log], [0], [dnl
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=OPEN_REQUEST flags=atomic
+ bundle_id=0x1 type=OPEN_REQUEST flags=ordered
 OFPT_BUNDLE_CONTROL (OF1.4):
  bundle_id=0x1 type=OPEN_REPLY flags=0
 OFPT_BARRIER_REPLY (OF1.4):
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=CLOSE_REQUEST flags=atomic
+ bundle_id=0x1 type=CLOSE_REQUEST flags=ordered
 OFPT_BUNDLE_CONTROL (OF1.4):
  bundle_id=0x1 type=CLOSE_REPLY flags=0
 OFPT_BARRIER_REPLY (OF1.4):
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=CLOSE_REQUEST flags=atomic
+ bundle_id=0x1 type=CLOSE_REQUEST flags=ordered
 OFPT_ERROR (OF1.4): OFPBFC_BUNDLE_CLOSED
 OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=CLOSE_REQUEST flags=atomic
+ bundle_id=0x1 type=CLOSE_REQUEST flags=ordered
 OFPT_BARRIER_REPLY (OF1.4):
 ])
 
@@ -3346,23 +3346,23 @@ ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir 
--pidfile >monitor.log 2
 AT_CAPTURE_FILE([monitor.log])
 
 # Open, Close, Close
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 02 
00 02"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 02 
00 01"
 ovs-appctl -t ovs-ofctl ofctl/barrier
 ovs-appctl -t ovs-ofctl exit
 
 AT_CHECK([ofctl_strip < monitor.log], [0], [dnl
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=OPEN_REQUEST flags=atomic
+ bundle_id=0x1 type=OPEN_REQUEST flags=ordered
 OFPT_BUNDLE_CONTROL (OF1.4):
  bundle_id=0x1 type=OPEN_REPLY flags=0
 OFPT_BARRIER_REPLY (OF1.4):
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=CLOSE_REQUEST flags=ordered
+ bundle_id=0x1 type=CLOSE_REQUEST flags=atomic
 OFPT_ERROR (OF1.4): OFPBFC_BAD_FLAGS
 OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=CLOSE_REQUEST flags=ordered
+ bundle_id=0x1 type=CLOSE_REQUEST flags=atomic
 OFPT_BARRIER_REPLY (OF1.4):
 ])
 
@@ -3378,16 +3378,16 @@ ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir 
--pidfile >monitor.log 2
 AT_CAPTURE_FILE([monitor.log])
 
 # Open, Close, Close
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 04 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 04 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
 ovs-appctl -t ovs-ofctl exit
 
 AT_CHECK([ofctl_strip < monitor.log], [0], [dnl
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=COMMIT_REQUEST flags=atomic
+ bundle_id=0x1 type=COMMIT_REQUEST flags=ordered
 OFPT_ERROR (OF1.4): OFPBFC_BAD_ID
 OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=COMMIT_REQUEST flags=atomic
+ bundle_id=0x1 type=COMMIT_REQUEST flags=ordered
 OFPT_BARRIER_REPLY (OF1.4):
 ])
 
@@ -3403,23 +3403,23 @@ ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir 
--pidfile >monitor.log 2
 AT_CAPTURE_FILE([monitor.log])
 
 # Open, Close, Close
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 00 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 04 
00 02"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 04 
00 01"
 ovs-appctl -t ovs-ofctl ofctl/barrier
 ovs-appctl -t ovs-ofctl exit
 
 AT_CHECK([ofctl_strip < monitor.log], [0], [dnl
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=OPEN_REQUEST flags=atomic
+ bundle_id=0x1 type=OPEN_REQUEST flags=ordered
 OFPT_BUNDLE_CONTROL (OF1.4):
  bundle_id=0x1 type=OPEN_REPLY flags=0
 OFPT_BARRIER_REPLY (OF1.4):
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=COMMIT_REQUEST flags=ordered
+ bundle_id=0x1 type=COMMIT_REQUEST flags=atomic
 OFPT_ERROR (OF1.4): OFPBFC_BAD_FLAGS
 OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=COMMIT_REQUEST flags=ordered
+ bundle_id=0x1 type=COMMIT_REQUEST flags=atomic
 OFPT_BARRIER_REPLY (OF1.4):
 ])
 
@@ -3435,16 +3435,16 @@ ovs-ofctl -O OpenFlow14 monitor br0 --detach --no-chdir 
--pidfile >monitor.log 2
 AT_CAPTURE_FILE([monitor.log])
 
 # Open, Close, Close
-ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 06 
00 01"
+ovs-appctl -t ovs-ofctl ofctl/send "05 21 00 10 00 00 00 0a 00 00 00 01 00 06 
00 02"
 ovs-appctl -t ovs-ofctl ofctl/barrier
 ovs-appctl -t ovs-ofctl exit
 
 AT_CHECK([ofctl_strip < monitor.log], [0], [dnl
 send: OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=DISCARD_REQUEST flags=atomic
+ bundle_id=0x1 type=DISCARD_REQUEST flags=ordered
 OFPT_ERROR (OF1.4): OFPBFC_BAD_ID
 OFPT_BUNDLE_CONTROL (OF1.4):
- bundle_id=0x1 type=DISCARD_REQUEST flags=atomic
+ bundle_id=0x1 type=DISCARD_REQUEST flags=ordered
 OFPT_BARRIER_REPLY (OF1.4):
 ])
 
-- 
1.7.10.4

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

Reply via email to