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